changeset 14681:95ac792d396e icedtea-3.17.0pre02

Merge jdk8u272-b04
author Andrew John Hughes <gnu_andrew@member.fsf.org>
date Sat, 24 Oct 2020 01:11:51 +0100
parents 192857f897ff (current diff) 4d586f39fed3 (diff)
children 6c72dc4234b5
files .hgtags THIRD_PARTY_README make/Bundles.gmk make/CompileJavaClasses.gmk src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java src/share/classes/com/sun/jndi/ldap/LdapCtx.java src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java src/share/classes/com/sun/media/sound/AbstractMidiDevice.java src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/package.html src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/package.html src/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/package.html src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11.java src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/package.html src/share/classes/com/sun/org/apache/xml/internal/security/c14n/package.html src/share/classes/com/sun/org/apache/xml/internal/security/encryption/AbstractSerializer.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/AgreementMethod.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/CipherData.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/CipherReference.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/CipherValue.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/DocumentSerializer.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/EncryptedData.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/EncryptedKey.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/EncryptedType.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/EncryptionMethod.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/EncryptionProperties.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/EncryptionProperty.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/Reference.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/ReferenceList.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/Serializer.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/Transforms.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipher.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipherInput.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipherParameters.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLEncryptionException.java src/share/classes/com/sun/org/apache/xml/internal/security/encryption/package.html src/share/classes/com/sun/org/apache/xml/internal/security/exceptions/package.html src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/package.html src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/package.html src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/package.html src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/EncryptedKeyResolver.java src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/package.html src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/package.html src/share/classes/com/sun/org/apache/xml/internal/security/keys/package.html src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/package.html src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/package.html src/share/classes/com/sun/org/apache/xml/internal/security/package.html src/share/classes/com/sun/org/apache/xml/internal/security/resource/package.html src/share/classes/com/sun/org/apache/xml/internal/security/signature/Reference.java src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java src/share/classes/com/sun/org/apache/xml/internal/security/signature/package.html src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/package.html src/share/classes/com/sun/org/apache/xml/internal/security/transforms/package.html src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementChecker.java src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementCheckerImpl.java src/share/classes/com/sun/org/apache/xml/internal/security/utils/EncryptionElementProxy.java src/share/classes/com/sun/org/apache/xml/internal/security/utils/package.html src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/package.html src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/package.html src/share/classes/java/util/concurrent/ForkJoinPool.java src/share/classes/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java src/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java src/share/classes/sun/font/SunFontManager.java src/share/classes/sun/management/HotSpotDiagnostic.java src/share/classes/sun/nio/ch/Net.java src/share/classes/sun/security/krb5/Config.java src/share/classes/sun/security/rsa/RSAKeyPairGenerator.java src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java src/share/javavm/export/jmm.h src/share/lib/security/java.security-aix src/share/lib/security/java.security-linux src/share/lib/security/java.security-macosx src/share/lib/security/java.security-solaris src/share/lib/security/java.security-windows src/share/native/sun/font/freetypeScaler.c src/solaris/classes/sun/awt/X11/XIconWindow.java src/solaris/classes/sun/awt/X11/XToolkit.java src/solaris/native/java/net/ExtendedOptionsImpl.c src/solaris/native/sun/nio/ch/sctp/Sctp.h src/solaris/native/sun/nio/ch/sctp/SctpNet.c src/solaris/native/sun/xawt/XToolkit.c src/windows/native/java/net/Inet4AddressImpl.c src/windows/native/java/net/Inet6AddressImpl.c src/windows/native/java/net/SocketInputStream.c src/windows/native/sun/net/spi/DefaultProxySelector.c src/windows/native/sun/windows/awt_Window.cpp test/ProblemList.txt test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh test/java/awt/dnd/BadSerializaionTest/BadSerializationTest.java test/java/awt/dnd/BadSerializaionTest/badAction test/java/awt/dnd/BadSerializaionTest/good test/java/awt/dnd/BadSerializaionTest/noEvents test/java/awt/dnd/BadSerializaionTest/nullComponent test/java/awt/dnd/BadSerializaionTest/nullDragSource test/java/awt/dnd/BadSerializaionTest/nullOrigin test/java/nio/channels/AsynchronousSocketChannel/Basic.java
diffstat 630 files changed, 45861 insertions(+), 13507 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Oct 14 03:38:19 2020 +0100
+++ b/.hgtags	Sat Oct 24 01:11:51 2020 +0100
@@ -1119,7 +1119,16 @@
 7ea5c6fef715848a237323fc0e4f83b3dcd9d993 jdk8u262-b03
 63cecc0bd71d5226d7bdf81aeaa2e662dbad54c9 jdk8u262-b04
 4789a6a01301851b530fddbf7b0ce28f717f3de7 jdk8u262-b05
+4789a6a01301851b530fddbf7b0ce28f717f3de7 jdk8u272-b00
 097f47e7fe97b47dcb02603d9d592e1cba7f564e jdk8u262-b06
 745caf348aeec7b19f9f92ad283e3f8bd498dd02 jdk8u262-b07
 235d2e871a2ec6ddc97956caddd69f589a390649 jdk8u262-b08
 e36dcb7d407e9d4d739e03ce1dd2b641bd59ec30 jdk8u262-b09
+66699ff7f013e0a0bf93fc925e0a9cdcdd92801d jdk8u262-b10
+66699ff7f013e0a0bf93fc925e0a9cdcdd92801d jdk8u262-ga
+66699ff7f013e0a0bf93fc925e0a9cdcdd92801d jdk8u265-b00
+9204e03217f70fdbb3dd492eb687fbfb61ee0d5c jdk8u265-b01
+9204e03217f70fdbb3dd492eb687fbfb61ee0d5c jdk8u265-ga
+2f117c5839733a3c17bf3fe99080df94b809b899 jdk8u272-b01
+2b92a111b4bdb19ca4c55eac5d54f4a93bb980d1 jdk8u272-b02
+fb9d9cfd0523ac01c0619ff172dc9c4bd71f240f jdk8u272-b03
--- a/THIRD_PARTY_README	Wed Oct 14 03:38:19 2020 +0100
+++ b/THIRD_PARTY_README	Sat Oct 24 01:11:51 2020 +0100
@@ -3028,8 +3028,7 @@
   Apache Commons Math 3.2
   Apache Derby 10.11.1.2
   Apache Jakarta BCEL 5.1 
-  Apache Jakarta Regexp 1.4 
-  Apache Santuario XML Security for Java 1.5.4
+  Apache Santuario XML Security for Java 2.1.1
   Apache Xalan-Java 2.7.2
   Apache Xerces Java 2.10.0 
   Apache XML Resolver 1.1 
--- a/make/Bundles.gmk	Wed Oct 14 03:38:19 2020 +0100
+++ b/make/Bundles.gmk	Sat Oct 24 01:11:51 2020 +0100
@@ -89,16 +89,16 @@
 	if [ -d "$<" ]; then $(MKDIR) -p $@; else $(CP) -f -R -L '$<' '$@'; fi
 
   $(JDK_BUNDLE_DIR)/MacOS/libjli.dylib:
-	$(ECHO) Creating link $(patsubst $(OUTPUT_ROOT)/%,%,$@)
+	$(ECHO) Copying $(patsubst $(OUTPUT_ROOT)/%,%,$@)
 	$(MKDIR) -p $(@D)
 	$(RM) $@
-	$(LN) -s ../Home/jre/lib/jli/libjli.dylib $@
+	$(CP) $(JDK_IMAGE_DIR)/jre/lib/jli/libjli.dylib $@
 
   $(JRE_BUNDLE_DIR)/MacOS/libjli.dylib:
-	$(ECHO) Creating link $(patsubst $(OUTPUT_ROOT)/%,%,$@)
+	$(ECHO) Copying $(patsubst $(OUTPUT_ROOT)/%,%,$@)
 	$(MKDIR) -p $(@D)
 	$(RM) $@
-	$(LN) -s ../Home/lib/jli/libjli.dylib $@
+	$(CP) $(JRE_IMAGE_DIR)/lib/jli/libjli.dylib $@
 
   $(JDK_BUNDLE_DIR)/Info.plist: $(SPEC)
 	$(ECHO) Creating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
--- a/make/CompileJavaClasses.gmk	Wed Oct 14 03:38:19 2020 +0100
+++ b/make/CompileJavaClasses.gmk	Sat Oct 24 01:11:51 2020 +0100
@@ -304,6 +304,11 @@
       $(JDK_TOPDIR)/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java
 endif
 
+LINUX_SRC_DIRS :=
+ifeq ($(OPENJDK_TARGET_OS),linux)
+     LINUX_SRC_DIRS += $(JDK_TOPDIR)/src/linux/classes
+endif
+
 # The exception handling of swing beaninfo
 # These resources violates the convention of having code and resources together under
 # $(JDK_TOPDIR)/src/.../classes directories
@@ -329,6 +334,7 @@
         $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/classes \
         $(MACOSX_SRC_DIRS) \
         $(AIX_SRC_DIRS) \
+        $(LINUX_SRC_DIRS) \
         $(JDK_OUTPUTDIR)/gensrc \
         $(JDK_OUTPUTDIR)/gensrc_no_srczip \
         $(CLOSED_SRC_DIRS),\
--- a/make/mapfiles/libnet/mapfile-vers	Wed Oct 14 03:38:19 2020 +0100
+++ b/make/mapfiles/libnet/mapfile-vers	Sat Oct 24 01:11:51 2020 +0100
@@ -99,6 +99,13 @@
 		Java_sun_net_ExtendedOptionsImpl_setFlowOption;
 		Java_sun_net_ExtendedOptionsImpl_getFlowOption;
 		Java_sun_net_ExtendedOptionsImpl_flowSupported;
+		Java_sun_net_ExtendedOptionsImpl_keepAliveOptionsSupported;
+		Java_sun_net_ExtendedOptionsImpl_setTcpKeepAliveProbes;
+		Java_sun_net_ExtendedOptionsImpl_setTcpKeepAliveTime;
+		Java_sun_net_ExtendedOptionsImpl_setTcpKeepAliveIntvl;
+		Java_sun_net_ExtendedOptionsImpl_getTcpKeepAliveProbes;
+		Java_sun_net_ExtendedOptionsImpl_getTcpKeepAliveTime;
+		Java_sun_net_ExtendedOptionsImpl_getTcpKeepAliveIntvl;
 		NET_AllocSockaddr;
 		NET_SockaddrToInetAddress;
                 NET_SockaddrEqualsInetAddress;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/linux/classes/jdk/internal/platform/cgroupv1/Metrics.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,461 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 jdk.internal.platform.cgroupv1;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.stream.Stream;
+
+public class Metrics implements jdk.internal.platform.Metrics {
+    private SubSystem memory;
+    private SubSystem cpu;
+    private SubSystem cpuacct;
+    private SubSystem cpuset;
+    private SubSystem blkio;
+    private boolean activeSubSystems;
+
+    // Values returned larger than this number are unlimited.
+    static long unlimited_minimum = 0x7FFFFFFFFF000000L;
+
+    private static final Metrics INSTANCE = initContainerSubSystems();
+
+    private static final String PROVIDER_NAME = "cgroupv1";
+
+    private Metrics() {
+        activeSubSystems = false;
+    }
+
+    public static Metrics getInstance() {
+        return INSTANCE;
+    }
+
+    private static Metrics initContainerSubSystems() {
+        Metrics metrics = new Metrics();
+
+        /**
+         * Find the cgroup mount points for subsystems
+         * by reading /proc/self/mountinfo
+         *
+         * Example for docker MemorySubSystem subsystem:
+         * 219 214 0:29 /docker/7208cebd00fa5f2e342b1094f7bed87fa25661471a4637118e65f1c995be8a34 /sys/fs/cgroup/MemorySubSystem ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,MemorySubSystem
+         *
+         * Example for host:
+         * 34 28 0:29 / /sys/fs/cgroup/MemorySubSystem rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,MemorySubSystem
+         */
+        try (Stream<String> lines =
+             Files.lines(Paths.get("/proc/self/mountinfo"))) {
+
+            lines.filter(line -> line.contains(" - cgroup "))
+                 .map(line -> line.split(" "))
+                 .forEach(entry -> createSubSystem(metrics, entry));
+
+        } catch (IOException e) {
+            return null;
+        }
+
+        /**
+         * Read /proc/self/cgroup and map host mount point to
+         * local one via /proc/self/mountinfo content above
+         *
+         * Docker example:
+         * 5:memory:/docker/6558aed8fc662b194323ceab5b964f69cf36b3e8af877a14b80256e93aecb044
+         *
+         * Host example:
+         * 5:memory:/user.slice
+         *
+         * Construct a path to the process specific memory and cpuset
+         * cgroup directory.
+         *
+         * For a container running under Docker from memory example above
+         * the paths would be:
+         *
+         * /sys/fs/cgroup/memory
+         *
+         * For a Host from memory example above the path would be:
+         *
+         * /sys/fs/cgroup/memory/user.slice
+         *
+         */
+        try (Stream<String> lines =
+             Files.lines(Paths.get("/proc/self/cgroup"))) {
+
+            lines.map(line -> line.split(":"))
+                 .filter(line -> (line.length >= 3))
+                 .forEach(line -> setSubSystemPath(metrics, line));
+
+        } catch (IOException e) {
+            return null;
+        }
+
+        // Return Metrics object if we found any subsystems.
+        if (metrics.activeSubSystems()) {
+            return metrics;
+        }
+
+        return null;
+    }
+
+    /**
+     * createSubSystem objects and initialize mount points
+     */
+    private static void createSubSystem(Metrics metric, String [] mountentry) {
+        if (mountentry.length < 5) return;
+
+        Path p = Paths.get(mountentry[4]);
+        String subsystemName = p.getFileName().toString();
+
+        if (subsystemName != null) {
+            switch (subsystemName) {
+                case "memory":
+                    metric.setMemorySubSystem(new SubSystem(mountentry[3], mountentry[4]));
+                    break;
+                case "cpuset":
+                    metric.setCpuSetSubSystem(new SubSystem(mountentry[3], mountentry[4]));
+                    break;
+                case "cpu,cpuacct":
+                case "cpuacct,cpu":
+                    metric.setCpuSubSystem(new SubSystem(mountentry[3], mountentry[4]));
+                    metric.setCpuAcctSubSystem(new SubSystem(mountentry[3], mountentry[4]));
+                    break;
+                case "cpuacct":
+                    metric.setCpuAcctSubSystem(new SubSystem(mountentry[3], mountentry[4]));
+                    break;
+                case "cpu":
+                    metric.setCpuSubSystem(new SubSystem(mountentry[3], mountentry[4]));
+                    break;
+                case "blkio":
+                    metric.setBlkIOSubSystem(new SubSystem(mountentry[3], mountentry[4]));
+                    break;
+                default:
+                    // Ignore subsystems that we don't support
+                    break;
+            }
+        }
+    }
+
+    /**
+     * setSubSystemPath based on the contents of /proc/self/cgroup
+     */
+    private static void setSubSystemPath(Metrics metric, String [] entry) {
+        String controller;
+        String base;
+        SubSystem subsystem = null;
+        SubSystem subsystem2 = null;
+
+        controller = entry[1];
+        base = entry[2];
+        if (controller != null && base != null) {
+            switch (controller) {
+                case "memory":
+                    subsystem = metric.MemorySubSystem();
+                    break;
+                case "cpuset":
+                    subsystem = metric.CpuSetSubSystem();
+                    break;
+                case "cpu,cpuacct":
+                case "cpuacct,cpu":
+                    subsystem = metric.CpuSubSystem();
+                    subsystem2 = metric.CpuAcctSubSystem();
+                    break;
+                case "cpuacct":
+                    subsystem = metric.CpuAcctSubSystem();
+                    break;
+                case "cpu":
+                    subsystem = metric.CpuSubSystem();
+                    break;
+                case "blkio":
+                    subsystem = metric.BlkIOSubSystem();
+                    break;
+                // Ignore subsystems that we don't support
+                default:
+                    break;
+            }
+        }
+
+        if (subsystem != null) {
+            subsystem.setPath(base);
+            metric.setActiveSubSystems();
+        }
+        if (subsystem2 != null) {
+            subsystem2.setPath(base);
+        }
+    }
+
+
+    private void setActiveSubSystems() {
+        activeSubSystems = true;
+    }
+
+    private boolean activeSubSystems() {
+        return activeSubSystems;
+    }
+
+    private void setMemorySubSystem(SubSystem memory) {
+        this.memory = memory;
+    }
+
+    private void setCpuSubSystem(SubSystem cpu) {
+        this.cpu = cpu;
+    }
+
+    private void setCpuAcctSubSystem(SubSystem cpuacct) {
+        this.cpuacct = cpuacct;
+    }
+
+    private void setCpuSetSubSystem(SubSystem cpuset) {
+        this.cpuset = cpuset;
+    }
+
+    private void setBlkIOSubSystem(SubSystem blkio) {
+        this.blkio = blkio;
+    }
+
+    private SubSystem MemorySubSystem() {
+        return memory;
+    }
+
+    private SubSystem CpuSubSystem() {
+        return cpu;
+    }
+
+    private SubSystem CpuAcctSubSystem() {
+        return cpuacct;
+    }
+
+    private SubSystem CpuSetSubSystem() {
+        return cpuset;
+    }
+
+    private SubSystem BlkIOSubSystem() {
+        return blkio;
+    }
+
+    public String getProvider() {
+        return PROVIDER_NAME;
+    }
+
+    /*****************************************************************
+     * CPU Accounting Subsystem
+     ****************************************************************/
+
+
+    public long getCpuUsage() {
+        return SubSystem.getLongValue(cpuacct, "cpuacct.usage");
+    }
+
+    public long[] getPerCpuUsage() {
+        String usagelist = SubSystem.getStringValue(cpuacct, "cpuacct.usage_percpu");
+        if (usagelist == null) {
+            return new long[0];
+        }
+
+        String list[] = usagelist.split(" ");
+        long percpu[] = new long[list.length];
+        for (int i = 0; i < list.length; i++) {
+            percpu[i] = Long.parseLong(list[i]);
+        }
+        return percpu;
+    }
+
+    public long getCpuUserUsage() {
+        return SubSystem.getLongEntry(cpuacct, "cpuacct.stat", "user");
+    }
+
+    public long getCpuSystemUsage() {
+        return SubSystem.getLongEntry(cpuacct, "cpuacct.stat", "system");
+    }
+
+
+    /*****************************************************************
+     * CPU Subsystem
+     ****************************************************************/
+
+
+    public long getCpuPeriod() {
+        return SubSystem.getLongValue(cpuacct, "cpu.cfs_period_us");
+    }
+
+    public long getCpuQuota() {
+        return SubSystem.getLongValue(cpuacct, "cpu.cfs_quota_us");
+    }
+
+    public long getCpuShares() {
+        long retval = SubSystem.getLongValue(cpuacct, "cpu.shares");
+        if (retval == 0 || retval == 1024)
+            return -1;
+        else
+            return retval;
+    }
+
+    public long getCpuNumPeriods() {
+        return SubSystem.getLongEntry(cpuacct, "cpu.stat", "nr_periods");
+    }
+
+    public long getCpuNumThrottled() {
+        return SubSystem.getLongEntry(cpuacct, "cpu.stat", "nr_throttled");
+    }
+
+    public long getCpuThrottledTime() {
+        return SubSystem.getLongEntry(cpuacct, "cpu.stat", "throttled_time");
+    }
+
+    public long getEffectiveCpuCount() {
+        return Runtime.getRuntime().availableProcessors();
+    }
+
+
+    /*****************************************************************
+     * CPUSet Subsystem
+     ****************************************************************/
+
+    public int[] getCpuSetCpus() {
+        return SubSystem.StringRangeToIntArray(SubSystem.getStringValue(cpuset, "cpuset.cpus"));
+    }
+
+    public int[] getEffectiveCpuSetCpus() {
+        return SubSystem.StringRangeToIntArray(SubSystem.getStringValue(cpuset, "cpuset.effective_cpus"));
+    }
+
+    public int[] getCpuSetMems() {
+        return SubSystem.StringRangeToIntArray(SubSystem.getStringValue(cpuset, "cpuset.mems"));
+    }
+
+    public int[] getEffectiveCpuSetMems() {
+        return SubSystem.StringRangeToIntArray(SubSystem.getStringValue(cpuset, "cpuset.effective_mems"));
+    }
+
+    public double getCpuSetMemoryPressure() {
+        return SubSystem.getDoubleValue(cpuset, "cpuset.memory_pressure");
+    }
+
+    public boolean isCpuSetMemoryPressureEnabled() {
+        long val = SubSystem.getLongValue(cpuset, "cpuset.memory_pressure_enabled");
+        return (val == 1);
+    }
+
+
+    /*****************************************************************
+     * Memory Subsystem
+     ****************************************************************/
+
+
+    public long getMemoryFailCount() {
+        return SubSystem.getLongValue(memory, "memory.failcnt");
+    }
+
+    public long getMemoryLimit() {
+        long retval = SubSystem.getLongValue(memory, "memory.limit_in_bytes");
+        return retval > unlimited_minimum ? -1L : retval;
+    }
+
+    public long getMemoryMaxUsage() {
+        return SubSystem.getLongValue(memory, "memory.max_usage_in_bytes");
+    }
+
+    public long getMemoryUsage() {
+        return SubSystem.getLongValue(memory, "memory.usage_in_bytes");
+    }
+
+    public long getKernelMemoryFailCount() {
+        return SubSystem.getLongValue(memory, "memory.kmem.failcnt");
+    }
+
+    public long getKernelMemoryLimit() {
+        long retval = SubSystem.getLongValue(memory, "memory.kmem.limit_in_bytes");
+        return retval > unlimited_minimum ? -1L : retval;
+    }
+
+    public long getKernelMemoryMaxUsage() {
+        return SubSystem.getLongValue(memory, "memory.kmem.max_usage_in_bytes");
+    }
+
+    public long getKernelMemoryUsage() {
+        return SubSystem.getLongValue(memory, "memory.kmem.usage_in_bytes");
+    }
+
+    public long getTcpMemoryFailCount() {
+        return SubSystem.getLongValue(memory, "memory.kmem.tcp.failcnt");
+    }
+
+    public long getTcpMemoryLimit() {
+        long retval =  SubSystem.getLongValue(memory, "memory.kmem.tcp.limit_in_bytes");
+        return retval > unlimited_minimum ? -1L : retval;
+    }
+
+    public long getTcpMemoryMaxUsage() {
+        return SubSystem.getLongValue(memory, "memory.kmem.tcp.max_usage_in_bytes");
+    }
+
+    public long getTcpMemoryUsage() {
+        return SubSystem.getLongValue(memory, "memory.kmem.tcp.usage_in_bytes");
+    }
+
+    public long getMemoryAndSwapFailCount() {
+        return SubSystem.getLongValue(memory, "memory.memsw.failcnt");
+    }
+
+    public long getMemoryAndSwapLimit() {
+        long retval = SubSystem.getLongValue(memory, "memory.memsw.limit_in_bytes");
+        return retval > unlimited_minimum ? -1L : retval;
+    }
+
+    public long getMemoryAndSwapMaxUsage() {
+        return SubSystem.getLongValue(memory, "memory.memsw.max_usage_in_bytes");
+    }
+
+    public long getMemoryAndSwapUsage() {
+        return SubSystem.getLongValue(memory, "memory.memsw.usage_in_bytes");
+    }
+
+    public boolean isMemoryOOMKillEnabled() {
+        long val = SubSystem.getLongEntry(memory, "memory.oom_control", "oom_kill_disable");
+        return (val == 0);
+    }
+
+    public long getMemorySoftLimit() {
+        long retval = SubSystem.getLongValue(memory, "memory.soft_limit_in_bytes");
+        return retval > unlimited_minimum ? -1L : retval;
+    }
+
+
+    /*****************************************************************
+     * BlKIO Subsystem
+     ****************************************************************/
+
+
+    public long getBlkIOServiceCount() {
+        return SubSystem.getLongEntry(blkio, "blkio.throttle.io_service_bytes", "Total");
+    }
+
+    public long getBlkIOServiced() {
+        return SubSystem.getLongEntry(blkio, "blkio.throttle.io_serviced", "Total");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/linux/classes/jdk/internal/platform/cgroupv1/SubSystem.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,208 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 jdk.internal.platform.cgroupv1;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+public class SubSystem {
+    String root;
+    String mountPoint;
+    String path;
+
+    public SubSystem(String root, String mountPoint) {
+        this.root = root;
+        this.mountPoint = mountPoint;
+    }
+
+    public void setPath(String cgroupPath) {
+        if (root != null && cgroupPath != null) {
+            if (root.equals("/")) {
+                if (cgroupPath.equals("/")) {
+                    path = mountPoint + cgroupPath;
+                }
+                else {
+                    path = mountPoint;
+                }
+            }
+            else {
+                if (root.equals(cgroupPath)) {
+                    path = mountPoint;
+                }
+                else {
+                    if (root.indexOf(cgroupPath) == 0) {
+                        if (cgroupPath.length() > root.length()) {
+                            String cgroupSubstr = cgroupPath.substring(root.length());
+                            path = mountPoint + cgroupSubstr;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public String path() {
+        return path;
+    }
+
+    /**
+     * getSubSystemStringValue
+     *
+     * Return the first line of the file "parm" argument from the subsystem.
+     *
+     * TODO:  Consider using weak references for caching BufferedReader object.
+     *
+     * @param subsystem
+     * @param parm
+     * @return Returns the contents of the file specified by param.
+     */
+    public static String getStringValue(SubSystem subsystem, String parm) {
+        if (subsystem == null) return null;
+
+        try(BufferedReader bufferedReader = Files.newBufferedReader(Paths.get(subsystem.path(), parm))) {
+            String line = bufferedReader.readLine();
+            return line;
+        }
+        catch (IOException e) {
+            return null;
+        }
+
+    }
+
+    public static long getLongValue(SubSystem subsystem, String parm) {
+        String strval = getStringValue(subsystem, parm);
+
+        if (strval == null) return 0L;
+
+        long retval = Long.parseLong(strval);
+
+        return retval;
+    }
+
+    public static double getDoubleValue(SubSystem subsystem, String parm) {
+        String strval = getStringValue(subsystem, parm);
+
+        if (strval == null) return 0L;
+
+        double retval = Double.parseDouble(strval);
+
+        return retval;
+    }
+
+    /**
+     * getSubSystemlongEntry
+     *
+     * Return the long value from the line containing the string "entryname"
+     * within file "parm" in the "subsystem".
+     *
+     * TODO:  Consider using weak references for caching BufferedReader object.
+     *
+     * @param subsystem
+     * @param parm
+     * @param entryname
+     * @return long value
+     */
+    public static long getLongEntry(SubSystem subsystem, String parm, String entryname) {
+        String val = null;
+
+        if (subsystem == null) return 0L;
+
+        try (Stream<String> lines = Files.lines(Paths.get(subsystem.path(), parm))) {
+
+            Optional<String> result = lines.map(line -> line.split(" "))
+                                           .filter(line -> (line.length == 2 &&
+                                                   line[0].equals(entryname)))
+                                           .map(line -> line[1])
+                                           .findFirst();
+
+            return result.isPresent() ? Long.parseLong(result.get()) : 0L;
+        }
+        catch (IOException e) {
+            return 0L;
+        }
+    }
+
+    public static int getIntValue(SubSystem subsystem, String parm) {
+        String val = getStringValue(subsystem, parm);
+
+        if (val == null) return 0;
+
+        return Integer.parseInt(val);
+    }
+
+    /**
+     * StringRangeToIntArray
+     *
+     * Convert a string in the form of  1,3-4,6 to an array of
+     * integers containing all the numbers in the range.
+     *
+     * @param range
+     * @return int[] containing a sorted list of processors or memory nodes
+     */
+    public static int[] StringRangeToIntArray(String range) {
+        int[] ints = new int[0];
+
+        if (range == null) return ints;
+
+        ArrayList<Integer> results = new ArrayList<>();
+        String strs[] = range.split(",");
+        for (String str : strs) {
+            if (str.contains("-")) {
+                String lohi[] = str.split("-");
+                // validate format
+                if (lohi.length != 2) {
+                    continue;
+                }
+                int lo = Integer.parseInt(lohi[0]);
+                int hi = Integer.parseInt(lohi[1]);
+                for (int i = lo; i <= hi; i++) {
+                    results.add(i);
+                }
+            }
+            else {
+                results.add(Integer.parseInt(str));
+            }
+        }
+
+        // sort results
+        results.sort(null);
+
+        // convert ArrayList to primitive int array
+        ints = new int[results.size()];
+        int i = 0;
+        for (Integer n : results) {
+            ints[i++] = n;
+        }
+
+        return ints;
+    }
+}
--- a/src/macosx/bin/java_md_macosx.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/macosx/bin/java_md_macosx.c	Sat Oct 24 01:11:51 2020 +0100
@@ -651,11 +651,31 @@
     }
 
     size_t indexOfLastPathComponent = pathLen - sizeOfLastPathComponent;
-    if (0 == strncmp(realPathToSelf + indexOfLastPathComponent, lastPathComponent, sizeOfLastPathComponent - 1)) {
+    if (0 == strncmp(realPathToSelf + indexOfLastPathComponent, lastPathComponent, sizeOfLastPathComponent)) {
         realPathToSelf[indexOfLastPathComponent + 1] = '\0';
         return JNI_TRUE;
     }
 
+    // If libjli.dylib is loaded from a macos bundle MacOS dir, find the JRE dir
+    // in ../Home.
+    const char altLastPathComponent[] = "/MacOS/libjli.dylib";
+    size_t sizeOfAltLastPathComponent = sizeof(altLastPathComponent) - 1;
+    if (pathLen < sizeOfLastPathComponent) {
+        return JNI_FALSE;
+    }
+
+    size_t indexOfAltLastPathComponent = pathLen - sizeOfAltLastPathComponent;
+    if (0 == strncmp(realPathToSelf + indexOfAltLastPathComponent, altLastPathComponent, sizeOfAltLastPathComponent)) {
+        JLI_Snprintf(realPathToSelf + indexOfAltLastPathComponent, sizeOfAltLastPathComponent, "%s", "/Home/jre");
+        if (access(realPathToSelf, F_OK) == 0) {
+            return JNI_TRUE;
+        }
+        JLI_Snprintf(realPathToSelf + indexOfAltLastPathComponent, sizeOfAltLastPathComponent, "%s", "/Home");
+        if (access(realPathToSelf, F_OK) == 0) {
+            return JNI_TRUE;
+        }
+    }
+
     if (!speculative)
       JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
     return JNI_FALSE;
--- a/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m	Sat Oct 24 01:11:51 2020 +0100
@@ -93,7 +93,6 @@
     CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
 #if USE_NSVIEW_FOR_SCRATCH
     [ctxinfo->context makeCurrentContext];
-    [ctxinfo->context setView: ctxinfo->scratchSurface];
 #else
     [ctxinfo->context clearDrawable];
     [ctxinfo->context makeCurrentContext];
--- a/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -60,6 +60,9 @@
     // can only be returned by the doFinal(...) call.
     private static final int MAX_BUF_SIZE = Integer.MAX_VALUE;
 
+    // data size when buffer is divided up to aid in intrinsics
+    private static final int TRIGGERLEN = 65536;  // 64k
+
     // buffer for AAD data; if null, meaning update has been called
     private ByteArrayOutputStream aadBuffer = new ByteArrayOutputStream();
     private int sizeOfAAD = 0;
@@ -379,12 +382,10 @@
     // Utility to process the last block; used by encryptFinal and decryptFinal
     void doLastBlock(byte[] in, int inOfs, int len, byte[] out, int outOfs,
                      boolean isEncrypt) throws IllegalBlockSizeException {
-        // process data in 'in'
-        gctrPAndC.doFinal(in, inOfs, len, out, outOfs);
-        processed += len;
-
         byte[] ct;
         int ctOfs;
+        int ilen = len;  // internal length
+
         if (isEncrypt) {
             ct = out;
             ctOfs = outOfs;
@@ -392,14 +393,37 @@
             ct = in;
             ctOfs = inOfs;
         }
-        int lastLen = len  % AES_BLOCK_SIZE;
+
+        // Divide up larger data sizes to trigger CTR & GHASH intrinsic quicker
+        if (len > TRIGGERLEN) {
+            int i = 0;
+            int tlen;  // incremental lengths
+            final int plen = AES_BLOCK_SIZE * 6;
+            // arbitrary formula to aid intrinsic without reaching buffer end
+            final int count = len / 1024;
+
+            while (count > i) {
+                tlen = gctrPAndC.update(in, inOfs, plen, out, outOfs);
+                ghashAllToS.update(ct, ctOfs, tlen);
+                inOfs += tlen;
+                outOfs += tlen;
+                ctOfs += tlen;
+                i++;
+            }
+            ilen -= count * plen;
+            processed += count * plen;
+        }
+
+        gctrPAndC.doFinal(in, inOfs, ilen, out, outOfs);
+        processed += ilen;
+
+        int lastLen = ilen % AES_BLOCK_SIZE;
         if (lastLen != 0) {
-            ghashAllToS.update(ct, ctOfs, len - lastLen);
-            byte[] padded =
-                expandToOneBlock(ct, (ctOfs + len - lastLen), lastLen);
-            ghashAllToS.update(padded);
+            ghashAllToS.update(ct, ctOfs, ilen - lastLen);
+            ghashAllToS.update(
+                    expandToOneBlock(ct, (ctOfs + ilen - lastLen), lastLen));
         } else {
-            ghashAllToS.update(ct, ctOfs, len);
+            ghashAllToS.update(ct, ctOfs, ilen);
         }
     }
 
@@ -559,15 +583,19 @@
         System.arraycopy(in, inOfs + len - tagLenBytes, tag, 0, tagLenBytes);
         len -= tagLenBytes;
 
-        if (len > 0) {
-            ibuffer.write(in, inOfs, len);
-        }
+        // If decryption is in-place or there is buffered "ibuffer" data, copy
+        // the "in" byte array into the ibuffer before proceeding.
+        if (in == out || ibuffer.size() > 0) {
+            if (len > 0) {
+                ibuffer.write(in, inOfs, len);
+            }
 
-        // refresh 'in' to all buffered-up bytes
-        in = ibuffer.toByteArray();
-        inOfs = 0;
-        len = in.length;
-        ibuffer.reset();
+            // refresh 'in' to all buffered-up bytes
+            in = ibuffer.toByteArray();
+            inOfs = 0;
+            len = in.length;
+            ibuffer.reset();
+        }
 
         if (len > 0) {
             doLastBlock(in, inOfs, len, out, outOfs, false);
--- a/src/share/classes/com/sun/jndi/ldap/LdapCtx.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/jndi/ldap/LdapCtx.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -2690,7 +2690,8 @@
                 synchronized (clnt) {
                     if (!clnt.isLdapv3
                         || clnt.referenceCount > 1
-                        || clnt.usingSaslStreams()) {
+                        || clnt.usingSaslStreams()
+                        || !clnt.conn.useable) {
                         closeConnection(SOFT_CLOSE);
                     }
                 }
--- a/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,7 +25,6 @@
 
 package com.sun.management;
 
-import java.util.List;
 import java.lang.management.PlatformManagedObject;
 
 /**
@@ -110,7 +109,7 @@
      * @throws IllegalArgumentException if the VM option of the given name
      *                                     does not exist.
      * @throws IllegalArgumentException if the new value is invalid.
-     * @throws IllegalArgumentException if the VM option is not writeable.
+     * @throws IllegalArgumentException if the VM option is not writable.
      * @throws NullPointerException if name or value is <tt>null</tt>.
      *
      * @throws  java.lang.SecurityException
--- a/src/share/classes/com/sun/media/sound/AbstractDataLine.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/media/sound/AbstractDataLine.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -59,10 +59,9 @@
     // current buffer size in bytes
     protected int bufferSize;
 
-    protected boolean running = false;
-    private boolean started = false;
-    private boolean active = false;
-
+    private volatile boolean running;
+    private volatile boolean started;
+    private volatile boolean active;
 
     /**
      * Constructs a new AbstractLine.
--- a/src/share/classes/com/sun/media/sound/AbstractLine.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/media/sound/AbstractLine.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -47,7 +47,7 @@
     protected final Line.Info info;
     protected Control[] controls;
     AbstractMixer mixer;
-    private boolean open     = false;
+    private volatile boolean open;
     private final Vector listeners = new Vector();
 
     /**
--- a/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -65,7 +65,7 @@
 
     // DEVICE STATE
 
-    private boolean open          = false;
+    private volatile boolean open;
     private int openRefCount;
 
     /** List of Receivers and Transmitters that opened the device implicitely.
@@ -75,7 +75,7 @@
     /**
      * This is the device handle returned from native code
      */
-    protected long id                   = 0;
+    protected volatile long id;
 
 
 
@@ -477,7 +477,7 @@
         (which opens the device implicitely).
      */
     abstract class AbstractReceiver implements MidiDeviceReceiver {
-        private boolean open = true;
+        private volatile boolean open = true;
 
 
         /** Deliver a MidiMessage.
--- a/src/share/classes/com/sun/media/sound/MidiInDevice.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/media/sound/MidiInDevice.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -38,7 +38,7 @@
  */
 final class MidiInDevice extends AbstractMidiDevice implements Runnable {
 
-    private Thread midiInThread = null;
+    private volatile Thread midiInThread;
 
     // CONSTRUCTOR
 
--- a/src/share/classes/com/sun/media/sound/RealTimeSequencer.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/media/sound/RealTimeSequencer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -106,7 +106,7 @@
     /**
      * True if the sequence is running.
      */
-    private boolean running = false;
+    private volatile boolean running;
 
 
     /** the thread for pushing out the MIDI messages */
@@ -116,7 +116,7 @@
     /**
      * True if we are recording
      */
-    private boolean recording = false;
+    private volatile boolean recording;
 
 
     /**
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/Init.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/Init.java	Sat Oct 24 01:11:51 2020 +0100
@@ -30,9 +30,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 
 import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
 import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm;
@@ -61,9 +59,8 @@
     /** The namespace for CONF file **/
     public static final String CONF_NS = "http://www.xmlsecurity.org/NS/#configuration";
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(Init.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(Init.class);
 
     /** Field alreadyInitialized */
     private static boolean alreadyInitialized = false;
@@ -72,7 +69,7 @@
      * Method isInitialized
      * @return true if the library is already initialized.
      */
-    public static synchronized final boolean isInitialized() {
+    public static final synchronized boolean isInitialized() {
         return Init.alreadyInitialized;
     }
 
@@ -87,16 +84,16 @@
 
         InputStream is =
             AccessController.doPrivileged(
-                new PrivilegedAction<InputStream>() {
-                    public InputStream run() {
+                (PrivilegedAction<InputStream>)
+                    () -> {
                         String cfile =
                             System.getProperty("com.sun.org.apache.xml.internal.security.resource.config");
                         if (cfile == null) {
                             return null;
                         }
-                        return getClass().getResourceAsStream(cfile);
+                        return Init.class.getResourceAsStream(cfile);
                     }
-                });
+                );
         if (is == null) {
             dynamicInit();
         } else {
@@ -117,9 +114,8 @@
         //
         I18n.init("en", "US");
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Registering default algorithms");
-        }
+        LOG.debug("Registering default algorithms");
+
         try {
             AccessController.doPrivileged(new PrivilegedExceptionAction<Void>(){
                 @Override public Void run() throws XMLSecurityException {
@@ -160,10 +156,10 @@
 
                     return null;
                 }
-           });
+            });
         } catch (PrivilegedActionException ex) {
             XMLSecurityException xse = (XMLSecurityException)ex.getException();
-            log.log(java.util.logging.Level.SEVERE, xse.getMessage(), xse);
+            LOG.error(xse.getMessage(), xse);
             xse.printStackTrace();
         }
     }
@@ -174,13 +170,7 @@
     private static void fileInit(InputStream is) {
         try {
             /* read library configuration file */
-            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-            dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
-
-            dbf.setNamespaceAware(true);
-            dbf.setValidating(false);
-
-            DocumentBuilder db = dbf.newDocumentBuilder();
+            DocumentBuilder db = XMLUtils.createDocumentBuilder(false);
             Document doc = db.parse(is);
             Node config = doc.getFirstChild();
             for (; config != null; config = config.getNextSibling()) {
@@ -189,7 +179,7 @@
                 }
             }
             if (config == null) {
-                log.log(java.util.logging.Level.SEVERE, "Error in reading configuration file - Configuration element not found");
+                LOG.error("Error in reading configuration file - Configuration element not found");
                 return;
             }
             for (Node el = config.getFirstChild(); el != null; el = el.getNextSibling()) {
@@ -197,11 +187,11 @@
                     continue;
                 }
                 String tag = el.getLocalName();
-                if (tag.equals("ResourceBundles")) {
+                if ("ResourceBundles".equals(tag)) {
                     Element resource = (Element)el;
                     /* configure internationalization */
-                    Attr langAttr = resource.getAttributeNode("defaultLanguageCode");
-                    Attr countryAttr = resource.getAttributeNode("defaultCountryCode");
+                    Attr langAttr = resource.getAttributeNodeNS(null, "defaultLanguageCode");
+                    Attr countryAttr = resource.getAttributeNodeNS(null, "defaultCountryCode");
                     String languageCode =
                         (langAttr == null) ? null : langAttr.getNodeValue();
                     String countryCode =
@@ -209,45 +199,41 @@
                     I18n.init(languageCode, countryCode);
                 }
 
-                if (tag.equals("CanonicalizationMethods")) {
+                if ("CanonicalizationMethods".equals(tag)) {
                     Element[] list =
                         XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "CanonicalizationMethod");
 
-                    for (int i = 0; i < list.length; i++) {
-                        String uri = list[i].getAttributeNS(null, "URI");
+                    for (Element element : list) {
+                        String uri = element.getAttributeNS(null, "URI");
                         String javaClass =
-                            list[i].getAttributeNS(null, "JAVACLASS");
+                            element.getAttributeNS(null, "JAVACLASS");
                         try {
                             Canonicalizer.register(uri, javaClass);
-                            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                                log.log(java.util.logging.Level.FINE, "Canonicalizer.register(" + uri + ", " + javaClass + ")");
-                            }
+                            LOG.debug("Canonicalizer.register({}, {})", uri, javaClass);
                         } catch (ClassNotFoundException e) {
                             Object exArgs[] = { uri, javaClass };
-                            log.log(java.util.logging.Level.SEVERE, I18n.translate("algorithm.classDoesNotExist", exArgs));
+                            LOG.error(I18n.translate("algorithm.classDoesNotExist", exArgs));
                         }
                     }
                 }
 
-                if (tag.equals("TransformAlgorithms")) {
+                if ("TransformAlgorithms".equals(tag)) {
                     Element[] tranElem =
                         XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "TransformAlgorithm");
 
-                    for (int i = 0; i < tranElem.length; i++) {
-                        String uri = tranElem[i].getAttributeNS(null, "URI");
+                    for (Element element : tranElem) {
+                        String uri = element.getAttributeNS(null, "URI");
                         String javaClass =
-                            tranElem[i].getAttributeNS(null, "JAVACLASS");
+                            element.getAttributeNS(null, "JAVACLASS");
                         try {
                             Transform.register(uri, javaClass);
-                            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                                log.log(java.util.logging.Level.FINE, "Transform.register(" + uri + ", " + javaClass + ")");
-                            }
+                            LOG.debug("Transform.register({}, {})", uri, javaClass);
                         } catch (ClassNotFoundException e) {
                             Object exArgs[] = { uri, javaClass };
 
-                            log.log(java.util.logging.Level.SEVERE, I18n.translate("algorithm.classDoesNotExist", exArgs));
+                            LOG.error(I18n.translate("algorithm.classDoesNotExist", exArgs));
                         } catch (NoClassDefFoundError ex) {
-                            log.log(java.util.logging.Level.WARNING, "Not able to found dependencies for algorithm, I'll keep working.");
+                            LOG.warn("Not able to found dependencies for algorithm, I'll keep working.");
                         }
                     }
                 }
@@ -257,64 +243,54 @@
                     if (algorithmsNode != null) {
                         Element[] algorithms =
                             XMLUtils.selectNodes(algorithmsNode.getFirstChild(), CONF_NS, "Algorithm");
-                        for (int i = 0; i < algorithms.length; i++) {
-                            Element element = algorithms[i];
-                            String id = element.getAttribute("URI");
+                        for (Element element : algorithms) {
+                            String id = element.getAttributeNS(null, "URI");
                             JCEMapper.register(id, new JCEMapper.Algorithm(element));
                         }
                     }
                 }
 
-                if (tag.equals("SignatureAlgorithms")) {
+                if ("SignatureAlgorithms".equals(tag)) {
                     Element[] sigElems =
                         XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "SignatureAlgorithm");
 
-                    for (int i = 0; i < sigElems.length; i++) {
-                        String uri = sigElems[i].getAttributeNS(null, "URI");
+                    for (Element sigElem : sigElems) {
+                        String uri = sigElem.getAttributeNS(null, "URI");
                         String javaClass =
-                            sigElems[i].getAttributeNS(null, "JAVACLASS");
+                            sigElem.getAttributeNS(null, "JAVACLASS");
 
                         /** $todo$ handle registering */
 
                         try {
                             SignatureAlgorithm.register(uri, javaClass);
-                            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                                log.log(java.util.logging.Level.FINE, "SignatureAlgorithm.register(" + uri + ", "
-                                          + javaClass + ")");
-                            }
+                            LOG.debug("SignatureAlgorithm.register({}, {})", uri, javaClass);
                         } catch (ClassNotFoundException e) {
                             Object exArgs[] = { uri, javaClass };
 
-                            log.log(java.util.logging.Level.SEVERE, I18n.translate("algorithm.classDoesNotExist", exArgs));
+                            LOG.error(I18n.translate("algorithm.classDoesNotExist", exArgs));
                         }
                     }
                 }
 
-                if (tag.equals("ResourceResolvers")) {
-                    Element[]resolverElem =
+                if ("ResourceResolvers".equals(tag)) {
+                    Element[] resolverElem =
                         XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "Resolver");
 
-                    for (int i = 0; i < resolverElem.length; i++) {
+                    for (Element element : resolverElem) {
                         String javaClass =
-                            resolverElem[i].getAttributeNS(null, "JAVACLASS");
+                            element.getAttributeNS(null, "JAVACLASS");
                         String description =
-                            resolverElem[i].getAttributeNS(null, "DESCRIPTION");
+                            element.getAttributeNS(null, "DESCRIPTION");
 
-                        if ((description != null) && (description.length() > 0)) {
-                            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                                log.log(java.util.logging.Level.FINE, "Register Resolver: " + javaClass + ": "
-                                          + description);
-                            }
+                        if (description != null && description.length() > 0) {
+                            LOG.debug("Register Resolver: {}: {}", javaClass, description);
                         } else {
-                            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                                log.log(java.util.logging.Level.FINE, "Register Resolver: " + javaClass
-                                          + ": For unknown purposes");
-                            }
+                            LOG.debug("Register Resolver: {}: For unknown purposes", javaClass);
                         }
                         try {
                             ResourceResolver.register(javaClass);
                         } catch (Throwable e) {
-                            log.log(java.util.logging.Level.WARNING,
+                            LOG.warn(
                                  "Cannot register:" + javaClass
                                  + " perhaps some needed jars are not installed",
                                  e
@@ -323,26 +299,20 @@
                     }
                 }
 
-                if (tag.equals("KeyResolver")){
+                if ("KeyResolver".equals(tag)){
                     Element[] resolverElem =
                         XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "Resolver");
-                    List<String> classNames = new ArrayList<String>(resolverElem.length);
-                    for (int i = 0; i < resolverElem.length; i++) {
+                    List<String> classNames = new ArrayList<>(resolverElem.length);
+                    for (Element element : resolverElem) {
                         String javaClass =
-                            resolverElem[i].getAttributeNS(null, "JAVACLASS");
+                            element.getAttributeNS(null, "JAVACLASS");
                         String description =
-                            resolverElem[i].getAttributeNS(null, "DESCRIPTION");
+                            element.getAttributeNS(null, "DESCRIPTION");
 
-                        if ((description != null) && (description.length() > 0)) {
-                            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                                log.log(java.util.logging.Level.FINE, "Register Resolver: " + javaClass + ": "
-                                          + description);
-                            }
+                        if (description != null && description.length() > 0) {
+                            LOG.debug("Register Resolver: {}: {}", javaClass, description);
                         } else {
-                            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                                log.log(java.util.logging.Level.FINE, "Register Resolver: " + javaClass
-                                          + ": For unknown purposes");
-                            }
+                            LOG.debug("Register Resolver: {}: For unknown purposes", javaClass);
                         }
                         classNames.add(javaClass);
                     }
@@ -350,27 +320,22 @@
                 }
 
 
-                if (tag.equals("PrefixMappings")){
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, "Now I try to bind prefixes:");
-                    }
+                if ("PrefixMappings".equals(tag)){
+                    LOG.debug("Now I try to bind prefixes:");
 
                     Element[] nl =
                         XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "PrefixMapping");
 
-                    for (int i = 0; i < nl.length; i++) {
-                        String namespace = nl[i].getAttributeNS(null, "namespace");
-                        String prefix = nl[i].getAttributeNS(null, "prefix");
-                        if (log.isLoggable(java.util.logging.Level.FINE)) {
-                            log.log(java.util.logging.Level.FINE, "Now I try to bind " + prefix + " to " + namespace);
-                        }
+                    for (Element element : nl) {
+                        String namespace = element.getAttributeNS(null, "namespace");
+                        String prefix = element.getAttributeNS(null, "prefix");
+                        LOG.debug("Now I try to bind {} to {}", prefix, namespace);
                         ElementProxy.setDefaultPrefix(namespace, prefix);
                     }
                 }
             }
         } catch (Exception e) {
-            log.log(java.util.logging.Level.SEVERE, "Bad: ", e);
-            e.printStackTrace();
+            LOG.error("Bad: ", e);
         }
     }
 
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/Algorithm.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/Algorithm.java	Sat Oct 24 01:11:51 2020 +0100
@@ -40,7 +40,6 @@
      */
     public Algorithm(Document doc, String algorithmURI) {
         super(doc);
-
         this.setAlgorithmURI(algorithmURI);
     }
 
@@ -48,11 +47,11 @@
      * Constructor Algorithm
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public Algorithm(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public Algorithm(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
     }
 
     /**
@@ -61,7 +60,7 @@
      * @return The URI of the algorithm
      */
     public String getAlgorithmURI() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_ALGORITHM);
+        return getLocalAttribute(Constants._ATT_ALGORITHM);
     }
 
     /**
@@ -71,9 +70,7 @@
      */
     protected void setAlgorithmURI(String algorithmURI) {
         if (algorithmURI != null) {
-            this.constructionElement.setAttributeNS(
-                null, Constants._ATT_ALGORITHM, algorithmURI
-            );
+            setLocalAttribute(Constants._ATT_ALGORITHM, algorithmURI);
         }
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/ClassLoaderUtils.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/ClassLoaderUtils.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,211 +23,19 @@
 
 package com.sun.org.apache.xml.internal.security.algorithms;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-
-/**
- * This class is extremely useful for loading resources and classes in a fault
- * tolerant manner that works across different applications servers. Do not
- * touch this unless you're a grizzled classloading guru veteran who is going to
- * verify any change on 6 different application servers.
- */
 // NOTE! This is a duplicate of utils.ClassLoaderUtils with public
 // modifiers changed to package-private. Make sure to integrate any future
 // changes to utils.ClassLoaderUtils to this file.
 final class ClassLoaderUtils {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static final java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(ClassLoaderUtils.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ClassLoaderUtils.class);
 
     private ClassLoaderUtils() {
     }
 
     /**
-     * Load a given resource. <p/> This method will try to load the resource
-     * using the following methods (in order):
-     * <ul>
-     * <li>From Thread.currentThread().getContextClassLoader()
-     * <li>From ClassLoaderUtil.class.getClassLoader()
-     * <li>callingClass.getClassLoader()
-     * </ul>
-     *
-     * @param resourceName The name of the resource to load
-     * @param callingClass The Class object of the calling object
-     */
-    static URL getResource(String resourceName, Class<?> callingClass) {
-        URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
-        if (url == null && resourceName.startsWith("/")) {
-            //certain classloaders need it without the leading /
-            url =
-                Thread.currentThread().getContextClassLoader().getResource(
-                    resourceName.substring(1)
-                );
-        }
-
-        ClassLoader cluClassloader = ClassLoaderUtils.class.getClassLoader();
-        if (cluClassloader == null) {
-            cluClassloader = ClassLoader.getSystemClassLoader();
-        }
-        if (url == null) {
-            url = cluClassloader.getResource(resourceName);
-        }
-        if (url == null && resourceName.startsWith("/")) {
-            //certain classloaders need it without the leading /
-            url = cluClassloader.getResource(resourceName.substring(1));
-        }
-
-        if (url == null) {
-            ClassLoader cl = callingClass.getClassLoader();
-
-            if (cl != null) {
-                url = cl.getResource(resourceName);
-            }
-        }
-
-        if (url == null) {
-            url = callingClass.getResource(resourceName);
-        }
-
-        if ((url == null) && (resourceName != null) && (resourceName.charAt(0) != '/')) {
-            return getResource('/' + resourceName, callingClass);
-        }
-
-        return url;
-    }
-
-    /**
-     * Load a given resources. <p/> This method will try to load the resources
-     * using the following methods (in order):
-     * <ul>
-     * <li>From Thread.currentThread().getContextClassLoader()
-     * <li>From ClassLoaderUtil.class.getClassLoader()
-     * <li>callingClass.getClassLoader()
-     * </ul>
-     *
-     * @param resourceName The name of the resource to load
-     * @param callingClass The Class object of the calling object
-     */
-    static List<URL> getResources(String resourceName, Class<?> callingClass) {
-        List<URL> ret = new ArrayList<URL>();
-        Enumeration<URL> urls = new Enumeration<URL>() {
-            public boolean hasMoreElements() {
-                return false;
-            }
-            public URL nextElement() {
-                return null;
-            }
-
-        };
-        try {
-            urls = Thread.currentThread().getContextClassLoader().getResources(resourceName);
-        } catch (IOException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
-            //ignore
-        }
-        if (!urls.hasMoreElements() && resourceName.startsWith("/")) {
-            //certain classloaders need it without the leading /
-            try {
-                urls =
-                    Thread.currentThread().getContextClassLoader().getResources(
-                        resourceName.substring(1)
-                    );
-            } catch (IOException e) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                }
-                // ignore
-            }
-        }
-
-        ClassLoader cluClassloader = ClassLoaderUtils.class.getClassLoader();
-        if (cluClassloader == null) {
-            cluClassloader = ClassLoader.getSystemClassLoader();
-        }
-        if (!urls.hasMoreElements()) {
-            try {
-                urls = cluClassloader.getResources(resourceName);
-            } catch (IOException e) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                }
-                // ignore
-            }
-        }
-        if (!urls.hasMoreElements() && resourceName.startsWith("/")) {
-            //certain classloaders need it without the leading /
-            try {
-                urls = cluClassloader.getResources(resourceName.substring(1));
-            } catch (IOException e) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                }
-                // ignore
-            }
-        }
-
-        if (!urls.hasMoreElements()) {
-            ClassLoader cl = callingClass.getClassLoader();
-
-            if (cl != null) {
-                try {
-                    urls = cl.getResources(resourceName);
-                } catch (IOException e) {
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                    }
-                    // ignore
-                }
-            }
-        }
-
-        if (!urls.hasMoreElements()) {
-            URL url = callingClass.getResource(resourceName);
-            if (url != null) {
-                ret.add(url);
-            }
-        }
-        while (urls.hasMoreElements()) {
-            ret.add(urls.nextElement());
-        }
-
-
-        if (ret.isEmpty() && (resourceName != null) && (resourceName.charAt(0) != '/')) {
-            return getResources('/' + resourceName, callingClass);
-        }
-        return ret;
-    }
-
-
-    /**
-     * This is a convenience method to load a resource as a stream. <p/> The
-     * algorithm used to find the resource is given in getResource()
-     *
-     * @param resourceName The name of the resource to load
-     * @param callingClass The Class object of the calling object
-     */
-    static InputStream getResourceAsStream(String resourceName, Class<?> callingClass) {
-        URL url = getResource(resourceName, callingClass);
-
-        try {
-            return (url != null) ? url.openStream() : null;
-        } catch (IOException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
-            return null;
-        }
-    }
-
-    /**
-     * Load a class with a given name. <p/> It will try to load the class in the
+     * Load a class with a given name. <p></p> It will try to load the class in the
      * following order:
      * <ul>
      * <li>From Thread.currentThread().getContextClassLoader()
@@ -249,9 +57,7 @@
                 return cl.loadClass(className);
             }
         } catch (ClassNotFoundException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
+            LOG.debug(e.getMessage(), e);
             //ignore
         }
         return loadClass2(className, callingClass);
@@ -271,9 +77,7 @@
                     return callingClass.getClassLoader().loadClass(className);
                 }
             }
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-            }
+            LOG.debug(ex.getMessage(), ex);
             throw ex;
         }
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,7 +25,6 @@
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
-import com.sun.org.apache.xml.internal.security.encryption.XMLCipher;
 import com.sun.org.apache.xml.internal.security.signature.XMLSignature;
 import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
 import org.w3c.dom.Element;
@@ -36,14 +35,13 @@
  */
 public class JCEMapper {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(JCEMapper.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(JCEMapper.class);
 
     private static Map<String, Algorithm> algorithmsMap =
         new ConcurrentHashMap<String, Algorithm>();
 
-    private static String providerName = null;
+    private static String providerName;
 
     /**
      * Method register
@@ -62,6 +60,7 @@
      * This method registers the default algorithms.
      */
     public static void registerDefaultAlgorithms() {
+        // Digest algorithms
         algorithmsMap.put(
             MessageDigestAlgorithm.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5,
             new Algorithm("", "MD5", "MessageDigest")
@@ -75,6 +74,10 @@
             new Algorithm("", "SHA-1", "MessageDigest")
         );
         algorithmsMap.put(
+            MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA224,
+            new Algorithm("", "SHA-224", "MessageDigest")
+        );
+        algorithmsMap.put(
             MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA256,
             new Algorithm("", "SHA-256", "MessageDigest")
         );
@@ -86,137 +89,114 @@
             MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA512,
             new Algorithm("", "SHA-512", "MessageDigest")
         );
+        // Signature algorithms
         algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_DSA,
-            new Algorithm("", "SHA1withDSA", "Signature")
+            new Algorithm("DSA", "SHA1withDSA", "Signature")
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_DSA_SHA256,
-            new Algorithm("", "SHA256withDSA", "Signature")
+            new Algorithm("DSA", "SHA256withDSA", "Signature")
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5,
-            new Algorithm("", "MD5withRSA", "Signature")
+            new Algorithm("RSA", "MD5withRSA", "Signature")
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_RSA_RIPEMD160,
-            new Algorithm("", "RIPEMD160withRSA", "Signature")
+            new Algorithm("RSA", "RIPEMD160withRSA", "Signature")
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1,
-            new Algorithm("", "SHA1withRSA", "Signature")
+            new Algorithm("RSA", "SHA1withRSA", "Signature")
+        );
+        algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA224,
+            new Algorithm("RSA", "SHA224withRSA", "Signature")
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256,
-            new Algorithm("", "SHA256withRSA", "Signature")
+            new Algorithm("RSA", "SHA256withRSA", "Signature")
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384,
-            new Algorithm("", "SHA384withRSA", "Signature")
+            new Algorithm("RSA", "SHA384withRSA", "Signature")
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512,
-            new Algorithm("", "SHA512withRSA", "Signature")
+            new Algorithm("RSA", "SHA512withRSA", "Signature")
+        );
+        algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1_MGF1,
+            new Algorithm("RSA", "SHA1withRSAandMGF1", "Signature")
+        );
+        algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA224_MGF1,
+            new Algorithm("RSA", "SHA224withRSAandMGF1", "Signature")
+        );
+        algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256_MGF1,
+            new Algorithm("RSA", "SHA256withRSAandMGF1", "Signature")
+        );
+        algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384_MGF1,
+            new Algorithm("RSA", "SHA384withRSAandMGF1", "Signature")
+        );
+        algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512_MGF1,
+            new Algorithm("RSA", "SHA512withRSAandMGF1", "Signature")
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA1,
-            new Algorithm("", "SHA1withECDSA", "Signature")
+            new Algorithm("EC", "SHA1withECDSA", "Signature")
+        );
+        algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA224,
+            new Algorithm("EC", "SHA224withECDSA", "Signature")
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA256,
-            new Algorithm("", "SHA256withECDSA", "Signature")
+            new Algorithm("EC", "SHA256withECDSA", "Signature")
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA384,
-            new Algorithm("", "SHA384withECDSA", "Signature")
+            new Algorithm("EC", "SHA384withECDSA", "Signature")
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA512,
-            new Algorithm("", "SHA512withECDSA", "Signature")
+            new Algorithm("EC", "SHA512withECDSA", "Signature")
+        );
+        algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_ECDSA_RIPEMD160,
+            new Algorithm("EC", "RIPEMD160withECDSA", "Signature")
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5,
-            new Algorithm("", "HmacMD5", "Mac")
+            new Algorithm("", "HmacMD5", "Mac", 0, 0)
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160,
-            new Algorithm("", "HMACRIPEMD160", "Mac")
+            new Algorithm("", "HMACRIPEMD160", "Mac", 0, 0)
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_MAC_HMAC_SHA1,
-            new Algorithm("", "HmacSHA1", "Mac")
+            new Algorithm("", "HmacSHA1", "Mac", 0, 0)
+        );
+        algorithmsMap.put(
+            XMLSignature.ALGO_ID_MAC_HMAC_SHA224,
+            new Algorithm("", "HmacSHA224", "Mac", 0, 0)
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_MAC_HMAC_SHA256,
-            new Algorithm("", "HmacSHA256", "Mac")
+            new Algorithm("", "HmacSHA256", "Mac", 0, 0)
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_MAC_HMAC_SHA384,
-            new Algorithm("", "HmacSHA384", "Mac")
+            new Algorithm("", "HmacSHA384", "Mac", 0, 0)
         );
         algorithmsMap.put(
             XMLSignature.ALGO_ID_MAC_HMAC_SHA512,
-            new Algorithm("", "HmacSHA512", "Mac")
-        );
-        algorithmsMap.put(
-            XMLCipher.TRIPLEDES,
-            new Algorithm("DESede", "DESede/CBC/ISO10126Padding", "BlockEncryption", 192)
-        );
-        algorithmsMap.put(
-            XMLCipher.AES_128,
-            new Algorithm("AES", "AES/CBC/ISO10126Padding", "BlockEncryption", 128)
-        );
-        algorithmsMap.put(
-            XMLCipher.AES_192,
-            new Algorithm("AES", "AES/CBC/ISO10126Padding", "BlockEncryption", 192)
-        );
-        algorithmsMap.put(
-            XMLCipher.AES_256,
-            new Algorithm("AES", "AES/CBC/ISO10126Padding", "BlockEncryption", 256)
-        );
-        algorithmsMap.put(
-            XMLCipher.AES_128_GCM,
-            new Algorithm("AES", "AES/GCM/NoPadding", "BlockEncryption", 128)
-        );
-        algorithmsMap.put(
-            XMLCipher.AES_192_GCM,
-            new Algorithm("AES", "AES/GCM/NoPadding", "BlockEncryption", 192)
-        );
-        algorithmsMap.put(
-            XMLCipher.AES_256_GCM,
-            new Algorithm("AES", "AES/GCM/NoPadding", "BlockEncryption", 256)
-        );
-        algorithmsMap.put(
-            XMLCipher.RSA_v1dot5,
-            new Algorithm("RSA", "RSA/ECB/PKCS1Padding", "KeyTransport")
-        );
-        algorithmsMap.put(
-            XMLCipher.RSA_OAEP,
-            new Algorithm("RSA", "RSA/ECB/OAEPPadding", "KeyTransport")
-        );
-        algorithmsMap.put(
-            XMLCipher.RSA_OAEP_11,
-            new Algorithm("RSA", "RSA/ECB/OAEPPadding", "KeyTransport")
-        );
-        algorithmsMap.put(
-            XMLCipher.DIFFIE_HELLMAN,
-            new Algorithm("", "", "KeyAgreement")
-        );
-        algorithmsMap.put(
-            XMLCipher.TRIPLEDES_KeyWrap,
-            new Algorithm("DESede", "DESedeWrap", "SymmetricKeyWrap", 192)
-        );
-        algorithmsMap.put(
-            XMLCipher.AES_128_KeyWrap,
-            new Algorithm("AES", "AESWrap", "SymmetricKeyWrap", 128)
-        );
-        algorithmsMap.put(
-            XMLCipher.AES_192_KeyWrap,
-            new Algorithm("AES", "AESWrap", "SymmetricKeyWrap", 192)
-        );
-        algorithmsMap.put(
-            XMLCipher.AES_256_KeyWrap,
-            new Algorithm("AES", "AESWrap", "SymmetricKeyWrap", 256)
+            new Algorithm("", "HmacSHA512", "Mac", 0, 0)
         );
     }
 
@@ -227,11 +207,7 @@
      * @return the JCE standard name corresponding to the given URI
      */
     public static String translateURItoJCEID(String algorithmURI) {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Request for URI " + algorithmURI);
-        }
-
-        Algorithm algorithm = algorithmsMap.get(algorithmURI);
+        Algorithm algorithm = getAlgorithm(algorithmURI);
         if (algorithm != null) {
             return algorithm.jceName;
         }
@@ -244,11 +220,7 @@
      * @return the class name that implements this algorithm
      */
     public static String getAlgorithmClassFromURI(String algorithmURI) {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Request for URI " + algorithmURI);
-        }
-
-        Algorithm algorithm = algorithmsMap.get(algorithmURI);
+        Algorithm algorithm = getAlgorithm(algorithmURI);
         if (algorithm != null) {
             return algorithm.algorithmClass;
         }
@@ -262,16 +234,21 @@
      * @return The length of the key used in the algorithm
      */
     public static int getKeyLengthFromURI(String algorithmURI) {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Request for URI " + algorithmURI);
-        }
-        Algorithm algorithm = algorithmsMap.get(algorithmURI);
+        Algorithm algorithm = getAlgorithm(algorithmURI);
         if (algorithm != null) {
             return algorithm.keyLength;
         }
         return 0;
     }
 
+    public static int getIVLengthFromURI(String algorithmURI) {
+        Algorithm algorithm = getAlgorithm(algorithmURI);
+        if (algorithm != null) {
+            return algorithm.ivLength;
+        }
+        return 0;
+    }
+
     /**
      * Method getJCEKeyAlgorithmFromURI
      *
@@ -279,12 +256,38 @@
      * @return The KeyAlgorithm for the given URI.
      */
     public static String getJCEKeyAlgorithmFromURI(String algorithmURI) {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Request for URI " + algorithmURI);
+        Algorithm algorithm = getAlgorithm(algorithmURI);
+         if (algorithm != null) {
+             return algorithm.requiredKey;
+         }
+        return null;
+    }
+
+    /**
+     * Method getJCEProviderFromURI
+     *
+     * @param algorithmURI
+     * @return The JCEProvider for the given URI.
+     */
+    public static String getJCEProviderFromURI(String algorithmURI) {
+        Algorithm algorithm = getAlgorithm(algorithmURI);
+        if (algorithm != null) {
+            return algorithm.jceProvider;
         }
-        Algorithm algorithm = algorithmsMap.get(algorithmURI);
-        if (algorithm != null) {
-            return algorithm.requiredKey;
+        return null;
+    }
+
+    /**
+     * Method getAlgorithm
+     *
+     * @param algorithmURI
+     * @return The Algorithm object for the given URI.
+     */
+    private static Algorithm getAlgorithm(String algorithmURI) {
+        LOG.debug("Request for URI {}", algorithmURI);
+
+        if (algorithmURI != null) {
+            return algorithmsMap.get(algorithmURI);
         }
         return null;
     }
@@ -301,7 +304,7 @@
      * Sets the default Provider for obtaining the security algorithms
      * @param provider the default providerId.
      * @throws SecurityException if a security manager is installed and the
-     *    caller does not have permission to set the JCE provider
+     *    caller does not have permission to register the JCE algorithm
      */
     public static void setProviderId(String provider) {
         JavaUtils.checkRegisterPermission();
@@ -317,40 +320,54 @@
         final String jceName;
         final String algorithmClass;
         final int keyLength;
+        final int ivLength;
+        final String jceProvider;
 
         /**
          * Gets data from element
          * @param el
          */
         public Algorithm(Element el) {
-            requiredKey = el.getAttribute("RequiredKey");
-            jceName = el.getAttribute("JCEName");
-            algorithmClass = el.getAttribute("AlgorithmClass");
+            requiredKey = el.getAttributeNS(null, "RequiredKey");
+            jceName = el.getAttributeNS(null, "JCEName");
+            algorithmClass = el.getAttributeNS(null, "AlgorithmClass");
+            jceProvider = el.getAttributeNS(null, "JCEProvider");
             if (el.hasAttribute("KeyLength")) {
-                keyLength = Integer.parseInt(el.getAttribute("KeyLength"));
+                keyLength = Integer.parseInt(el.getAttributeNS(null, "KeyLength"));
             } else {
                 keyLength = 0;
             }
+            if (el.hasAttribute("IVLength")) {
+                ivLength = Integer.parseInt(el.getAttributeNS(null, "IVLength"));
+            } else {
+                ivLength = 0;
+            }
         }
 
         public Algorithm(String requiredKey, String jceName) {
-            this(requiredKey, jceName, null, 0);
+            this(requiredKey, jceName, null, 0, 0);
         }
 
         public Algorithm(String requiredKey, String jceName, String algorithmClass) {
-            this(requiredKey, jceName, algorithmClass, 0);
+            this(requiredKey, jceName, algorithmClass, 0, 0);
         }
 
         public Algorithm(String requiredKey, String jceName, int keyLength) {
-            this(requiredKey, jceName, null, keyLength);
+            this(requiredKey, jceName, null, keyLength, 0);
         }
 
-        public Algorithm(String requiredKey, String jceName, String algorithmClass, int keyLength) {
+        public Algorithm(String requiredKey, String jceName, String algorithmClass, int keyLength, int ivLength) {
+            this(requiredKey, jceName, algorithmClass, keyLength, ivLength, null);
+        }
+
+        public Algorithm(String requiredKey, String jceName,
+                         String algorithmClass, int keyLength, int ivLength, String jceProvider) {
             this.requiredKey = requiredKey;
             this.jceName = jceName;
             this.algorithmClass = algorithmClass;
             this.keyLength = keyLength;
+            this.ivLength = ivLength;
+            this.jceProvider = jceProvider;
         }
     }
-
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java	Sat Oct 24 01:11:51 2020 +0100
@@ -31,7 +31,7 @@
 import org.w3c.dom.Document;
 
 /**
- * Digest Message wrapper & selector class.
+ * Digest Message wrapper and selector class.
  *
  * <pre>
  * MessageDigestAlgorithm.getInstance()
@@ -44,6 +44,9 @@
         Constants.MoreAlgorithmsSpecNS + "md5";
     /** Digest - Required SHA1*/
     public static final String ALGO_ID_DIGEST_SHA1 = Constants.SignatureSpecNS + "sha1";
+    /** Message Digest - OPTIONAL SHA224*/
+    public static final String ALGO_ID_DIGEST_SHA224 =
+        Constants.MoreAlgorithmsSpecNS + "sha224";
     /** Message Digest - RECOMMENDED SHA256*/
     public static final String ALGO_ID_DIGEST_SHA256 =
         EncryptionConstants.EncryptionSpecNS + "sha256";
@@ -121,7 +124,7 @@
      *
      * @return the actual {@link java.security.MessageDigest} algorithm object
      */
-    public java.security.MessageDigest getAlgorithm() {
+    public MessageDigest getAlgorithm() {
         return algorithm;
     }
 
@@ -134,7 +137,7 @@
      * @return the result of the {@link java.security.MessageDigest#isEqual} method
      */
     public static boolean isEqual(byte[] digesta, byte[] digestb) {
-        return java.security.MessageDigest.isEqual(digesta, digestb);
+        return MessageDigest.isEqual(digesta, digestb);
     }
 
     /**
@@ -243,12 +246,12 @@
         algorithm.update(buf, offset, len);
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseNamespace() {
         return Constants.SignatureSpecNS;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_DIGESTMETHOD;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java	Sat Oct 24 01:11:51 2020 +0100
@@ -46,13 +46,11 @@
  * Allows selection of digital signature's algorithm, private keys, other
  * security parameters, and algorithm's ID.
  *
- * @author Christian Geuer-Pollmann
  */
 public class SignatureAlgorithm extends Algorithm {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(SignatureAlgorithm.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(SignatureAlgorithm.class);
 
     /** All available algorithm classes are registered here */
     private static Map<String, Class<? extends SignatureAlgorithmSpi>> algorithmHash =
@@ -75,7 +73,7 @@
         this.algorithmURI = algorithmURI;
 
         signatureAlgorithm = getSignatureAlgorithmSpi(algorithmURI);
-        signatureAlgorithm.engineGetContextFromElement(this.constructionElement);
+        signatureAlgorithm.engineGetContextFromElement(getElement());
     }
 
     /**
@@ -93,10 +91,10 @@
         this.algorithmURI = algorithmURI;
 
         signatureAlgorithm = getSignatureAlgorithmSpi(algorithmURI);
-        signatureAlgorithm.engineGetContextFromElement(this.constructionElement);
+        signatureAlgorithm.engineGetContextFromElement(getElement());
 
         signatureAlgorithm.engineSetHMACOutputLength(hmacOutputLength);
-        ((IntegrityHmac)signatureAlgorithm).engineAddContextToElement(constructionElement);
+        ((IntegrityHmac)signatureAlgorithm).engineAddContextToElement(getElement());
     }
 
     /**
@@ -107,7 +105,7 @@
      * @throws XMLSecurityException
      */
     public SignatureAlgorithm(Element element, String baseURI) throws XMLSecurityException {
-        this(element, baseURI, false);
+        this(element, baseURI, true);
     }
 
     /**
@@ -137,7 +135,7 @@
         }
 
         signatureAlgorithm = getSignatureAlgorithmSpi(algorithmURI);
-        signatureAlgorithm.engineGetContextFromElement(this.constructionElement);
+        signatureAlgorithm.engineGetContextFromElement(getElement());
     }
 
     /**
@@ -148,20 +146,16 @@
         try {
             Class<? extends SignatureAlgorithmSpi> implementingClass =
                 algorithmHash.get(algorithmURI);
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Create URI \"" + algorithmURI + "\" class \""
-                   + implementingClass + "\"");
+            LOG.debug("Create URI \"{}\" class \"{}\"", algorithmURI, implementingClass);
+            if (implementingClass == null) {
+                Object exArgs[] = { algorithmURI };
+                throw new XMLSignatureException("algorithms.NoSuchAlgorithmNoEx", exArgs);
             }
-            return implementingClass.newInstance();
-        }  catch (IllegalAccessException ex) {
+            SignatureAlgorithmSpi tmp = implementingClass.newInstance();
+            return tmp;
+        }  catch (IllegalAccessException | InstantiationException | NullPointerException ex) {
             Object exArgs[] = { algorithmURI, ex.getMessage() };
-            throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, ex);
-        } catch (InstantiationException ex) {
-            Object exArgs[] = { algorithmURI, ex.getMessage() };
-            throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, ex);
-        } catch (NullPointerException ex) {
-            Object exArgs[] = { algorithmURI, ex.getMessage() };
-            throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, ex);
+            throw new XMLSignatureException(ex, "algorithms.NoSuchAlgorithm", exArgs);
         }
     }
 
@@ -311,14 +305,14 @@
      * @return the URI representation of Transformation algorithm
      */
     public final String getURI() {
-        return constructionElement.getAttributeNS(null, Constants._ATT_ALGORITHM);
+        return getLocalAttribute(Constants._ATT_ALGORITHM);
     }
 
     /**
      * Registers implementing class of the SignatureAlgorithm with algorithmURI
      *
-     * @param algorithmURI algorithmURI URI representation of <code>SignatureAlgorithm</code>.
-     * @param implementingClass <code>implementingClass</code> the implementing class of
+     * @param algorithmURI algorithmURI URI representation of {@code SignatureAlgorithm}.
+     * @param implementingClass {@code implementingClass} the implementing class of
      * {@link SignatureAlgorithmSpi}
      * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI is already registered
      * @throws XMLSignatureException
@@ -330,9 +324,7 @@
        throws AlgorithmAlreadyRegisteredException, ClassNotFoundException,
            XMLSignatureException {
         JavaUtils.checkRegisterPermission();
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Try to register " + algorithmURI + " " + implementingClass);
-        }
+        LOG.debug("Try to register {} {}", algorithmURI, implementingClass);
 
         // are we already registered?
         Class<? extends SignatureAlgorithmSpi> registeredClass = algorithmHash.get(algorithmURI);
@@ -349,15 +341,15 @@
             algorithmHash.put(algorithmURI, clazz);
         } catch (NullPointerException ex) {
             Object exArgs[] = { algorithmURI, ex.getMessage() };
-            throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs, ex);
+            throw new XMLSignatureException(ex, "algorithms.NoSuchAlgorithm", exArgs);
         }
     }
 
     /**
-     * Registers implementing class of the Transform algorithm with algorithmURI
+     * Registers implementing class of the SignatureAlgorithm with algorithmURI
      *
-     * @param algorithmURI algorithmURI URI representation of <code>SignatureAlgorithm</code>.
-     * @param implementingClass <code>implementingClass</code> the implementing class of
+     * @param algorithmURI algorithmURI URI representation of {@code SignatureAlgorithm}.
+     * @param implementingClass {@code implementingClass} the implementing class of
      * {@link SignatureAlgorithmSpi}
      * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI is already registered
      * @throws XMLSignatureException
@@ -368,9 +360,7 @@
        throws AlgorithmAlreadyRegisteredException, ClassNotFoundException,
            XMLSignatureException {
         JavaUtils.checkRegisterPermission();
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Try to register " + algorithmURI + " " + implementingClass);
-        }
+        LOG.debug("Try to register {} {}", algorithmURI, implementingClass);
 
         // are we already registered?
         Class<? extends SignatureAlgorithmSpi> registeredClass = algorithmHash.get(algorithmURI);
@@ -408,6 +398,9 @@
             SignatureBaseRSA.SignatureRSARIPEMD160.class
         );
         algorithmHash.put(
+            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA224, SignatureBaseRSA.SignatureRSASHA224.class
+        );
+        algorithmHash.put(
             XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256, SignatureBaseRSA.SignatureRSASHA256.class
         );
         algorithmHash.put(
@@ -417,9 +410,27 @@
             XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512, SignatureBaseRSA.SignatureRSASHA512.class
         );
         algorithmHash.put(
+            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1_MGF1, SignatureBaseRSA.SignatureRSASHA1MGF1.class
+        );
+        algorithmHash.put(
+            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA224_MGF1, SignatureBaseRSA.SignatureRSASHA224MGF1.class
+        );
+        algorithmHash.put(
+            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256_MGF1, SignatureBaseRSA.SignatureRSASHA256MGF1.class
+        );
+        algorithmHash.put(
+            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384_MGF1, SignatureBaseRSA.SignatureRSASHA384MGF1.class
+        );
+        algorithmHash.put(
+            XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512_MGF1, SignatureBaseRSA.SignatureRSASHA512MGF1.class
+        );
+        algorithmHash.put(
             XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA1, SignatureECDSA.SignatureECDSASHA1.class
         );
         algorithmHash.put(
+            XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA224, SignatureECDSA.SignatureECDSASHA224.class
+        );
+        algorithmHash.put(
             XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA256, SignatureECDSA.SignatureECDSASHA256.class
         );
         algorithmHash.put(
@@ -429,12 +440,18 @@
             XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA512, SignatureECDSA.SignatureECDSASHA512.class
         );
         algorithmHash.put(
+            XMLSignature.ALGO_ID_SIGNATURE_ECDSA_RIPEMD160, SignatureECDSA.SignatureECDSARIPEMD160.class
+        );
+        algorithmHash.put(
             XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5, IntegrityHmac.IntegrityHmacMD5.class
         );
         algorithmHash.put(
             XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160, IntegrityHmac.IntegrityHmacRIPEMD160.class
         );
         algorithmHash.put(
+            XMLSignature.ALGO_ID_MAC_HMAC_SHA224, IntegrityHmac.IntegrityHmacSHA224.class
+        );
+        algorithmHash.put(
             XMLSignature.ALGO_ID_MAC_HMAC_SHA256, IntegrityHmac.IntegrityHmacSHA256.class
         );
         algorithmHash.put(
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithmSpi.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithmSpi.java	Sat Oct 24 01:11:51 2020 +0100
@@ -32,9 +32,9 @@
 public abstract class SignatureAlgorithmSpi {
 
     /**
-     * Returns the URI representation of <code>Transformation algorithm</code>
+     * Returns the URI representation of {@code Transformation algorithm}
      *
-     * @return the URI representation of <code>Transformation algorithm</code>
+     * @return the URI representation of {@code Transformation algorithm}
      */
     protected abstract String engineGetURI();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/ECDSAUtils.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,918 @@
+/*
+ * 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.io.IOException;
+import java.math.BigInteger;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public final class ECDSAUtils {
+
+    private ECDSAUtils() {
+        // complete
+    }
+
+    /**
+     * Converts an ASN.1 ECDSA value to a XML Signature ECDSA Value.
+     * <p></p>
+     * The JAVA JCE ECDSA Signature algorithm creates ASN.1 encoded (r, s) value
+     * pairs; the XML Signature requires the core BigInteger values.
+     *
+     * @param asn1Bytes
+     * @return the decode bytes
+     * @throws IOException
+     * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
+     * @see <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc4050.txt">3.3. ECDSA Signatures</A>
+     */
+    public static byte[] convertASN1toXMLDSIG(byte asn1Bytes[]) throws IOException {
+
+        if (asn1Bytes.length < 8 || asn1Bytes[0] != 48) {
+            throw new IOException("Invalid ASN.1 format of ECDSA signature");
+        }
+        int offset;
+        if (asn1Bytes[1] > 0) {
+            offset = 2;
+        } else if (asn1Bytes[1] == (byte) 0x81) {
+            offset = 3;
+        } else {
+            throw new IOException("Invalid ASN.1 format of ECDSA signature");
+        }
+
+        byte rLength = asn1Bytes[offset + 1];
+        int i;
+
+        for (i = rLength; i > 0 && asn1Bytes[offset + 2 + rLength - i] == 0; i--); //NOPMD
+
+        byte sLength = asn1Bytes[offset + 2 + rLength + 1];
+        int j;
+
+        for (j = sLength; j > 0 && asn1Bytes[offset + 2 + rLength + 2 + sLength - j] == 0; j--); //NOPMD
+
+        int rawLen = Math.max(i, j);
+
+        if ((asn1Bytes[offset - 1] & 0xff) != asn1Bytes.length - offset
+                || (asn1Bytes[offset - 1] & 0xff) != 2 + rLength + 2 + sLength
+                || asn1Bytes[offset] != 2
+                || asn1Bytes[offset + 2 + rLength] != 2) {
+            throw new IOException("Invalid ASN.1 format of ECDSA signature");
+        }
+        byte xmldsigBytes[] = new byte[2 * rawLen];
+
+        System.arraycopy(asn1Bytes, offset + 2 + rLength - i, xmldsigBytes, rawLen - i, i);
+        System.arraycopy(asn1Bytes, offset + 2 + rLength + 2 + sLength - j, xmldsigBytes,
+                2 * rawLen - j, j);
+
+        return xmldsigBytes;
+    }
+
+    /**
+     * Converts a XML Signature ECDSA Value to an ASN.1 DSA value.
+     * <p></p>
+     * The JAVA JCE ECDSA Signature algorithm creates ASN.1 encoded (r, s) value
+     * pairs; the XML Signature requires the core BigInteger values.
+     *
+     * @param xmldsigBytes
+     * @return the encoded ASN.1 bytes
+     * @throws IOException
+     * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
+     * @see <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc4050.txt">3.3. ECDSA Signatures</A>
+     */
+    public static byte[] convertXMLDSIGtoASN1(byte xmldsigBytes[]) throws IOException {
+
+        int rawLen = xmldsigBytes.length / 2;
+
+        int i;
+
+        for (i = rawLen; i > 0 && xmldsigBytes[rawLen - i] == 0; i--); //NOPMD
+
+        int j = i;
+
+        if (xmldsigBytes[rawLen - i] < 0) {
+            j += 1;
+        }
+
+        int k;
+
+        for (k = rawLen; k > 0 && xmldsigBytes[2 * rawLen - k] == 0; k--); //NOPMD
+
+        int l = k;
+
+        if (xmldsigBytes[2 * rawLen - k] < 0) {
+            l += 1;
+        }
+
+        int len = 2 + j + 2 + l;
+        if (len > 255) {
+            throw new IOException("Invalid XMLDSIG format of ECDSA signature");
+        }
+        int offset;
+        byte asn1Bytes[];
+        if (len < 128) {
+            asn1Bytes = new byte[2 + 2 + j + 2 + l];
+            offset = 1;
+        } else {
+            asn1Bytes = new byte[3 + 2 + j + 2 + l];
+            asn1Bytes[1] = (byte) 0x81;
+            offset = 2;
+        }
+        asn1Bytes[0] = 48;
+        asn1Bytes[offset++] = (byte) len;
+        asn1Bytes[offset++] = 2;
+        asn1Bytes[offset++] = (byte) j;
+
+        System.arraycopy(xmldsigBytes, rawLen - i, asn1Bytes, offset + j - i, i);
+
+        offset += j;
+
+        asn1Bytes[offset++] = 2;
+        asn1Bytes[offset++] = (byte) l;
+
+        System.arraycopy(xmldsigBytes, 2 * rawLen - k, asn1Bytes, offset + l - k, k);
+
+        return asn1Bytes;
+    }
+
+    private static final List<ECCurveDefinition> ecCurveDefinitions = new ArrayList<>();
+
+    static {
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp112r1",
+                        "1.3.132.0.6",
+                        "db7c2abf62e35e668076bead208b",
+                        "db7c2abf62e35e668076bead2088",
+                        "659ef8ba043916eede8911702b22",
+                        "09487239995a5ee76b55f9c2f098",
+                        "a89ce5af8724c0a23e0e0ff77500",
+                        "db7c2abf62e35e7628dfac6561c5",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp112r2",
+                        "1.3.132.0.7",
+                        "db7c2abf62e35e668076bead208b",
+                        "6127c24c05f38a0aaaf65c0ef02c",
+                        "51def1815db5ed74fcc34c85d709",
+                        "4ba30ab5e892b4e1649dd0928643",
+                        "adcd46f5882e3747def36e956e97",
+                        "36df0aafd8b8d7597ca10520d04b",
+                        4)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp128r1",
+                        "1.3.132.0.28",
+                        "fffffffdffffffffffffffffffffffff",
+                        "fffffffdfffffffffffffffffffffffc",
+                        "e87579c11079f43dd824993c2cee5ed3",
+                        "161ff7528b899b2d0c28607ca52c5b86",
+                        "cf5ac8395bafeb13c02da292dded7a83",
+                        "fffffffe0000000075a30d1b9038a115",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp128r2",
+                        "1.3.132.0.29",
+                        "fffffffdffffffffffffffffffffffff",
+                        "d6031998d1b3bbfebf59cc9bbff9aee1",
+                        "5eeefca380d02919dc2c6558bb6d8a5d",
+                        "7b6aa5d85e572983e6fb32a7cdebc140",
+                        "27b6916a894d3aee7106fe805fc34b44",
+                        "3fffffff7fffffffbe0024720613b5a3",
+                        4)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp160k1",
+                        "1.3.132.0.9",
+                        "fffffffffffffffffffffffffffffffeffffac73",
+                        "0000000000000000000000000000000000000000",
+                        "0000000000000000000000000000000000000007",
+                        "3b4c382ce37aa192a4019e763036f4f5dd4d7ebb",
+                        "938cf935318fdced6bc28286531733c3f03c4fee",
+                        "0100000000000000000001b8fa16dfab9aca16b6b3",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp160r1",
+                        "1.3.132.0.8",
+                        "ffffffffffffffffffffffffffffffff7fffffff",
+                        "ffffffffffffffffffffffffffffffff7ffffffc",
+                        "1c97befc54bd7a8b65acf89f81d4d4adc565fa45",
+                        "4a96b5688ef573284664698968c38bb913cbfc82",
+                        "23a628553168947d59dcc912042351377ac5fb32",
+                        "0100000000000000000001f4c8f927aed3ca752257",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp160r2",
+                        "1.3.132.0.30",
+                        "fffffffffffffffffffffffffffffffeffffac73",
+                        "fffffffffffffffffffffffffffffffeffffac70",
+                        "b4e134d3fb59eb8bab57274904664d5af50388ba",
+                        "52dcb034293a117e1f4ff11b30f7199d3144ce6d",
+                        "feaffef2e331f296e071fa0df9982cfea7d43f2e",
+                        "0100000000000000000000351ee786a818f3a1a16b",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp192k1",
+                        "1.3.132.0.31",
+                        "fffffffffffffffffffffffffffffffffffffffeffffee37",
+                        "000000000000000000000000000000000000000000000000",
+                        "000000000000000000000000000000000000000000000003",
+                        "db4ff10ec057e9ae26b07d0280b7f4341da5d1b1eae06c7d",
+                        "9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d",
+                        "fffffffffffffffffffffffe26f2fc170f69466a74defd8d",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp192r1 [NIST P-192, X9.62 prime192v1]",
+                        "1.2.840.10045.3.1.1",
+                        "fffffffffffffffffffffffffffffffeffffffffffffffff",
+                        "fffffffffffffffffffffffffffffffefffffffffffffffc",
+                        "64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
+                        "188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
+                        "07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
+                        "ffffffffffffffffffffffff99def836146bc9b1b4d22831",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp224k1",
+                        "1.3.132.0.32",
+                        "fffffffffffffffffffffffffffffffffffffffffffffffeffffe56d",
+                        "00000000000000000000000000000000000000000000000000000000",
+                        "00000000000000000000000000000000000000000000000000000005",
+                        "a1455b334df099df30fc28a169a467e9e47075a90f7e650eb6b7a45c",
+                        "7e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5",
+                        "010000000000000000000000000001dce8d2ec6184caf0a971769fb1f7",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp224r1 [NIST P-224]",
+                        "1.3.132.0.33",
+                        "ffffffffffffffffffffffffffffffff000000000000000000000001",
+                        "fffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
+                        "b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
+                        "b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
+                        "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
+                        "ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp256k1",
+                        "1.3.132.0.10",
+                        "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
+                        "0000000000000000000000000000000000000000000000000000000000000000",
+                        "0000000000000000000000000000000000000000000000000000000000000007",
+                        "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
+                        "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
+                        "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp256r1 [NIST P-256, X9.62 prime256v1]",
+                        "1.2.840.10045.3.1.7",
+                        "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+                        "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
+                        "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
+                        "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
+                        "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
+                        "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp384r1 [NIST P-384]",
+                        "1.3.132.0.34",
+                        "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
+                        "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc",
+                        "b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef",
+                        "aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7",
+                        "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f",
+                        "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "secp521r1 [NIST P-521]",
+                        "1.3.132.0.35",
+                        "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+                        "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
+                        "0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
+                        "00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
+                        "011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
+                        "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 prime192v2",
+                        "1.2.840.10045.3.1.2",
+                        "fffffffffffffffffffffffffffffffeffffffffffffffff",
+                        "fffffffffffffffffffffffffffffffefffffffffffffffc",
+                        "cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953",
+                        "eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a",
+                        "6574d11d69b6ec7a672bb82a083df2f2b0847de970b2de15",
+                        "fffffffffffffffffffffffe5fb1a724dc80418648d8dd31",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 prime192v3",
+                        "1.2.840.10045.3.1.3",
+                        "fffffffffffffffffffffffffffffffeffffffffffffffff",
+                        "fffffffffffffffffffffffffffffffefffffffffffffffc",
+                        "22123dc2395a05caa7423daeccc94760a7d462256bd56916",
+                        "7d29778100c65a1da1783716588dce2b8b4aee8e228f1896",
+                        "38a90f22637337334b49dcb66a6dc8f9978aca7648a943b0",
+                        "ffffffffffffffffffffffff7a62d031c83f4294f640ec13",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 prime239v1",
+                        "1.2.840.10045.3.1.4",
+                        "7fffffffffffffffffffffff7fffffffffff8000000000007fffffffffff",
+                        "7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc",
+                        "6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a",
+                        "0ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf",
+                        "7debe8e4e90a5dae6e4054ca530ba04654b36818ce226b39fccb7b02f1ae",
+                        "7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 prime239v2",
+                        "1.2.840.10045.3.1.5",
+                        "7fffffffffffffffffffffff7fffffffffff8000000000007fffffffffff",
+                        "7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc",
+                        "617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c",
+                        "38af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7",
+                        "5b0125e4dbea0ec7206da0fc01d9b081329fb555de6ef460237dff8be4ba",
+                        "7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 prime239v3",
+                        "1.2.840.10045.3.1.6",
+                        "7fffffffffffffffffffffff7fffffffffff8000000000007fffffffffff",
+                        "7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc",
+                        "255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e",
+                        "6768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a",
+                        "1607e6898f390c06bc1d552bad226f3b6fcfe48b6e818499af18e3ed6cf3",
+                        "7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551",
+                        1)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect113r1",
+                        "1.3.132.0.4",
+                        "020000000000000000000000000201",
+                        "003088250ca6e7c7fe649ce85820f7",
+                        "00e8bee4d3e2260744188be0e9c723",
+                        "009d73616f35f4ab1407d73562c10f",
+                        "00a52830277958ee84d1315ed31886",
+                        "0100000000000000d9ccec8a39e56f",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect113r2",
+                        "1.3.132.0.5",
+                        "020000000000000000000000000201",
+                        "00689918dbec7e5a0dd6dfc0aa55c7",
+                        "0095e9a9ec9b297bd4bf36e059184f",
+                        "01a57a6a7b26ca5ef52fcdb8164797",
+                        "00b3adc94ed1fe674c06e695baba1d",
+                        "010000000000000108789b2496af93",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect131r1",
+                        "1.3.132.0.22",
+                        "080000000000000000000000000000010d",
+                        "07a11b09a76b562144418ff3ff8c2570b8",
+                        "0217c05610884b63b9c6c7291678f9d341",
+                        "0081baf91fdf9833c40f9c181343638399",
+                        "078c6e7ea38c001f73c8134b1b4ef9e150",
+                        "0400000000000000023123953a9464b54d",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect131r2",
+                        "1.3.132.0.23",
+                        "080000000000000000000000000000010d",
+                        "03e5a88919d7cafcbf415f07c2176573b2",
+                        "04b8266a46c55657ac734ce38f018f2192",
+                        "0356dcd8f2f95031ad652d23951bb366a8",
+                        "0648f06d867940a5366d9e265de9eb240f",
+                        "0400000000000000016954a233049ba98f",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect163k1 [NIST K-163]",
+                        "1.3.132.0.1",
+                        "0800000000000000000000000000000000000000c9",
+                        "000000000000000000000000000000000000000001",
+                        "000000000000000000000000000000000000000001",
+                        "02fe13c0537bbc11acaa07d793de4e6d5e5c94eee8",
+                        "0289070fb05d38ff58321f2e800536d538ccdaa3d9",
+                        "04000000000000000000020108a2e0cc0d99f8a5ef",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect163r1",
+                        "1.3.132.0.2",
+                        "0800000000000000000000000000000000000000c9",
+                        "07b6882caaefa84f9554ff8428bd88e246d2782ae2",
+                        "0713612dcddcb40aab946bda29ca91f73af958afd9",
+                        "0369979697ab43897789566789567f787a7876a654",
+                        "00435edb42efafb2989d51fefce3c80988f41ff883",
+                        "03ffffffffffffffffffff48aab689c29ca710279b",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect163r2 [NIST B-163]",
+                        "1.3.132.0.15",
+                        "0800000000000000000000000000000000000000c9",
+                        "000000000000000000000000000000000000000001",
+                        "020a601907b8c953ca1481eb10512f78744a3205fd",
+                        "03f0eba16286a2d57ea0991168d4994637e8343e36",
+                        "00d51fbc6c71a0094fa2cdd545b11c5c0c797324f1",
+                        "040000000000000000000292fe77e70c12a4234c33",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect193r1",
+                        "1.3.132.0.24",
+                        "02000000000000000000000000000000000000000000008001",
+                        "0017858feb7a98975169e171f77b4087de098ac8a911df7b01",
+                        "00fdfb49bfe6c3a89facadaa7a1e5bbc7cc1c2e5d831478814",
+                        "01f481bc5f0ff84a74ad6cdf6fdef4bf6179625372d8c0c5e1",
+                        "0025e399f2903712ccf3ea9e3a1ad17fb0b3201b6af7ce1b05",
+                        "01000000000000000000000000c7f34a778f443acc920eba49",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect193r2",
+                        "1.3.132.0.25",
+                        "02000000000000000000000000000000000000000000008001",
+                        "0163f35a5137c2ce3ea6ed8667190b0bc43ecd69977702709b",
+                        "00c9bb9e8927d4d64c377e2ab2856a5b16e3efb7f61d4316ae",
+                        "00d9b67d192e0367c803f39e1a7e82ca14a651350aae617e8f",
+                        "01ce94335607c304ac29e7defbd9ca01f596f927224cdecf6c",
+                        "010000000000000000000000015aab561b005413ccd4ee99d5",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect233k1 [NIST K-233]",
+                        "1.3.132.0.26",
+                        "020000000000000000000000000000000000000004000000000000000001",
+                        "000000000000000000000000000000000000000000000000000000000000",
+                        "000000000000000000000000000000000000000000000000000000000001",
+                        "017232ba853a7e731af129f22ff4149563a419c26bf50a4c9d6eefad6126",
+                        "01db537dece819b7f70f555a67c427a8cd9bf18aeb9b56e0c11056fae6a3",
+                        "008000000000000000000000000000069d5bb915bcd46efb1ad5f173abdf",
+                        4)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect233r1 [NIST B-233]",
+                        "1.3.132.0.27",
+                        "020000000000000000000000000000000000000004000000000000000001",
+                        "000000000000000000000000000000000000000000000000000000000001",
+                        "0066647ede6c332c7f8c0923bb58213b333b20e9ce4281fe115f7d8f90ad",
+                        "00fac9dfcbac8313bb2139f1bb755fef65bc391f8b36f8f8eb7371fd558b",
+                        "01006a08a41903350678e58528bebf8a0beff867a7ca36716f7e01f81052",
+                        "01000000000000000000000000000013e974e72f8a6922031d2603cfe0d7",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect239k1",
+                        "1.3.132.0.3",
+                        "800000000000000000004000000000000000000000000000000000000001",
+                        "000000000000000000000000000000000000000000000000000000000000",
+                        "000000000000000000000000000000000000000000000000000000000001",
+                        "29a0b6a887a983e9730988a68727a8b2d126c44cc2cc7b2a6555193035dc",
+                        "76310804f12e549bdb011c103089e73510acb275fc312a5dc6b76553f0ca",
+                        "2000000000000000000000000000005a79fec67cb6e91f1c1da800e478a5",
+                        4)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect283k1 [NIST K-283]",
+                        "1.3.132.0.16",
+                        "0800000000000000000000000000000000000000000000000000000000000000000010a1",
+                        "000000000000000000000000000000000000000000000000000000000000000000000000",
+                        "000000000000000000000000000000000000000000000000000000000000000000000001",
+                        "0503213f78ca44883f1a3b8162f188e553cd265f23c1567a16876913b0c2ac2458492836",
+                        "01ccda380f1c9e318d90f95d07e5426fe87e45c0e8184698e45962364e34116177dd2259",
+                        "01ffffffffffffffffffffffffffffffffffe9ae2ed07577265dff7f94451e061e163c61",
+                        4)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect283r1 [NIST B-283]",
+                        "1.3.132.0.17",
+                        "0800000000000000000000000000000000000000000000000000000000000000000010a1",
+                        "000000000000000000000000000000000000000000000000000000000000000000000001",
+                        "027b680ac8b8596da5a4af8a19a0303fca97fd7645309fa2a581485af6263e313b79a2f5",
+                        "05f939258db7dd90e1934f8c70b0dfec2eed25b8557eac9c80e2e198f8cdbecd86b12053",
+                        "03676854fe24141cb98fe6d4b20d02b4516ff702350eddb0826779c813f0df45be8112f4",
+                        "03ffffffffffffffffffffffffffffffffffef90399660fc938a90165b042a7cefadb307",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect409k1 [NIST K-409]",
+                        "1.3.132.0.36",
+                        "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+                        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+                        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+                        "0060f05f658f49c1ad3ab1890f7184210efd0987e307c84c27accfb8f9f67cc2c460189eb5aaaa62ee222eb1b35540cfe9023746",
+                        "01e369050b7c4e42acba1dacbf04299c3460782f918ea427e6325165e9ea10e3da5f6c42e9c55215aa9ca27a5863ec48d8e0286b",
+                        "007ffffffffffffffffffffffffffffffffffffffffffffffffffe5f83b2d4ea20400ec4557d5ed3e3e7ca5b4b5c83b8e01e5fcf",
+                        4)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect409r1 [NIST B-409]",
+                        "1.3.132.0.37",
+                        "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+                        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+                        "0021a5c2c8ee9feb5c4b9a753b7b476b7fd6422ef1f3dd674761fa99d6ac27c8a9a197b272822f6cd57a55aa4f50ae317b13545f",
+                        "015d4860d088ddb3496b0c6064756260441cde4af1771d4db01ffe5b34e59703dc255a868a1180515603aeab60794e54bb7996a7",
+                        "0061b1cfab6be5f32bbfa78324ed106a7636b9c5a7bd198d0158aa4f5488d08f38514f1fdf4b4f40d2181b3681c364ba0273c706",
+                        "010000000000000000000000000000000000000000000000000001e2aad6a612f33307be5fa47c3c9e052f838164cd37d9a21173",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect571k1 [NIST K-571]",
+                        "1.3.132.0.38",
+                        "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+                        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+                        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+                        "026eb7a859923fbc82189631f8103fe4ac9ca2970012d5d46024804801841ca44370958493b205e647da304db4ceb08cbbd1ba39494776fb988b47174dca88c7e2945283a01c8972",
+                        "0349dc807f4fbf374f4aeade3bca95314dd58cec9f307a54ffc61efc006d8a2c9d4979c0ac44aea74fbebbb9f772aedcb620b01a7ba7af1b320430c8591984f601cd4c143ef1c7a3",
+                        "020000000000000000000000000000000000000000000000000000000000000000000000131850e1f19a63e4b391a8db917f4138b630d84be5d639381e91deb45cfe778f637c1001",
+                        4)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "sect571r1 [NIST B-571]",
+                        "1.3.132.0.39",
+                        "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+                        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+                        "02f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a",
+                        "0303001d34b856296c16c0d40d3cd7750a93d1d2955fa80aa5f40fc8db7b2abdbde53950f4c0d293cdd711a35b67fb1499ae60038614f1394abfa3b4c850d927e1e7769c8eec2d19",
+                        "037bf27342da639b6dccfffeb73d69d78c6c27a6009cbbca1980f8533921e8a684423e43bab08a576291af8f461bb2a8b3531d2f0485c19b16e2f1516e23dd3c1a4827af1b8ac15b",
+                        "03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 c2tnb191v1",
+                        "1.2.840.10045.3.0.5",
+                        "800000000000000000000000000000000000000000000201",
+                        "2866537b676752636a68f56554e12640276b649ef7526267",
+                        "2e45ef571f00786f67b0081b9495a3d95462f5de0aa185ec",
+                        "36b3daf8a23206f9c4f299d7b21a9c369137f2c84ae1aa0d",
+                        "765be73433b3f95e332932e70ea245ca2418ea0ef98018fb",
+                        "40000000000000000000000004a20e90c39067c893bbb9a5",
+                        2)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 c2tnb191v2",
+                        "1.2.840.10045.3.0.6",
+                        "800000000000000000000000000000000000000000000201",
+                        "401028774d7777c7b7666d1366ea432071274f89ff01e718",
+                        "0620048d28bcbd03b6249c99182b7c8cd19700c362c46a01",
+                        "3809b2b7cc1b28cc5a87926aad83fd28789e81e2c9e3bf10",
+                        "17434386626d14f3dbf01760d9213a3e1cf37aec437d668a",
+                        "20000000000000000000000050508cb89f652824e06b8173",
+                        4)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 c2tnb191v3",
+                        "1.2.840.10045.3.0.7",
+                        "800000000000000000000000000000000000000000000201",
+                        "6c01074756099122221056911c77d77e77a777e7e7e77fcb",
+                        "71fe1af926cf847989efef8db459f66394d90f32ad3f15e8",
+                        "375d4ce24fde434489de8746e71786015009e66e38a926dd",
+                        "545a39176196575d985999366e6ad34ce0a77cd7127b06be",
+                        "155555555555555555555555610c0b196812bfb6288a3ea3",
+                        6)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 c2tnb239v1",
+                        "1.2.840.10045.3.0.11",
+                        "800000000000000000000000000000000000000000000000001000000001",
+                        "32010857077c5431123a46b808906756f543423e8d27877578125778ac76",
+                        "790408f2eedaf392b012edefb3392f30f4327c0ca3f31fc383c422aa8c16",
+                        "57927098fa932e7c0a96d3fd5b706ef7e5f5c156e16b7e7c86038552e91d",
+                        "61d8ee5077c33fecf6f1a16b268de469c3c7744ea9a971649fc7a9616305",
+                        "2000000000000000000000000000000f4d42ffe1492a4993f1cad666e447",
+                        4)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 c2tnb239v2",
+                        "1.2.840.10045.3.0.12",
+                        "800000000000000000000000000000000000000000000000001000000001",
+                        "4230017757a767fae42398569b746325d45313af0766266479b75654e65f",
+                        "5037ea654196cff0cd82b2c14a2fcf2e3ff8775285b545722f03eacdb74b",
+                        "28f9d04e900069c8dc47a08534fe76d2b900b7d7ef31f5709f200c4ca205",
+                        "5667334c45aff3b5a03bad9dd75e2c71a99362567d5453f7fa6e227ec833",
+                        "1555555555555555555555555555553c6f2885259c31e3fcdf154624522d",
+                        6)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 c2tnb239v3",
+                        "1.2.840.10045.3.0.13",
+                        "800000000000000000000000000000000000000000000000001000000001",
+                        "01238774666a67766d6676f778e676b66999176666e687666d8766c66a9f",
+                        "6a941977ba9f6a435199acfc51067ed587f519c5ecb541b8e44111de1d40",
+                        "70f6e9d04d289c4e89913ce3530bfde903977d42b146d539bf1bde4e9c92",
+                        "2e5a0eaf6e5e1305b9004dce5c0ed7fe59a35608f33837c816d80b79f461",
+                        "0cccccccccccccccccccccccccccccac4912d2d9df903ef9888b8a0e4cff",
+                        0xA)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 c2tnb359v1",
+                        "1.2.840.10045.3.0.18",
+                        "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001",
+                        "5667676a654b20754f356ea92017d946567c46675556f19556a04616b567d223a5e05656fb549016a96656a557",
+                        "2472e2d0197c49363f1fe7f5b6db075d52b6947d135d8ca445805d39bc345626089687742b6329e70680231988",
+                        "3c258ef3047767e7ede0f1fdaa79daee3841366a132e163aced4ed2401df9c6bdcde98e8e707c07a2239b1b097",
+                        "53d7e08529547048121e9c95f3791dd804963948f34fae7bf44ea82365dc7868fe57e4ae2de211305a407104bd",
+                        "01af286bca1af286bca1af286bca1af286bca1af286bc9fb8f6b85c556892c20a7eb964fe7719e74f490758d3b",
+                        0x4C)
+        );
+
+        ecCurveDefinitions.add(
+                new ECCurveDefinition(
+                        "X9.62 c2tnb431r1",
+                        "1.2.840.10045.3.0.20",
+                        "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001",
+                        "1a827ef00dd6fc0e234caf046c6a5d8a85395b236cc4ad2cf32a0cadbdc9ddf620b0eb9906d0957f6c6feacd615468df104de296cd8f",
+                        "10d9b4a3d9047d8b154359abfb1b7f5485b04ceb868237ddc9deda982a679a5a919b626d4e50a8dd731b107a9962381fb5d807bf2618",
+                        "120fc05d3c67a99de161d2f4092622feca701be4f50f4758714e8a87bbf2a658ef8c21e7c5efe965361f6c2999c0c247b0dbd70ce6b7",
+                        "20d0af8903a96f8d5fa2c255745d3c451b302c9346d9b7e485e7bce41f6b591f3e8f6addcbb0bc4c2f947a7de1a89b625d6a598b3760",
+                        "0340340340340340340340340340340340340340340340340340340323c313fab50589703b5ec68d3587fec60d161cc149c1ad4a91",
+                        0x2760)
+        );
+    }
+
+    public static String getOIDFromPublicKey(ECPublicKey ecPublicKey) {
+        ECParameterSpec ecParameterSpec = ecPublicKey.getParams();
+        BigInteger order = ecParameterSpec.getOrder();
+        BigInteger affineX = ecParameterSpec.getGenerator().getAffineX();
+        BigInteger affineY = ecParameterSpec.getGenerator().getAffineY();
+        BigInteger a = ecParameterSpec.getCurve().getA();
+        BigInteger b = ecParameterSpec.getCurve().getB();
+        int h = ecParameterSpec.getCofactor();
+        ECField ecField = ecParameterSpec.getCurve().getField();
+        BigInteger field;
+        if (ecField instanceof ECFieldFp) {
+            ECFieldFp ecFieldFp = (ECFieldFp) ecField;
+            field = ecFieldFp.getP();
+        } else {
+            ECFieldF2m ecFieldF2m = (ECFieldF2m) ecField;
+            field = ecFieldF2m.getReductionPolynomial();
+        }
+
+        Iterator<ECCurveDefinition> ecCurveDefinitionIterator = ecCurveDefinitions.iterator();
+        while (ecCurveDefinitionIterator.hasNext()) {
+            ECCurveDefinition ecCurveDefinition = ecCurveDefinitionIterator.next();
+            String oid = ecCurveDefinition.equals(field, a, b, affineX, affineY, order, h);
+            if (oid != null) {
+                return oid;
+            }
+        }
+        return null;
+    }
+
+    public static ECCurveDefinition getECCurveDefinition(String oid) {
+        Iterator<ECCurveDefinition> ecCurveDefinitionIterator = ecCurveDefinitions.iterator();
+        while (ecCurveDefinitionIterator.hasNext()) {
+            ECCurveDefinition ecCurveDefinition = ecCurveDefinitionIterator.next();
+            if (ecCurveDefinition.getOid().equals(oid)) {
+                return ecCurveDefinition;
+            }
+        }
+        return null;
+    }
+
+    public static class ECCurveDefinition {
+
+        private final String name;
+        private final String oid;
+        private final String field;
+        private final String a;
+        private final String b;
+        private final String x;
+        private final String y;
+        private final String n;
+        private final int h;
+
+        public ECCurveDefinition(String name, String oid, String field, String a, String b, String x, String y, String n, int h) {
+            this.name = name;
+            this.oid = oid;
+            this.field = field;
+            this.a = a;
+            this.b = b;
+            this.x = x;
+            this.y = y;
+            this.n = n;
+            this.h = h;
+        }
+
+        /**
+         * returns the ec oid if parameter are equal to this definition
+         */
+        public String equals(BigInteger field, BigInteger a, BigInteger b, BigInteger x, BigInteger y, BigInteger n, int h) {
+            if (this.field.equals(field.toString(16))
+                    && this.a.equals(a.toString(16))
+                    && this.b.equals(b.toString(16))
+                    && this.x.equals(x.toString(16))
+                    && this.y.equals(y.toString(16))
+                    && this.n.equals(n.toString(16))
+                    && this.h == h) {
+                return this.oid;
+            }
+            return null;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public String getOid() {
+            return oid;
+        }
+
+        public String getField() {
+            return field;
+        }
+
+        public String getA() {
+            return a;
+        }
+
+        public String getB() {
+            return b;
+        }
+
+        public String getX() {
+            return x;
+        }
+
+        public String getY() {
+            return y;
+        }
+
+        public String getN() {
+            return n;
+        }
+
+        public int getH() {
+            return h;
+        }
+    }
+
+    public static byte[] encodePoint(ECPoint ecPoint, EllipticCurve ellipticCurve) {
+        int size = (ellipticCurve.getField().getFieldSize() + 7) / 8;
+        byte affineXBytes[] = stripLeadingZeros(ecPoint.getAffineX().toByteArray());
+        byte affineYBytes[] = stripLeadingZeros(ecPoint.getAffineY().toByteArray());
+        byte encodedBytes[] = new byte[size * 2 + 1];
+        encodedBytes[0] = 0x04; //uncompressed
+        System.arraycopy(affineXBytes, 0, encodedBytes, size - affineXBytes.length + 1, affineXBytes.length);
+        System.arraycopy(affineYBytes, 0, encodedBytes, encodedBytes.length - affineYBytes.length, affineYBytes.length);
+        return encodedBytes;
+    }
+
+    public static ECPoint decodePoint(byte[] encodedBytes, EllipticCurve elliptiCcurve) {
+        if (encodedBytes[0] != 0x04) {
+            throw new IllegalArgumentException("Only uncompressed format is supported");
+        }
+
+        int size = (elliptiCcurve.getField().getFieldSize() + 7) / 8;
+        byte affineXBytes[] = new byte[size];
+        byte affineYBytes[] = new byte[size];
+        System.arraycopy(encodedBytes, 1, affineXBytes, 0, size);
+        System.arraycopy(encodedBytes, size + 1, affineYBytes, 0, size);
+        return new ECPoint(new BigInteger(1, affineXBytes), new BigInteger(1, affineYBytes));
+    }
+
+    public static byte[] stripLeadingZeros(byte[] bytes) {
+        int i;
+        for (i = 0; i < bytes.length - 1; i++) {
+            if (bytes[i] != 0) {
+                break;
+            }
+        }
+
+        if (i == 0) {
+            return bytes;
+        } else {
+            byte stripped[] = new byte[bytes.length - i];
+            System.arraycopy(bytes, i, stripped, 0, stripped.length);
+            return stripped;
+        }
+    }
+}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java	Sat Oct 24 01:11:51 2020 +0100
@@ -44,21 +44,20 @@
 
 public abstract class IntegrityHmac extends SignatureAlgorithmSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(IntegrityHmac.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(IntegrityHmac.class);
 
     /** Field macAlgorithm */
-    private Mac macAlgorithm = null;
+    private Mac macAlgorithm;
 
     /** Field HMACOutputLength */
-    private int HMACOutputLength = 0;
+    private int HMACOutputLength;
     private boolean HMACOutputLengthSet = false;
 
     /**
      * Method engineGetURI
      *
-     *@inheritDoc
+     *{@inheritDoc}
      */
     public abstract String engineGetURI();
 
@@ -74,9 +73,7 @@
      */
     public IntegrityHmac() throws XMLSignatureException {
         String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Created IntegrityHmacSHA1 using " + algorithmID);
-        }
+        LOG.debug("Created IntegrityHmacSHA1 using {}", algorithmID);
 
         try {
             this.macAlgorithm = Mac.getInstance(algorithmID);
@@ -96,7 +93,7 @@
      * @throws XMLSignatureException
      */
     protected void engineSetParameter(AlgorithmParameterSpec params) throws XMLSignatureException {
-        throw new XMLSignatureException("empty");
+        throw new XMLSignatureException("empty", new Object[]{"Incorrect method call"});
     }
 
     public void reset() {
@@ -116,9 +113,7 @@
     protected boolean engineVerify(byte[] signature) throws XMLSignatureException {
         try {
             if (this.HMACOutputLengthSet && this.HMACOutputLength < getDigestLength()) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "HMACOutputLength must not be less than " + getDigestLength());
-                }
+                LOG.debug("HMACOutputLength must not be less than {}", getDigestLength());
                 Object[] exArgs = { String.valueOf(getDigestLength()) };
                 throw new XMLSignatureException("algorithms.HMACOutputLengthMin", exArgs);
             } else {
@@ -126,7 +121,7 @@
                 return MessageDigestAlgorithm.isEqual(completeResult, signature);
             }
         } catch (IllegalStateException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
@@ -139,7 +134,10 @@
      */
     protected void engineInitVerify(Key secretKey) throws XMLSignatureException {
         if (!(secretKey instanceof SecretKey)) {
-            String supplied = secretKey.getClass().getName();
+            String supplied = null;
+            if (secretKey != null) {
+                supplied = secretKey.getClass().getName();
+            }
             String needed = SecretKey.class.getName();
             Object exArgs[] = { supplied, needed };
 
@@ -156,12 +154,10 @@
                 this.macAlgorithm = Mac.getInstance(macAlgorithm.getAlgorithm());
             } catch (Exception e) {
                 // this shouldn't occur, but if it does, restore previous Mac
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Exception when reinstantiating Mac:" + e);
-                }
+                LOG.debug("Exception when reinstantiating Mac: {}", e);
                 this.macAlgorithm = mac;
             }
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
@@ -175,16 +171,14 @@
     protected byte[] engineSign() throws XMLSignatureException {
         try {
             if (this.HMACOutputLengthSet && this.HMACOutputLength < getDigestLength()) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "HMACOutputLength must not be less than " + getDigestLength());
-                }
+                LOG.debug("HMACOutputLength must not be less than {}", getDigestLength());
                 Object[] exArgs = { String.valueOf(getDigestLength()) };
                 throw new XMLSignatureException("algorithms.HMACOutputLengthMin", exArgs);
             } else {
                 return this.macAlgorithm.doFinal();
             }
         } catch (IllegalStateException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
@@ -195,19 +189,7 @@
      * @throws XMLSignatureException
      */
     protected void engineInitSign(Key secretKey) throws XMLSignatureException {
-        if (!(secretKey instanceof SecretKey)) {
-            String supplied = secretKey.getClass().getName();
-            String needed = SecretKey.class.getName();
-            Object exArgs[] = { supplied, needed };
-
-            throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs);
-        }
-
-        try {
-            this.macAlgorithm.init(secretKey);
-        } catch (InvalidKeyException ex) {
-            throw new XMLSignatureException("empty", ex);
-        }
+        engineInitSign(secretKey, (AlgorithmParameterSpec)null);
     }
 
     /**
@@ -221,7 +203,10 @@
         Key secretKey, AlgorithmParameterSpec algorithmParameterSpec
     ) throws XMLSignatureException {
         if (!(secretKey instanceof SecretKey)) {
-            String supplied = secretKey.getClass().getName();
+            String supplied = null;
+            if (secretKey != null) {
+                supplied = secretKey.getClass().getName();
+            }
             String needed = SecretKey.class.getName();
             Object exArgs[] = { supplied, needed };
 
@@ -229,11 +214,15 @@
         }
 
         try {
-            this.macAlgorithm.init(secretKey, algorithmParameterSpec);
+            if (algorithmParameterSpec == null) {
+                this.macAlgorithm.init(secretKey);
+            } else {
+                this.macAlgorithm.init(secretKey, algorithmParameterSpec);
+            }
         } catch (InvalidKeyException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (InvalidAlgorithmParameterException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
@@ -260,7 +249,7 @@
         try {
             this.macAlgorithm.update(input);
         } catch (IllegalStateException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
@@ -275,7 +264,7 @@
         try {
             this.macAlgorithm.update(input);
         } catch (IllegalStateException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
@@ -292,13 +281,13 @@
         try {
             this.macAlgorithm.update(buf, offset, len);
         } catch (IllegalStateException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
     /**
      * Method engineGetJCEAlgorithmString
-     * @inheritDoc
+     * {@inheritDoc}
      *
      */
     protected String engineGetJCEAlgorithmString() {
@@ -308,7 +297,7 @@
     /**
      * Method engineGetJCEAlgorithmString
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected String engineGetJCEProviderName() {
         return this.macAlgorithm.getProvider().getName();
@@ -360,7 +349,7 @@
             Element HMElem =
                 XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_HMACOUTPUTLENGTH);
             Text HMText =
-                doc.createTextNode(Integer.valueOf(this.HMACOutputLength).toString());
+                doc.createTextNode("" + this.HMACOutputLength);
 
             HMElem.appendChild(HMText);
             XMLUtils.addReturnToElement(element);
@@ -385,7 +374,7 @@
 
         /**
          * Method engineGetURI
-         * @inheritDoc
+         * {@inheritDoc}
          *
          */
         public String engineGetURI() {
@@ -398,6 +387,34 @@
     }
 
     /**
+     * Class IntegrityHmacSHA224
+     */
+    public static class IntegrityHmacSHA224 extends IntegrityHmac {
+
+        /**
+         * Constructor IntegrityHmacSHA224
+         *
+         * @throws XMLSignatureException
+         */
+        public IntegrityHmacSHA224() throws XMLSignatureException {
+            super();
+        }
+
+        /**
+         * Method engineGetURI
+         *
+         * {@inheritDoc}
+         */
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_MAC_HMAC_SHA224;
+        }
+
+        int getDigestLength() {
+            return 224;
+        }
+    }
+
+    /**
      * Class IntegrityHmacSHA256
      */
     public static class IntegrityHmacSHA256 extends IntegrityHmac {
@@ -414,7 +431,7 @@
         /**
          * Method engineGetURI
          *
-         * @inheritDoc
+         * {@inheritDoc}
          */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_MAC_HMAC_SHA256;
@@ -441,7 +458,7 @@
 
         /**
          * Method engineGetURI
-         * @inheritDoc
+         * {@inheritDoc}
          *
          */
         public String engineGetURI() {
@@ -469,7 +486,7 @@
 
         /**
          * Method engineGetURI
-         * @inheritDoc
+         * {@inheritDoc}
          *
          */
         public String engineGetURI() {
@@ -498,7 +515,7 @@
         /**
          * Method engineGetURI
          *
-         * @inheritDoc
+         * {@inheritDoc}
          */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160;
@@ -526,7 +543,7 @@
         /**
          * Method engineGetURI
          *
-         * @inheritDoc
+         * {@inheritDoc}
          */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5;
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java	Sat Oct 24 01:11:51 2020 +0100
@@ -40,15 +40,14 @@
 
 public abstract class SignatureBaseRSA extends SignatureAlgorithmSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(SignatureBaseRSA.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(SignatureBaseRSA.class);
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public abstract String engineGetURI();
 
     /** Field algorithm */
-    private java.security.Signature signatureAlgorithm = null;
+    private Signature signatureAlgorithm;
 
     /**
      * Constructor SignatureRSA
@@ -58,15 +57,13 @@
     public SignatureBaseRSA() throws XMLSignatureException {
         String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Created SignatureRSA using " + algorithmID);
-        }
+        LOG.debug("Created SignatureRSA using {}", algorithmID);
         String provider = JCEMapper.getProviderId();
         try {
             if (provider == null) {
                 this.signatureAlgorithm = Signature.getInstance(algorithmID);
             } else {
-                this.signatureAlgorithm = Signature.getInstance(algorithmID,provider);
+                this.signatureAlgorithm = Signature.getInstance(algorithmID, provider);
             }
         } catch (java.security.NoSuchAlgorithmException ex) {
             Object[] exArgs = { algorithmID, ex.getLocalizedMessage() };
@@ -79,29 +76,32 @@
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineSetParameter(AlgorithmParameterSpec params)
         throws XMLSignatureException {
         try {
             this.signatureAlgorithm.setParameter(params);
         } catch (InvalidAlgorithmParameterException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected boolean engineVerify(byte[] signature) throws XMLSignatureException {
         try {
             return this.signatureAlgorithm.verify(signature);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineInitVerify(Key publicKey) throws XMLSignatureException {
         if (!(publicKey instanceof PublicKey)) {
-            String supplied = publicKey.getClass().getName();
+            String supplied = null;
+            if (publicKey != null) {
+                supplied = publicKey.getClass().getName();
+            }
             String needed = PublicKey.class.getName();
             Object exArgs[] = { supplied, needed };
 
@@ -119,46 +119,30 @@
             } catch (Exception e) {
                 // this shouldn't occur, but if it does, restore previous
                 // Signature
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Exception when reinstantiating Signature:" + e);
-                }
+                LOG.debug("Exception when reinstantiating Signature: {}", e);
                 this.signatureAlgorithm = sig;
             }
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected byte[] engineSign() throws XMLSignatureException {
         try {
             return this.signatureAlgorithm.sign();
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineInitSign(Key privateKey, SecureRandom secureRandom)
         throws XMLSignatureException {
         if (!(privateKey instanceof PrivateKey)) {
-            String supplied = privateKey.getClass().getName();
-            String needed = PrivateKey.class.getName();
-            Object exArgs[] = { supplied, needed };
-
-            throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs);
-        }
-
-        try {
-            this.signatureAlgorithm.initSign((PrivateKey) privateKey, secureRandom);
-        } catch (InvalidKeyException ex) {
-            throw new XMLSignatureException("empty", ex);
-        }
-    }
-
-    /** @inheritDoc */
-    protected void engineInitSign(Key privateKey) throws XMLSignatureException {
-        if (!(privateKey instanceof PrivateKey)) {
-            String supplied = privateKey.getClass().getName();
+            String supplied = null;
+            if (privateKey != null) {
+                supplied = privateKey.getClass().getName();
+            }
             String needed = PrivateKey.class.getName();
             Object exArgs[] = { supplied, needed };
 
@@ -166,56 +150,65 @@
         }
 
         try {
-            this.signatureAlgorithm.initSign((PrivateKey) privateKey);
+            if (secureRandom == null) {
+                this.signatureAlgorithm.initSign((PrivateKey) privateKey);
+            } else {
+                this.signatureAlgorithm.initSign((PrivateKey) privateKey, secureRandom);
+            }
         } catch (InvalidKeyException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
+    protected void engineInitSign(Key privateKey) throws XMLSignatureException {
+        engineInitSign(privateKey, (SecureRandom)null);
+    }
+
+    /** {@inheritDoc} */
     protected void engineUpdate(byte[] input) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(input);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineUpdate(byte input) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(input);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineUpdate(byte buf[], int offset, int len) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(buf, offset, len);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected String engineGetJCEAlgorithmString() {
         return this.signatureAlgorithm.getAlgorithm();
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected String engineGetJCEProviderName() {
         return this.signatureAlgorithm.getProvider().getName();
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineSetHMACOutputLength(int HMACOutputLength)
         throws XMLSignatureException {
         throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC");
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineInitSign(
         Key signingKey, AlgorithmParameterSpec algorithmParameterSpec
     ) throws XMLSignatureException {
@@ -236,13 +229,33 @@
             super();
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1;
         }
     }
 
     /**
+     * Class SignatureRSASHA224
+     */
+    public static class SignatureRSASHA224 extends SignatureBaseRSA {
+
+        /**
+         * Constructor SignatureRSASHA224
+         *
+         * @throws XMLSignatureException
+         */
+        public SignatureRSASHA224() throws XMLSignatureException {
+            super();
+        }
+
+        /** {@inheritDoc} */
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA224;
+        }
+    }
+
+    /**
      * Class SignatureRSASHA256
      */
     public static class SignatureRSASHA256 extends SignatureBaseRSA {
@@ -256,7 +269,7 @@
             super();
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256;
         }
@@ -276,7 +289,7 @@
             super();
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384;
         }
@@ -296,7 +309,7 @@
             super();
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512;
         }
@@ -316,7 +329,7 @@
             super();
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_RIPEMD160;
         }
@@ -336,9 +349,109 @@
             super();
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5;
         }
     }
+
+    /**
+     * Class SignatureRSASHA1MGF1
+     */
+    public static class SignatureRSASHA1MGF1 extends SignatureBaseRSA {
+
+        /**
+         * Constructor SignatureRSASHA1MGF1
+         *
+         * @throws XMLSignatureException
+         */
+        public SignatureRSASHA1MGF1() throws XMLSignatureException {
+            super();
+        }
+
+        /** {@inheritDoc} */
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1_MGF1;
+        }
+    }
+
+    /**
+     * Class SignatureRSASHA224MGF1
+     */
+    public static class SignatureRSASHA224MGF1 extends SignatureBaseRSA {
+
+        /**
+         * Constructor SignatureRSASHA224MGF1
+         *
+         * @throws XMLSignatureException
+         */
+        public SignatureRSASHA224MGF1() throws XMLSignatureException {
+            super();
+        }
+
+        /** {@inheritDoc} */
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA224_MGF1;
+        }
+    }
+
+    /**
+     * Class SignatureRSASHA256MGF1
+     */
+    public static class SignatureRSASHA256MGF1 extends SignatureBaseRSA {
+
+        /**
+         * Constructor SignatureRSASHA256MGF1
+         *
+         * @throws XMLSignatureException
+         */
+        public SignatureRSASHA256MGF1() throws XMLSignatureException {
+            super();
+        }
+
+        /** {@inheritDoc} */
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256_MGF1;
+        }
+    }
+
+    /**
+     * Class SignatureRSASHA384MGF1
+     */
+    public static class SignatureRSASHA384MGF1 extends SignatureBaseRSA {
+
+        /**
+         * Constructor SignatureRSASHA384MGF1
+         *
+         * @throws XMLSignatureException
+         */
+        public SignatureRSASHA384MGF1() throws XMLSignatureException {
+            super();
+        }
+
+        /** {@inheritDoc} */
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384_MGF1;
+        }
+    }
+
+    /**
+     * Class SignatureRSASHA512MGF1
+     */
+    public static class SignatureRSASHA512MGF1 extends SignatureBaseRSA {
+
+        /**
+         * Constructor SignatureRSASHA512MGF1
+         *
+         * @throws XMLSignatureException
+         */
+        public SignatureRSASHA512MGF1() throws XMLSignatureException {
+            super();
+        }
+
+        /** {@inheritDoc} */
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512_MGF1;
+        }
+    }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java	Sat Oct 24 01:11:51 2020 +0100
@@ -33,22 +33,24 @@
 import java.security.SignatureException;
 import java.security.interfaces.DSAKey;
 import java.security.spec.AlgorithmParameterSpec;
+import java.util.Base64;
 
 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.Base64;
+import com.sun.org.apache.xml.internal.security.utils.Constants;
 import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
 
 public class SignatureDSA extends SignatureAlgorithmSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(SignatureDSA.class.getName());
+    public static final String URI = Constants.SignatureSpecNS + "dsa-sha1";
+
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(SignatureDSA.class);
 
     /** Field algorithm */
-    private java.security.Signature signatureAlgorithm = null;
+    private Signature signatureAlgorithm;
 
     /** size of Q */
     private int size;
@@ -56,7 +58,7 @@
     /**
      * Method engineGetURI
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected String engineGetURI() {
         return XMLSignature.ALGO_ID_SIGNATURE_DSA;
@@ -69,9 +71,7 @@
      */
     public SignatureDSA() throws XMLSignatureException {
         String algorithmID = JCEMapper.translateURItoJCEID(engineGetURI());
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Created SignatureDSA using " + algorithmID);
-        }
+        LOG.debug("Created SignatureDSA using {}", algorithmID);
 
         String provider = JCEMapper.getProviderId();
         try {
@@ -91,25 +91,25 @@
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected void engineSetParameter(AlgorithmParameterSpec params)
         throws XMLSignatureException {
         try {
             this.signatureAlgorithm.setParameter(params);
         } catch (InvalidAlgorithmParameterException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected boolean engineVerify(byte[] signature)
         throws XMLSignatureException {
         try {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Called DSA.verify() on " + Base64.encode(signature));
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Called DSA.verify() on " + Base64.getMimeEncoder().encodeToString(signature));
             }
 
             byte[] jcebytes = JavaUtils.convertDsaXMLDSIGtoASN1(signature,
@@ -117,18 +117,21 @@
 
             return this.signatureAlgorithm.verify(jcebytes);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (IOException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected void engineInitVerify(Key publicKey) throws XMLSignatureException {
         if (!(publicKey instanceof PublicKey)) {
-            String supplied = publicKey.getClass().getName();
+            String supplied = null;
+            if (publicKey != null) {
+                supplied = publicKey.getClass().getName();
+            }
             String needed = PublicKey.class.getName();
             Object exArgs[] = { supplied, needed };
 
@@ -146,18 +149,16 @@
             } catch (Exception e) {
                 // this shouldn't occur, but if it does, restore previous
                 // Signature
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Exception when reinstantiating Signature:" + e);
-                }
+                LOG.debug("Exception when reinstantiating Signature: {}", e);
                 this.signatureAlgorithm = sig;
             }
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
         size = ((DSAKey)publicKey).getParams().getQ().bitLength();
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected byte[] engineSign() throws XMLSignatureException {
         try {
@@ -165,19 +166,22 @@
 
             return JavaUtils.convertDsaASN1toXMLDSIG(jcebytes, size/8);
         } catch (IOException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected void engineInitSign(Key privateKey, SecureRandom secureRandom)
         throws XMLSignatureException {
         if (!(privateKey instanceof PrivateKey)) {
-            String supplied = privateKey.getClass().getName();
+            String supplied = null;
+            if (privateKey != null) {
+                supplied = privateKey.getClass().getName();
+            }
             String needed = PrivateKey.class.getName();
             Object exArgs[] = { supplied, needed };
 
@@ -185,70 +189,61 @@
         }
 
         try {
-            this.signatureAlgorithm.initSign((PrivateKey) privateKey, secureRandom);
+            if (secureRandom == null) {
+                this.signatureAlgorithm.initSign((PrivateKey) privateKey);
+            } else {
+                this.signatureAlgorithm.initSign((PrivateKey) privateKey, secureRandom);
+            }
         } catch (InvalidKeyException ex) {
-            throw new XMLSignatureException("empty", ex);
-        }
-        size = ((DSAKey)privateKey).getParams().getQ().bitLength();
-    }
-
-    /**
-     * @inheritDoc
-     */
-    protected void engineInitSign(Key privateKey) throws XMLSignatureException {
-        if (!(privateKey instanceof PrivateKey)) {
-            String supplied = privateKey.getClass().getName();
-            String needed = PrivateKey.class.getName();
-            Object exArgs[] = { supplied, needed };
-
-            throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs);
-        }
-
-        try {
-            this.signatureAlgorithm.initSign((PrivateKey) privateKey);
-        } catch (InvalidKeyException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
         size = ((DSAKey)privateKey).getParams().getQ().bitLength();
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
+     */
+    protected void engineInitSign(Key privateKey) throws XMLSignatureException {
+        engineInitSign(privateKey, (SecureRandom)null);
+    }
+
+    /**
+     * {@inheritDoc}
      */
     protected void engineUpdate(byte[] input) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(input);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected void engineUpdate(byte input) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(input);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected void engineUpdate(byte buf[], int offset, int len) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(buf, offset, len);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
     /**
      * Method engineGetJCEAlgorithmString
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected String engineGetJCEAlgorithmString() {
         return this.signatureAlgorithm.getAlgorithm();
@@ -257,7 +252,7 @@
     /**
      * Method engineGetJCEProviderName
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected String engineGetJCEProviderName() {
         return this.signatureAlgorithm.getProvider().getName();
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java	Sat Oct 24 01:11:51 2020 +0100
@@ -33,34 +33,31 @@
 import java.security.Signature;
 import java.security.SignatureException;
 import java.security.spec.AlgorithmParameterSpec;
+import java.util.Base64;
 
 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.Base64;
 
 /**
  *
- * @author $Author: raul $
- * @author Alex Dupre
  */
 public abstract class SignatureECDSA extends SignatureAlgorithmSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(SignatureECDSA.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(SignatureECDSA.class);
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public abstract String engineGetURI();
 
     /** Field algorithm */
-    private java.security.Signature signatureAlgorithm = null;
+    private Signature signatureAlgorithm;
 
     /**
      * Converts an ASN.1 ECDSA value to a XML Signature ECDSA Value.
      *
-     * The JAVA JCE ECDSA Signature algorithm creates ASN.1 encoded (r,s) value
+     * The JAVA JCE ECDSA Signature algorithm creates ASN.1 encoded (r, s) value
      * pairs; the XML Signature requires the core BigInteger values.
      *
      * @param asn1Bytes
@@ -71,51 +68,13 @@
      * @see <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc4050.txt">3.3. ECDSA Signatures</A>
      */
     public static byte[] convertASN1toXMLDSIG(byte asn1Bytes[]) throws IOException {
-
-        if (asn1Bytes.length < 8 || asn1Bytes[0] != 48) {
-            throw new IOException("Invalid ASN.1 format of ECDSA signature");
-        }
-        int offset;
-        if (asn1Bytes[1] > 0) {
-            offset = 2;
-        } else if (asn1Bytes[1] == (byte) 0x81) {
-            offset = 3;
-        } else {
-            throw new IOException("Invalid ASN.1 format of ECDSA signature");
-        }
-
-        byte rLength = asn1Bytes[offset + 1];
-        int i;
-
-        for (i = rLength; (i > 0) && (asn1Bytes[(offset + 2 + rLength) - i] == 0); i--);
-
-        byte sLength = asn1Bytes[offset + 2 + rLength + 1];
-        int j;
-
-        for (j = sLength;
-            (j > 0) && (asn1Bytes[(offset + 2 + rLength + 2 + sLength) - j] == 0); j--);
-
-        int rawLen = Math.max(i, j);
-
-        if ((asn1Bytes[offset - 1] & 0xff) != asn1Bytes.length - offset
-            || (asn1Bytes[offset - 1] & 0xff) != 2 + rLength + 2 + sLength
-            || asn1Bytes[offset] != 2
-            || asn1Bytes[offset + 2 + rLength] != 2) {
-            throw new IOException("Invalid ASN.1 format of ECDSA signature");
-        }
-        byte xmldsigBytes[] = new byte[2*rawLen];
-
-        System.arraycopy(asn1Bytes, (offset + 2 + rLength) - i, xmldsigBytes, rawLen - i, i);
-        System.arraycopy(asn1Bytes, (offset + 2 + rLength + 2 + sLength) - j, xmldsigBytes,
-                         2*rawLen - j, j);
-
-        return xmldsigBytes;
+        return ECDSAUtils.convertASN1toXMLDSIG(asn1Bytes);
     }
 
     /**
      * Converts a XML Signature ECDSA Value to an ASN.1 DSA value.
      *
-     * The JAVA JCE ECDSA Signature algorithm creates ASN.1 encoded (r,s) value
+     * The JAVA JCE ECDSA Signature algorithm creates ASN.1 encoded (r, s) value
      * pairs; the XML Signature requires the core BigInteger values.
      *
      * @param xmldsigBytes
@@ -126,58 +85,7 @@
      * @see <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc4050.txt">3.3. ECDSA Signatures</A>
      */
     public static byte[] convertXMLDSIGtoASN1(byte xmldsigBytes[]) throws IOException {
-
-        int rawLen = xmldsigBytes.length/2;
-
-        int i;
-
-        for (i = rawLen; (i > 0) && (xmldsigBytes[rawLen - i] == 0); i--);
-
-        int j = i;
-
-        if (xmldsigBytes[rawLen - i] < 0) {
-            j += 1;
-        }
-
-        int k;
-
-        for (k = rawLen; (k > 0) && (xmldsigBytes[2*rawLen - k] == 0); k--);
-
-        int l = k;
-
-        if (xmldsigBytes[2*rawLen - k] < 0) {
-            l += 1;
-        }
-
-        int len = 2 + j + 2 + l;
-        if (len > 255) {
-            throw new IOException("Invalid XMLDSIG format of ECDSA signature");
-        }
-        int offset;
-        byte asn1Bytes[];
-        if (len < 128) {
-            asn1Bytes = new byte[2 + 2 + j + 2 + l];
-            offset = 1;
-        } else {
-            asn1Bytes = new byte[3 + 2 + j + 2 + l];
-            asn1Bytes[1] = (byte) 0x81;
-            offset = 2;
-        }
-        asn1Bytes[0] = 48;
-        asn1Bytes[offset++] = (byte) len;
-        asn1Bytes[offset++] = 2;
-        asn1Bytes[offset++] = (byte) j;
-
-        System.arraycopy(xmldsigBytes, rawLen - i, asn1Bytes, (offset + j) - i, i);
-
-        offset += j;
-
-        asn1Bytes[offset++] = 2;
-        asn1Bytes[offset++] = (byte) l;
-
-        System.arraycopy(xmldsigBytes, 2*rawLen - k, asn1Bytes, (offset + l) - k, k);
-
-        return asn1Bytes;
+        return ECDSAUtils.convertXMLDSIGtoASN1(xmldsigBytes);
     }
 
     /**
@@ -189,15 +97,13 @@
 
         String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Created SignatureECDSA using " + algorithmID);
-        }
+        LOG.debug("Created SignatureECDSA using {}", algorithmID);
         String provider = JCEMapper.getProviderId();
         try {
             if (provider == null) {
                 this.signatureAlgorithm = Signature.getInstance(algorithmID);
             } else {
-                this.signatureAlgorithm = Signature.getInstance(algorithmID,provider);
+                this.signatureAlgorithm = Signature.getInstance(algorithmID, provider);
             }
         } catch (java.security.NoSuchAlgorithmException ex) {
             Object[] exArgs = { algorithmID, ex.getLocalizedMessage() };
@@ -210,38 +116,41 @@
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineSetParameter(AlgorithmParameterSpec params)
         throws XMLSignatureException {
         try {
             this.signatureAlgorithm.setParameter(params);
         } catch (InvalidAlgorithmParameterException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected boolean engineVerify(byte[] signature) throws XMLSignatureException {
         try {
             byte[] jcebytes = SignatureECDSA.convertXMLDSIGtoASN1(signature);
 
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Called ECDSA.verify() on " + Base64.encode(signature));
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Called ECDSA.verify() on " + Base64.getMimeEncoder().encodeToString(signature));
             }
 
             return this.signatureAlgorithm.verify(jcebytes);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (IOException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineInitVerify(Key publicKey) throws XMLSignatureException {
 
         if (!(publicKey instanceof PublicKey)) {
-            String supplied = publicKey.getClass().getName();
+            String supplied = null;
+            if (publicKey != null) {
+                supplied = publicKey.getClass().getName();
+            }
             String needed = PublicKey.class.getName();
             Object exArgs[] = { supplied, needed };
 
@@ -259,50 +168,34 @@
             } catch (Exception e) {
                 // this shouldn't occur, but if it does, restore previous
                 // Signature
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Exception when reinstantiating Signature:" + e);
-                }
+                LOG.debug("Exception when reinstantiating Signature: {}", e);
                 this.signatureAlgorithm = sig;
             }
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected byte[] engineSign() throws XMLSignatureException {
         try {
             byte jcebytes[] = this.signatureAlgorithm.sign();
 
             return SignatureECDSA.convertASN1toXMLDSIG(jcebytes);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (IOException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineInitSign(Key privateKey, SecureRandom secureRandom)
         throws XMLSignatureException {
         if (!(privateKey instanceof PrivateKey)) {
-            String supplied = privateKey.getClass().getName();
-            String needed = PrivateKey.class.getName();
-            Object exArgs[] = { supplied, needed };
-
-            throw new XMLSignatureException("algorithms.WrongKeyForThisOperation", exArgs);
-        }
-
-        try {
-            this.signatureAlgorithm.initSign((PrivateKey) privateKey, secureRandom);
-        } catch (InvalidKeyException ex) {
-            throw new XMLSignatureException("empty", ex);
-        }
-    }
-
-    /** @inheritDoc */
-    protected void engineInitSign(Key privateKey) throws XMLSignatureException {
-        if (!(privateKey instanceof PrivateKey)) {
-            String supplied = privateKey.getClass().getName();
+            String supplied = null;
+            if (privateKey != null) {
+                supplied = privateKey.getClass().getName();
+            }
             String needed = PrivateKey.class.getName();
             Object exArgs[] = { supplied, needed };
 
@@ -310,56 +203,65 @@
         }
 
         try {
-            this.signatureAlgorithm.initSign((PrivateKey) privateKey);
+            if (secureRandom == null) {
+                this.signatureAlgorithm.initSign((PrivateKey) privateKey);
+            } else {
+                this.signatureAlgorithm.initSign((PrivateKey) privateKey, secureRandom);
+            }
         } catch (InvalidKeyException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
+    protected void engineInitSign(Key privateKey) throws XMLSignatureException {
+        engineInitSign(privateKey, (SecureRandom)null);
+    }
+
+    /** {@inheritDoc} */
     protected void engineUpdate(byte[] input) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(input);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineUpdate(byte input) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(input);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineUpdate(byte buf[], int offset, int len) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(buf, offset, len);
         } catch (SignatureException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected String engineGetJCEAlgorithmString() {
         return this.signatureAlgorithm.getAlgorithm();
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected String engineGetJCEProviderName() {
         return this.signatureAlgorithm.getProvider().getName();
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineSetHMACOutputLength(int HMACOutputLength)
         throws XMLSignatureException {
         throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC");
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected void engineInitSign(
         Key signingKey, AlgorithmParameterSpec algorithmParameterSpec
     ) throws XMLSignatureException {
@@ -367,13 +269,12 @@
     }
 
     /**
-     * Class SignatureRSASHA1
+     * Class SignatureECDSASHA1
      *
-     * @author $Author: marcx $
      */
     public static class SignatureECDSASHA1 extends SignatureECDSA {
         /**
-         * Constructor SignatureRSASHA1
+         * Constructor SignatureECDSASHA1
          *
          * @throws XMLSignatureException
          */
@@ -381,21 +282,40 @@
             super();
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA1;
         }
     }
 
     /**
-     * Class SignatureRSASHA256
+     * Class SignatureECDSASHA224
+     */
+    public static class SignatureECDSASHA224 extends SignatureECDSA {
+
+        /**
+         * Constructor SignatureECDSASHA224
+         *
+         * @throws XMLSignatureException
+         */
+        public SignatureECDSASHA224() throws XMLSignatureException {
+            super();
+        }
+
+        /** {@inheritDoc} */
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA224;
+        }
+    }
+
+    /**
+     * Class SignatureECDSASHA256
      *
-     * @author Alex Dupre
      */
     public static class SignatureECDSASHA256 extends SignatureECDSA {
 
         /**
-         * Constructor SignatureRSASHA256
+         * Constructor SignatureECDSASHA256
          *
          * @throws XMLSignatureException
          */
@@ -403,21 +323,20 @@
             super();
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA256;
         }
     }
 
     /**
-     * Class SignatureRSASHA384
+     * Class SignatureECDSASHA384
      *
-     * @author Alex Dupre
      */
     public static class SignatureECDSASHA384 extends SignatureECDSA {
 
         /**
-         * Constructor SignatureRSASHA384
+         * Constructor SignatureECDSASHA384
          *
          * @throws XMLSignatureException
          */
@@ -425,21 +344,20 @@
             super();
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA384;
         }
     }
 
     /**
-     * Class SignatureRSASHA512
+     * Class SignatureECDSASHA512
      *
-     * @author Alex Dupre
      */
     public static class SignatureECDSASHA512 extends SignatureECDSA {
 
         /**
-         * Constructor SignatureRSASHA512
+         * Constructor SignatureECDSASHA512
          *
          * @throws XMLSignatureException
          */
@@ -447,10 +365,30 @@
             super();
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA512;
         }
     }
 
+    /**
+     * Class SignatureECDSARIPEMD160
+     */
+    public static class SignatureECDSARIPEMD160 extends SignatureECDSA {
+
+        /**
+         * Constructor SignatureECDSARIPEMD160
+         *
+         * @throws XMLSignatureException
+         */
+        public SignatureECDSARIPEMD160() throws XMLSignatureException {
+            super();
+        }
+
+        /** {@inheritDoc} */
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_ECDSA_RIPEMD160;
+        }
+    }
+
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML> <HEAD> </HEAD> <BODY> <P>
-implementations of {@link com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi}.
-</P></BODY> </HTML>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-algorithm factories.
-</P></BODY></HTML>
\ No newline at end of file
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/CanonicalizationException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/CanonicalizationException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -27,7 +27,6 @@
 /**
  * Class CanonicalizationException
  *
- * @author Christian Geuer-Pollmann
  */
 public class CanonicalizationException extends XMLSecurityException {
 
@@ -44,6 +43,10 @@
         super();
     }
 
+    public CanonicalizationException(Exception ex) {
+        super(ex);
+    }
+
     /**
      * Constructor CanonicalizationException
      *
@@ -66,23 +69,33 @@
     /**
      * Constructor CanonicalizationException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public CanonicalizationException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public CanonicalizationException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor CanonicalizationException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
     public CanonicalizationException(
-        String msgID, Object exArgs[], Exception originalException
+        Exception originalException, String msgID, Object exArgs[]
     ) {
-        super(msgID, exArgs, originalException);
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public CanonicalizationException(String msgID, Object exArgs[], Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,13 +25,12 @@
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
-import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 
 import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_OmitComments;
 import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_WithComments;
@@ -42,6 +41,7 @@
 import com.sun.org.apache.xml.internal.security.c14n.implementations.CanonicalizerPhysical;
 import com.sun.org.apache.xml.internal.security.exceptions.AlgorithmAlreadyRegisteredException;
 import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -49,12 +49,11 @@
 
 /**
  *
- * @author Christian Geuer-Pollmann
  */
 public class Canonicalizer {
 
     /** The output encoding of canonicalized data */
-    public static final String ENCODING = "UTF8";
+    public static final String ENCODING = StandardCharsets.UTF_8.name();
 
     /**
      * XPath Expression for selecting every node and continuous comments joined
@@ -103,6 +102,7 @@
         new ConcurrentHashMap<String, Class<? extends CanonicalizerSpi>>();
 
     private final CanonicalizerSpi canonicalizerSpi;
+    private boolean secureValidation;
 
     /**
      * Constructor Canonicalizer
@@ -120,7 +120,7 @@
         } catch (Exception e) {
             Object exArgs[] = { algorithmURI };
             throw new InvalidCanonicalizerException(
-                "signature.Canonicalizer.UnknownCanonicalizer", exArgs, e
+                e, "signature.Canonicalizer.UnknownCanonicalizer", exArgs
             );
         }
     }
@@ -160,7 +160,8 @@
         }
 
         canonicalizerHash.put(
-            algorithmURI, (Class<? extends CanonicalizerSpi>)Class.forName(implementingClass)
+            algorithmURI, (Class<? extends CanonicalizerSpi>)
+            ClassLoaderUtils.loadClass(implementingClass, Canonicalizer.class)
         );
     }
 
@@ -242,7 +243,7 @@
     /**
      * This method tries to canonicalize the given bytes. It's possible to even
      * canonicalize non-wellformed sequences if they are well-formed after being
-     * wrapped with a <CODE>&gt;a&lt;...&gt;/a&lt;</CODE>.
+     * wrapped with a {@code &gt;a&lt;...&gt;/a&lt;}.
      *
      * @param inputBytes
      * @return the result of the canonicalization.
@@ -254,47 +255,43 @@
     public byte[] canonicalize(byte[] inputBytes)
         throws javax.xml.parsers.ParserConfigurationException,
         java.io.IOException, org.xml.sax.SAXException, CanonicalizationException {
-        InputStream bais = new ByteArrayInputStream(inputBytes);
-        InputSource in = new InputSource(bais);
-        DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
-        dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
+        Document document = null;
+        try (InputStream bais = new ByteArrayInputStream(inputBytes)) {
+            InputSource in = new InputSource(bais);
 
-        dfactory.setNamespaceAware(true);
-
-        // needs to validate for ID attribute normalization
-        dfactory.setValidating(true);
-
-        DocumentBuilder db = dfactory.newDocumentBuilder();
+            // needs to validate for ID attribute normalization
+            DocumentBuilder db = XMLUtils.createDocumentBuilder(true, secureValidation);
 
-        /*
-         * for some of the test vectors from the specification,
-         * there has to be a validating parser for ID attributes, default
-         * attribute values, NMTOKENS, etc.
-         * Unfortunately, the test vectors do use different DTDs or
-         * even no DTD. So Xerces 1.3.1 fires many warnings about using
-         * ErrorHandlers.
-         *
-         * Text from the spec:
-         *
-         * The input octet stream MUST contain a well-formed XML document,
-         * but the input need not be validated. However, the attribute
-         * value normalization and entity reference resolution MUST be
-         * performed in accordance with the behaviors of a validating
-         * XML processor. As well, nodes for default attributes (declared
-         * in the ATTLIST with an AttValue but not specified) are created
-         * in each element. Thus, the declarations in the document type
-         * declaration are used to help create the canonical form, even
-         * though the document type declaration is not retained in the
-         * canonical form.
-         */
-        db.setErrorHandler(new com.sun.org.apache.xml.internal.security.utils.IgnoreAllErrorHandler());
+            /*
+             * for some of the test vectors from the specification,
+             * there has to be a validating parser for ID attributes, default
+             * attribute values, NMTOKENS, etc.
+             * Unfortunately, the test vectors do use different DTDs or
+             * even no DTD. So Xerces 1.3.1 fires many warnings about using
+             * ErrorHandlers.
+             *
+             * Text from the spec:
+             *
+             * The input octet stream MUST contain a well-formed XML document,
+             * but the input need not be validated. However, the attribute
+             * value normalization and entity reference resolution MUST be
+             * performed in accordance with the behaviors of a validating
+             * XML processor. As well, nodes for default attributes (declared
+             * in the ATTLIST with an AttValue but not specified) are created
+             * in each element. Thus, the declarations in the document type
+             * declaration are used to help create the canonical form, even
+             * though the document type declaration is not retained in the
+             * canonical form.
+             */
+            db.setErrorHandler(new com.sun.org.apache.xml.internal.security.utils.IgnoreAllErrorHandler());
 
-        Document document = db.parse(in);
+            document = db.parse(in);
+        }
         return this.canonicalizeSubtree(document);
     }
 
     /**
-     * Canonicalizes the subtree rooted by <CODE>node</CODE>.
+     * Canonicalizes the subtree rooted by {@code node}.
      *
      * @param node The node to canonicalize
      * @return the result of the c14n.
@@ -302,11 +299,12 @@
      * @throws CanonicalizationException
      */
     public byte[] canonicalizeSubtree(Node node) throws CanonicalizationException {
+        canonicalizerSpi.secureValidation = secureValidation;
         return canonicalizerSpi.engineCanonicalizeSubTree(node);
     }
 
     /**
-     * Canonicalizes the subtree rooted by <CODE>node</CODE>.
+     * Canonicalizes the subtree rooted by {@code node}.
      *
      * @param node
      * @param inclusiveNamespaces
@@ -315,11 +313,26 @@
      */
     public byte[] canonicalizeSubtree(Node node, String inclusiveNamespaces)
         throws CanonicalizationException {
+        canonicalizerSpi.secureValidation = secureValidation;
         return canonicalizerSpi.engineCanonicalizeSubTree(node, inclusiveNamespaces);
     }
 
     /**
-     * Canonicalizes an XPath node set. The <CODE>xpathNodeSet</CODE> is treated
+     * Canonicalizes the subtree rooted by {@code node}.
+     *
+     * @param node
+     * @param inclusiveNamespaces
+     * @return the result of the c14n.
+     * @throws CanonicalizationException
+     */
+    public byte[] canonicalizeSubtree(Node node, String inclusiveNamespaces, boolean propagateDefaultNamespace)
+            throws CanonicalizationException {
+        canonicalizerSpi.secureValidation = secureValidation;
+        return canonicalizerSpi.engineCanonicalizeSubTree(node, inclusiveNamespaces, propagateDefaultNamespace);
+    }
+
+    /**
+     * Canonicalizes an XPath node set. The {@code xpathNodeSet} is treated
      * as a list of XPath nodes, not as a list of subtrees.
      *
      * @param xpathNodeSet
@@ -328,11 +341,12 @@
      */
     public byte[] canonicalizeXPathNodeSet(NodeList xpathNodeSet)
         throws CanonicalizationException {
+        canonicalizerSpi.secureValidation = secureValidation;
         return canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet);
     }
 
     /**
-     * Canonicalizes an XPath node set. The <CODE>xpathNodeSet</CODE> is treated
+     * Canonicalizes an XPath node set. The {@code xpathNodeSet} is treated
      * as a list of XPath nodes, not as a list of subtrees.
      *
      * @param xpathNodeSet
@@ -343,6 +357,7 @@
     public byte[] canonicalizeXPathNodeSet(
         NodeList xpathNodeSet, String inclusiveNamespaces
     ) throws CanonicalizationException {
+        canonicalizerSpi.secureValidation = secureValidation;
         return
             canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet, inclusiveNamespaces);
     }
@@ -356,6 +371,7 @@
      */
     public byte[] canonicalizeXPathNodeSet(Set<Node> xpathNodeSet)
         throws CanonicalizationException {
+        canonicalizerSpi.secureValidation = secureValidation;
         return canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet);
     }
 
@@ -370,6 +386,7 @@
     public byte[] canonicalizeXPathNodeSet(
         Set<Node> xpathNodeSet, String inclusiveNamespaces
     ) throws CanonicalizationException {
+        canonicalizerSpi.secureValidation = secureValidation;
         return
             canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet, inclusiveNamespaces);
     }
@@ -399,4 +416,12 @@
         canonicalizerSpi.reset = false;
     }
 
+    public boolean isSecureValidation() {
+        return secureValidation;
+    }
+
+    public void setSecureValidation(boolean secureValidation) {
+        this.secureValidation = secureValidation;
+    }
+
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/CanonicalizerSpi.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/CanonicalizerSpi.java	Sat Oct 24 01:11:51 2020 +0100
@@ -26,9 +26,7 @@
 import java.io.OutputStream;
 import java.util.Set;
 
-import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Document;
@@ -39,12 +37,12 @@
 /**
  * Base class which all Canonicalization algorithms extend.
  *
- * @author Christian Geuer-Pollmann
  */
 public abstract class CanonicalizerSpi {
 
     /** Reset the writer after a c14n */
     protected boolean reset = false;
+    protected boolean secureValidation;
 
     /**
      * Method canonicalize
@@ -61,17 +59,14 @@
         throws javax.xml.parsers.ParserConfigurationException, java.io.IOException,
         org.xml.sax.SAXException, CanonicalizationException {
 
-        java.io.InputStream bais = new ByteArrayInputStream(inputBytes);
-        InputSource in = new InputSource(bais);
-        DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
-        dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
+        Document document = null;
+        try (java.io.InputStream bais = new ByteArrayInputStream(inputBytes)) {
+            InputSource in = new InputSource(bais);
 
-        // needs to validate for ID attribute normalization
-        dfactory.setNamespaceAware(true);
+            DocumentBuilder db = XMLUtils.createDocumentBuilder(false, secureValidation);
 
-        DocumentBuilder db = dfactory.newDocumentBuilder();
-
-        Document document = db.parse(in);
+            document = db.parse(in);
+        }
         return this.engineCanonicalizeSubTree(document);
     }
 
@@ -160,10 +155,31 @@
         throws CanonicalizationException;
 
     /**
+     * C14n a node tree.
+     *
+     * @param rootNode
+     * @param inclusiveNamespaces
+     * @param propagateDefaultNamespace If true the default namespace will be propagated to the c14n-ized root element
+     * @return the c14n bytes
+     * @throws CanonicalizationException
+     */
+    public abstract byte[] engineCanonicalizeSubTree(
+            Node rootNode, String inclusiveNamespaces, boolean propagateDefaultNamespace)
+            throws CanonicalizationException;
+
+    /**
      * Sets the writer where the canonicalization ends. ByteArrayOutputStream if
      * none is set.
      * @param os
      */
     public abstract void setWriter(OutputStream os);
 
+    public boolean isSecureValidation() {
+        return secureValidation;
+    }
+
+    public void setSecureValidation(boolean secureValidation) {
+        this.secureValidation = secureValidation;
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/ClassLoaderUtils.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,84 @@
+/*
+ * 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.c14n;
+
+// NOTE! This is a duplicate of utils.ClassLoaderUtils with public
+// modifiers changed to package-private. Make sure to integrate any future
+// changes to utils.ClassLoaderUtils to this file.
+final class ClassLoaderUtils {
+
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ClassLoaderUtils.class);
+
+    private ClassLoaderUtils() {
+    }
+
+    /**
+     * Load a class with a given name. <p></p> It will try to load the class in the
+     * following order:
+     * <ul>
+     * <li>From Thread.currentThread().getContextClassLoader()
+     * <li>Using the basic Class.forName()
+     * <li>From ClassLoaderUtil.class.getClassLoader()
+     * <li>From the callingClass.getClassLoader()
+     * </ul>
+     *
+     * @param className The name of the class to load
+     * @param callingClass The Class object of the calling object
+     * @throws ClassNotFoundException If the class cannot be found anywhere.
+     */
+    static Class<?> loadClass(String className, Class<?> callingClass)
+        throws ClassNotFoundException {
+        try {
+            ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
+            if (cl != null) {
+                return cl.loadClass(className);
+            }
+        } catch (ClassNotFoundException e) {
+            LOG.debug(e.getMessage(), e);
+            //ignore
+        }
+        return loadClass2(className, callingClass);
+    }
+
+    private static Class<?> loadClass2(String className, Class<?> callingClass)
+        throws ClassNotFoundException {
+        try {
+            return Class.forName(className);
+        } catch (ClassNotFoundException ex) {
+            try {
+                if (ClassLoaderUtils.class.getClassLoader() != null) {
+                    return ClassLoaderUtils.class.getClassLoader().loadClass(className);
+                }
+            } catch (ClassNotFoundException exc) {
+                if (callingClass != null && callingClass.getClassLoader() != null) {
+                    return callingClass.getClassLoader().loadClass(className);
+                }
+            }
+            LOG.debug(ex.getMessage(), ex);
+            throw ex;
+        }
+    }
+}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/InvalidCanonicalizerException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/InvalidCanonicalizerException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -61,23 +61,33 @@
     /**
      * Constructor InvalidCanonicalizerException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public InvalidCanonicalizerException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public InvalidCanonicalizerException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor InvalidCanonicalizerException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
     public InvalidCanonicalizerException(
-        String msgID, Object exArgs[], Exception originalException
+        Exception originalException, String msgID, Object exArgs[]
     ) {
-        super(msgID, exArgs, originalException);
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public InvalidCanonicalizerException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/AttrCompare.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/AttrCompare.java	Sat Oct 24 01:11:51 2020 +0100
@@ -41,7 +41,6 @@
  *   key (an empty namespace URI is lexicographically least).
  * </UL>
  *
- * @author Christian Geuer-Pollmann
  */
 public class AttrCompare implements Comparator<Attr>, Serializable {
 
@@ -117,6 +116,6 @@
             return a;
         }
 
-        return (attr0.getLocalName()).compareTo(attr1.getLocalName());
+        return attr0.getLocalName().compareTo(attr1.getLocalName());
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/C14nHelper.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/C14nHelper.java	Sat Oct 24 01:11:51 2020 +0100
@@ -31,9 +31,8 @@
 /**
  * Temporary swapped static functions from the normalizer Section
  *
- * @author Christian Geuer-Pollmann
  */
-public class C14nHelper {
+public final class C14nHelper {
 
     /**
      * Constructor C14nHelper
@@ -100,7 +99,7 @@
         }
 
         String nodeAttrName = attr.getNodeName();
-        boolean definesDefaultNS = nodeAttrName.equals("xmlns");
+        boolean definesDefaultNS = "xmlns".equals(nodeAttrName);
         boolean definesNonDefaultNS = nodeAttrName.startsWith("xmlns:");
 
         if ((definesDefaultNS || definesNonDefaultNS) && namespaceIsRelative(attr)) {
@@ -145,7 +144,8 @@
         if (ctxNode != null) {
             NamedNodeMap attributes = ctxNode.getAttributes();
 
-            for (int i = 0; i < attributes.getLength(); i++) {
+            int length = attributes.getLength();
+            for (int i = 0; i < length; i++) {
                 C14nHelper.assertNotRelativeNS((Attr) attributes.item(i));
             }
         } else {
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML> <HEAD> </HEAD> <BODY> <P>
-helper classes for canonicalization.
-</P></BODY> </HTML>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,687 +0,0 @@
-/*
- * 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.c14n.implementations;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import javax.xml.parsers.ParserConfigurationException;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
-
-import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
-import com.sun.org.apache.xml.internal.security.c14n.helper.C14nHelper;
-import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
-import com.sun.org.apache.xml.internal.security.utils.Constants;
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
-
-/**
- * Implements <A HREF="http://www.w3.org/TR/2008/PR-xml-c14n11-20080129/">
- * Canonical XML Version 1.1</A>, a W3C Proposed Recommendation from 29
- * January 2008.
- *
- * @author Sean Mullan
- * @author Raul Benito
- */
-public abstract class Canonicalizer11 extends CanonicalizerBase {
-
-    private static final String XMLNS_URI = Constants.NamespaceSpecNS;
-    private static final String XML_LANG_URI = Constants.XML_LANG_SPACE_SpecNS;
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(Canonicalizer11.class.getName());
-    private final SortedSet<Attr> result = new TreeSet<Attr>(COMPARE);
-
-    private boolean firstCall = true;
-
-    private static class XmlAttrStack {
-        static class XmlsStackElement {
-            int level;
-            boolean rendered = false;
-            List<Attr> nodes = new ArrayList<Attr>();
-        };
-
-        int currentLevel = 0;
-        int lastlevel = 0;
-        XmlsStackElement cur;
-        List<XmlsStackElement> levels = new ArrayList<XmlsStackElement>();
-
-        void push(int level) {
-            currentLevel = level;
-            if (currentLevel == -1) {
-                return;
-            }
-            cur = null;
-            while (lastlevel >= currentLevel) {
-                levels.remove(levels.size() - 1);
-                int newSize = levels.size();
-                if (newSize == 0) {
-                    lastlevel = 0;
-                    return;
-                }
-                lastlevel = (levels.get(newSize - 1)).level;
-            }
-        }
-
-        void addXmlnsAttr(Attr n) {
-            if (cur == null) {
-                cur = new XmlsStackElement();
-                cur.level = currentLevel;
-                levels.add(cur);
-                lastlevel = currentLevel;
-            }
-            cur.nodes.add(n);
-        }
-
-        void getXmlnsAttr(Collection<Attr> col) {
-            int size = levels.size() - 1;
-            if (cur == null) {
-                cur = new XmlsStackElement();
-                cur.level = currentLevel;
-                lastlevel = currentLevel;
-                levels.add(cur);
-            }
-            boolean parentRendered = false;
-            XmlsStackElement e = null;
-            if (size == -1) {
-                parentRendered = true;
-            } else {
-                e = levels.get(size);
-                if (e.rendered && e.level + 1 == currentLevel) {
-                    parentRendered = true;
-                }
-            }
-            if (parentRendered) {
-                col.addAll(cur.nodes);
-                cur.rendered = true;
-                return;
-            }
-
-            Map<String, Attr> loa = new HashMap<String, Attr>();
-            List<Attr> baseAttrs = new ArrayList<Attr>();
-            boolean successiveOmitted = true;
-            for (; size >= 0; size--) {
-                e = levels.get(size);
-                if (e.rendered) {
-                    successiveOmitted = false;
-                }
-                Iterator<Attr> it = e.nodes.iterator();
-                while (it.hasNext() && successiveOmitted) {
-                    Attr n = it.next();
-                    if (n.getLocalName().equals("base") && !e.rendered) {
-                        baseAttrs.add(n);
-                    } else if (!loa.containsKey(n.getName())) {
-                        loa.put(n.getName(), n);
-                    }
-                }
-            }
-            if (!baseAttrs.isEmpty()) {
-                Iterator<Attr> it = col.iterator();
-                String base = null;
-                Attr baseAttr = null;
-                while (it.hasNext()) {
-                    Attr n = it.next();
-                    if (n.getLocalName().equals("base")) {
-                        base = n.getValue();
-                        baseAttr = n;
-                        break;
-                    }
-                }
-                it = baseAttrs.iterator();
-                while (it.hasNext()) {
-                    Attr n = it.next();
-                    if (base == null) {
-                        base = n.getValue();
-                        baseAttr = n;
-                    } else {
-                        try {
-                            base = joinURI(n.getValue(), base);
-                        } catch (URISyntaxException ue) {
-                            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                                log.log(java.util.logging.Level.FINE, ue.getMessage(), ue);
-                            }
-                        }
-                    }
-                }
-                if (base != null && base.length() != 0) {
-                    baseAttr.setValue(base);
-                    col.add(baseAttr);
-                }
-            }
-
-            cur.rendered = true;
-            col.addAll(loa.values());
-        }
-    };
-
-    private XmlAttrStack xmlattrStack = new XmlAttrStack();
-
-    /**
-     * Constructor Canonicalizer11
-     *
-     * @param includeComments
-     */
-    public Canonicalizer11(boolean includeComments) {
-        super(includeComments);
-    }
-
-    /**
-     * Always throws a CanonicalizationException because this is inclusive c14n.
-     *
-     * @param xpathNodeSet
-     * @param inclusiveNamespaces
-     * @return none it always fails
-     * @throws CanonicalizationException always
-     */
-    public byte[] engineCanonicalizeXPathNodeSet(
-        Set<Node> xpathNodeSet, String inclusiveNamespaces
-    ) throws CanonicalizationException {
-        throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation");
-    }
-
-    /**
-     * Always throws a CanonicalizationException because this is inclusive c14n.
-     *
-     * @param rootNode
-     * @param inclusiveNamespaces
-     * @return none it always fails
-     * @throws CanonicalizationException
-     */
-    public byte[] engineCanonicalizeSubTree(
-        Node rootNode, String inclusiveNamespaces
-    ) throws CanonicalizationException {
-        throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation");
-    }
-
-    /**
-     * Returns the Attr[]s to be output for the given element.
-     * <br>
-     * The code of this method is a copy of {@link #handleAttributes(Element,
-     * NameSpaceSymbTable)},
-     * whereas it takes into account that subtree-c14n is -- well --
-     * subtree-based.
-     * So if the element in question isRoot of c14n, it's parent is not in the
-     * node set, as well as all other ancestors.
-     *
-     * @param element
-     * @param ns
-     * @return the Attr[]s to be output
-     * @throws CanonicalizationException
-     */
-    @Override
-    protected Iterator<Attr> handleAttributesSubtree(Element element, NameSpaceSymbTable ns)
-        throws CanonicalizationException {
-        if (!element.hasAttributes() && !firstCall) {
-            return null;
-        }
-        // result will contain the attrs which have to be output
-        final SortedSet<Attr> result = this.result;
-        result.clear();
-
-        if (element.hasAttributes()) {
-            NamedNodeMap attrs = element.getAttributes();
-            int attrsLength = attrs.getLength();
-
-            for (int i = 0; i < attrsLength; i++) {
-                Attr attribute = (Attr) attrs.item(i);
-                String NUri = attribute.getNamespaceURI();
-                String NName = attribute.getLocalName();
-                String NValue = attribute.getValue();
-
-                if (!XMLNS_URI.equals(NUri)) {
-                    // It's not a namespace attr node. Add to the result and continue.
-                    result.add(attribute);
-                } else if (!(XML.equals(NName) && XML_LANG_URI.equals(NValue))) {
-                    // The default mapping for xml must not be output.
-                    Node n = ns.addMappingAndRender(NName, NValue, attribute);
-
-                    if (n != null) {
-                        // Render the ns definition
-                        result.add((Attr)n);
-                        if (C14nHelper.namespaceIsRelative(attribute)) {
-                            Object exArgs[] = {element.getTagName(), NName, attribute.getNodeValue()};
-                            throw new CanonicalizationException(
-                                "c14n.Canonicalizer.RelativeNamespace", exArgs
-                            );
-                        }
-                    }
-                }
-            }
-        }
-
-        if (firstCall) {
-            // It is the first node of the subtree
-            // Obtain all the namespaces defined in the parents, and added to the output.
-            ns.getUnrenderedNodes(result);
-            // output the attributes in the xml namespace.
-            xmlattrStack.getXmlnsAttr(result);
-            firstCall = false;
-        }
-
-        return result.iterator();
-    }
-
-    /**
-     * Returns the Attr[]s to be output for the given element.
-     * <br>
-     * IMPORTANT: This method expects to work on a modified DOM tree, i.e. a
-     * DOM which has been prepared using
-     * {@link com.sun.org.apache.xml.internal.security.utils.XMLUtils#circumventBug2650(
-     * org.w3c.dom.Document)}.
-     *
-     * @param element
-     * @param ns
-     * @return the Attr[]s to be output
-     * @throws CanonicalizationException
-     */
-    @Override
-    protected Iterator<Attr> handleAttributes(Element element, NameSpaceSymbTable ns)
-        throws CanonicalizationException {
-        // result will contain the attrs which have to be output
-        xmlattrStack.push(ns.getLevel());
-        boolean isRealVisible = isVisibleDO(element, ns.getLevel()) == 1;
-        final SortedSet<Attr> result = this.result;
-        result.clear();
-
-        if (element.hasAttributes()) {
-            NamedNodeMap attrs = element.getAttributes();
-            int attrsLength = attrs.getLength();
-
-            for (int i = 0; i < attrsLength; i++) {
-                Attr attribute = (Attr) attrs.item(i);
-                String NUri = attribute.getNamespaceURI();
-                String NName = attribute.getLocalName();
-                String NValue = attribute.getValue();
-
-                if (!XMLNS_URI.equals(NUri)) {
-                    //A non namespace definition node.
-                    if (XML_LANG_URI.equals(NUri)) {
-                        if (NName.equals("id")) {
-                            if (isRealVisible) {
-                                // treat xml:id like any other attribute
-                                // (emit it, but don't inherit it)
-                                result.add(attribute);
-                            }
-                        } else {
-                            xmlattrStack.addXmlnsAttr(attribute);
-                        }
-                    } else if (isRealVisible) {
-                        //The node is visible add the attribute to the list of output attributes.
-                        result.add(attribute);
-                    }
-                } else if (!XML.equals(NName) || !XML_LANG_URI.equals(NValue)) {
-                    /* except omit namespace node with local name xml, which defines
-                     * the xml prefix, if its string value is
-                     * http://www.w3.org/XML/1998/namespace.
-                     */
-                    // add the prefix binding to the ns symb table.
-                    if (isVisible(attribute))  {
-                        if (isRealVisible || !ns.removeMappingIfRender(NName)) {
-                            // The xpath select this node output it if needed.
-                            Node n = ns.addMappingAndRender(NName, NValue, attribute);
-                            if (n != null) {
-                                result.add((Attr)n);
-                                if (C14nHelper.namespaceIsRelative(attribute)) {
-                                    Object exArgs[] = { element.getTagName(), NName, attribute.getNodeValue() };
-                                    throw new CanonicalizationException(
-                                        "c14n.Canonicalizer.RelativeNamespace", exArgs
-                                    );
-                                }
-                            }
-                        }
-                    } else {
-                        if (isRealVisible && !XMLNS.equals(NName)) {
-                            ns.removeMapping(NName);
-                        } else {
-                            ns.addMapping(NName, NValue, attribute);
-                        }
-                    }
-                }
-            }
-        }
-
-        if (isRealVisible) {
-            //The element is visible, handle the xmlns definition
-            Attr xmlns = element.getAttributeNodeNS(XMLNS_URI, XMLNS);
-            Node n = null;
-            if (xmlns == null) {
-                //No xmlns def just get the already defined.
-                n = ns.getMapping(XMLNS);
-            } else if (!isVisible(xmlns)) {
-                //There is a definition but the xmlns is not selected by the xpath.
-                //then xmlns=""
-                n = ns.addMappingAndRender(
-                        XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
-            }
-            //output the xmlns def if needed.
-            if (n != null) {
-                result.add((Attr)n);
-            }
-            //Float all xml:* attributes of the unselected parent elements to this one.
-            xmlattrStack.getXmlnsAttr(result);
-            ns.getUnrenderedNodes(result);
-        }
-
-        return result.iterator();
-    }
-
-    protected void circumventBugIfNeeded(XMLSignatureInput input)
-        throws CanonicalizationException, ParserConfigurationException,
-        IOException, SAXException {
-        if (!input.isNeedsToBeExpanded()) {
-            return;
-        }
-        Document doc = null;
-        if (input.getSubNode() != null) {
-            doc = XMLUtils.getOwnerDocument(input.getSubNode());
-        } else {
-            doc = XMLUtils.getOwnerDocument(input.getNodeSet());
-        }
-        XMLUtils.circumventBug2650(doc);
-    }
-
-    protected void handleParent(Element e, NameSpaceSymbTable ns) {
-        if (!e.hasAttributes() && e.getNamespaceURI() == null) {
-            return;
-        }
-        xmlattrStack.push(-1);
-        NamedNodeMap attrs = e.getAttributes();
-        int attrsLength = attrs.getLength();
-        for (int i = 0; i < attrsLength; i++) {
-            Attr attribute = (Attr) attrs.item(i);
-            String NName = attribute.getLocalName();
-            String NValue = attribute.getNodeValue();
-
-            if (Constants.NamespaceSpecNS.equals(attribute.getNamespaceURI())) {
-                if (!XML.equals(NName) || !Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) {
-                    ns.addMapping(NName, NValue, attribute);
-                }
-            } else if (!"id".equals(NName) && XML_LANG_URI.equals(attribute.getNamespaceURI())) {
-                xmlattrStack.addXmlnsAttr(attribute);
-            }
-        }
-        if (e.getNamespaceURI() != null) {
-            String NName = e.getPrefix();
-            String NValue = e.getNamespaceURI();
-            String Name;
-            if (NName == null || NName.equals("")) {
-                NName = "xmlns";
-                Name = "xmlns";
-            } else {
-                Name = "xmlns:" + NName;
-            }
-            Attr n = e.getOwnerDocument().createAttributeNS("http://www.w3.org/2000/xmlns/", Name);
-            n.setValue(NValue);
-            ns.addMapping(NName, NValue, n);
-        }
-    }
-
-    private static String joinURI(String baseURI, String relativeURI) throws URISyntaxException {
-        String bscheme = null;
-        String bauthority = null;
-        String bpath = "";
-        String bquery = null;
-
-        // pre-parse the baseURI
-        if (baseURI != null) {
-            if (baseURI.endsWith("..")) {
-                baseURI = baseURI + "/";
-            }
-            URI base = new URI(baseURI);
-            bscheme = base.getScheme();
-            bauthority = base.getAuthority();
-            bpath = base.getPath();
-            bquery = base.getQuery();
-        }
-
-        URI r = new URI(relativeURI);
-        String rscheme = r.getScheme();
-        String rauthority = r.getAuthority();
-        String rpath = r.getPath();
-        String rquery = r.getQuery();
-
-        String tscheme, tauthority, tpath, tquery;
-        if (rscheme != null && rscheme.equals(bscheme)) {
-            rscheme = null;
-        }
-        if (rscheme != null) {
-            tscheme = rscheme;
-            tauthority = rauthority;
-            tpath = removeDotSegments(rpath);
-            tquery = rquery;
-        } else {
-            if (rauthority != null) {
-                tauthority = rauthority;
-                tpath = removeDotSegments(rpath);
-                tquery = rquery;
-            } else {
-                if (rpath.length() == 0) {
-                    tpath = bpath;
-                    if (rquery != null) {
-                        tquery = rquery;
-                    } else {
-                        tquery = bquery;
-                    }
-                } else {
-                    if (rpath.startsWith("/")) {
-                        tpath = removeDotSegments(rpath);
-                    } else {
-                        if (bauthority != null && bpath.length() == 0) {
-                            tpath = "/" + rpath;
-                        } else {
-                            int last = bpath.lastIndexOf('/');
-                            if (last == -1) {
-                                tpath = rpath;
-                            } else {
-                                tpath = bpath.substring(0, last+1) + rpath;
-                            }
-                        }
-                        tpath = removeDotSegments(tpath);
-                    }
-                    tquery = rquery;
-                }
-                tauthority = bauthority;
-            }
-            tscheme = bscheme;
-        }
-        return new URI(tscheme, tauthority, tpath, tquery, null).toString();
-    }
-
-    private static String removeDotSegments(String path) {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "STEP   OUTPUT BUFFER\t\tINPUT BUFFER");
-        }
-
-        // 1. The input buffer is initialized with the now-appended path
-        // components then replace occurrences of "//" in the input buffer
-        // with "/" until no more occurrences of "//" are in the input buffer.
-        String input = path;
-        while (input.indexOf("//") > -1) {
-            input = input.replaceAll("//", "/");
-        }
-
-        // Initialize the output buffer with the empty string.
-        StringBuilder output = new StringBuilder();
-
-        // If the input buffer starts with a root slash "/" then move this
-        // character to the output buffer.
-        if (input.charAt(0) == '/') {
-            output.append("/");
-            input = input.substring(1);
-        }
-
-        printStep("1 ", output.toString(), input);
-
-        // While the input buffer is not empty, loop as follows
-        while (input.length() != 0) {
-            // 2A. If the input buffer begins with a prefix of "./",
-            // then remove that prefix from the input buffer
-            // else if the input buffer begins with a prefix of "../", then
-            // if also the output does not contain the root slash "/" only,
-            // then move this prefix to the end of the output buffer else
-            // remove that prefix
-            if (input.startsWith("./")) {
-                input = input.substring(2);
-                printStep("2A", output.toString(), input);
-            } else if (input.startsWith("../")) {
-                input = input.substring(3);
-                if (!output.toString().equals("/")) {
-                    output.append("../");
-                }
-                printStep("2A", output.toString(), input);
-                // 2B. if the input buffer begins with a prefix of "/./" or "/.",
-                // where "." is a complete path segment, then replace that prefix
-                // with "/" in the input buffer; otherwise,
-            } else if (input.startsWith("/./")) {
-                input = input.substring(2);
-                printStep("2B", output.toString(), input);
-            } else if (input.equals("/.")) {
-                // FIXME: what is complete path segment?
-                input = input.replaceFirst("/.", "/");
-                printStep("2B", output.toString(), input);
-                // 2C. if the input buffer begins with a prefix of "/../" or "/..",
-                // where ".." is a complete path segment, then replace that prefix
-                // with "/" in the input buffer and if also the output buffer is
-                // empty, last segment in the output buffer equals "../" or "..",
-                // where ".." is a complete path segment, then append ".." or "/.."
-                // for the latter case respectively to the output buffer else
-                // remove the last segment and its preceding "/" (if any) from the
-                // output buffer and if hereby the first character in the output
-                // buffer was removed and it was not the root slash then delete a
-                // leading slash from the input buffer; otherwise,
-            } else if (input.startsWith("/../")) {
-                input = input.substring(3);
-                if (output.length() == 0) {
-                    output.append("/");
-                } else if (output.toString().endsWith("../")) {
-                    output.append("..");
-                } else if (output.toString().endsWith("..")) {
-                    output.append("/..");
-                } else {
-                    int index = output.lastIndexOf("/");
-                    if (index == -1) {
-                        output = new StringBuilder();
-                        if (input.charAt(0) == '/') {
-                            input = input.substring(1);
-                        }
-                    } else {
-                        output = output.delete(index, output.length());
-                    }
-                }
-                printStep("2C", output.toString(), input);
-            } else if (input.equals("/..")) {
-                // FIXME: what is complete path segment?
-                input = input.replaceFirst("/..", "/");
-                if (output.length() == 0) {
-                    output.append("/");
-                } else if (output.toString().endsWith("../")) {
-                    output.append("..");
-                } else if (output.toString().endsWith("..")) {
-                    output.append("/..");
-                } else {
-                    int index = output.lastIndexOf("/");
-                    if (index == -1) {
-                        output = new StringBuilder();
-                        if (input.charAt(0) == '/') {
-                            input = input.substring(1);
-                        }
-                    } else {
-                        output = output.delete(index, output.length());
-                    }
-                }
-                printStep("2C", output.toString(), input);
-                // 2D. if the input buffer consists only of ".", then remove
-                // 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 if (input.equals(".")) {
-                input = "";
-                printStep("2D", output.toString(), input);
-            } else if (input.equals("..")) {
-                if (!output.toString().equals("/")) {
-                    output.append("..");
-                }
-                input = "";
-                printStep("2D", output.toString(), input);
-                // 2E. move the first path segment (if any) in the input buffer
-                // to the end of the output buffer, including the initial "/"
-                // character (if any) and any subsequent characters up to, but not
-                // including, the next "/" character or the end of the input buffer.
-            } else {
-                int end = -1;
-                int begin = input.indexOf('/');
-                if (begin == 0) {
-                    end = input.indexOf('/', 1);
-                } else {
-                    end = begin;
-                    begin = 0;
-                }
-                String segment;
-                if (end == -1) {
-                    segment = input.substring(begin);
-                    input = "";
-                } else {
-                    segment = input.substring(begin, end);
-                    input = input.substring(end);
-                }
-                output.append(segment);
-                printStep("2E", output.toString(), input);
-            }
-        }
-
-        // 3. Finally, if the only or last segment of the output buffer is
-        // "..", where ".." is a complete path segment not followed by a slash
-        // then append a slash "/". The output buffer is returned as the result
-        // of remove_dot_segments
-        if (output.toString().endsWith("..")) {
-            output.append("/");
-            printStep("3 ", output.toString(), input);
-        }
-
-        return output.toString();
-    }
-
-    private static void printStep(String step, String output, String input) {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, " " + step + ":   " + output);
-            if (output.length() == 0) {
-                log.log(java.util.logging.Level.FINE, "\t\t\t\t" + input);
-            } else {
-                log.log(java.util.logging.Level.FINE, "\t\t\t" + input);
-            }
-        }
-    }
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_OmitComments.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_OmitComments.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,12 +25,11 @@
 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
 
 /**
- * @author Sean Mullan
  */
-public class Canonicalizer11_OmitComments extends Canonicalizer11 {
+public class Canonicalizer11_OmitComments extends Canonicalizer20010315 {
 
     public Canonicalizer11_OmitComments() {
-        super(false);
+        super(false, true);
     }
 
     public final String engineGetURI() {
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_WithComments.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_WithComments.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,12 +25,11 @@
 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
 
 /**
- * @author Sean Mullan
  */
-public class Canonicalizer11_WithComments extends Canonicalizer11 {
+public class Canonicalizer11_WithComments extends Canonicalizer20010315 {
 
     public Canonicalizer11_WithComments() {
-        super(true);
+        super(true, true);
     }
 
     public final String engineGetURI() {
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,11 +23,7 @@
 package com.sun.org.apache.xml.internal.security.c14n.implementations;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
+import java.io.OutputStream;
 import java.util.Map;
 import java.util.Set;
 import java.util.SortedSet;
@@ -38,9 +34,9 @@
 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
 import com.sun.org.apache.xml.internal.security.c14n.helper.C14nHelper;
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
-import com.sun.org.apache.xml.internal.security.utils.Constants;
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
@@ -51,97 +47,13 @@
  * Implements <A HREF="http://www.w3.org/TR/2001/REC-xml-c14n-20010315">Canonical
  * XML Version 1.0</A>, a W3C Recommendation from 15 March 2001.
  *
- * @author Christian Geuer-Pollmann <geuerp@apache.org>
  */
 public abstract class Canonicalizer20010315 extends CanonicalizerBase {
-    private static final String XMLNS_URI = Constants.NamespaceSpecNS;
-    private static final String XML_LANG_URI = Constants.XML_LANG_SPACE_SpecNS;
 
     private boolean firstCall = true;
-    private final SortedSet<Attr> result = new TreeSet<Attr>(COMPARE);
 
-    private static class XmlAttrStack {
-        static class XmlsStackElement {
-            int level;
-            boolean rendered = false;
-            List<Attr> nodes = new ArrayList<Attr>();
-        };
-
-        int currentLevel = 0;
-        int lastlevel = 0;
-        XmlsStackElement cur;
-        List<XmlsStackElement> levels = new ArrayList<XmlsStackElement>();
-
-        void push(int level) {
-            currentLevel = level;
-            if (currentLevel == -1) {
-                return;
-            }
-            cur = null;
-            while (lastlevel >= currentLevel) {
-                levels.remove(levels.size() - 1);
-                int newSize = levels.size();
-                if (newSize == 0) {
-                    lastlevel = 0;
-                    return;
-                }
-                lastlevel = (levels.get(newSize - 1)).level;
-            }
-        }
-
-        void addXmlnsAttr(Attr n) {
-            if (cur == null) {
-                cur = new XmlsStackElement();
-                cur.level = currentLevel;
-                levels.add(cur);
-                lastlevel = currentLevel;
-            }
-            cur.nodes.add(n);
-        }
-
-        void getXmlnsAttr(Collection<Attr> col) {
-            int size = levels.size() - 1;
-            if (cur == null) {
-                cur = new XmlsStackElement();
-                cur.level = currentLevel;
-                lastlevel = currentLevel;
-                levels.add(cur);
-            }
-            boolean parentRendered = false;
-            XmlsStackElement e = null;
-            if (size == -1) {
-                parentRendered = true;
-            } else {
-                e = levels.get(size);
-                if (e.rendered && e.level + 1 == currentLevel) {
-                    parentRendered = true;
-                }
-            }
-            if (parentRendered) {
-                col.addAll(cur.nodes);
-                cur.rendered = true;
-                return;
-            }
-
-            Map<String, Attr> loa = new HashMap<String, Attr>();
-            for (; size >= 0; size--) {
-                e = levels.get(size);
-                Iterator<Attr> it = e.nodes.iterator();
-                while (it.hasNext()) {
-                    Attr n = it.next();
-                    if (!loa.containsKey(n.getName())) {
-                        loa.put(n.getName(), n);
-                    }
-                }
-            }
-
-            cur.rendered = true;
-            col.addAll(loa.values());
-        }
-
-    }
-
-    private XmlAttrStack xmlattrStack = new XmlAttrStack();
+    private final XmlAttrStack xmlattrStack;
+    private final boolean c14n11;
 
     /**
      * Constructor Canonicalizer20010315
@@ -149,9 +61,22 @@
      * @param includeComments
      */
     public Canonicalizer20010315(boolean includeComments) {
+        this(includeComments, false);
+    }
+
+    /**
+     * Constructor Canonicalizer20010315
+     *
+     * @param includeComments
+     * @param c14n11 Whether this is a Canonical XML 1.1 implementation or not
+     */
+    public Canonicalizer20010315(boolean includeComments, boolean c14n11) {
         super(includeComments);
+        xmlattrStack = new XmlAttrStack(c14n11);
+        this.c14n11 = c14n11;
     }
 
+
     /**
      * Always throws a CanonicalizationException because this is inclusive c14n.
      *
@@ -183,28 +108,44 @@
     }
 
     /**
-     * Returns the Attr[]s to be output for the given element.
+     * Always throws a CanonicalizationException because this is inclusive c14n.
+     *
+     * @param rootNode
+     * @param inclusiveNamespaces
+     * @return none it always fails
+     * @throws CanonicalizationException
+     */
+    public byte[] engineCanonicalizeSubTree(
+            Node rootNode, String inclusiveNamespaces, boolean propagateDefaultNamespace)
+            throws CanonicalizationException {
+
+        /** $todo$ well, should we throw UnsupportedOperationException ? */
+        throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation");
+    }
+
+    /**
+     * Output the Attr[]s for the given element.
      * <br>
-     * The code of this method is a copy of {@link #handleAttributes(Element,
-     * NameSpaceSymbTable)},
+     * The code of this method is a copy of {@link #outputAttributes(Element,
+     * NameSpaceSymbTable, Map<String, byte[]>)},
      * whereas it takes into account that subtree-c14n is -- well -- subtree-based.
      * So if the element in question isRoot of c14n, it's parent is not in the
      * node set, as well as all other ancestors.
      *
      * @param element
      * @param ns
-     * @return the Attr[]s to be output
-     * @throws CanonicalizationException
+     * @param cache
+     * @throws CanonicalizationException, DOMException, IOException
      */
     @Override
-    protected Iterator<Attr> handleAttributesSubtree(Element element, NameSpaceSymbTable ns)
-        throws CanonicalizationException {
+    protected void outputAttributesSubtree(Element element, NameSpaceSymbTable ns,
+                                           Map<String, byte[]> cache)
+        throws CanonicalizationException, DOMException, IOException {
         if (!element.hasAttributes() && !firstCall) {
-            return null;
+            return;
         }
         // result will contain the attrs which have to be output
-        final SortedSet<Attr> result = this.result;
-        result.clear();
+        SortedSet<Attr> result = new TreeSet<Attr>(COMPARE);
 
         if (element.hasAttributes()) {
             NamedNodeMap attrs = element.getAttributes();
@@ -246,11 +187,15 @@
             firstCall = false;
         }
 
-        return result.iterator();
+        OutputStream writer = getWriter();
+        //we output all Attrs which are available
+        for (Attr attr : result) {
+            outputAttrToWriter(attr.getNodeName(), attr.getNodeValue(), writer, cache);
+        }
     }
 
     /**
-     * Returns the Attr[]s to be output for the given element.
+     * Output the Attr[]s for the given element.
      * <br>
      * IMPORTANT: This method expects to work on a modified DOM tree, i.e. a DOM which has
      * been prepared using {@link com.sun.org.apache.xml.internal.security.utils.XMLUtils#circumventBug2650(
@@ -258,17 +203,17 @@
      *
      * @param element
      * @param ns
-     * @return the Attr[]s to be output
-     * @throws CanonicalizationException
+     * @param cache
+     * @throws CanonicalizationException, DOMException, IOException
      */
     @Override
-    protected Iterator<Attr> handleAttributes(Element element, NameSpaceSymbTable ns)
-        throws CanonicalizationException {
+    protected void outputAttributes(Element element, NameSpaceSymbTable ns,
+                                    Map<String, byte[]> cache)
+        throws CanonicalizationException, DOMException, IOException {
         // result will contain the attrs which have to be output
         xmlattrStack.push(ns.getLevel());
         boolean isRealVisible = isVisibleDO(element, ns.getLevel()) == 1;
-        final SortedSet<Attr> result = this.result;
-        result.clear();
+        SortedSet<Attr> result = new TreeSet<Attr>(COMPARE);
 
         if (element.hasAttributes()) {
             NamedNodeMap attrs = element.getAttributes();
@@ -283,7 +228,15 @@
                 if (!XMLNS_URI.equals(NUri)) {
                     //A non namespace definition node.
                     if (XML_LANG_URI.equals(NUri)) {
-                        xmlattrStack.addXmlnsAttr(attribute);
+                        if (c14n11 && "id".equals(NName)) {
+                            if (isRealVisible) {
+                                // treat xml:id like any other attribute
+                                // (emit it, but don't inherit it)
+                                result.add(attribute);
+                            }
+                        } else {
+                            xmlattrStack.addXmlnsAttr(attribute);
+                        }
                     } else if (isRealVisible) {
                         //The node is visible add the attribute to the list of output attributes.
                         result.add(attribute);
@@ -339,7 +292,11 @@
             ns.getUnrenderedNodes(result);
         }
 
-        return result.iterator();
+        OutputStream writer = getWriter();
+        //we output all Attrs which are available
+        for (Attr attr : result) {
+            outputAttrToWriter(attr.getNodeName(), attr.getNodeValue(), writer, cache);
+        }
     }
 
     protected void circumventBugIfNeeded(XMLSignatureInput input)
@@ -369,11 +326,12 @@
             String NName = attribute.getLocalName();
             String NValue = attribute.getNodeValue();
 
-            if (Constants.NamespaceSpecNS.equals(attribute.getNamespaceURI())) {
-                if (!XML.equals(NName) || !Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) {
+            if (XMLNS_URI.equals(attribute.getNamespaceURI())) {
+                if (!XML.equals(NName) || !XML_LANG_URI.equals(NValue)) {
                     ns.addMapping(NName, NValue, attribute);
                 }
-            } else if (XML_LANG_URI.equals(attribute.getNamespaceURI())) {
+            } else if (XML_LANG_URI.equals(attribute.getNamespaceURI())
+                && (!c14n11 || c14n11 && !"id".equals(NName))) {
                 xmlattrStack.addXmlnsAttr(attribute);
             }
         }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,7 +23,8 @@
 package com.sun.org.apache.xml.internal.security.c14n.implementations;
 
 import java.io.IOException;
-import java.util.Iterator;
+import java.io.OutputStream;
+import java.util.Map;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
@@ -33,9 +34,9 @@
 import com.sun.org.apache.xml.internal.security.c14n.helper.C14nHelper;
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
 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.Attr;
+import org.w3c.dom.DOMException;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
@@ -45,31 +46,25 @@
 /**
  * Implements &quot; <A
  * HREF="http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/">Exclusive XML
- * Canonicalization, Version 1.0 </A>&quot; <BR />
+ * Canonicalization, Version 1.0 </A>&quot; <p></p>
  * Credits: During restructuring of the Canonicalizer framework, Ren??
  * Kollmorgen from Software AG submitted an implementation of ExclC14n which
  * fitted into the old architecture and which based heavily on my old (and slow)
  * implementation of "Canonical XML". A big "thank you" to Ren?? for this.
- * <BR />
+ * <p></p>
  * <i>THIS </i> implementation is a complete rewrite of the algorithm.
  *
- * @author Christian Geuer-Pollmann <geuerp@apache.org>
- * @version $Revision: 1147448 $
- * @see <a href="http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/ Exclusive#">
- *          XML Canonicalization, Version 1.0</a>
+ * @see <a href="http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/">
+ *          Exclusive XML Canonicalization, Version 1.0</a>
  */
 public abstract class Canonicalizer20010315Excl extends CanonicalizerBase {
 
-    private static final String XML_LANG_URI = Constants.XML_LANG_SPACE_SpecNS;
-    private static final String XMLNS_URI = Constants.NamespaceSpecNS;
-
     /**
-      * This Set contains the names (Strings like "xmlns" or "xmlns:foo") of
-      * the inclusive namespaces.
-      */
+     * This Set contains the names (Strings like "xmlns" or "xmlns:foo") of
+     * the inclusive namespaces.
+     */
     private SortedSet<String> inclusiveNSSet;
-
-    private final SortedSet<Attr> result = new TreeSet<Attr>(COMPARE);
+    private boolean propagateDefaultNamespace = false;
 
     /**
      * Constructor Canonicalizer20010315Excl
@@ -82,7 +77,7 @@
 
     /**
      * Method engineCanonicalizeSubTree
-     * @inheritDoc
+     * {@inheritDoc}
      * @param rootNode
      *
      * @throws CanonicalizationException
@@ -94,7 +89,7 @@
 
     /**
      * Method engineCanonicalizeSubTree
-     *  @inheritDoc
+     *  {@inheritDoc}
      * @param rootNode
      * @param inclusiveNamespaces
      *
@@ -108,6 +103,22 @@
 
     /**
      * Method engineCanonicalizeSubTree
+     *  {@inheritDoc}
+     * @param rootNode
+     * @param inclusiveNamespaces
+     * @param propagateDefaultNamespace If true the default namespace will be propagated to the c14n-ized root element
+     *
+     * @throws CanonicalizationException
+     */
+    public byte[] engineCanonicalizeSubTree(
+            Node rootNode, String inclusiveNamespaces, boolean propagateDefaultNamespace
+    ) throws CanonicalizationException {
+        this.propagateDefaultNamespace = propagateDefaultNamespace;
+        return engineCanonicalizeSubTree(rootNode, inclusiveNamespaces, null);
+    }
+
+    /**
+     * Method engineCanonicalizeSubTree
      * @param rootNode
      * @param inclusiveNamespaces
      * @param excl A element to exclude from the c14n process.
@@ -137,7 +148,7 @@
 
     /**
      * Method engineCanonicalizeXPathNodeSet
-     * @inheritDoc
+     * {@inheritDoc}
      * @param xpathNodeSet
      * @param inclusiveNamespaces
      * @throws CanonicalizationException
@@ -150,11 +161,11 @@
     }
 
     @Override
-    protected Iterator<Attr> handleAttributesSubtree(Element element, NameSpaceSymbTable ns)
-        throws CanonicalizationException {
+    protected void outputAttributesSubtree(Element element, NameSpaceSymbTable ns,
+                                           Map<String, byte[]> cache)
+        throws CanonicalizationException, DOMException, IOException {
         // result will contain the attrs which have to be output
-        final SortedSet<Attr> result = this.result;
-        result.clear();
+        SortedSet<Attr> result = new TreeSet<Attr>(COMPARE);
 
         // The prefix visibly utilized (in the attribute or in the name) in
         // the element
@@ -193,6 +204,13 @@
                 }
             }
         }
+        if (propagateDefaultNamespace && ns.getLevel() == 1 &&
+                inclusiveNSSet.contains(XMLNS) &&
+                ns.getMappingWithoutRendered(XMLNS) == null) {
+                ns.removeMapping(XMLNS);
+                ns.addMapping(
+                    XMLNS, "", getNullNode(element.getOwnerDocument()));
+        }
         String prefix = null;
         if (element.getNamespaceURI() != null
             && !(element.getPrefix() == null || element.getPrefix().length() == 0)) {
@@ -209,20 +227,22 @@
             }
         }
 
-        return result.iterator();
+        OutputStream writer = getWriter();
+        //we output all Attrs which are available
+        for (Attr attr : result) {
+            outputAttrToWriter(attr.getNodeName(), attr.getNodeValue(), writer, cache);
+        }
     }
 
     /**
-     * @inheritDoc
-     * @param element
-     * @throws CanonicalizationException
+     * {@inheritDoc}
      */
     @Override
-    protected final Iterator<Attr> handleAttributes(Element element, NameSpaceSymbTable ns)
-        throws CanonicalizationException {
+    protected void outputAttributes(Element element, NameSpaceSymbTable ns,
+                                    Map<String, byte[]> cache)
+        throws CanonicalizationException, DOMException, IOException {
         // result will contain the attrs which have to be output
-        final SortedSet<Attr> result = this.result;
-        result.clear();
+        SortedSet<Attr> result = new TreeSet<Attr>(COMPARE);
 
         // The prefix visibly utilized (in the attribute or in the name) in
         // the element
@@ -312,7 +332,11 @@
             }
         }
 
-        return result.iterator();
+        OutputStream writer = getWriter();
+        //we output all Attrs which are available
+        for (Attr attr : result) {
+            outputAttrToWriter(attr.getNodeName(), attr.getNodeValue(), writer, cache);
+        }
     }
 
     protected void circumventBugIfNeeded(XMLSignatureInput input)
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclOmitComments.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclOmitComments.java	Sat Oct 24 01:11:51 2020 +0100
@@ -33,12 +33,12 @@
         super(false);
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public final String engineGetURI() {
         return Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public final boolean engineGetIncludeComments() {
         return false;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclWithComments.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclWithComments.java	Sat Oct 24 01:11:51 2020 +0100
@@ -37,12 +37,12 @@
         super(true);
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public final String engineGetURI() {
         return Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public final boolean engineGetIncludeComments() {
         return true;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315OmitComments.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315OmitComments.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,7 +25,6 @@
 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
 
 /**
- * @author Christian Geuer-Pollmann
  */
 public class Canonicalizer20010315OmitComments extends Canonicalizer20010315 {
 
@@ -37,12 +36,12 @@
         super(false);
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public final String engineGetURI() {
         return Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public final boolean engineGetIncludeComments() {
         return false;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315WithComments.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315WithComments.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,7 +25,6 @@
 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
 
 /**
- * @author Christian Geuer-Pollmann
  */
 public class Canonicalizer20010315WithComments extends Canonicalizer20010315 {
 
@@ -36,12 +35,12 @@
         super(true);
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public final String engineGetURI() {
         return Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public final boolean engineGetIncludeComments() {
         return true;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java	Sat Oct 24 01:11:51 2020 +0100
@@ -46,8 +46,9 @@
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Comment;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
-import org.w3c.dom.Document;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.ProcessingInstruction;
@@ -55,12 +56,14 @@
 
 /**
  * Abstract base class for canonicalization algorithms.
- *
- * @author Christian Geuer-Pollmann <geuerp@apache.org>
+ * Please note that these implementations are NOT thread safe - please see the following JIRA for more information:
+ * https://issues.apache.org/jira/browse/SANTUARIO-463
  */
 public abstract class CanonicalizerBase extends CanonicalizerSpi {
     public static final String XML = "xml";
     public static final String XMLNS = "xmlns";
+    public static final String XMLNS_URI = Constants.NamespaceSpecNS;
+    public static final String XML_LANG_URI = Constants.XML_LANG_SPACE_SpecNS;
 
     protected static final AttrCompare COMPARE = new AttrCompare();
 
@@ -96,9 +99,9 @@
     private Node excludeNode;
     private OutputStream writer = new ByteArrayOutputStream();
 
-    /**
-     * The null xmlns definition.
-     */
+   /**
+    * The null xmlns definition.
+    */
     private Attr nullNode;
 
     /**
@@ -112,7 +115,7 @@
 
     /**
      * Method engineCanonicalizeSubTree
-     * @inheritDoc
+     * {@inheritDoc}
      * @param rootNode
      * @throws CanonicalizationException
      */
@@ -123,7 +126,7 @@
 
     /**
      * Method engineCanonicalizeXPathNodeSet
-     * @inheritDoc
+     * {@inheritDoc}
      * @param xpathNodeSet
      * @throws CanonicalizationException
      */
@@ -161,14 +164,12 @@
                 }
             }
             return null;
-        } catch (CanonicalizationException ex) {
-            throw new CanonicalizationException("empty", ex);
         } catch (ParserConfigurationException ex) {
-            throw new CanonicalizationException("empty", ex);
+            throw new CanonicalizationException(ex);
         } catch (IOException ex) {
-            throw new CanonicalizationException("empty", ex);
+            throw new CanonicalizationException(ex);
         } catch (SAXException ex) {
-            throw new CanonicalizationException("empty", ex);
+            throw new CanonicalizationException(ex);
         }
     }
 
@@ -179,6 +180,10 @@
         this.writer = writer;
     }
 
+    protected OutputStream getWriter() {
+        return writer;
+    }
+
     /**
      * Canonicalizes a Subtree node.
      *
@@ -224,9 +229,9 @@
             return null;
 
         } catch (UnsupportedEncodingException ex) {
-            throw new CanonicalizationException("empty", ex);
+            throw new CanonicalizationException(ex);
         } catch (IOException ex) {
-            throw new CanonicalizationException("empty", ex);
+            throw new CanonicalizationException(ex);
         }
     }
 
@@ -243,7 +248,7 @@
     protected final void canonicalizeSubTree(
         Node currentNode, NameSpaceSymbTable ns, Node endnode, int documentLevel
     ) throws CanonicalizationException, IOException {
-        if (isVisibleInt(currentNode) == -1) {
+        if (currentNode == null || isVisibleInt(currentNode) == -1) {
             return;
         }
         Node sibling = null;
@@ -251,7 +256,7 @@
         final OutputStream writer = this.writer;
         final Node excludeNode = this.excludeNode;
         final boolean includeComments = this.includeComments;
-        Map<String, byte[]> cache = new HashMap<String, byte[]>();
+        Map<String, byte[]> cache = new HashMap<>();
         do {
             switch (currentNode.getNodeType()) {
 
@@ -259,7 +264,8 @@
             case Node.NOTATION_NODE :
             case Node.ATTRIBUTE_NODE :
                 // illegal node type during traversal
-                throw new CanonicalizationException("empty");
+                throw new CanonicalizationException("empty",
+                                                    new Object[]{"illegal node type during traversal"});
 
             case Node.DOCUMENT_FRAGMENT_NODE :
             case Node.DOCUMENT_NODE :
@@ -294,14 +300,8 @@
                 String name = currentElement.getTagName();
                 UtfHelpper.writeByte(name, writer, cache);
 
-                Iterator<Attr> attrs = this.handleAttributesSubtree(currentElement, ns);
-                if (attrs != null) {
-                    //we output all Attrs which are available
-                    while (attrs.hasNext()) {
-                        Attr attr = attrs.next();
-                        outputAttrToWriter(attr.getNodeName(), attr.getNodeValue(), writer, cache);
-                    }
-                }
+                outputAttributesSubtree(currentElement, ns, cache);
+
                 writer.write('>');
                 sibling = currentNode.getFirstChild();
                 if (sibling == null) {
@@ -373,9 +373,9 @@
             }
             return null;
         } catch (UnsupportedEncodingException ex) {
-            throw new CanonicalizationException("empty", ex);
+            throw new CanonicalizationException(ex);
         } catch (IOException ex) {
-            throw new CanonicalizationException("empty", ex);
+            throw new CanonicalizationException(ex);
         }
     }
 
@@ -403,9 +403,8 @@
         }
         Node sibling = null;
         Node parentNode = null;
-        OutputStream writer = this.writer;
         int documentLevel = NODE_BEFORE_DOCUMENT_ELEMENT;
-        Map<String, byte[]> cache = new HashMap<String, byte[]>();
+        Map<String, byte[]> cache = new HashMap<>();
         do {
             switch (currentNode.getNodeType()) {
 
@@ -413,7 +412,8 @@
             case Node.NOTATION_NODE :
             case Node.ATTRIBUTE_NODE :
                 // illegal node type during traversal
-                throw new CanonicalizationException("empty");
+                throw new CanonicalizationException("empty",
+                                                    new Object[]{"illegal node type during traversal"});
 
             case Node.DOCUMENT_FRAGMENT_NODE :
             case Node.DOCUMENT_NODE :
@@ -422,7 +422,7 @@
                 break;
 
             case Node.COMMENT_NODE :
-                if (this.includeComments && (isVisibleDO(currentNode, ns.getLevel()) == 1)) {
+                if (this.includeComments && isVisibleDO(currentNode, ns.getLevel()) == 1) {
                     outputCommentToWriter((Comment) currentNode, writer, documentLevel);
                 }
                 break;
@@ -438,8 +438,8 @@
                 if (isVisible(currentNode)) {
                     outputTextToWriter(currentNode.getNodeValue(), writer);
                     for (Node nextSibling = currentNode.getNextSibling();
-                        (nextSibling != null) && ((nextSibling.getNodeType() == Node.TEXT_NODE)
-                            || (nextSibling.getNodeType() == Node.CDATA_SECTION_NODE));
+                        nextSibling != null && (nextSibling.getNodeType() == Node.TEXT_NODE
+                            || nextSibling.getNodeType() == Node.CDATA_SECTION_NODE);
                         nextSibling = nextSibling.getNextSibling()) {
                         outputTextToWriter(nextSibling.getNodeValue(), writer);
                         currentNode = nextSibling;
@@ -458,7 +458,7 @@
                     sibling = currentNode.getNextSibling();
                     break;
                 }
-                currentNodeIsVisible = (i == 1);
+                currentNodeIsVisible = i == 1;
                 if (currentNodeIsVisible) {
                     ns.outputNodePush();
                     writer.write('<');
@@ -468,14 +468,8 @@
                     ns.push();
                 }
 
-                Iterator<Attr> attrs = handleAttributes(currentElement,ns);
-                if (attrs != null) {
-                    //we output all Attrs which are available
-                    while (attrs.hasNext()) {
-                        Attr attr = attrs.next();
-                        outputAttrToWriter(attr.getNodeName(), attr.getNodeValue(), writer, cache);
-                    }
-                }
+                outputAttributes(currentElement, ns, cache);
+
                 if (currentNodeIsVisible) {
                     writer.write('>');
                 }
@@ -535,13 +529,13 @@
         if (nodeFilter != null) {
             Iterator<NodeFilter> it = nodeFilter.iterator();
             while (it.hasNext()) {
-                int i = (it.next()).isNodeIncludeDO(currentNode, level);
+                int i = it.next().isNodeIncludeDO(currentNode, level);
                 if (i != 1) {
                     return i;
                 }
             }
         }
-        if ((this.xpathNodeSet != null) && !this.xpathNodeSet.contains(currentNode)) {
+        if (this.xpathNodeSet != null && !this.xpathNodeSet.contains(currentNode)) {
             return 0;
         }
         return 1;
@@ -551,13 +545,13 @@
         if (nodeFilter != null) {
             Iterator<NodeFilter> it = nodeFilter.iterator();
             while (it.hasNext()) {
-                int i = (it.next()).isNodeInclude(currentNode);
+                int i = it.next().isNodeInclude(currentNode);
                 if (i != 1) {
                     return i;
                 }
             }
         }
-        if ((this.xpathNodeSet != null) && !this.xpathNodeSet.contains(currentNode)) {
+        if (this.xpathNodeSet != null && !this.xpathNodeSet.contains(currentNode)) {
             return 0;
         }
         return 1;
@@ -572,7 +566,7 @@
                 }
             }
         }
-        if ((this.xpathNodeSet != null) && !this.xpathNodeSet.contains(currentNode)) {
+        if (this.xpathNodeSet != null && !this.xpathNodeSet.contains(currentNode)) {
             return false;
         }
         return true;
@@ -621,7 +615,7 @@
             return;
         }
         //Obtain all the parents of the element
-        List<Element> parents = new ArrayList<Element>();
+        List<Element> parents = new ArrayList<>();
         Node parent = n1;
         while (parent != null && Node.ELEMENT_NODE == parent.getNodeType()) {
             parents.add((Element)parent);
@@ -634,35 +628,34 @@
             handleParent(ele, ns);
         }
         parents.clear();
-        Attr nsprefix;
-        if (((nsprefix = ns.getMappingWithoutRendered(XMLNS)) != null)
-                && "".equals(nsprefix.getValue())) {
+        Attr nsprefix = ns.getMappingWithoutRendered(XMLNS);
+        if (nsprefix != null && "".equals(nsprefix.getValue())) {
             ns.addMappingAndRender(
                     XMLNS, "", getNullNode(nsprefix.getOwnerDocument()));
         }
     }
 
     /**
-     * Obtain the attributes to output for this node in XPathNodeSet c14n.
+     * Output the attributes for this node in XPathNodeSet c14n.
      *
      * @param element
      * @param ns
-     * @return the attributes nodes to output.
-     * @throws CanonicalizationException
+     * @param cache
+     * @throws CanonicalizationException, DOMException, IOException
      */
-    abstract Iterator<Attr> handleAttributes(Element element, NameSpaceSymbTable ns)
-        throws CanonicalizationException;
+    abstract void outputAttributes(Element element, NameSpaceSymbTable ns, Map<String, byte[]> cache)
+        throws CanonicalizationException, DOMException, IOException;
 
     /**
-     * Obtain the attributes to output for this node in a Subtree c14n.
+     * Output the attributes for this node in a Subtree c14n.
      *
      * @param element
      * @param ns
-     * @return the attributes nodes to output.
-     * @throws CanonicalizationException
+     * @param cache
+     * @throws CanonicalizationException, DOMException, IOException
      */
-    abstract Iterator<Attr> handleAttributesSubtree(Element element, NameSpaceSymbTable ns)
-        throws CanonicalizationException;
+    abstract void outputAttributesSubtree(Element element, NameSpaceSymbTable ns, Map<String, byte[]> cache)
+        throws CanonicalizationException, DOMException, IOException;
 
     abstract void circumventBugIfNeeded(XMLSignatureInput input)
         throws CanonicalizationException, ParserConfigurationException, IOException, SAXException;
@@ -672,13 +665,13 @@
      *
      * The string value of the node is modified by replacing
      * <UL>
-     * <LI>all ampersands (&) with <CODE>&amp;amp;</CODE></LI>
-     * <LI>all open angle brackets (<) with <CODE>&amp;lt;</CODE></LI>
-     * <LI>all quotation mark characters with <CODE>&amp;quot;</CODE></LI>
-     * <LI>and the whitespace characters <CODE>#x9</CODE>, #xA, and #xD, with character
+     * <LI>all ampersands with {@code &amp;amp;}</LI>
+     * <LI>all open angle brackets with {@code &amp;lt;}</LI>
+     * <LI>all quotation mark characters with {@code &amp;quot;}</LI>
+     * <LI>and the whitespace characters {@code #x9}, #xA, and #xD, with character
      * references. The character references are written in uppercase
-     * hexadecimal with no leading zeroes (for example, <CODE>#xD</CODE> is represented
-     * by the character reference <CODE>&amp;#xD;</CODE>)</LI>
+     * hexadecimal with no leading zeroes (for example, {@code #xD} is represented
+     * by the character reference {@code &amp;#xD;})</LI>
      * </UL>
      *
      * @param name
@@ -697,7 +690,8 @@
         final int length = value.length();
         int i = 0;
         while (i < length) {
-            char c = value.charAt(i++);
+            int c = value.codePointAt(i);
+            i += Character.charCount(c);
 
             switch (c) {
 
@@ -729,7 +723,7 @@
                 if (c < 0x80) {
                     writer.write(c);
                 } else {
-                    UtfHelpper.writeCharToUtf8(c, writer);
+                    UtfHelpper.writeCodePointToUtf8(c, writer);
                 }
                 continue;
             }
@@ -757,15 +751,16 @@
         final String target = currentPI.getTarget();
         int length = target.length();
 
-        for (int i = 0; i < length; i++) {
-            char c = target.charAt(i);
+        for (int i = 0; i < length; ) {
+            int c = target.codePointAt(i);
+            i += Character.charCount(c);
             if (c == 0x0D) {
                 writer.write(XD.clone());
             } else {
                 if (c < 0x80) {
                     writer.write(c);
                 } else {
-                    UtfHelpper.writeCharToUtf8(c, writer);
+                    UtfHelpper.writeCodePointToUtf8(c, writer);
                 }
             }
         }
@@ -777,12 +772,13 @@
         if (length > 0) {
             writer.write(' ');
 
-            for (int i = 0; i < length; i++) {
-                char c = data.charAt(i);
+            for (int i = 0; i < length; ) {
+                int c = data.codePointAt(i);
+                i += Character.charCount(c);
                 if (c == 0x0D) {
                     writer.write(XD.clone());
                 } else {
-                    UtfHelpper.writeCharToUtf8(c, writer);
+                    UtfHelpper.writeCodePointToUtf8(c, writer);
                 }
             }
         }
@@ -811,15 +807,16 @@
         final String data = currentComment.getData();
         final int length = data.length();
 
-        for (int i = 0; i < length; i++) {
-            char c = data.charAt(i);
+        for (int i = 0; i < length; ) {
+            int c = data.codePointAt(i);
+            i += Character.charCount(c);
             if (c == 0x0D) {
                 writer.write(XD.clone());
             } else {
                 if (c < 0x80) {
                     writer.write(c);
                 } else {
-                    UtfHelpper.writeCharToUtf8(c, writer);
+                    UtfHelpper.writeCodePointToUtf8(c, writer);
                 }
             }
         }
@@ -842,8 +839,9 @@
     ) throws IOException {
         final int length = text.length();
         byte[] toWrite;
-        for (int i = 0; i < length; i++) {
-            char c = text.charAt(i);
+        for (int i = 0; i < length; ) {
+            int c = text.codePointAt(i);
+            i += Character.charCount(c);
 
             switch (c) {
 
@@ -867,7 +865,7 @@
                 if (c < 0x80) {
                     writer.write(c);
                 } else {
-                    UtfHelpper.writeCharToUtf8(c, writer);
+                    UtfHelpper.writeCodePointToUtf8(c, writer);
                 }
                 continue;
             }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java	Sat Oct 24 01:11:51 2020 +0100
@@ -24,7 +24,7 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
@@ -36,6 +36,7 @@
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Comment;
+import org.w3c.dom.DOMException;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
@@ -54,8 +55,6 @@
  */
 public class CanonicalizerPhysical extends CanonicalizerBase {
 
-    private final SortedSet<Attr> result = new TreeSet<Attr>(COMPARE);
-
     /**
      * Constructor Canonicalizer20010315
      */
@@ -94,31 +93,43 @@
     }
 
     /**
-     * Returns the Attr[]s to be output for the given element.
+     * Always throws a CanonicalizationException.
+     *
+     * @param rootNode
+     * @param inclusiveNamespaces
+     * @return none it always fails
+     * @throws CanonicalizationException
+     */
+    public byte[] engineCanonicalizeSubTree(
+            Node rootNode, String inclusiveNamespaces, boolean propagateDefaultNamespace)
+            throws CanonicalizationException {
+
+        /** $todo$ well, should we throw UnsupportedOperationException ? */
+        throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation");
+    }
+
+    /**
+     * Output the Attr[]s for the given element.
      * <br>
-     * The code of this method is a copy of {@link #handleAttributes(Element,
-     * NameSpaceSymbTable)},
+     * The code of this method is a copy of {@link #outputAttributes(Element,
+     * NameSpaceSymbTable, Map<String, byte[]>)},
      * whereas it takes into account that subtree-c14n is -- well -- subtree-based.
      * So if the element in question isRoot of c14n, it's parent is not in the
      * node set, as well as all other ancestors.
      *
      * @param element
      * @param ns
-     * @return the Attr[]s to be output
-     * @throws CanonicalizationException
+     * @param cache
+     * @throws CanonicalizationException, DOMException, IOException
      */
     @Override
-    protected Iterator<Attr> handleAttributesSubtree(Element element, NameSpaceSymbTable ns)
-        throws CanonicalizationException {
-        if (!element.hasAttributes()) {
-            return null;
-        }
+    protected void outputAttributesSubtree(Element element, NameSpaceSymbTable ns,
+                                           Map<String, byte[]> cache)
+        throws CanonicalizationException, DOMException, IOException {
+        if (element.hasAttributes()) {
+            // result will contain all the attrs declared directly on that element
+            SortedSet<Attr> result = new TreeSet<Attr>(COMPARE);
 
-        // result will contain all the attrs declared directly on that element
-        final SortedSet<Attr> result = this.result;
-        result.clear();
-
-        if (element.hasAttributes()) {
             NamedNodeMap attrs = element.getAttributes();
             int attrsLength = attrs.getLength();
 
@@ -126,22 +137,19 @@
                 Attr attribute = (Attr) attrs.item(i);
                 result.add(attribute);
             }
+
+            OutputStream writer = getWriter();
+            //we output all Attrs which are available
+            for (Attr attr : result) {
+                outputAttrToWriter(attr.getNodeName(), attr.getNodeValue(), writer, cache);
+            }
         }
-
-        return result.iterator();
     }
 
-    /**
-     * Returns the Attr[]s to be output for the given element.
-     *
-     * @param element
-     * @param ns
-     * @return the Attr[]s to be output
-     * @throws CanonicalizationException
-     */
     @Override
-    protected Iterator<Attr> handleAttributes(Element element, NameSpaceSymbTable ns)
-        throws CanonicalizationException {
+    protected void outputAttributes(Element element, NameSpaceSymbTable ns,
+                                    Map<String, byte[]> cache)
+        throws CanonicalizationException, DOMException, IOException {
 
         /** $todo$ well, should we throw UnsupportedOperationException ? */
         throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation");
@@ -157,12 +165,12 @@
         // nothing to do
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public final String engineGetURI() {
         return Canonicalizer.ALGO_ID_C14N_PHYSICAL;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public final boolean engineGetIncludeComments() {
         return true;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java	Sat Oct 24 01:11:51 2020 +0100
@@ -35,7 +35,6 @@
  * A stack based Symbol Table.
  *<br>For speed reasons all the symbols are introduced in the same map,
  * and at the same time in a list so it can be removed when the frame is pop back.
- * @author Raul Benito
  */
 public class NameSpaceSymbTable {
 
@@ -59,7 +58,7 @@
      * Default constractor
      **/
     public NameSpaceSymbTable() {
-        level = new ArrayList<SymbMap>();
+        level = new ArrayList<>();
         //Insert the default binding for xmlns.
         symb = (SymbMap) initialMap.clone();
     }
@@ -74,7 +73,7 @@
         while (it.hasNext()) {
             NameSpaceSymbEntry n = it.next();
             //put them rendered?
-            if ((!n.rendered) && (n.n != null)) {
+            if (!n.rendered && n.n != null) {
                 n = (NameSpaceSymbEntry) n.clone();
                 needsClone();
                 symb.put(n.prefix, n);
@@ -123,7 +122,7 @@
             if (size == 0) {
                 cloned = false;
             } else {
-                cloned = (level.get(size - 1) != symb);
+                cloned = level.get(size - 1) != symb;
             }
         } else {
             cloned = false;
@@ -191,7 +190,7 @@
      **/
     public boolean addMapping(String prefix, String uri, Attr n) {
         NameSpaceSymbEntry ob = symb.get(prefix);
-        if ((ob != null) && uri.equals(ob.uri)) {
+        if (ob != null && uri.equals(ob.uri)) {
             //If we have it previously defined. Don't keep working.
             return false;
         }
@@ -203,7 +202,7 @@
             //We have a previous definition store it for the pop.
             //Check if a previous definition(not the inmidiatly one) has been rendered.
             ne.lastrendered = ob.lastrendered;
-            if ((ob.lastrendered != null) && (ob.lastrendered.equals(uri))) {
+            if (ob.lastrendered != null && ob.lastrendered.equals(uri)) {
                 //Yes it is. Mark as rendered.
                 ne.rendered = true;
             }
@@ -222,7 +221,7 @@
     public Node addMappingAndRender(String prefix, String uri, Attr n) {
         NameSpaceSymbEntry ob = symb.get(prefix);
 
-        if ((ob != null) && uri.equals(ob.uri)) {
+        if (ob != null && uri.equals(ob.uri)) {
             if (!ob.rendered) {
                 ob = (NameSpaceSymbEntry) ob.clone();
                 needsClone();
@@ -234,11 +233,11 @@
             return null;
         }
 
-        NameSpaceSymbEntry ne = new NameSpaceSymbEntry(uri,n,true,prefix);
+        NameSpaceSymbEntry ne = new NameSpaceSymbEntry(uri, n, true, prefix);
         ne.lastrendered = uri;
         needsClone();
         symb.put(prefix, ne);
-        if ((ob != null) && (ob.lastrendered != null) && (ob.lastrendered.equals(uri))) {
+        if (ob != null && ob.lastrendered != null && ob.lastrendered.equals(uri)) {
             ne.rendered = true;
             return null;
         }
@@ -304,7 +303,7 @@
         this.prefix = prefix;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public Object clone() {
         try {
             return super.clone();
@@ -312,7 +311,7 @@
             return null;
         }
     }
-};
+}
 
 class SymbMap implements Cloneable {
     int free = 23;
@@ -329,7 +328,7 @@
         Object oldKey = keys[index];
         keys[index] = key;
         entries[index] = value;
-        if ((oldKey == null || !oldKey.equals(key)) && (--free == 0)) {
+        if ((oldKey == null || !oldKey.equals(key)) && --free == 0) {
             free = entries.length;
             int newCapacity = free << 2;
             rehash(newCapacity);
@@ -337,9 +336,9 @@
     }
 
     List<NameSpaceSymbEntry> entrySet() {
-        List<NameSpaceSymbEntry> a = new ArrayList<NameSpaceSymbEntry>();
+        List<NameSpaceSymbEntry> a = new ArrayList<>();
         for (int i = 0;i < entries.length;i++) {
-            if ((entries[i] != null) && !("".equals(entries[i].uri))) {
+            if (entries[i] != null && !"".equals(entries[i].uri)) {
                 a.add(entries[i]);
             }
         }
@@ -353,21 +352,21 @@
         int index = (obj.hashCode() & 0x7fffffff) % length;
         Object cur = set[index];
 
-        if (cur == null || (cur.equals(obj))) {
+        if (cur == null || cur.equals(obj)) {
             return index;
         }
         length--;
         do {
             index = index == length ? 0 : ++index;
             cur = set[index];
-        } while (cur != null && (!cur.equals(obj)));
+        } while (cur != null && !cur.equals(obj));
         return index;
     }
 
     /**
      * rehashes the map to the new capacity.
      *
-     * @param newCapacity an <code>int</code> value
+     * @param newCapacity an {@code int} value
      */
     protected void rehash(int newCapacity) {
         int oldCapacity = keys.length;
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/UtfHelpper.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/UtfHelpper.java	Sat Oct 24 01:11:51 2020 +0100
@@ -24,11 +24,27 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Map;
 
-public class UtfHelpper {
+public final class UtfHelpper {
 
-    static final void writeByte(
+    /**
+     * Revert to the old behavior (version 2 or before), i.e. surrogate pairs characters becomes
+     * '??' in output. Set system property com.sun.org.apache.xml.internal.security.c14n.oldUtf8=true if you want
+     * to verify signatures generated by version 2 or before that contains 32 bit chars in the
+     * XML document.
+     */
+    private static final boolean OLD_UTF8 =
+        AccessController.doPrivileged((PrivilegedAction<Boolean>)
+            () -> Boolean.getBoolean("com.sun.org.apache.xml.internal.security.c14n.oldUtf8"));
+
+    private UtfHelpper() {
+        // complete
+    }
+
+    public static void writeByte(
         final String str,
         final OutputStream out,
         Map<String, byte[]> cache
@@ -42,12 +58,73 @@
         out.write(result);
     }
 
-    static final void writeCharToUtf8(final char c, final OutputStream out) throws IOException {
+    public static void writeCodePointToUtf8(final int c, final OutputStream out) throws IOException {
+        if (!Character.isValidCodePoint(c) || c >= 0xD800 && c <= 0xDBFF || c >= 0xDC00 && c <= 0xDFFF) {
+            // valid code point: c >= 0x0000 && c <= 0x10FFFF
+            out.write(0x3f);
+            return;
+        }
+        if (OLD_UTF8 && c >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+            // version 2 or before output 2 question mark characters for 32 bit chars
+            out.write(0x3f);
+            out.write(0x3f);
+            return;
+        }
+
+        if (c < 0x80) {
+            // 0x00000000 - 0x0000007F
+            // 0xxxxxxx
+            out.write(c);
+            return;
+        }
+        byte extraByte = 0;
+        if (c < 0x800) {
+            // 0x00000080 - 0x000007FF
+            // 110xxxxx 10xxxxxx
+            extraByte = 1;
+        } else if (c < 0x10000) {
+            // 0x00000800 - 0x0000FFFF
+            // 1110xxxx 10xxxxxx 10xxxxxx
+            extraByte = 2;
+        } else if (c < 0x200000) {
+            // 0x00010000 - 0x001FFFFF
+            // 11110xxx 10xxxxx 10xxxxxx 10xxxxxx
+            extraByte = 3;
+        } else if (c < 0x4000000) {
+            // 0x00200000 - 0x03FFFFFF
+            // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+            // already outside valid Character range, just for completeness
+            extraByte = 4;
+        } else if (c <= 0x7FFFFFFF) {
+            // 0x04000000 - 0x7FFFFFFF
+            // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+            // already outside valid Character range, just for completeness
+            extraByte = 5;
+        } else {
+            // 0x80000000 - 0xFFFFFFFF
+            // case not possible as java has no unsigned int
+            out.write(0x3f);
+            return;
+        }
+
+        byte write;
+        int shift = 6 * extraByte;
+        write = (byte)((0xFE << (6 - extraByte)) | (c >>> shift));
+        out.write(write);
+        for (int i = extraByte - 1; i >= 0; i--) {
+            shift -= 6;
+            write = (byte)(0x80 | ((c >>> shift) & 0x3F));
+            out.write(write);
+        }
+    }
+
+    @Deprecated
+    public static void writeCharToUtf8(final char c, final OutputStream out) throws IOException {
         if (c < 0x80) {
             out.write(c);
             return;
         }
-        if ((c >= 0xD800 && c <= 0xDBFF) || (c >= 0xDC00 && c <= 0xDFFF)) {
+        if (c >= 0xD800 && c <= 0xDBFF || c >= 0xDC00 && c <= 0xDFFF) {
             //No Surrogates in sun java
             out.write(0x3f);
             return;
@@ -59,7 +136,7 @@
             ch = (char)(c>>>12);
             write = 0xE0;
             if (ch > 0) {
-                write |= (ch & 0x0F);
+                write |= ch & 0x0F;
             }
             out.write(write);
             write = 0x80;
@@ -70,104 +147,149 @@
         }
         ch = (char)(c>>>6);
         if (ch > 0) {
-            write |= (ch & bias);
+            write |= ch & bias;
         }
         out.write(write);
         out.write(0x80 | ((c) & 0x3F));
 
     }
 
-    static final void writeStringToUtf8(
-        final String str,
-        final OutputStream out
-    ) throws IOException{
+    public static void writeStringToUtf8(
+        final String str, final OutputStream out
+    ) throws IOException {
         final int length = str.length();
         int i = 0;
-        char c;
+        int c;
         while (i < length) {
-            c = str.charAt(i++);
+            c = str.codePointAt(i);
+            i += Character.charCount(c);
+            if (!Character.isValidCodePoint(c) || c >= 0xD800 && c <= 0xDBFF || c >= 0xDC00 && c <= 0xDFFF) {
+                // valid code point: c >= 0x0000 && c <= 0x10FFFF
+                out.write(0x3f);
+                continue;
+            }
+            if (OLD_UTF8 && c >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+                // version 2 or before output 2 question mark characters for 32 bit chars
+                out.write(0x3f);
+                out.write(0x3f);
+                continue;
+            }
             if (c < 0x80)  {
                 out.write(c);
                 continue;
             }
-            if ((c >= 0xD800 && c <= 0xDBFF) || (c >= 0xDC00 && c <= 0xDFFF)) {
-                //No Surrogates in sun java
+            byte extraByte = 0;
+            if (c < 0x800) {
+                // 0x00000080 - 0x000007FF
+                // 110xxxxx 10xxxxxx
+                extraByte = 1;
+            } else if (c < 0x10000) {
+                // 0x00000800 - 0x0000FFFF
+                // 1110xxxx 10xxxxxx 10xxxxxx
+                extraByte = 2;
+            } else if (c < 0x200000) {
+                // 0x00010000 - 0x001FFFFF
+                // 11110xxx 10xxxxx 10xxxxxx 10xxxxxx
+                extraByte = 3;
+            } else if (c < 0x4000000) {
+                // 0x00200000 - 0x03FFFFFF
+                // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+                // already outside valid Character range, just for completeness
+                extraByte = 4;
+            } else if (c <= 0x7FFFFFFF) {
+                // 0x04000000 - 0x7FFFFFFF
+                // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+                // already outside valid Character range, just for completeness
+                extraByte = 5;
+            } else {
+                // 0x80000000 - 0xFFFFFFFF
+                // case not possible as java has no unsigned int
                 out.write(0x3f);
                 continue;
             }
-            char ch;
-            int bias;
-            int write;
-            if (c > 0x07FF) {
-                ch = (char)(c>>>12);
-                write = 0xE0;
-                if (ch > 0) {
-                    write |= (ch & 0x0F);
-                }
+            byte write;
+            int shift = 6 * extraByte;
+            write = (byte)((0xFE << (6 - extraByte)) | (c >>> shift));
+            out.write(write);
+            for (int j = extraByte - 1; j >= 0; j--) {
+                shift -= 6;
+                write = (byte)(0x80 | ((c >>> shift) & 0x3F));
                 out.write(write);
-                write = 0x80;
-                bias = 0x3F;
-            } else {
-                write = 0xC0;
-                bias = 0x1F;
             }
-            ch = (char)(c>>>6);
-            if (ch > 0) {
-                write |= (ch & bias);
-            }
-            out.write(write);
-            out.write(0x80 | ((c) & 0x3F));
 
         }
 
     }
 
-    public static final byte[] getStringInUtf8(final String str) {
+    public static byte[] getStringInUtf8(final String str) {
         final int length = str.length();
         boolean expanded = false;
         byte[] result = new byte[length];
         int i = 0;
         int out = 0;
-        char c;
+        int c;
         while (i < length) {
-            c = str.charAt(i++);
+            c = str.codePointAt(i);
+            i += Character.charCount(c);
+            if (!Character.isValidCodePoint(c) || c >= 0xD800 && c <= 0xDBFF || c >= 0xDC00 && c <= 0xDFFF) {
+                // valid code point: c >= 0x0000 && c <= 0x10FFFF
+                result[out++] = (byte)0x3f;
+                continue;
+            }
+            if (OLD_UTF8 && c >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+                // version 2 or before output 2 question mark characters for 32 bit chars
+                result[out++] = (byte)0x3f;
+                result[out++] = (byte)0x3f;
+                continue;
+            }
             if (c < 0x80) {
                 result[out++] = (byte)c;
                 continue;
             }
-            if ((c >= 0xD800 && c <= 0xDBFF) || (c >= 0xDC00 && c <= 0xDFFF)) {
-                //No Surrogates in sun java
-                result[out++] = 0x3f;
-                continue;
-            }
             if (!expanded) {
-                byte newResult[] = new byte[3*length];
+                byte newResult[] = new byte[6*length];
                 System.arraycopy(result, 0, newResult, 0, out);
                 result = newResult;
                 expanded = true;
             }
-            char ch;
-            int bias;
+            byte extraByte = 0;
+            if (c < 0x800) {
+                // 0x00000080 - 0x000007FF
+                // 110xxxxx 10xxxxxx
+                extraByte = 1;
+            } else if (c < 0x10000) {
+                // 0x00000800 - 0x0000FFFF
+                // 1110xxxx 10xxxxxx 10xxxxxx
+                extraByte = 2;
+            } else if (c < 0x200000) {
+                // 0x00010000 - 0x001FFFFF
+                // 11110xxx 10xxxxx 10xxxxxx 10xxxxxx
+                extraByte = 3;
+            } else if (c < 0x4000000) {
+                // 0x00200000 - 0x03FFFFFF
+                // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+                // already outside valid Character range, just for completeness
+                extraByte = 4;
+            } else if (c <= 0x7FFFFFFF) {
+                // 0x04000000 - 0x7FFFFFFF
+                // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+                // already outside valid Character range, just for completeness
+                extraByte = 5;
+            } else {
+                // 0x80000000 - 0xFFFFFFFF
+                // case not possible as java has no unsigned int
+                result[out++] = 0x3f;
+                continue;
+            }
             byte write;
-            if (c > 0x07FF) {
-                ch = (char)(c>>>12);
-                write = (byte)0xE0;
-                if (ch > 0) {
-                    write |= (ch & 0x0F);
-                }
+            int shift = 6 * extraByte;
+            write = (byte)((0xFE << (6 - extraByte)) | (c >>> shift));
+            result[out++] = write;
+            for (int j = extraByte - 1; j >= 0; j--) {
+                shift -= 6;
+                write = (byte)(0x80 | ((c >>> shift) & 0x3F));
                 result[out++] = write;
-                write = (byte)0x80;
-                bias = 0x3F;
-            } else {
-                write = (byte)0xC0;
-                bias = 0x1F;
             }
-            ch = (char)(c>>>6);
-            if (ch > 0) {
-                write |= (ch & bias);
-            }
-            result[out++] = write;
-            result[out++] = (byte)(0x80 | ((c) & 0x3F));
         }
         if (expanded) {
             byte newResult[] = new byte[out];
@@ -176,5 +298,4 @@
         }
         return result;
     }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/XmlAttrStack.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,412 @@
+/*
+ * 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.c14n.implementations;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.w3c.dom.Attr;
+
+/**
+ * An XmlAttrStack that is shared between the Canonical XML 1.0 and 1.1 implementations.
+ */
+class XmlAttrStack {
+
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(XmlAttrStack.class);
+
+    static class XmlsStackElement {
+        int level;
+        boolean rendered = false;
+        List<Attr> nodes = new ArrayList<>();
+    }
+
+    private int currentLevel = 0;
+    private int lastlevel = 0;
+    private XmlsStackElement cur;
+    private List<XmlsStackElement> levels = new ArrayList<>();
+    private boolean c14n11;
+
+    public XmlAttrStack(boolean c14n11) {
+        this.c14n11 = c14n11;
+    }
+
+    void push(int level) {
+        currentLevel = level;
+        if (currentLevel == -1) {
+            return;
+        }
+        cur = null;
+        while (lastlevel >= currentLevel) {
+            levels.remove(levels.size() - 1);
+            int newSize = levels.size();
+            if (newSize == 0) {
+                lastlevel = 0;
+                return;
+            }
+            lastlevel = levels.get(newSize - 1).level;
+        }
+    }
+
+    void addXmlnsAttr(Attr n) {
+        if (cur == null) {
+            cur = new XmlsStackElement();
+            cur.level = currentLevel;
+            levels.add(cur);
+            lastlevel = currentLevel;
+        }
+        cur.nodes.add(n);
+    }
+
+    void getXmlnsAttr(Collection<Attr> col) {
+        int size = levels.size() - 1;
+        if (cur == null) {
+            cur = new XmlsStackElement();
+            cur.level = currentLevel;
+            lastlevel = currentLevel;
+            levels.add(cur);
+        }
+        boolean parentRendered = false;
+        XmlsStackElement e = null;
+        if (size == -1) {
+            parentRendered = true;
+        } else {
+            e = levels.get(size);
+            if (e.rendered && e.level + 1 == currentLevel) {
+                parentRendered = true;
+            }
+        }
+        if (parentRendered) {
+            col.addAll(cur.nodes);
+            cur.rendered = true;
+            return;
+        }
+
+        Map<String, Attr> loa = new HashMap<>();
+        if (c14n11) {
+            List<Attr> baseAttrs = new ArrayList<>();
+            boolean successiveOmitted = true;
+            for (; size >= 0; size--) {
+                e = levels.get(size);
+                if (e.rendered) {
+                    successiveOmitted = false;
+                }
+                Iterator<Attr> it = e.nodes.iterator();
+                while (it.hasNext() && successiveOmitted) {
+                    Attr n = it.next();
+                    if (n.getLocalName().equals("base") && !e.rendered) {
+                        baseAttrs.add(n);
+                    } else if (!loa.containsKey(n.getName())) {
+                        loa.put(n.getName(), n);
+                    }
+                }
+            }
+            if (!baseAttrs.isEmpty()) {
+                Iterator<Attr> it = col.iterator();
+                String base = null;
+                Attr baseAttr = null;
+                while (it.hasNext()) {
+                    Attr n = it.next();
+                    if (n.getLocalName().equals("base")) {
+                        base = n.getValue();
+                        baseAttr = n;
+                        break;
+                    }
+                }
+                it = baseAttrs.iterator();
+                while (it.hasNext()) {
+                    Attr n = it.next();
+                    if (base == null) {
+                        base = n.getValue();
+                        baseAttr = n;
+                    } else {
+                        try {
+                            base = joinURI(n.getValue(), base);
+                        } catch (URISyntaxException ue) {
+                            LOG.debug(ue.getMessage(), ue);
+                        }
+                    }
+                }
+                if (base != null && base.length() != 0) {
+                    baseAttr.setValue(base);
+                    col.add(baseAttr);
+                }
+            }
+        } else {
+            for (; size >= 0; size--) {
+                e = levels.get(size);
+                Iterator<Attr> it = e.nodes.iterator();
+                while (it.hasNext()) {
+                    Attr n = it.next();
+                    if (!loa.containsKey(n.getName())) {
+                        loa.put(n.getName(), n);
+                    }
+                }
+            }
+        }
+
+        cur.rendered = true;
+        col.addAll(loa.values());
+    }
+
+    private static String joinURI(String baseURI, String relativeURI) throws URISyntaxException {
+        String bscheme = null;
+        String bauthority = null;
+        String bpath = "";
+        String bquery = null;
+
+        // pre-parse the baseURI
+        if (baseURI != null) {
+            if (baseURI.endsWith("..")) {
+                baseURI = baseURI + "/";
+            }
+            URI base = new URI(baseURI);
+            bscheme = base.getScheme();
+            bauthority = base.getAuthority();
+            bpath = base.getPath();
+            bquery = base.getQuery();
+        }
+
+        URI r = new URI(relativeURI);
+        String rscheme = r.getScheme();
+        String rauthority = r.getAuthority();
+        String rpath = r.getPath();
+        String rquery = r.getQuery();
+
+        String tscheme, tauthority, tpath, tquery;
+        if (rscheme != null && rscheme.equals(bscheme)) {
+            rscheme = null;
+        }
+        if (rscheme != null) {
+            tscheme = rscheme;
+            tauthority = rauthority;
+            tpath = removeDotSegments(rpath);
+            tquery = rquery;
+        } else {
+            if (rauthority != null) {
+                tauthority = rauthority;
+                tpath = removeDotSegments(rpath);
+                tquery = rquery;
+            } else {
+                if (rpath.length() == 0) {
+                    tpath = bpath;
+                    if (rquery != null) {
+                        tquery = rquery;
+                    } else {
+                        tquery = bquery;
+                    }
+                } else {
+                    if (rpath.startsWith("/")) {
+                        tpath = removeDotSegments(rpath);
+                    } else {
+                        if (bauthority != null && bpath.length() == 0) {
+                            tpath = "/" + rpath;
+                        } else {
+                            int last = bpath.lastIndexOf('/');
+                            if (last == -1) {
+                                tpath = rpath;
+                            } else {
+                                tpath = bpath.substring(0, last+1) + rpath;
+                            }
+                        }
+                        tpath = removeDotSegments(tpath);
+                    }
+                    tquery = rquery;
+                }
+                tauthority = bauthority;
+            }
+            tscheme = bscheme;
+        }
+        return new URI(tscheme, tauthority, tpath, tquery, null).toString();
+    }
+
+    private static String removeDotSegments(String path) {
+        LOG.debug("STEP OUTPUT BUFFER\t\tINPUT BUFFER");
+
+        // 1. The input buffer is initialized with the now-appended path
+        // components then replace occurrences of "//" in the input buffer
+        // with "/" until no more occurrences of "//" are in the input buffer.
+        String input = path;
+        while (input.indexOf("//") > -1) {
+            input = input.replaceAll("//", "/");
+        }
+
+        // Initialize the output buffer with the empty string.
+        StringBuilder output = new StringBuilder();
+
+        // If the input buffer starts with a root slash "/" then move this
+        // character to the output buffer.
+        if (input.charAt(0) == '/') {
+            output.append("/");
+            input = input.substring(1);
+        }
+
+        printStep("1 ", output.toString(), input);
+
+        // While the input buffer is not empty, loop as follows
+        while (input.length() != 0) {
+            // 2A. If the input buffer begins with a prefix of "./",
+            // then remove that prefix from the input buffer
+            // else if the input buffer begins with a prefix of "../", then
+            // if also the output does not contain the root slash "/" only,
+            // then move this prefix to the end of the output buffer else
+            // remove that prefix
+            if (input.startsWith("./")) {
+                input = input.substring(2);
+                printStep("2A", output.toString(), input);
+            } else if (input.startsWith("../")) {
+                input = input.substring(3);
+                if (!output.toString().equals("/")) {
+                    output.append("../");
+                }
+                printStep("2A", output.toString(), input);
+                // 2B. if the input buffer begins with a prefix of "/./" or "/.",
+                // where "." is a complete path segment, then replace that prefix
+                // with "/" in the input buffer; otherwise,
+            } else if (input.startsWith("/./")) {
+                input = input.substring(2);
+                printStep("2B", output.toString(), input);
+            } else if (input.equals("/.")) {
+                // FIXME: what is complete path segment?
+                input = input.replaceFirst("/.", "/");
+                printStep("2B", output.toString(), input);
+                // 2C. if the input buffer begins with a prefix of "/../" or "/..",
+                // where ".." is a complete path segment, then replace that prefix
+                // with "/" in the input buffer and if also the output buffer is
+                // empty, last segment in the output buffer equals "../" or "..",
+                // where ".." is a complete path segment, then append ".." or "/.."
+                // for the latter case respectively to the output buffer else
+                // remove the last segment and its preceding "/" (if any) from the
+                // output buffer and if hereby the first character in the output
+                // buffer was removed and it was not the root slash then delete a
+                // leading slash from the input buffer; otherwise,
+            } else if (input.startsWith("/../")) {
+                input = input.substring(3);
+                if (output.length() == 0) {
+                    output.append("/");
+                } else if (output.toString().endsWith("../")) {
+                    output.append("..");
+                } else if (output.toString().endsWith("..")) {
+                    output.append("/..");
+                } else {
+                    int index = output.lastIndexOf("/");
+                    if (index == -1) {
+                        output = new StringBuilder();
+                        if (input.charAt(0) == '/') {
+                            input = input.substring(1);
+                        }
+                    } else {
+                        output = output.delete(index, output.length());
+                    }
+                }
+                printStep("2C", output.toString(), input);
+            } else if (input.equals("/..")) {
+                // FIXME: what is complete path segment?
+                input = input.replaceFirst("/..", "/");
+                if (output.length() == 0) {
+                    output.append("/");
+                } else if (output.toString().endsWith("../")) {
+                    output.append("..");
+                } else if (output.toString().endsWith("..")) {
+                    output.append("/..");
+                } else {
+                    int index = output.lastIndexOf("/");
+                    if (index == -1) {
+                        output = new StringBuilder();
+                        if (input.charAt(0) == '/') {
+                            input = input.substring(1);
+                        }
+                    } else {
+                        output = output.delete(index, output.length());
+                    }
+                }
+                printStep("2C", output.toString(), input);
+                // 2D. if the input buffer consists only of ".", then remove
+                // 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 if (input.equals(".")) {
+                input = "";
+                printStep("2D", output.toString(), input);
+            } else if (input.equals("..")) {
+                if (!output.toString().equals("/")) {
+                    output.append("..");
+                }
+                input = "";
+                printStep("2D", output.toString(), input);
+                // 2E. move the first path segment (if any) in the input buffer
+                // to the end of the output buffer, including the initial "/"
+                // character (if any) and any subsequent characters up to, but not
+                // including, the next "/" character or the end of the input buffer.
+            } else {
+                int end = -1;
+                int begin = input.indexOf('/');
+                if (begin == 0) {
+                    end = input.indexOf('/', 1);
+                } else {
+                    end = begin;
+                    begin = 0;
+                }
+                String segment;
+                if (end == -1) {
+                    segment = input.substring(begin);
+                    input = "";
+                } else {
+                    segment = input.substring(begin, end);
+                    input = input.substring(end);
+                }
+                output.append(segment);
+                printStep("2E", output.toString(), input);
+            }
+        }
+
+        // 3. Finally, if the only or last segment of the output buffer is
+        // "..", where ".." is a complete path segment not followed by a slash
+        // then append a slash "/". The output buffer is returned as the result
+        // of remove_dot_segments
+        if (output.toString().endsWith("..")) {
+            output.append("/");
+            printStep("3 ", output.toString(), input);
+        }
+
+        return output.toString();
+    }
+
+    private static void printStep(String step, String output, String input) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(" " + step + ":   " + output);
+            if (output.length() == 0) {
+                LOG.debug("\t\t\t\t" + input);
+            } else {
+                LOG.debug("\t\t\t" + input);
+            }
+        }
+    }
+}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML> <HEAD> </HEAD> <BODY> <P>
-canonicalization implementations.
-</P></BODY> </HTML>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-Canonicalization related material and algorithms.
-</P></BODY></HTML>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/AbstractSerializer.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,249 +0,0 @@
-/*
- * 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.encryption;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * Converts <code>String</code>s into <code>Node</code>s and visa versa.
- *
- * An abstract class for common Serializer functionality
- */
-public abstract class AbstractSerializer implements Serializer {
-
-    protected Canonicalizer canon;
-
-    public void setCanonicalizer(Canonicalizer canon) {
-        this.canon = canon;
-    }
-
-    /**
-     * Returns a <code>String</code> representation of the specified
-     * <code>Element</code>.
-     * <p/>
-     * Refer also to comments about setup of format.
-     *
-     * @param element the <code>Element</code> to serialize.
-     * @return the <code>String</code> representation of the serilaized
-     *   <code>Element</code>.
-     * @throws Exception
-     */
-    public String serialize(Element element) throws Exception {
-        return canonSerialize(element);
-    }
-
-    /**
-     * Returns a <code>byte[]</code> representation of the specified
-     * <code>Element</code>.
-     *
-     * @param element the <code>Element</code> to serialize.
-     * @return the <code>byte[]</code> representation of the serilaized
-     *   <code>Element</code>.
-     * @throws Exception
-     */
-    public byte[] serializeToByteArray(Element element) throws Exception {
-        return canonSerializeToByteArray(element);
-    }
-
-    /**
-     * Returns a <code>String</code> representation of the specified
-     * <code>NodeList</code>.
-     * <p/>
-     * This is a special case because the NodeList may represent a
-     * <code>DocumentFragment</code>. A document fragment may be a
-     * non-valid XML document (refer to appropriate description of
-     * W3C) because it my start with a non-element node, e.g. a text
-     * node.
-     * <p/>
-     * The methods first converts the node list into a document fragment.
-     * Special care is taken to not destroy the current document, thus
-     * the method clones the nodes (deep cloning) before it appends
-     * them to the document fragment.
-     * <p/>
-     * Refer also to comments about setup of format.
-     *
-     * @param content the <code>NodeList</code> to serialize.
-     * @return the <code>String</code> representation of the serialized
-     *   <code>NodeList</code>.
-     * @throws Exception
-     */
-    public String serialize(NodeList content) throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        canon.setWriter(baos);
-        canon.notReset();
-        for (int i = 0; i < content.getLength(); i++) {
-            canon.canonicalizeSubtree(content.item(i));
-        }
-        String ret = baos.toString("UTF-8");
-        baos.reset();
-        return ret;
-    }
-
-    /**
-     * Returns a <code>byte[]</code> representation of the specified
-     * <code>NodeList</code>.
-     *
-     * @param content the <code>NodeList</code> to serialize.
-     * @return the <code>byte[]</code> representation of the serialized
-     *   <code>NodeList</code>.
-     * @throws Exception
-     */
-    public byte[] serializeToByteArray(NodeList content) throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        canon.setWriter(baos);
-        canon.notReset();
-        for (int i = 0; i < content.getLength(); i++) {
-            canon.canonicalizeSubtree(content.item(i));
-        }
-        return baos.toByteArray();
-    }
-
-    /**
-     * Use the Canonicalizer to serialize the node
-     * @param node
-     * @return the canonicalization of the node
-     * @throws Exception
-     */
-    public String canonSerialize(Node node) throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        canon.setWriter(baos);
-        canon.notReset();
-        canon.canonicalizeSubtree(node);
-        String ret = baos.toString("UTF-8");
-        baos.reset();
-        return ret;
-    }
-
-    /**
-     * Use the Canonicalizer to serialize the node
-     * @param node
-     * @return the (byte[]) canonicalization of the node
-     * @throws Exception
-     */
-    public byte[] canonSerializeToByteArray(Node node) throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        canon.setWriter(baos);
-        canon.notReset();
-        canon.canonicalizeSubtree(node);
-        return baos.toByteArray();
-    }
-
-    /**
-     * @param source
-     * @param ctx
-     * @return the Node resulting from the parse of the source
-     * @throws XMLEncryptionException
-     */
-    public abstract Node deserialize(String source, Node ctx) throws XMLEncryptionException;
-
-    /**
-     * @param source
-     * @param ctx
-     * @return the Node resulting from the parse of the source
-     * @throws XMLEncryptionException
-     */
-    public abstract Node deserialize(byte[] source, Node ctx) throws XMLEncryptionException;
-
-    protected static byte[] createContext(byte[] source, Node ctx) throws XMLEncryptionException {
-        // Create the context to parse the document against
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        try {
-            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(byteArrayOutputStream, "UTF-8");
-            outputStreamWriter.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?><dummy");
-
-            // Run through each node up to the document node and find any xmlns: nodes
-            Map<String, String> storedNamespaces = new HashMap<String, String>();
-            Node wk = ctx;
-            while (wk != null) {
-                NamedNodeMap atts = wk.getAttributes();
-                if (atts != null) {
-                    for (int i = 0; i < atts.getLength(); ++i) {
-                        Node att = atts.item(i);
-                        String nodeName = att.getNodeName();
-                        if ((nodeName.equals("xmlns") || nodeName.startsWith("xmlns:"))
-                                && !storedNamespaces.containsKey(att.getNodeName())) {
-                            outputStreamWriter.write(" ");
-                            outputStreamWriter.write(nodeName);
-                            outputStreamWriter.write("=\"");
-                            outputStreamWriter.write(att.getNodeValue());
-                            outputStreamWriter.write("\"");
-                            storedNamespaces.put(nodeName, att.getNodeValue());
-                        }
-                    }
-                }
-                wk = wk.getParentNode();
-            }
-            outputStreamWriter.write(">");
-            outputStreamWriter.flush();
-            byteArrayOutputStream.write(source);
-
-            outputStreamWriter.write("</dummy>");
-            outputStreamWriter.close();
-
-            return byteArrayOutputStream.toByteArray();
-        } catch (UnsupportedEncodingException e) {
-            throw new XMLEncryptionException("empty", e);
-        } catch (IOException e) {
-            throw new XMLEncryptionException("empty", e);
-        }
-    }
-
-    protected static String createContext(String source, Node ctx) {
-        // Create the context to parse the document against
-        StringBuilder sb = new StringBuilder();
-        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><dummy");
-
-        // Run through each node up to the document node and find any xmlns: nodes
-        Map<String, String> storedNamespaces = new HashMap<String, String>();
-        Node wk = ctx;
-        while (wk != null) {
-            NamedNodeMap atts = wk.getAttributes();
-            if (atts != null) {
-                for (int i = 0; i < atts.getLength(); ++i) {
-                    Node att = atts.item(i);
-                    String nodeName = att.getNodeName();
-                    if ((nodeName.equals("xmlns") || nodeName.startsWith("xmlns:"))
-                        && !storedNamespaces.containsKey(att.getNodeName())) {
-                        sb.append(" " + nodeName + "=\"" + att.getNodeValue() + "\"");
-                        storedNamespaces.put(nodeName, att.getNodeValue());
-                    }
-                }
-            }
-            wk = wk.getParentNode();
-        }
-        sb.append(">" + source + "</dummy>");
-        return sb.toString();
-    }
-
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/AgreementMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/*
- * 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.encryption;
-
-import java.util.Iterator;
-import com.sun.org.apache.xml.internal.security.keys.KeyInfo;
-import org.w3c.dom.Element;
-
-/**
- * A Key Agreement algorithm provides for the derivation of a shared secret key
- * based on a shared secret computed from certain types of compatible public
- * keys from both the sender and the recipient. Information from the originator
- * to determine the secret is indicated by an optional OriginatorKeyInfo
- * parameter child of an {@code AgreementMethod} element while that
- * associated with the recipient is indicated by an optional RecipientKeyInfo. A
- * shared key is derived from this shared secret by a method determined by the
- * Key Agreement algorithm.
- * <p>
- * <b>Note:</b> XML Encryption does not provide an on-line key agreement
- * negotiation protocol. The {@code AgreementMethod} element can be used by
- * the originator to identify the keys and computational procedure that were
- * used to obtain a shared encryption key. The method used to obtain or select
- * the keys or algorithm used for the agreement computation is beyond the scope
- * of this specification.
- * <p>
- * The {@code AgreementMethod} element appears as the content of a
- * {@code ds:KeyInfo} since, like other {@code ds:KeyInfo} children,
- * it yields a key. This {@code ds:KeyInfo} is in turn a child of an
- * {@code EncryptedData} or {@code EncryptedKey} element. The
- * Algorithm attribute and KeySize child of the {@code EncryptionMethod}
- * element under this {@code EncryptedData} or {@code EncryptedKey}
- * element are implicit parameters to the key agreement computation. In cases
- * where this {@code EncryptionMethod} algorithm {@code URI} is
- * insufficient to determine the key length, a KeySize MUST have been included.
- * In addition, the sender may place a KA-Nonce element under
- * {@code AgreementMethod} to assure that different keying material is
- * generated even for repeated agreements using the same sender and recipient
- * public keys.
- * <p>
- * If the agreed key is being used to wrap a key, then
- * {@code AgreementMethod} would appear inside a {@code ds:KeyInfo}
- * inside an {@code EncryptedKey} element.
- * <p>
- * The Schema for AgreementMethod is as follows:
- * <pre>{@code
- * <element name="AgreementMethod" type="xenc:AgreementMethodType"/>
- * <complexType name="AgreementMethodType" mixed="true">
- *     <sequence>
- *         <element name="KA-Nonce" minOccurs="0" type="base64Binary"/>
- *         <!-- <element ref="ds:DigestMethod" minOccurs="0"/> -->
- *         <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
- *         <element name="OriginatorKeyInfo" minOccurs="0" type="ds:KeyInfoType"/>
- *         <element name="RecipientKeyInfo" minOccurs="0" type="ds:KeyInfoType"/>
- *     </sequence>
- *     <attribute name="Algorithm" type="anyURI" use="required"/>
- * </complexType>
- * }</pre>
- *
- * @author Axl Mattheus
- */
-public interface AgreementMethod {
-
-    /**
-     * Returns a {@code byte} array.
-     * @return a {@code byte} array.
-     */
-    byte[] getKANonce();
-
-    /**
-     * Sets the KANonce.jj
-     * @param kanonce
-     */
-    void setKANonce(byte[] kanonce);
-
-    /**
-     * Returns additional information regarding the {@code AgreementMethod}.
-     * @return additional information regarding the {@code AgreementMethod}.
-     */
-    Iterator<Element> getAgreementMethodInformation();
-
-    /**
-     * Adds additional {@code AgreementMethod} information.
-     *
-     * @param info a {@code Element} that represents additional information
-     * specified by
-     *   <pre>{@code
-     *     <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
-     *   }</pre>
-     */
-    void addAgreementMethodInformation(Element info);
-
-    /**
-     * Removes additional {@code AgreementMethod} information.
-     *
-     * @param info a {@code Element} that represents additional information
-     * specified by
-     *   <pre>{@code
-     *     <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
-     *   }</pre>
-     */
-    void revoveAgreementMethodInformation(Element info);
-
-    /**
-     * Returns information relating to the originator's shared secret.
-     *
-     * @return information relating to the originator's shared secret.
-     */
-    KeyInfo getOriginatorKeyInfo();
-
-    /**
-     * Sets the information relating to the originator's shared secret.
-     *
-     * @param keyInfo information relating to the originator's shared secret.
-     */
-    void setOriginatorKeyInfo(KeyInfo keyInfo);
-
-    /**
-     * Returns information relating to the recipient's shared secret.
-     *
-     * @return information relating to the recipient's shared secret.
-     */
-    KeyInfo getRecipientKeyInfo();
-
-    /**
-     * Sets the information relating to the recipient's shared secret.
-     *
-     * @param keyInfo information relating to the recipient's shared secret.
-     */
-    void setRecipientKeyInfo(KeyInfo keyInfo);
-
-    /**
-     * Returns the algorithm URI of this {@code CryptographicMethod}.
-     *
-     * @return the algorithm URI of this {@code CryptographicMethod}
-     */
-    String getAlgorithm();
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/CipherData.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * 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.encryption;
-
-/**
- * {@code CipherData} provides encrypted data. It must either contain the
- * encrypted octet sequence as base64 encoded text of the
- * {@code CipherValue} element, or provide a reference to an external
- * location containing the encrypted octet sequence via the
- * {@code CipherReference} element.
- * <p>
- * The schema definition is as follows:
- * <pre>{@code
- * <element name='CipherData' type='xenc:CipherDataType'/>
- * <complexType name='CipherDataType'>
- *     <choice>
- *         <element name='CipherValue' type='base64Binary'/>
- *         <element ref='xenc:CipherReference'/>
- *     </choice>
- * </complexType>
- * }</pre>
- *
- * @author Axl Mattheus
- */
-public interface CipherData {
-
-    /** VALUE_TYPE ASN */
-    int VALUE_TYPE = 0x00000001;
-
-    /** REFERENCE_TYPE ASN */
-    int REFERENCE_TYPE = 0x00000002;
-
-    /**
-     * Returns the type of encrypted data contained in the
-     * {@code CipherData}.
-     *
-     * @return {@code VALUE_TYPE} if the encrypted data is contained as
-     *   {@code CipherValue} or {@code REFERENCE_TYPE} if the
-     *   encrypted data is contained as {@code CipherReference}.
-     */
-    int getDataType();
-
-    /**
-     * Returns the cipher value as a base64 encoded {@code byte} array.
-     *
-     * @return the {@code CipherData}'s value.
-     */
-    CipherValue getCipherValue();
-
-    /**
-     * Sets the {@code CipherData}'s value.
-     *
-     * @param value the value of the {@code CipherData}.
-     * @throws XMLEncryptionException
-     */
-    void setCipherValue(CipherValue value) throws XMLEncryptionException;
-
-    /**
-     * Returns a reference to an external location containing the encrypted
-     * octet sequence ({@code byte} array).
-     *
-     * @return the reference to an external location containing the encrypted
-     * octet sequence.
-     */
-    CipherReference getCipherReference();
-
-    /**
-     * Sets the {@code CipherData}'s reference.
-     *
-     * @param reference an external location containing the encrypted octet sequence.
-     * @throws XMLEncryptionException
-     */
-    void setCipherReference(CipherReference reference) throws XMLEncryptionException;
-}
-
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/CipherReference.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * 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.encryption;
-
-import org.w3c.dom.Attr;
-
-/**
- * {@code CipherReference} identifies a source which, when processed,
- * yields the encrypted octet sequence.
- * <p>
- * The actual value is obtained as follows. The {@code CipherReference URI}
- * contains an identifier that is dereferenced. Should the
- * Transforms, the data resulting from dereferencing the {@code URI} is
- * transformed as specified so as to yield the intended cipher value. For
- * example, if the value is base64 encoded within an XML document; the
- * transforms could specify an XPath expression followed by a base64 decoding so
- * as to extract the octets.
- * <p>
- * The syntax of the {@code URI} and Transforms is similar to that of
- * [XML-DSIG]. However, there is a difference between signature and encryption
- * processing. In [XML-DSIG] both generation and validation processing start
- * with the same source data and perform that transform in the same order. In
- * encryption, the decryptor has only the cipher data and the specified
- * transforms are enumerated for the decryptor, in the order necessary to obtain
- * the octets. Consequently, because it has different semantics Transforms is in
- * the &xenc; namespace.
- * <p>
- * The schema definition is as follows:
- * <pre>{@code
- * <element name='CipherReference' type='xenc:CipherReferenceType'/>
- * <complexType name='CipherReferenceType'>
- *     <sequence>
- *         <element name='Transforms' type='xenc:TransformsType' minOccurs='0'/>
- *     </sequence>
- *     <attribute name='URI' type='anyURI' use='required'/>
- * </complexType>
- * }<pre>
- *
- * @author Axl Mattheus
- */
-public interface CipherReference {
-    /**
-     * Returns an {@code URI} that contains an identifier that should be
-     * dereferenced.
-     * @return an {@code URI} that contains an identifier that should be
-     * dereferenced.
-     */
-    String getURI();
-
-    /**
-     * Gets the URI as an Attribute node.  Used to meld the CipherReference
-     * with the XMLSignature ResourceResolvers
-     * @return the URI as an Attribute node
-     */
-    Attr getURIAsAttr();
-
-    /**
-     * Returns the {@code Transforms} that specifies how to transform the
-     * {@code URI} to yield the appropriate cipher value.
-     *
-     * @return the transform that specifies how to transform the reference to
-     *   yield the intended cipher value.
-     */
-    Transforms getTransforms();
-
-    /**
-     * Sets the {@code Transforms} that specifies how to transform the
-     * {@code URI} to yield the appropriate cipher value.
-     *
-     * @param transforms the set of {@code Transforms} that specifies how
-     *   to transform the reference to yield the intended cipher value.
-     */
-    void setTransforms(Transforms transforms);
-}
-
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/CipherValue.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * 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.encryption;
-
-/**
- * <code>CipherValue</code> is the wrapper for cipher text.
- *
- * @author Axl Mattheus
- */
-public interface CipherValue {
-    /**
-     * Returns the Base 64 encoded, encrypted octets that is the
-     * <code>CipherValue</code>.
-     *
-     * @return cipher value.
-     */
-    String getValue();
-
-    /**
-     * Sets the Base 64 encoded, encrypted octets that is the
-     * <code>CipherValue</code>.
-     *
-     * @param value the cipher value.
-     */
-    void setValue(String value);
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/DocumentSerializer.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * 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.encryption;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.StringReader;
-
-import javax.xml.XMLConstants;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.DocumentFragment;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-/**
- * Converts <code>String</code>s into <code>Node</code>s and visa versa.
- */
-public class DocumentSerializer extends AbstractSerializer {
-
-    protected DocumentBuilderFactory dbf;
-
-    /**
-     * @param source
-     * @param ctx
-     * @return the Node resulting from the parse of the source
-     * @throws XMLEncryptionException
-     */
-    public Node deserialize(byte[] source, Node ctx) throws XMLEncryptionException {
-        byte[] fragment = createContext(source, ctx);
-        return deserialize(ctx, new InputSource(new ByteArrayInputStream(fragment)));
-    }
-
-    /**
-     * @param source
-     * @param ctx
-     * @return the Node resulting from the parse of the source
-     * @throws XMLEncryptionException
-     */
-    public Node deserialize(String source, Node ctx) throws XMLEncryptionException {
-        String fragment = createContext(source, ctx);
-        return deserialize(ctx, new InputSource(new StringReader(fragment)));
-    }
-
-    /**
-     * @param ctx
-     * @param inputSource
-     * @return the Node resulting from the parse of the source
-     * @throws XMLEncryptionException
-     */
-    private Node deserialize(Node ctx, InputSource inputSource) throws XMLEncryptionException {
-        try {
-            if (dbf == null) {
-                dbf = DocumentBuilderFactory.newInstance();
-                dbf.setNamespaceAware(true);
-                dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
-                dbf.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
-                dbf.setValidating(false);
-            }
-            DocumentBuilder db = dbf.newDocumentBuilder();
-            Document d = db.parse(inputSource);
-
-            Document contextDocument = null;
-            if (Node.DOCUMENT_NODE == ctx.getNodeType()) {
-                contextDocument = (Document)ctx;
-            } else {
-                contextDocument = ctx.getOwnerDocument();
-            }
-
-            Element fragElt =
-                    (Element) contextDocument.importNode(d.getDocumentElement(), true);
-            DocumentFragment result = contextDocument.createDocumentFragment();
-            Node child = fragElt.getFirstChild();
-            while (child != null) {
-                fragElt.removeChild(child);
-                result.appendChild(child);
-                child = fragElt.getFirstChild();
-            }
-            return result;
-        } catch (SAXException se) {
-            throw new XMLEncryptionException("empty", se);
-        } catch (ParserConfigurationException pce) {
-            throw new XMLEncryptionException("empty", pce);
-        } catch (IOException ioe) {
-            throw new XMLEncryptionException("empty", ioe);
-        }
-    }
-
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/EncryptedData.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * 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.encryption;
-
-/**
- * The {@code EncryptedData} element is the core element in the syntax. Not
- * only does its {@code CipherData} child contain the encrypted data, but
- * it's also the element that replaces the encrypted element, or serves as the
- * new document root.
- * <p>
- * It's schema definition is as follows:
- * <p>
- * <pre>{@code
- * <element name='EncryptedData' type='xenc:EncryptedDataType'/>
- * <complexType name='EncryptedDataType'>
- *     <complexContent>
- *         <extension base='xenc:EncryptedType'/>
- *     </complexContent>
- * </complexType>
- * }</pre>
- *
- * @author Axl Mattheus
- */
-public interface EncryptedData extends EncryptedType {
-}
-
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/EncryptedKey.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * 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.encryption;
-
-/**
- * The {@code EncryptedKey} element is used to transport encryption keys
- * from the originator to a known recipient(s). It may be used as a stand-alone
- * XML document, be placed within an application document, or appear inside an
- * {@code EncryptedData} element as a child of a {@code ds:KeyInfo}
- * element. The key value is always encrypted to the recipient(s). When
- * {@code EncryptedKey} is decrypted the resulting octets are made
- * available to the {@code EncryptionMethod} algorithm without any
- * additional processing.
- * <p>
- * Its schema definition is as follows:
- * <pre>{@code
- * <element name='EncryptedKey' type='xenc:EncryptedKeyType'/>
- * <complexType name='EncryptedKeyType'>
- *     <complexContent>
- *         <extension base='xenc:EncryptedType'>
- *             <sequence>
- *                 <element ref='xenc:ReferenceList' minOccurs='0'/>
- *                 <element name='CarriedKeyName' type='string' minOccurs='0'/>
- *             </sequence>
- *             <attribute name='Recipient' type='string' use='optional'/>
- *         </extension>
- *     </complexContent>
- * </complexType>
- * }</pre>
- *
- * @author Axl Mattheus
- */
-public interface EncryptedKey extends EncryptedType {
-
-    /**
-     * Returns a hint as to which recipient this encrypted key value is intended for.
-     *
-     * @return the recipient of the {@code EncryptedKey}.
-     */
-    String getRecipient();
-
-    /**
-     * Sets the recipient for this {@code EncryptedKey}.
-     *
-     * @param recipient the recipient for this {@code EncryptedKey}.
-     */
-    void setRecipient(String recipient);
-
-    /**
-     * Returns pointers to data and keys encrypted using this key. The reference
-     * list may contain multiple references to {@code EncryptedKey} and
-     * {@code EncryptedData} elements. This is done using
-     * {@code KeyReference} and {@code DataReference} elements
-     * respectively.
-     *
-     * @return an {@code Iterator} over all the {@code ReferenceList}s
-     *   contained in this {@code EncryptedKey}.
-     */
-    ReferenceList getReferenceList();
-
-    /**
-     * Sets the {@code ReferenceList} to the {@code EncryptedKey}.
-     *
-     * @param list a list of pointers to data elements encrypted using this key.
-     */
-    void setReferenceList(ReferenceList list);
-
-    /**
-     * Returns a user readable name with the key value. This may then be used to
-     * reference the key using the {@code ds:KeyName} element within
-     * {@code ds:KeyInfo}. The same {@code CarriedKeyName} label,
-     * unlike an ID type, may occur multiple times within a single document. The
-     * value of the key is to be the same in all {@code EncryptedKey}
-     * elements identified with the same {@code CarriedKeyName} label
-     * within a single XML document.
-     * <br>
-     * <b>Note</b> that because whitespace is significant in the value of
-     * the {@code ds:KeyName} element, whitespace is also significant in
-     * the value of the {@code CarriedKeyName} element.
-     *
-     * @return over all the carried names contained in
-     *   this {@code EncryptedKey}.
-     */
-    String getCarriedName();
-
-    /**
-     * Sets the carried name.
-     *
-     * @param name the carried name.
-     */
-    void setCarriedName(String name);
-}
-
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/EncryptedType.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * 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.encryption;
-
-import com.sun.org.apache.xml.internal.security.keys.KeyInfo;
-
-/**
- * EncryptedType is the abstract type from which {@code EncryptedData} and
- * {@code EncryptedKey} are derived. While these two latter element types
- * are very similar with respect to their content models, a syntactical
- * distinction is useful to processing.
- * <p>
- * Its schema definition is as follows:
- * <pre>{@code
- * <complexType name='EncryptedType' abstract='true'>
- *     <sequence>
- *         <element name='EncryptionMethod' type='xenc:EncryptionMethodType'
- *             minOccurs='0'/>
- *         <element ref='ds:KeyInfo' minOccurs='0'/>
- *         <element ref='xenc:CipherData'/>
- *         <element ref='xenc:EncryptionProperties' minOccurs='0'/>
- *     </sequence>
- *     <attribute name='Id' type='ID' use='optional'/>
- *     <attribute name='Type' type='anyURI' use='optional'/>
- *     <attribute name='MimeType' type='string' use='optional'/>
- *     <attribute name='Encoding' type='anyURI' use='optional'/>
- * </complexType>
- * }</pre>
- *
- * @author Axl Mattheus
- */
-public interface EncryptedType {
-
-    /**
-     * Returns a {@code String} providing for the standard method of
-     * assigning an id to the element within the document context.
-     *
-     * @return the id for the {@code EncryptedType}.
-     */
-    String getId();
-
-    /**
-     * Sets the id.
-     *
-     * @param id
-     */
-    void setId(String id);
-
-    /**
-     * Returns an {@code URI} identifying type information about the
-     * plaintext form of the encrypted content. While optional, this
-     * specification takes advantage of it for mandatory processing described in
-     * Processing Rules: Decryption (section 4.2). If the
-     * {@code EncryptedData} element contains data of Type 'element' or
-     * element 'content', and replaces that data in an XML document context, it
-     * is strongly recommended the Type attribute be provided. Without this
-     * information, the decryptor will be unable to automatically restore the
-     * XML document to its original cleartext form.
-     *
-     * @return the identifier for the type of information in plaintext form of
-     *   encrypted content.
-     */
-    String getType();
-
-    /**
-     * Sets the type.
-     *
-     * @param type an {@code URI} identifying type information about the
-     *   plaintext form of the encrypted content.
-     */
-    void setType(String type);
-
-    /**
-     * Returns a {@code String} which describes the media type of the data
-     * which has been encrypted. The value of this attribute has values defined
-     * by [MIME]. For example, if the data that is encrypted is a base64 encoded
-     * PNG, the transfer Encoding may be specified as
-     * 'http://www.w3.org/2000/09/xmldsig#base64' and the MimeType as
-     * 'image/png'.
-     * <br>
-     * This attribute is purely advisory; no validation of the MimeType
-     * information is required and it does not indicate the encryption
-     * application must do any additional processing. Note, this information may
-     * not be necessary if it is already bound to the identifier in the Type
-     * attribute. For example, the Element and Content types defined in this
-     * specification are always UTF-8 encoded text.
-     *
-     * @return the media type of the data which was encrypted.
-     */
-    String getMimeType();
-
-    /**
-     * Sets the mime type.
-     *
-     * @param type a {@code String} which describes the media type of the
-     *   data which has been encrypted.
-     */
-    void setMimeType(String type);
-
-    /**
-     * Return an {@code URI} representing the encoding of the
-     * {@code EncryptedType}.
-     *
-     * @return the encoding of this {@code EncryptedType}.
-     */
-    String getEncoding();
-
-    /**
-     * Sets the {@code URI} representing the encoding of the
-     * {@code EncryptedType}.
-     *
-     * @param encoding
-     */
-    void setEncoding(String encoding);
-
-    /**
-     * Returns an {@code EncryptionMethod} that describes the encryption
-     * algorithm applied to the cipher data. If the element is absent, the
-     * encryption algorithm must be known by the recipient or the decryption
-     * will fail.
-     *
-     * @return the method used to encrypt the cipher data.
-     */
-    EncryptionMethod getEncryptionMethod();
-
-    /**
-     * Sets the {@code EncryptionMethod} used to encrypt the cipher data.
-     *
-     * @param method the {@code EncryptionMethod}.
-     */
-    void setEncryptionMethod(EncryptionMethod method);
-
-    /**
-     * Returns the {@code ds:KeyInfo}, that carries information about the
-     * key used to encrypt the data. Subsequent sections of this specification
-     * define new elements that may appear as children of
-     * {@code ds:KeyInfo}.
-     *
-     * @return information about the key that encrypted the cipher data.
-     */
-    KeyInfo getKeyInfo();
-
-    /**
-     * Sets the encryption key information.
-     *
-     * @param info the {@code ds:KeyInfo}, that carries information about
-     *   the key used to encrypt the data.
-     */
-    void setKeyInfo(KeyInfo info);
-
-    /**
-     * Returns the {@code CipherReference} that contains the
-     * {@code CipherValue} or {@code CipherReference} with the
-     * encrypted data.
-     *
-     * @return the cipher data for the encrypted type.
-     */
-    CipherData getCipherData();
-
-    /**
-     * Returns additional information concerning the generation of the
-     * {@code EncryptedType}.
-     *
-     * @return information relating to the generation of the
-     *   {@code EncryptedType}.
-     */
-    EncryptionProperties getEncryptionProperties();
-
-    /**
-     * Sets the {@code EncryptionProperties} that supplies additional
-     * information about the generation of the {@code EncryptedType}.
-     *
-     * @param properties
-     */
-    void setEncryptionProperties(EncryptionProperties properties);
-}
-
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/EncryptionMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/*
- * 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.encryption;
-
-import java.util.Iterator;
-import org.w3c.dom.Element;
-
-/**
- * {@code EncryptionMethod} describes the encryption algorithm applied to
- * the cipher data. If the element is absent, the encryption algorithm must be
- * known by the recipient or the decryption will fail.
- * <p>
- * It is defined as follows:
- * <pre>{@code
- * <complexType name='EncryptionMethodType' mixed='true'>
- *     <sequence>
- *         <element name='KeySize' minOccurs='0' type='xenc:KeySizeType'/>
- *         <element name='OAEPparams' minOccurs='0' type='base64Binary'/>
- *         <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
- *     </sequence>
- *     <attribute name='Algorithm' type='anyURI' use='required'/>
- * </complexType>
- * }</pre>
- *
- * @author Axl Mattheus
- */
-public interface EncryptionMethod {
-    /**
-     * Returns the algorithm applied to the cipher data.
-     *
-     * @return the encryption algorithm.
-     */
-    String getAlgorithm();
-
-    /**
-     * Returns the key size of the key of the algorithm applied to the cipher
-     * data.
-     *
-     * @return the key size.
-     */
-    int getKeySize();
-
-    /**
-     * Sets the size of the key of the algorithm applied to the cipher data.
-     *
-     * @param size the key size.
-     */
-    void setKeySize(int size);
-
-    /**
-     * Returns the OAEP parameters of the algorithm applied applied to the
-     * cipher data.
-     *
-     * @return the OAEP parameters.
-     */
-    byte[] getOAEPparams();
-
-    /**
-     * Sets the OAEP parameters.
-     *
-     * @param parameters the OAEP parameters.
-     */
-    void setOAEPparams(byte[] parameters);
-
-    /**
-     * Set the Digest Algorithm to use
-     * @param digestAlgorithm the Digest Algorithm to use
-     */
-    void setDigestAlgorithm(String digestAlgorithm);
-
-    /**
-     * Get the Digest Algorithm to use
-     * @return the Digest Algorithm to use
-     */
-    String getDigestAlgorithm();
-
-    /**
-     * Set the MGF Algorithm to use
-     * @param mgfAlgorithm the MGF Algorithm to use
-     */
-    void setMGFAlgorithm(String mgfAlgorithm);
-
-    /**
-     * Get the MGF Algorithm to use
-     * @return the MGF Algorithm to use
-     */
-    String getMGFAlgorithm();
-
-    /**
-     * Returns an iterator over all the additional elements contained in the
-     * {@code EncryptionMethod}.
-     *
-     * @return an {@code Iterator} over all the additional information
-     *   about the {@code EncryptionMethod}.
-     */
-    Iterator<Element> getEncryptionMethodInformation();
-
-    /**
-     * Adds encryption method information.
-     *
-     * @param information additional encryption method information.
-     */
-    void addEncryptionMethodInformation(Element information);
-
-    /**
-     * Removes encryption method information.
-     *
-     * @param information the information to remove from the
-     *   {@code EncryptionMethod}.
-     */
-    void removeEncryptionMethodInformation(Element information);
-}
-
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/EncryptionProperties.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * 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.encryption;
-
-import java.util.Iterator;
-
-/**
- * {@code EncryptionProperties} can hold additional information concerning
- * the generation of the {@code EncryptedData} or
- * {@code EncryptedKey}. This information is wraped int an
- * {@code EncryptionProperty} element. Examples of additional information
- * is e.g., a date/time stamp or the serial number of cryptographic hardware
- * used during encryption).
- * <p>
- * It is defined as follows:
- * <pre>{@code
- * <element name='EncryptionProperties' type='xenc:EncryptionPropertiesType'/>
- * <complexType name='EncryptionPropertiesType'>
- *     <sequence>
- *         <element ref='xenc:EncryptionProperty' maxOccurs='unbounded'/>
- *     </sequence>
- *     <attribute name='Id' type='ID' use='optional'/>
- * </complexType>
- * }</pre>
- *
- * @author Axl Mattheus
- */
-public interface EncryptionProperties {
-
-    /**
-     * Returns the {@code EncryptionProperties}' id.
-     *
-     * @return the id.
-     */
-    String getId();
-
-    /**
-     * Sets the id.
-     *
-     * @param id the id.
-     */
-    void setId(String id);
-
-    /**
-     * Returns an {@code Iterator} over all the
-     * {@code EncryptionPropterty} elements contained in this
-     * {@code EncryptionProperties}.
-     *
-     * @return an {@code Iterator} over all the encryption properties.
-     */
-    Iterator<EncryptionProperty> getEncryptionProperties();
-
-    /**
-     * Adds an {@code EncryptionProperty}.
-     *
-     * @param property
-     */
-    void addEncryptionProperty(EncryptionProperty property);
-
-    /**
-     * Removes the specified {@code EncryptionProperty}.
-     *
-     * @param property
-     */
-    void removeEncryptionProperty(EncryptionProperty property);
-}
-
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/EncryptionProperty.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/*
- * 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.encryption;
-
-import java.util.Iterator;
-import org.w3c.dom.Element;
-
-/**
- * Additional information items concerning the generation of the
- * {@code EncryptedData} or {@code EncryptedKey} can be placed in an
- * {@code EncryptionProperty} element (e.g., date/time stamp or the serial
- * number of cryptographic hardware used during encryption). The Target
- * attribute identifies the {@code EncryptedType} structure being
- * described. anyAttribute permits the inclusion of attributes from the XML
- * namespace to be included (i.e., {@code xml:space},
- * {@code xml:lang}, and {@code xml:base}).
- * <p>
- * It is defined as follows:
- * <pre>{@code
- * <element name='EncryptionProperty' type='xenc:EncryptionPropertyType'/>
- * <complexType name='EncryptionPropertyType' mixed='true'>
- *     <choice maxOccurs='unbounded'>
- *         <any namespace='##other' processContents='lax'/>
- *     </choice>
- *     <attribute name='Target' type='anyURI' use='optional'/>
- *     <attribute name='Id' type='ID' use='optional'/>
- *     <anyAttribute namespace="http://www.w3.org/XML/1998/namespace"/>
- * </complexType>
- * }</pre>
- *
- * @author Axl Mattheus
- */
-public interface EncryptionProperty {
-
-    /**
-     * Returns the {@code EncryptedType} being described.
-     *
-     * @return the {@code EncryptedType} being described by this
-     *   {@code EncryptionProperty}.
-     */
-    String getTarget();
-
-    /**
-     * Sets the target.
-     *
-     * @param target
-     */
-    void setTarget(String target);
-
-    /**
-     * Returns the id of the {@CODE EncryptionProperty}.
-     *
-     * @return the id.
-     */
-    String getId();
-
-    /**
-     * Sets the id.
-     *
-     * @param id
-     */
-    void setId(String id);
-
-    /**
-     * Returns the attribute's value in the {@code xml} namespace.
-     *
-     * @param attribute
-     * @return the attribute's value.
-     */
-    String getAttribute(String attribute);
-
-    /**
-     * Set the attribute value.
-     *
-     * @param attribute the attribute's name.
-     * @param value the attribute's value.
-     */
-    void setAttribute(String attribute, String value);
-
-    /**
-     * Returns the properties of the {@CODE EncryptionProperty}.
-     *
-     * @return an {@code Iterator} over all the additional encryption
-     *   information contained in this class.
-     */
-    Iterator<Element> getEncryptionInformation();
-
-    /**
-     * Adds encryption information.
-     *
-     * @param information the additional encryption information.
-     */
-    void addEncryptionInformation(Element information);
-
-    /**
-     * Removes encryption information.
-     *
-     * @param information the information to remove.
-     */
-    void removeEncryptionInformation(Element information);
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/Reference.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * 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.encryption;
-
-import java.util.Iterator;
-import org.w3c.dom.Element;
-
-/**
- * A wrapper for a pointer from a key value of an {@code EncryptedKey} to
- * items encrypted by that key value ({@code EncryptedData} or
- * {@code EncryptedKey} elements).
- * <p>
- * It is defined as follows:
- * <pre>{@code
- * <complexType name='ReferenceType'>
- *     <sequence>
- *         <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
- *     </sequence>
- *     <attribute name='URI' type='anyURI' use='required'/>
- * </complexType>
- * }</pre>
- *
- * @author Axl Mattheus
- * @see ReferenceList
- */
-public interface Reference {
-    /**
-     * Returns the {@code Element} tag name for this {@code Reference}.
-     *
-     * @return the tag name of this {@code Reference}.
-     */
-    String getType();
-
-    /**
-     * Returns a {@code URI} that points to an {@code Element} that
-     * were encrypted using the key defined in the enclosing
-     * {@code EncryptedKey} element.
-     *
-     * @return an Uniform Resource Identifier that qualifies an
-     *   {@code EncryptedType}.
-     */
-    String getURI();
-
-    /**
-     * Sets a {@code URI} that points to an {@code Element} that
-     * were encrypted using the key defined in the enclosing
-     * {@code EncryptedKey} element.
-     *
-     * @param uri the Uniform Resource Identifier that qualifies an
-     *   {@code EncryptedType}.
-     */
-    void setURI(String uri);
-
-    /**
-     * Returns an {@code Iterator} over all the child elements contained in
-     * this {@code Reference} that will aid the recipient in retrieving the
-     * {@code EncryptedKey} and/or {@code EncryptedData} elements.
-     * These could include information such as XPath transforms, decompression
-     * transforms, or information on how to retrieve the elements from a
-     * document storage facility.
-     *
-     * @return child elements.
-     */
-    Iterator<Element> getElementRetrievalInformation();
-
-    /**
-     * Adds retrieval information.
-     *
-     * @param info
-     */
-    void addElementRetrievalInformation(Element info);
-
-    /**
-     * Removes the specified retrieval information.
-     *
-     * @param info
-     */
-    void removeElementRetrievalInformation(Element info);
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/ReferenceList.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * 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.encryption;
-
-import java.util.Iterator;
-
-/**
- * {@code ReferenceList} is an element that contains pointers from a key
- * value of an {@code EncryptedKey} to items encrypted by that key value
- * ({@code EncryptedData} or {@code EncryptedKey} elements).
- * <p>
- * It is defined as follows:
- * <pre>{@code
- * <element name='ReferenceList'>
- *     <complexType>
- *         <choice minOccurs='1' maxOccurs='unbounded'>
- *             <element name='DataReference' type='xenc:ReferenceType'/>
- *             <element name='KeyReference' type='xenc:ReferenceType'/>
- *         </choice>
- *     </complexType>
- * </element>
- * }</pre>
- *
- * @author Axl Mattheus
- * @see Reference
- */
-public interface ReferenceList {
-
-    /** DATA TAG */
-    int DATA_REFERENCE = 0x00000001;
-
-    /** KEY TAG */
-    int KEY_REFERENCE  = 0x00000002;
-
-    /**
-     * Adds a reference to this reference list.
-     *
-     * @param reference the reference to add.
-     * @throws IllegalAccessException if the {@code Reference} is not an
-     *   instance of {@code DataReference} or {@code KeyReference}.
-     */
-    void add(Reference reference);
-
-    /**
-     * Removes a reference from the {@code ReferenceList}.
-     *
-     * @param reference the reference to remove.
-     */
-    void remove(Reference reference);
-
-    /**
-     * Returns the size of the {@code ReferenceList}.
-     *
-     * @return the size of the {@code ReferenceList}.
-     */
-    int size();
-
-    /**
-     * Indicates if the {@code ReferenceList} is empty.
-     *
-     * @return {@code <b>true</b>} if the {@code ReferenceList} is
-     *     empty, else {@code <b>false</b>}.
-     */
-    boolean isEmpty();
-
-    /**
-     * Returns an {@code Iterator} over all the {@code Reference}s
-     * contained in this {@code ReferenceList}.
-     *
-     * @return Iterator.
-     */
-    Iterator<Reference> getReferences();
-
-    /**
-     * {@code DataReference} factory method. Returns a
-     * {@code DataReference}.
-     * @param uri
-     * @return a {@code DataReference}.
-     */
-    Reference newDataReference(String uri);
-
-    /**
-     * {@code KeyReference} factory method. Returns a
-     * {@code KeyReference}.
-     * @param uri
-     * @return a {@code KeyReference}.
-     */
-    Reference newKeyReference(String uri);
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/Serializer.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * 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.encryption;
-
-import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * Converts <code>String</code>s into <code>Node</code>s and visa versa.
- */
-public interface Serializer {
-
-    /**
-     * Set the Canonicalizer object to use.
-     */
-    void setCanonicalizer(Canonicalizer canon);
-
-    /**
-     * Returns a <code>byte[]</code> representation of the specified
-     * <code>Element</code>.
-     *
-     * @param element the <code>Element</code> to serialize.
-     * @return the <code>byte[]</code> representation of the serilaized
-     *   <code>Element</code>.
-     * @throws Exception
-     */
-    byte[] serializeToByteArray(Element element) throws Exception;
-
-    /**
-     * Returns a <code>byte[]</code> representation of the specified
-     * <code>NodeList</code>.
-     *
-     * @param content the <code>NodeList</code> to serialize.
-     * @return the <code>byte[]</code> representation of the serialized
-     *   <code>NodeList</code>.
-     * @throws Exception
-     */
-    byte[] serializeToByteArray(NodeList content) throws Exception;
-
-    /**
-     * Use the Canonicalizer to serialize the node
-     * @param node
-     * @return the (byte[]) canonicalization of the node
-     * @throws Exception
-     */
-    byte[] canonSerializeToByteArray(Node node) throws Exception;
-
-    /**
-     * @param source
-     * @param ctx
-     * @return the Node resulting from the parse of the source
-     * @throws XMLEncryptionException
-     */
-    Node deserialize(byte[] source, Node ctx) throws XMLEncryptionException;
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/Transforms.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * 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.encryption;
-
-/**
- * A container for {@code ds:Transform}s.
- * <p>
- * It is defined as follows:
- * <pre>{@code
- * <complexType name='TransformsType'>
- *     <sequence>
- *         <element ref='ds:Transform' maxOccurs='unbounded'/>
- *     </sequence>
- * </complexType>
- * }</pre>
- *
- * @author Axl Mattheus
- * @see com.sun.org.apache.xml.internal.security.encryption.CipherReference
- */
-public interface Transforms {
-    /**
-     * Temporary method to turn the XMLEncryption Transforms class
-     * into a DS class.  The main logic is currently implemented in the
-     * DS class, so we need to get to get the base class.
-     * <p>
-     * <b>Note</b> This will be removed in future versions
-     */
-    com.sun.org.apache.xml.internal.security.transforms.Transforms getDSTransforms();
-
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipher.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3539 +0,0 @@
-/*
- * 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.encryption;
-
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.SecureRandom;
-import java.security.spec.MGF1ParameterSpec;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.OAEPParameterSpec;
-import javax.crypto.spec.PSource;
-
-import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
-import com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm;
-import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
-import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
-import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
-import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
-import com.sun.org.apache.xml.internal.security.keys.KeyInfo;
-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.keyresolver.implementations.EncryptedKeyResolver;
-import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;
-import com.sun.org.apache.xml.internal.security.transforms.InvalidTransformException;
-import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
-import com.sun.org.apache.xml.internal.security.utils.Base64;
-import com.sun.org.apache.xml.internal.security.utils.Constants;
-import com.sun.org.apache.xml.internal.security.utils.ElementProxy;
-import com.sun.org.apache.xml.internal.security.utils.EncryptionConstants;
-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 org.w3c.dom.NodeList;
-
-/**
- * <code>XMLCipher</code> encrypts and decrypts the contents of
- * <code>Document</code>s, <code>Element</code>s and <code>Element</code>
- * contents. It was designed to resemble <code>javax.crypto.Cipher</code> in
- * order to facilitate understanding of its functioning.
- *
- * @author Axl Mattheus (Sun Microsystems)
- * @author Christian Geuer-Pollmann
- */
-public class XMLCipher {
-
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(XMLCipher.class.getName());
-
-    /** Triple DES EDE (192 bit key) in CBC mode */
-    public static final String TRIPLEDES =
-        EncryptionConstants.ALGO_ID_BLOCKCIPHER_TRIPLEDES;
-
-    /** AES 128 Cipher */
-    public static final String AES_128 =
-        EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128;
-
-    /** AES 256 Cipher */
-    public static final String AES_256 =
-        EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256;
-
-    /** AES 192 Cipher */
-    public static final String AES_192 =
-        EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192;
-
-    /** AES 128 GCM Cipher */
-    public static final String AES_128_GCM =
-        EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM;
-
-    /** AES 192 GCM Cipher */
-    public static final String AES_192_GCM =
-        EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192_GCM;
-
-    /** AES 256 GCM Cipher */
-    public static final String AES_256_GCM =
-        EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM;
-
-    /** RSA 1.5 Cipher */
-    public static final String RSA_v1dot5 =
-        EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15;
-
-    /** RSA OAEP Cipher */
-    public static final String RSA_OAEP =
-        EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP;
-
-    /** RSA OAEP Cipher */
-    public static final String RSA_OAEP_11 =
-        EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP_11;
-
-    /** DIFFIE_HELLMAN Cipher */
-    public static final String DIFFIE_HELLMAN =
-        EncryptionConstants.ALGO_ID_KEYAGREEMENT_DH;
-
-    /** Triple DES EDE (192 bit key) in CBC mode KEYWRAP*/
-    public static final String TRIPLEDES_KeyWrap =
-        EncryptionConstants.ALGO_ID_KEYWRAP_TRIPLEDES;
-
-    /** AES 128 Cipher KeyWrap */
-    public static final String AES_128_KeyWrap =
-        EncryptionConstants.ALGO_ID_KEYWRAP_AES128;
-
-    /** AES 256 Cipher KeyWrap */
-    public static final String AES_256_KeyWrap =
-        EncryptionConstants.ALGO_ID_KEYWRAP_AES256;
-
-    /** AES 192 Cipher KeyWrap */
-    public static final String AES_192_KeyWrap =
-        EncryptionConstants.ALGO_ID_KEYWRAP_AES192;
-
-    /** SHA1 Cipher */
-    public static final String SHA1 =
-        Constants.ALGO_ID_DIGEST_SHA1;
-
-    /** SHA256 Cipher */
-    public static final String SHA256 =
-        MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA256;
-
-    /** SHA512 Cipher */
-    public static final String SHA512 =
-        MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA512;
-
-    /** RIPEMD Cipher */
-    public static final String RIPEMD_160 =
-        MessageDigestAlgorithm.ALGO_ID_DIGEST_RIPEMD160;
-
-    /** XML Signature NS */
-    public static final String XML_DSIG =
-        Constants.SignatureSpecNS;
-
-    /** N14C_XML */
-    public static final String N14C_XML =
-        Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS;
-
-    /** N14C_XML with comments*/
-    public static final String N14C_XML_WITH_COMMENTS =
-        Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS;
-
-    /** N14C_XML exclusive */
-    public static final String EXCL_XML_N14C =
-        Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
-
-    /** N14C_XML exclusive with comments*/
-    public static final String EXCL_XML_N14C_WITH_COMMENTS =
-        Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS;
-
-    /** N14C_PHYSICAL preserve the physical representation*/
-    public static final String PHYSICAL_XML_N14C =
-        Canonicalizer.ALGO_ID_C14N_PHYSICAL;
-
-    /** Base64 encoding */
-    public static final String BASE64_ENCODING =
-        com.sun.org.apache.xml.internal.security.transforms.Transforms.TRANSFORM_BASE64_DECODE;
-
-    /** ENCRYPT Mode */
-    public static final int ENCRYPT_MODE = Cipher.ENCRYPT_MODE;
-
-    /** DECRYPT Mode */
-    public static final int DECRYPT_MODE = Cipher.DECRYPT_MODE;
-
-    /** UNWRAP Mode */
-    public static final int UNWRAP_MODE  = Cipher.UNWRAP_MODE;
-
-    /** WRAP Mode */
-    public static final int WRAP_MODE    = Cipher.WRAP_MODE;
-
-    private static final String ENC_ALGORITHMS = TRIPLEDES + "\n" +
-    AES_128 + "\n" + AES_256 + "\n" + AES_192 + "\n" + RSA_v1dot5 + "\n" +
-    RSA_OAEP + "\n" + RSA_OAEP_11 + "\n" + TRIPLEDES_KeyWrap + "\n" +
-    AES_128_KeyWrap + "\n" + AES_256_KeyWrap + "\n" + AES_192_KeyWrap + "\n" +
-    AES_128_GCM + "\n" + AES_192_GCM + "\n" + AES_256_GCM + "\n";
-
-    /** Cipher created during initialisation that is used for encryption */
-    private Cipher contextCipher;
-
-    /** Mode that the XMLCipher object is operating in */
-    private int cipherMode = Integer.MIN_VALUE;
-
-    /** URI of algorithm that is being used for cryptographic operation */
-    private String algorithm = null;
-
-    /** Cryptographic provider requested by caller */
-    private String requestedJCEProvider = null;
-
-    /** Holds c14n to serialize, if initialized then _always_ use this c14n to serialize */
-    private Canonicalizer canon;
-
-    /** Used for creation of DOM nodes in WRAP and ENCRYPT modes */
-    private Document contextDocument;
-
-    /** Instance of factory used to create XML Encryption objects */
-    private Factory factory;
-
-    /** Serializer class for going to/from UTF-8 */
-    private Serializer serializer;
-
-    /** Local copy of user's key */
-    private Key key;
-
-    /** Local copy of the kek (used to decrypt EncryptedKeys during a
-     *  DECRYPT_MODE operation */
-    private Key kek;
-
-    // The EncryptedKey being built (part of a WRAP operation) or read
-    // (part of an UNWRAP operation)
-    private EncryptedKey ek;
-
-    // The EncryptedData being built (part of a WRAP operation) or read
-    // (part of an UNWRAP operation)
-    private EncryptedData ed;
-
-    private SecureRandom random;
-
-    private boolean secureValidation;
-
-    private String digestAlg;
-
-    /** List of internal KeyResolvers for DECRYPT and UNWRAP modes. */
-    private List<KeyResolverSpi> internalKeyResolvers;
-
-    /**
-     * Set the Serializer algorithm to use
-     */
-    public void setSerializer(Serializer serializer) {
-        this.serializer = serializer;
-        serializer.setCanonicalizer(this.canon);
-    }
-
-    /**
-     * Get the Serializer algorithm to use
-     */
-    public Serializer getSerializer() {
-        return serializer;
-    }
-
-    /**
-     * Creates a new <code>XMLCipher</code>.
-     *
-     * @param transformation    the name of the transformation, e.g.,
-     *                          <code>XMLCipher.TRIPLEDES</code>. If null the XMLCipher can only
-     *                          be used for decrypt or unwrap operations where the encryption method
-     *                          is defined in the <code>EncryptionMethod</code> element.
-     * @param provider          the JCE provider that supplies the transformation,
-     *                          if null use the default provider.
-     * @param canon             the name of the c14n algorithm, if
-     *                          <code>null</code> use standard serializer
-     * @param digestMethod      An optional digestMethod to use.
-     */
-    private XMLCipher(
-        String transformation,
-        String provider,
-        String canonAlg,
-        String digestMethod
-    ) throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Constructing XMLCipher...");
-        }
-
-        factory = new Factory();
-
-        algorithm = transformation;
-        requestedJCEProvider = provider;
-        digestAlg = digestMethod;
-
-        // Create a canonicalizer - used when serializing DOM to octets
-        // prior to encryption (and for the reverse)
-
-        try {
-            if (canonAlg == null) {
-                // The default is to preserve the physical representation.
-                this.canon = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_PHYSICAL);
-            } else {
-                this.canon = Canonicalizer.getInstance(canonAlg);
-            }
-        } catch (InvalidCanonicalizerException ice) {
-            throw new XMLEncryptionException("empty", ice);
-        }
-
-        if (serializer == null) {
-            serializer = new DocumentSerializer();
-        }
-        serializer.setCanonicalizer(this.canon);
-
-        if (transformation != null) {
-            contextCipher = constructCipher(transformation, digestMethod);
-        }
-    }
-
-    /**
-     * Checks to ensure that the supplied algorithm is valid.
-     *
-     * @param algorithm the algorithm to check.
-     * @return true if the algorithm is valid, otherwise false.
-     * @since 1.0.
-     */
-    private static boolean isValidEncryptionAlgorithm(String algorithm) {
-        return (
-            algorithm.equals(TRIPLEDES) ||
-            algorithm.equals(AES_128) ||
-            algorithm.equals(AES_256) ||
-            algorithm.equals(AES_192) ||
-            algorithm.equals(AES_128_GCM) ||
-            algorithm.equals(AES_192_GCM) ||
-            algorithm.equals(AES_256_GCM) ||
-            algorithm.equals(RSA_v1dot5) ||
-            algorithm.equals(RSA_OAEP) ||
-            algorithm.equals(RSA_OAEP_11) ||
-            algorithm.equals(TRIPLEDES_KeyWrap) ||
-            algorithm.equals(AES_128_KeyWrap) ||
-            algorithm.equals(AES_256_KeyWrap) ||
-            algorithm.equals(AES_192_KeyWrap)
-        );
-    }
-
-    /**
-     * Validate the transformation argument of getInstance or getProviderInstance
-     *
-     * @param transformation the name of the transformation, e.g.,
-     *   <code>XMLCipher.TRIPLEDES</code> which is shorthand for
-     *   &quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&quot;
-     */
-    private static void validateTransformation(String transformation) {
-        if (null == transformation) {
-            throw new NullPointerException("Transformation unexpectedly null...");
-        }
-        if (!isValidEncryptionAlgorithm(transformation)) {
-            log.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS);
-        }
-    }
-
-    /**
-     * Returns an <code>XMLCipher</code> that implements the specified
-     * transformation and operates on the specified context document.
-     * <p>
-     * If the default provider package supplies an implementation of the
-     * requested transformation, an instance of Cipher containing that
-     * implementation is returned. If the transformation is not available in
-     * the default provider package, other provider packages are searched.
-     * <p>
-     * <b>NOTE<sub>1</sub>:</b> The transformation name does not follow the same
-     * pattern as that outlined in the Java Cryptography Extension Reference
-     * Guide but rather that specified by the XML Encryption Syntax and
-     * Processing document. The rational behind this is to make it easier for a
-     * novice at writing Java Encryption software to use the library.
-     * <p>
-     * <b>NOTE<sub>2</sub>:</b> <code>getInstance()</code> does not follow the
-     * same pattern regarding exceptional conditions as that used in
-     * <code>javax.crypto.Cipher</code>. Instead, it only throws an
-     * <code>XMLEncryptionException</code> which wraps an underlying exception.
-     * The stack trace from the exception should be self explanatory.
-     *
-     * @param transformation the name of the transformation, e.g.,
-     *   <code>XMLCipher.TRIPLEDES</code> which is shorthand for
-     *   &quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&quot;
-     * @throws XMLEncryptionException
-     * @return the XMLCipher
-     * @see javax.crypto.Cipher#getInstance(java.lang.String)
-     */
-    public static XMLCipher getInstance(String transformation) throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Getting XMLCipher with transformation");
-        }
-        validateTransformation(transformation);
-        return new XMLCipher(transformation, null, null, null);
-    }
-
-    /**
-     * Returns an <code>XMLCipher</code> that implements the specified
-     * transformation, operates on the specified context document and serializes
-     * the document with the specified canonicalization algorithm before it
-     * encrypts the document.
-     * <p>
-     *
-     * @param transformation    the name of the transformation
-     * @param canon             the name of the c14n algorithm, if <code>null</code> use
-     *                          standard serializer
-     * @return the XMLCipher
-     * @throws XMLEncryptionException
-     */
-    public static XMLCipher getInstance(String transformation, String canon)
-        throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Getting XMLCipher with transformation and c14n algorithm");
-        }
-        validateTransformation(transformation);
-        return new XMLCipher(transformation, null, canon, null);
-    }
-
-    /**
-     * Returns an <code>XMLCipher</code> that implements the specified
-     * transformation, operates on the specified context document and serializes
-     * the document with the specified canonicalization algorithm before it
-     * encrypts the document.
-     * <p>
-     *
-     * @param transformation    the name of the transformation
-     * @param canon             the name of the c14n algorithm, if <code>null</code> use
-     *                          standard serializer
-     * @param digestMethod      An optional digestMethod to use
-     * @return the XMLCipher
-     * @throws XMLEncryptionException
-     */
-    public static XMLCipher getInstance(String transformation, String canon, String digestMethod)
-        throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Getting XMLCipher with transformation and c14n algorithm");
-        }
-        validateTransformation(transformation);
-        return new XMLCipher(transformation, null, canon, digestMethod);
-    }
-
-    /**
-     * Returns an <code>XMLCipher</code> that implements the specified
-     * transformation and operates on the specified context document.
-     *
-     * @param transformation    the name of the transformation
-     * @param provider          the JCE provider that supplies the transformation
-     * @return the XMLCipher
-     * @throws XMLEncryptionException
-     */
-    public static XMLCipher getProviderInstance(String transformation, String provider)
-        throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Getting XMLCipher with transformation and provider");
-        }
-        if (null == provider) {
-            throw new NullPointerException("Provider unexpectedly null..");
-        }
-        validateTransformation(transformation);
-        return new XMLCipher(transformation, provider, null, null);
-    }
-
-    /**
-     * Returns an <code>XMLCipher</code> that implements the specified
-     * transformation, operates on the specified context document and serializes
-     * the document with the specified canonicalization algorithm before it
-     * encrypts the document.
-     * <p>
-     *
-     * @param transformation    the name of the transformation
-     * @param provider          the JCE provider that supplies the transformation
-     * @param canon             the name of the c14n algorithm, if <code>null</code> use standard
-     *                          serializer
-     * @return the XMLCipher
-     * @throws XMLEncryptionException
-     */
-    public static XMLCipher getProviderInstance(
-        String transformation, String provider, String canon
-    ) throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Getting XMLCipher with transformation, provider and c14n algorithm");
-        }
-        if (null == provider) {
-            throw new NullPointerException("Provider unexpectedly null..");
-        }
-        validateTransformation(transformation);
-        return new XMLCipher(transformation, provider, canon, null);
-    }
-
-    /**
-     * Returns an <code>XMLCipher</code> that implements the specified
-     * transformation, operates on the specified context document and serializes
-     * the document with the specified canonicalization algorithm before it
-     * encrypts the document.
-     * <p>
-     *
-     * @param transformation    the name of the transformation
-     * @param provider          the JCE provider that supplies the transformation
-     * @param canon             the name of the c14n algorithm, if <code>null</code> use standard
-     *                          serializer
-     * @param digestMethod      An optional digestMethod to use
-     * @return the XMLCipher
-     * @throws XMLEncryptionException
-     */
-    public static XMLCipher getProviderInstance(
-        String transformation, String provider, String canon, String digestMethod
-    ) throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Getting XMLCipher with transformation, provider and c14n algorithm");
-        }
-        if (null == provider) {
-            throw new NullPointerException("Provider unexpectedly null..");
-        }
-        validateTransformation(transformation);
-        return new XMLCipher(transformation, provider, canon, digestMethod);
-    }
-
-    /**
-     * Returns an <code>XMLCipher</code> that implements no specific
-     * transformation, and can therefore only be used for decrypt or
-     * unwrap operations where the encryption method is defined in the
-     * <code>EncryptionMethod</code> element.
-     *
-     * @return The XMLCipher
-     * @throws XMLEncryptionException
-     */
-    public static XMLCipher getInstance() throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Getting XMLCipher with no arguments");
-        }
-        return new XMLCipher(null, null, null, null);
-    }
-
-    /**
-     * Returns an <code>XMLCipher</code> that implements no specific
-     * transformation, and can therefore only be used for decrypt or
-     * unwrap operations where the encryption method is defined in the
-     * <code>EncryptionMethod</code> element.
-     *
-     * Allows the caller to specify a provider that will be used for
-     * cryptographic operations.
-     *
-     * @param provider          the JCE provider that supplies the transformation
-     * @return the XMLCipher
-     * @throws XMLEncryptionException
-     */
-    public static XMLCipher getProviderInstance(String provider) throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Getting XMLCipher with provider");
-        }
-        return new XMLCipher(null, provider, null, null);
-    }
-
-    /**
-     * Initializes this cipher with a key.
-     * <p>
-     * The cipher is initialized for one of the following four operations:
-     * encryption, decryption, key wrapping or key unwrapping, depending on the
-     * value of opmode.
-     *
-     * For WRAP and ENCRYPT modes, this also initialises the internal
-     * EncryptedKey or EncryptedData (with a CipherValue)
-     * structure that will be used during the ensuing operations.  This
-     * can be obtained (in order to modify KeyInfo elements etc. prior to
-     * finalising the encryption) by calling
-     * {@link #getEncryptedData} or {@link #getEncryptedKey}.
-     *
-     * @param opmode the operation mode of this cipher (this is one of the
-     *   following: ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE or UNWRAP_MODE)
-     * @param key
-     * @see javax.crypto.Cipher#init(int, java.security.Key)
-     * @throws XMLEncryptionException
-     */
-    public void init(int opmode, Key key) throws XMLEncryptionException {
-        // sanity checks
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Initializing XMLCipher...");
-        }
-
-        ek = null;
-        ed = null;
-
-        switch (opmode) {
-
-        case ENCRYPT_MODE :
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "opmode = ENCRYPT_MODE");
-            }
-            ed = createEncryptedData(CipherData.VALUE_TYPE, "NO VALUE YET");
-            break;
-        case DECRYPT_MODE :
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "opmode = DECRYPT_MODE");
-            }
-            break;
-        case WRAP_MODE :
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "opmode = WRAP_MODE");
-            }
-            ek = createEncryptedKey(CipherData.VALUE_TYPE, "NO VALUE YET");
-            break;
-        case UNWRAP_MODE :
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "opmode = UNWRAP_MODE");
-            }
-            break;
-        default :
-            log.log(java.util.logging.Level.SEVERE, "Mode unexpectedly invalid");
-            throw new XMLEncryptionException("Invalid mode in init");
-        }
-
-        cipherMode = opmode;
-        this.key = key;
-    }
-
-    /**
-     * Set whether secure validation is enabled or not. The default is false.
-     */
-    public void setSecureValidation(boolean secureValidation) {
-        this.secureValidation = secureValidation;
-    }
-
-    /**
-     * This method is used to add a custom {@link KeyResolverSpi} to an XMLCipher.
-     * These KeyResolvers are used in KeyInfo objects in DECRYPT and
-     * UNWRAP modes.
-     *
-     * @param keyResolver
-     */
-    public void registerInternalKeyResolver(KeyResolverSpi keyResolver) {
-        if (internalKeyResolvers == null) {
-            internalKeyResolvers = new ArrayList<KeyResolverSpi>();
-        }
-        internalKeyResolvers.add(keyResolver);
-    }
-
-    /**
-     * Get the EncryptedData being built
-     * <p>
-     * Returns the EncryptedData being built during an ENCRYPT operation.
-     * This can then be used by applications to add KeyInfo elements and
-     * set other parameters.
-     *
-     * @return The EncryptedData being built
-     */
-    public EncryptedData getEncryptedData() {
-        // Sanity checks
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Returning EncryptedData");
-        }
-        return ed;
-    }
-
-    /**
-     * Get the EncryptedData being build
-     *
-     * Returns the EncryptedData being built during an ENCRYPT operation.
-     * This can then be used by applications to add KeyInfo elements and
-     * set other parameters.
-     *
-     * @return The EncryptedData being built
-     */
-    public EncryptedKey getEncryptedKey() {
-        // Sanity checks
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Returning EncryptedKey");
-        }
-        return ek;
-    }
-
-    /**
-     * Set a Key Encryption Key.
-     * <p>
-     * The Key Encryption Key (KEK) is used for encrypting/decrypting
-     * EncryptedKey elements.  By setting this separately, the XMLCipher
-     * class can know whether a key applies to the data part or wrapped key
-     * part of an encrypted object.
-     *
-     * @param kek The key to use for de/encrypting key data
-     */
-
-    public void setKEK(Key kek) {
-        this.kek = kek;
-    }
-
-    /**
-     * Martial an EncryptedData
-     *
-     * Takes an EncryptedData object and returns a DOM Element that
-     * represents the appropriate <code>EncryptedData</code>
-     * <p>
-     * <b>Note:</b> This should only be used in cases where the context
-     * document has been passed in via a call to doFinal.
-     *
-     * @param encryptedData EncryptedData object to martial
-     * @return the DOM <code>Element</code> representing the passed in
-     * object
-     */
-    public Element martial(EncryptedData encryptedData) {
-        return factory.toElement(encryptedData);
-    }
-
-    /**
-     * Martial an EncryptedData
-     *
-     * Takes an EncryptedData object and returns a DOM Element that
-     * represents the appropriate <code>EncryptedData</code>
-     *
-     * @param context The document that will own the returned nodes
-     * @param encryptedData EncryptedData object to martial
-     * @return the DOM <code>Element</code> representing the passed in
-     * object
-     */
-    public Element martial(Document context, EncryptedData encryptedData) {
-        contextDocument = context;
-        return factory.toElement(encryptedData);
-    }
-
-    /**
-     * Martial an EncryptedKey
-     *
-     * Takes an EncryptedKey object and returns a DOM Element that
-     * represents the appropriate <code>EncryptedKey</code>
-     *
-     * <p>
-     * <b>Note:</b> This should only be used in cases where the context
-     * document has been passed in via a call to doFinal.
-     *
-     * @param encryptedKey EncryptedKey object to martial
-     * @return the DOM <code>Element</code> representing the passed in
-     * object
-     */
-    public Element martial(EncryptedKey encryptedKey) {
-        return factory.toElement(encryptedKey);
-    }
-
-    /**
-     * Martial an EncryptedKey
-     *
-     * Takes an EncryptedKey object and returns a DOM Element that
-     * represents the appropriate <code>EncryptedKey</code>
-     *
-     * @param context The document that will own the created nodes
-     * @param encryptedKey EncryptedKey object to martial
-     * @return the DOM <code>Element</code> representing the passed in
-     * object
-     */
-    public Element martial(Document context, EncryptedKey encryptedKey) {
-        contextDocument = context;
-        return factory.toElement(encryptedKey);
-    }
-
-    /**
-     * Martial a ReferenceList
-     *
-     * Takes a ReferenceList object and returns a DOM Element that
-     * represents the appropriate <code>ReferenceList</code>
-     *
-     * <p>
-     * <b>Note:</b> This should only be used in cases where the context
-     * document has been passed in via a call to doFinal.
-     *
-     * @param referenceList ReferenceList object to martial
-     * @return the DOM <code>Element</code> representing the passed in
-     * object
-     */
-    public Element martial(ReferenceList referenceList) {
-        return factory.toElement(referenceList);
-    }
-
-    /**
-     * Martial a ReferenceList
-     *
-     * Takes a ReferenceList object and returns a DOM Element that
-     * represents the appropriate <code>ReferenceList</code>
-     *
-     * @param context The document that will own the created nodes
-     * @param referenceList ReferenceList object to martial
-     * @return the DOM <code>Element</code> representing the passed in
-     * object
-     */
-    public Element martial(Document context, ReferenceList referenceList) {
-        contextDocument = context;
-        return factory.toElement(referenceList);
-    }
-
-    /**
-     * Encrypts an <code>Element</code> and replaces it with its encrypted
-     * counterpart in the context <code>Document</code>, that is, the
-     * <code>Document</code> specified when one calls
-     * {@link #getInstance(String) getInstance}.
-     *
-     * @param element the <code>Element</code> to encrypt.
-     * @return the context <code>Document</code> with the encrypted
-     *   <code>Element</code> having replaced the source <code>Element</code>.
-     *  @throws Exception
-     */
-    private Document encryptElement(Element element) throws Exception{
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Encrypting element...");
-        }
-        if (null == element) {
-            log.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
-        }
-        if (cipherMode != ENCRYPT_MODE && log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE...");
-        }
-
-        if (algorithm == null) {
-            throw new XMLEncryptionException("XMLCipher instance without transformation specified");
-        }
-        encryptData(contextDocument, element, false);
-
-        Element encryptedElement = factory.toElement(ed);
-
-        Node sourceParent = element.getParentNode();
-        sourceParent.replaceChild(encryptedElement, element);
-
-        return contextDocument;
-    }
-
-    /**
-     * Encrypts a <code>NodeList</code> (the contents of an
-     * <code>Element</code>) and replaces its parent <code>Element</code>'s
-     * content with this the resulting <code>EncryptedType</code> within the
-     * context <code>Document</code>, that is, the <code>Document</code>
-     * specified when one calls
-     * {@link #getInstance(String) getInstance}.
-     *
-     * @param element the <code>NodeList</code> to encrypt.
-     * @return the context <code>Document</code> with the encrypted
-     *   <code>NodeList</code> having replaced the content of the source
-     *   <code>Element</code>.
-     * @throws Exception
-     */
-    private Document encryptElementContent(Element element) throws /* XMLEncryption */Exception {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Encrypting element content...");
-        }
-        if (null == element) {
-            log.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
-        }
-        if (cipherMode != ENCRYPT_MODE && log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE...");
-        }
-
-        if (algorithm == null) {
-            throw new XMLEncryptionException("XMLCipher instance without transformation specified");
-        }
-        encryptData(contextDocument, element, true);
-
-        Element encryptedElement = factory.toElement(ed);
-
-        removeContent(element);
-        element.appendChild(encryptedElement);
-
-        return contextDocument;
-    }
-
-    /**
-     * Process a DOM <code>Document</code> node. The processing depends on the
-     * initialization parameters of {@link #init(int, Key) init()}.
-     *
-     * @param context the context <code>Document</code>.
-     * @param source the <code>Document</code> to be encrypted or decrypted.
-     * @return the processed <code>Document</code>.
-     * @throws Exception to indicate any exceptional conditions.
-     */
-    public Document doFinal(Document context, Document source) throws /* XMLEncryption */Exception {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Processing source document...");
-        }
-        if (null == context) {
-            log.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
-        }
-        if (null == source) {
-            log.log(java.util.logging.Level.SEVERE, "Source document unexpectedly null...");
-        }
-
-        contextDocument = context;
-
-        Document result = null;
-
-        switch (cipherMode) {
-        case DECRYPT_MODE:
-            result = decryptElement(source.getDocumentElement());
-            break;
-        case ENCRYPT_MODE:
-            result = encryptElement(source.getDocumentElement());
-            break;
-        case UNWRAP_MODE:
-        case WRAP_MODE:
-            break;
-        default:
-            throw new XMLEncryptionException("empty", new IllegalStateException());
-        }
-
-        return result;
-    }
-
-    /**
-     * Process a DOM <code>Element</code> node. The processing depends on the
-     * initialization parameters of {@link #init(int, Key) init()}.
-     *
-     * @param context the context <code>Document</code>.
-     * @param element the <code>Element</code> to be encrypted.
-     * @return the processed <code>Document</code>.
-     * @throws Exception to indicate any exceptional conditions.
-     */
-    public Document doFinal(Document context, Element element) throws /* XMLEncryption */Exception {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Processing source element...");
-        }
-        if (null == context) {
-            log.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
-        }
-        if (null == element) {
-            log.log(java.util.logging.Level.SEVERE, "Source element unexpectedly null...");
-        }
-
-        contextDocument = context;
-
-        Document result = null;
-
-        switch (cipherMode) {
-        case DECRYPT_MODE:
-            result = decryptElement(element);
-            break;
-        case ENCRYPT_MODE:
-            result = encryptElement(element);
-            break;
-        case UNWRAP_MODE:
-        case WRAP_MODE:
-            break;
-        default:
-            throw new XMLEncryptionException("empty", new IllegalStateException());
-        }
-
-        return result;
-    }
-
-    /**
-     * Process the contents of a DOM <code>Element</code> node. The processing
-     * depends on the initialization parameters of
-     * {@link #init(int, Key) init()}.
-     *
-     * @param context the context <code>Document</code>.
-     * @param element the <code>Element</code> which contents is to be
-     *   encrypted.
-     * @param content
-     * @return the processed <code>Document</code>.
-     * @throws Exception to indicate any exceptional conditions.
-     */
-    public Document doFinal(Document context, Element element, boolean content)
-        throws /* XMLEncryption*/ Exception {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Processing source element...");
-        }
-        if (null == context) {
-            log.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
-        }
-        if (null == element) {
-            log.log(java.util.logging.Level.SEVERE, "Source element unexpectedly null...");
-        }
-
-        contextDocument = context;
-
-        Document result = null;
-
-        switch (cipherMode) {
-        case DECRYPT_MODE:
-            if (content) {
-                result = decryptElementContent(element);
-            } else {
-                result = decryptElement(element);
-            }
-            break;
-        case ENCRYPT_MODE:
-            if (content) {
-                result = encryptElementContent(element);
-            } else {
-                result = encryptElement(element);
-            }
-            break;
-        case UNWRAP_MODE:
-        case WRAP_MODE:
-            break;
-        default:
-            throw new XMLEncryptionException("empty", new IllegalStateException());
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns an <code>EncryptedData</code> interface. Use this operation if
-     * you want to have full control over the contents of the
-     * <code>EncryptedData</code> structure.
-     *
-     * This does not change the source document in any way.
-     *
-     * @param context the context <code>Document</code>.
-     * @param element the <code>Element</code> that will be encrypted.
-     * @return the <code>EncryptedData</code>
-     * @throws Exception
-     */
-    public EncryptedData encryptData(Document context, Element element) throws
-        /* XMLEncryption */Exception {
-        return encryptData(context, element, false);
-    }
-
-    /**
-     * Returns an <code>EncryptedData</code> interface. Use this operation if
-     * you want to have full control over the serialization of the element
-     * or element content.
-     *
-     * This does not change the source document in any way.
-     *
-     * @param context the context <code>Document</code>.
-     * @param type a URI identifying type information about the plaintext form
-     *    of the encrypted content (may be <code>null</code>)
-     * @param serializedData the serialized data
-     * @return the <code>EncryptedData</code>
-     * @throws Exception
-     */
-    public EncryptedData encryptData(
-        Document context, String type, InputStream serializedData
-    ) throws Exception {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Encrypting element...");
-        }
-        if (null == context) {
-            log.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
-        }
-        if (null == serializedData) {
-            log.log(java.util.logging.Level.SEVERE, "Serialized data unexpectedly null...");
-        }
-        if (cipherMode != ENCRYPT_MODE && log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE...");
-        }
-
-        return encryptData(context, null, type, serializedData);
-    }
-
-    /**
-     * Returns an <code>EncryptedData</code> interface. Use this operation if
-     * you want to have full control over the contents of the
-     * <code>EncryptedData</code> structure.
-     *
-     * This does not change the source document in any way.
-     *
-     * @param context the context <code>Document</code>.
-     * @param element the <code>Element</code> that will be encrypted.
-     * @param contentMode <code>true</code> to encrypt element's content only,
-     *    <code>false</code> otherwise
-     * @return the <code>EncryptedData</code>
-     * @throws Exception
-     */
-    public EncryptedData encryptData(
-        Document context, Element element, boolean contentMode
-    ) throws /* XMLEncryption */ Exception {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Encrypting element...");
-        }
-        if (null == context) {
-            log.log(java.util.logging.Level.SEVERE, "Context document unexpectedly null...");
-        }
-        if (null == element) {
-            log.log(java.util.logging.Level.SEVERE, "Element unexpectedly null...");
-        }
-        if (cipherMode != ENCRYPT_MODE && log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE...");
-        }
-
-        if (contentMode) {
-            return encryptData(context, element, EncryptionConstants.TYPE_CONTENT, null);
-        } else {
-            return encryptData(context, element, EncryptionConstants.TYPE_ELEMENT, null);
-        }
-    }
-
-    private EncryptedData encryptData(
-        Document context, Element element, String type, InputStream serializedData
-    ) throws /* XMLEncryption */ Exception {
-        contextDocument = context;
-
-        if (algorithm == null) {
-            throw new XMLEncryptionException("XMLCipher instance without transformation specified");
-        }
-
-        byte[] serializedOctets = null;
-        if (serializedData == null) {
-            if (type.equals(EncryptionConstants.TYPE_CONTENT)) {
-                NodeList children = element.getChildNodes();
-                if (null != children) {
-                    serializedOctets = serializer.serializeToByteArray(children);
-                } else {
-                    Object exArgs[] = { "Element has no content." };
-                    throw new XMLEncryptionException("empty", exArgs);
-                }
-            } else {
-                serializedOctets = serializer.serializeToByteArray(element);
-            }
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Serialized octets:\n" + new String(serializedOctets, "UTF-8"));
-            }
-        }
-
-        byte[] encryptedBytes = null;
-
-        // Now create the working cipher if none was created already
-        Cipher c;
-        if (contextCipher == null) {
-            c = constructCipher(algorithm, null);
-        } else {
-            c = contextCipher;
-        }
-        // Now perform the encryption
-
-        try {
-            // The Spec mandates a 96-bit IV for GCM algorithms
-            if (AES_128_GCM.equals(algorithm) || AES_192_GCM.equals(algorithm)
-                || AES_256_GCM.equals(algorithm)) {
-                if (random == null) {
-                    random = SecureRandom.getInstance("SHA1PRNG");
-                }
-                byte[] temp = new byte[12];
-                random.nextBytes(temp);
-                IvParameterSpec paramSpec = new IvParameterSpec(temp);
-                c.init(cipherMode, key, paramSpec);
-            } else {
-                c.init(cipherMode, key);
-            }
-        } catch (InvalidKeyException ike) {
-            throw new XMLEncryptionException("empty", ike);
-        } catch (NoSuchAlgorithmException ex) {
-            throw new XMLEncryptionException("empty", ex);
-        }
-
-        try {
-            if (serializedData != null) {
-                int numBytes;
-                byte[] buf = new byte[8192];
-                ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                while ((numBytes = serializedData.read(buf)) != -1) {
-                    byte[] data = c.update(buf, 0, numBytes);
-                    baos.write(data);
-                }
-                baos.write(c.doFinal());
-                encryptedBytes = baos.toByteArray();
-            } else {
-                encryptedBytes = c.doFinal(serializedOctets);
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Expected cipher.outputSize = " +
-                        Integer.toString(c.getOutputSize(serializedOctets.length)));
-                }
-            }
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Actual cipher.outputSize = "
-                             + Integer.toString(encryptedBytes.length));
-            }
-        } catch (IllegalStateException ise) {
-            throw new XMLEncryptionException("empty", ise);
-        } catch (IllegalBlockSizeException ibse) {
-            throw new XMLEncryptionException("empty", ibse);
-        } catch (BadPaddingException bpe) {
-            throw new XMLEncryptionException("empty", bpe);
-        } catch (UnsupportedEncodingException uee) {
-            throw new XMLEncryptionException("empty", uee);
-        }
-
-        // Now build up to a properly XML Encryption encoded octet stream
-        // IvParameterSpec iv;
-        byte[] iv = c.getIV();
-        byte[] finalEncryptedBytes = new byte[iv.length + encryptedBytes.length];
-        System.arraycopy(iv, 0, finalEncryptedBytes, 0, iv.length);
-        System.arraycopy(encryptedBytes, 0, finalEncryptedBytes, iv.length, encryptedBytes.length);
-        String base64EncodedEncryptedOctets = Base64.encode(finalEncryptedBytes);
-
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Encrypted octets:\n" + base64EncodedEncryptedOctets);
-            log.log(java.util.logging.Level.FINE, "Encrypted octets length = " + base64EncodedEncryptedOctets.length());
-        }
-
-        try {
-            CipherData cd = ed.getCipherData();
-            CipherValue cv = cd.getCipherValue();
-            // cv.setValue(base64EncodedEncryptedOctets.getBytes());
-            cv.setValue(base64EncodedEncryptedOctets);
-
-            if (type != null) {
-                ed.setType(new URI(type).toString());
-            }
-            EncryptionMethod method =
-                factory.newEncryptionMethod(new URI(algorithm).toString());
-            method.setDigestAlgorithm(digestAlg);
-            ed.setEncryptionMethod(method);
-        } catch (URISyntaxException ex) {
-            throw new XMLEncryptionException("empty", ex);
-        }
-        return ed;
-    }
-
-    /**
-     * Returns an <code>EncryptedData</code> interface. Use this operation if
-     * you want to load an <code>EncryptedData</code> structure from a DOM
-     * structure and manipulate the contents.
-     *
-     * @param context the context <code>Document</code>.
-     * @param element the <code>Element</code> that will be loaded
-     * @throws XMLEncryptionException
-     * @return the <code>EncryptedData</code>
-     */
-    public EncryptedData loadEncryptedData(Document context, Element element)
-        throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Loading encrypted element...");
-        }
-        if (null == context) {
-            throw new NullPointerException("Context document unexpectedly null...");
-        }
-        if (null == element) {
-            throw new NullPointerException("Element unexpectedly null...");
-        }
-        if (cipherMode != DECRYPT_MODE) {
-            throw new XMLEncryptionException("XMLCipher unexpectedly not in DECRYPT_MODE...");
-        }
-
-        contextDocument = context;
-        ed = factory.newEncryptedData(element);
-
-        return ed;
-    }
-
-    /**
-     * Returns an <code>EncryptedKey</code> interface. Use this operation if
-     * you want to load an <code>EncryptedKey</code> structure from a DOM
-     * structure and manipulate the contents.
-     *
-     * @param context the context <code>Document</code>.
-     * @param element the <code>Element</code> that will be loaded
-     * @return the <code>EncryptedKey</code>
-     * @throws XMLEncryptionException
-     */
-    public EncryptedKey loadEncryptedKey(Document context, Element element)
-        throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Loading encrypted key...");
-        }
-        if (null == context) {
-            throw new NullPointerException("Context document unexpectedly null...");
-        }
-        if (null == element) {
-            throw new NullPointerException("Element unexpectedly null...");
-        }
-        if (cipherMode != UNWRAP_MODE && cipherMode != DECRYPT_MODE) {
-            throw new XMLEncryptionException(
-                "XMLCipher unexpectedly not in UNWRAP_MODE or DECRYPT_MODE..."
-            );
-        }
-
-        contextDocument = context;
-        ek = factory.newEncryptedKey(element);
-        return ek;
-    }
-
-    /**
-     * Returns an <code>EncryptedKey</code> interface. Use this operation if
-     * you want to load an <code>EncryptedKey</code> structure from a DOM
-     * structure and manipulate the contents.
-     *
-     * Assumes that the context document is the document that owns the element
-     *
-     * @param element the <code>Element</code> that will be loaded
-     * @return the <code>EncryptedKey</code>
-     * @throws XMLEncryptionException
-     */
-    public EncryptedKey loadEncryptedKey(Element element) throws XMLEncryptionException {
-        return loadEncryptedKey(element.getOwnerDocument(), element);
-    }
-
-    /**
-     * Encrypts a key to an EncryptedKey structure
-     *
-     * @param doc the Context document that will be used to general DOM
-     * @param key Key to encrypt (will use previously set KEK to
-     * perform encryption
-     * @return the <code>EncryptedKey</code>
-     * @throws XMLEncryptionException
-     */
-    public EncryptedKey encryptKey(Document doc, Key key) throws XMLEncryptionException {
-        return encryptKey(doc, key, null, null);
-    }
-
-    /**
-     * Encrypts a key to an EncryptedKey structure
-     *
-     * @param doc the Context document that will be used to general DOM
-     * @param key Key to encrypt (will use previously set KEK to
-     * perform encryption
-     * @param mgfAlgorithm The xenc11 MGF Algorithm to use
-     * @param oaepParams The OAEPParams to use
-     * @return the <code>EncryptedKey</code>
-     * @throws XMLEncryptionException
-     */
-    public EncryptedKey encryptKey(
-        Document doc,
-        Key key,
-        String mgfAlgorithm,
-        byte[] oaepParams
-    ) throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Encrypting key ...");
-        }
-
-        if (null == key) {
-            log.log(java.util.logging.Level.SEVERE, "Key unexpectedly null...");
-        }
-        if (cipherMode != WRAP_MODE) {
-            log.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in WRAP_MODE...");
-        }
-        if (algorithm == null) {
-            throw new XMLEncryptionException("XMLCipher instance without transformation specified");
-        }
-
-        contextDocument = doc;
-
-        byte[] encryptedBytes = null;
-        Cipher c;
-
-        if (contextCipher == null) {
-            // Now create the working cipher
-            c = constructCipher(algorithm, null);
-        } else {
-            c = contextCipher;
-        }
-        // Now perform the encryption
-
-        try {
-            // Should internally generate an IV
-            // todo - allow user to set an IV
-            OAEPParameterSpec oaepParameters =
-                constructOAEPParameters(
-                    algorithm, digestAlg, mgfAlgorithm, oaepParams
-                );
-            if (oaepParameters == null) {
-                c.init(Cipher.WRAP_MODE, this.key);
-            } else {
-                c.init(Cipher.WRAP_MODE, this.key, oaepParameters);
-            }
-            encryptedBytes = c.wrap(key);
-        } catch (InvalidKeyException ike) {
-            throw new XMLEncryptionException("empty", ike);
-        } catch (IllegalBlockSizeException ibse) {
-            throw new XMLEncryptionException("empty", ibse);
-        } catch (InvalidAlgorithmParameterException e) {
-            throw new XMLEncryptionException("empty", e);
-        }
-
-        String base64EncodedEncryptedOctets = Base64.encode(encryptedBytes);
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Encrypted key octets:\n" + base64EncodedEncryptedOctets);
-            log.log(java.util.logging.Level.FINE, "Encrypted key octets length = " + base64EncodedEncryptedOctets.length());
-        }
-
-        CipherValue cv = ek.getCipherData().getCipherValue();
-        cv.setValue(base64EncodedEncryptedOctets);
-
-        try {
-            EncryptionMethod method = factory.newEncryptionMethod(new URI(algorithm).toString());
-            method.setDigestAlgorithm(digestAlg);
-            method.setMGFAlgorithm(mgfAlgorithm);
-            method.setOAEPparams(oaepParams);
-            ek.setEncryptionMethod(method);
-        } catch (URISyntaxException ex) {
-            throw new XMLEncryptionException("empty", ex);
-        }
-        return ek;
-    }
-
-    /**
-     * Decrypt a key from a passed in EncryptedKey structure
-     *
-     * @param encryptedKey Previously loaded EncryptedKey that needs
-     * to be decrypted.
-     * @param algorithm Algorithm for the decryption
-     * @return a key corresponding to the given type
-     * @throws XMLEncryptionException
-     */
-    public Key decryptKey(EncryptedKey encryptedKey, String algorithm)
-        throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Decrypting key from previously loaded EncryptedKey...");
-        }
-
-        if (cipherMode != UNWRAP_MODE && log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in UNWRAP_MODE...");
-        }
-
-        if (algorithm == null) {
-            throw new XMLEncryptionException("Cannot decrypt a key without knowing the algorithm");
-        }
-
-        if (key == null) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Trying to find a KEK via key resolvers");
-            }
-
-            KeyInfo ki = encryptedKey.getKeyInfo();
-            if (ki != null) {
-                ki.setSecureValidation(secureValidation);
-                try {
-                    String keyWrapAlg = encryptedKey.getEncryptionMethod().getAlgorithm();
-                    String keyType = JCEMapper.getJCEKeyAlgorithmFromURI(keyWrapAlg);
-                    if ("RSA".equals(keyType)) {
-                        key = ki.getPrivateKey();
-                    } else {
-                        key = ki.getSecretKey();
-                    }
-                }
-                catch (Exception e) {
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                    }
-                }
-            }
-            if (key == null) {
-                log.log(java.util.logging.Level.SEVERE, "XMLCipher::decryptKey called without a KEK and cannot resolve");
-                throw new XMLEncryptionException("Unable to decrypt without a KEK");
-            }
-        }
-
-        // Obtain the encrypted octets
-        XMLCipherInput cipherInput = new XMLCipherInput(encryptedKey);
-        cipherInput.setSecureValidation(secureValidation);
-        byte[] encryptedBytes = cipherInput.getBytes();
-
-        String jceKeyAlgorithm = JCEMapper.getJCEKeyAlgorithmFromURI(algorithm);
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "JCE Key Algorithm: " + jceKeyAlgorithm);
-        }
-
-        Cipher c;
-        if (contextCipher == null) {
-            // Now create the working cipher
-            c =
-                constructCipher(
-                    encryptedKey.getEncryptionMethod().getAlgorithm(),
-                    encryptedKey.getEncryptionMethod().getDigestAlgorithm()
-                );
-        } else {
-            c = contextCipher;
-        }
-
-        Key ret;
-
-        try {
-            EncryptionMethod encMethod = encryptedKey.getEncryptionMethod();
-            OAEPParameterSpec oaepParameters =
-                constructOAEPParameters(
-                    encMethod.getAlgorithm(), encMethod.getDigestAlgorithm(),
-                    encMethod.getMGFAlgorithm(), encMethod.getOAEPparams()
-                );
-            if (oaepParameters == null) {
-                c.init(Cipher.UNWRAP_MODE, key);
-            } else {
-                c.init(Cipher.UNWRAP_MODE, key, oaepParameters);
-            }
-            ret = c.unwrap(encryptedBytes, jceKeyAlgorithm, Cipher.SECRET_KEY);
-        } catch (InvalidKeyException ike) {
-            throw new XMLEncryptionException("empty", ike);
-        } catch (NoSuchAlgorithmException nsae) {
-            throw new XMLEncryptionException("empty", nsae);
-        } catch (InvalidAlgorithmParameterException e) {
-            throw new XMLEncryptionException("empty", e);
-        }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Decryption of key type " + algorithm + " OK");
-        }
-
-        return ret;
-    }
-
-    /**
-     * Construct an OAEPParameterSpec object from the given parameters
-     */
-    private OAEPParameterSpec constructOAEPParameters(
-        String encryptionAlgorithm,
-        String digestAlgorithm,
-        String mgfAlgorithm,
-        byte[] oaepParams
-    ) {
-        if (XMLCipher.RSA_OAEP.equals(encryptionAlgorithm)
-            || XMLCipher.RSA_OAEP_11.equals(encryptionAlgorithm)) {
-
-            String jceDigestAlgorithm = "SHA-1";
-            if (digestAlgorithm != null) {
-                jceDigestAlgorithm = JCEMapper.translateURItoJCEID(digestAlgorithm);
-            }
-
-            PSource.PSpecified pSource = PSource.PSpecified.DEFAULT;
-            if (oaepParams != null) {
-                pSource = new PSource.PSpecified(oaepParams);
-            }
-
-            MGF1ParameterSpec mgfParameterSpec = new MGF1ParameterSpec("SHA-1");
-            if (XMLCipher.RSA_OAEP_11.equals(encryptionAlgorithm)) {
-                if (EncryptionConstants.MGF1_SHA256.equals(mgfAlgorithm)) {
-                    mgfParameterSpec = new MGF1ParameterSpec("SHA-256");
-                } else if (EncryptionConstants.MGF1_SHA384.equals(mgfAlgorithm)) {
-                    mgfParameterSpec = new MGF1ParameterSpec("SHA-384");
-                } else if (EncryptionConstants.MGF1_SHA512.equals(mgfAlgorithm)) {
-                    mgfParameterSpec = new MGF1ParameterSpec("SHA-512");
-                }
-            }
-            return new OAEPParameterSpec(jceDigestAlgorithm, "MGF1", mgfParameterSpec, pSource);
-        }
-
-        return null;
-    }
-
-    /**
-     * Construct a Cipher object
-     */
-    private Cipher constructCipher(String algorithm, String digestAlgorithm) throws XMLEncryptionException {
-        String jceAlgorithm = JCEMapper.translateURItoJCEID(algorithm);
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "JCE Algorithm = " + jceAlgorithm);
-        }
-
-        Cipher c;
-        try {
-            if (requestedJCEProvider == null) {
-                c = Cipher.getInstance(jceAlgorithm);
-            } else {
-                c = Cipher.getInstance(jceAlgorithm, requestedJCEProvider);
-            }
-        } catch (NoSuchAlgorithmException nsae) {
-            // Check to see if an RSA OAEP MGF-1 with SHA-1 algorithm was requested
-            // Some JDKs don't support RSA/ECB/OAEPPadding
-            if (XMLCipher.RSA_OAEP.equals(algorithm)
-                && (digestAlgorithm == null
-                    || MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA1.equals(digestAlgorithm))) {
-                try {
-                    if (requestedJCEProvider == null) {
-                        c = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
-                    } else {
-                        c = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding", requestedJCEProvider);
-                    }
-                } catch (Exception ex) {
-                    throw new XMLEncryptionException("empty", ex);
-                }
-            } else {
-                throw new XMLEncryptionException("empty", nsae);
-            }
-        } catch (NoSuchProviderException nspre) {
-            throw new XMLEncryptionException("empty", nspre);
-        } catch (NoSuchPaddingException nspae) {
-            throw new XMLEncryptionException("empty", nspae);
-        }
-
-        return c;
-    }
-
-    /**
-     * Decrypt a key from a passed in EncryptedKey structure.  This version
-     * is used mainly internally, when  the cipher already has an
-     * EncryptedData loaded.  The algorithm URI will be read from the
-     * EncryptedData
-     *
-     * @param encryptedKey Previously loaded EncryptedKey that needs
-     * to be decrypted.
-     * @return a key corresponding to the given type
-     * @throws XMLEncryptionException
-     */
-    public Key decryptKey(EncryptedKey encryptedKey) throws XMLEncryptionException {
-        return decryptKey(encryptedKey, ed.getEncryptionMethod().getAlgorithm());
-    }
-
-    /**
-     * Removes the contents of a <code>Node</code>.
-     *
-     * @param node the <code>Node</code> to clear.
-     */
-    private static void removeContent(Node node) {
-        while (node.hasChildNodes()) {
-            node.removeChild(node.getFirstChild());
-        }
-    }
-
-    /**
-     * Decrypts <code>EncryptedData</code> in a single-part operation.
-     *
-     * @param element the <code>EncryptedData</code> to decrypt.
-     * @return the <code>Node</code> as a result of the decrypt operation.
-     * @throws XMLEncryptionException
-     */
-    private Document decryptElement(Element element) throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Decrypting element...");
-        }
-
-        if (cipherMode != DECRYPT_MODE) {
-            log.log(java.util.logging.Level.SEVERE, "XMLCipher unexpectedly not in DECRYPT_MODE...");
-        }
-
-        byte[] octets = decryptToByteArray(element);
-
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Decrypted octets:\n" + new String(octets));
-        }
-
-        Node sourceParent = element.getParentNode();
-        Node decryptedNode = serializer.deserialize(octets, sourceParent);
-
-        // The de-serialiser returns a node whose children we need to take on.
-        if (sourceParent != null && Node.DOCUMENT_NODE == sourceParent.getNodeType()) {
-            // If this is a content decryption, this may have problems
-            contextDocument.removeChild(contextDocument.getDocumentElement());
-            contextDocument.appendChild(decryptedNode);
-        } else if (sourceParent != null) {
-            sourceParent.replaceChild(decryptedNode, element);
-        }
-
-        return contextDocument;
-    }
-
-    /**
-     *
-     * @param element
-     * @return the <code>Node</code> as a result of the decrypt operation.
-     * @throws XMLEncryptionException
-     */
-    private Document decryptElementContent(Element element) throws XMLEncryptionException {
-        Element e =
-            (Element) element.getElementsByTagNameNS(
-                EncryptionConstants.EncryptionSpecNS,
-                EncryptionConstants._TAG_ENCRYPTEDDATA
-            ).item(0);
-
-        if (null == e) {
-            throw new XMLEncryptionException("No EncryptedData child element.");
-        }
-
-        return decryptElement(e);
-    }
-
-    /**
-     * Decrypt an EncryptedData element to a byte array.
-     *
-     * When passed in an EncryptedData node, returns the decryption
-     * as a byte array.
-     *
-     * Does not modify the source document.
-     * @param element
-     * @return the bytes resulting from the decryption
-     * @throws XMLEncryptionException
-     */
-    public byte[] decryptToByteArray(Element element) throws XMLEncryptionException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Decrypting to ByteArray...");
-        }
-
-        if (cipherMode != DECRYPT_MODE) {
-            log.log(java.util.logging.Level.SEVERE, "XMLCipher unexpectedly not in DECRYPT_MODE...");
-        }
-
-        EncryptedData encryptedData = factory.newEncryptedData(element);
-
-        if (key == null) {
-            KeyInfo ki = encryptedData.getKeyInfo();
-            if (ki != null) {
-                try {
-                    // Add an EncryptedKey resolver
-                    String encMethodAlgorithm = encryptedData.getEncryptionMethod().getAlgorithm();
-                    EncryptedKeyResolver resolver = new EncryptedKeyResolver(encMethodAlgorithm, kek);
-                    if (internalKeyResolvers != null) {
-                        int size = internalKeyResolvers.size();
-                        for (int i = 0; i < size; i++) {
-                            resolver.registerInternalKeyResolver(internalKeyResolvers.get(i));
-                        }
-                    }
-                    ki.registerInternalKeyResolver(resolver);
-                    ki.setSecureValidation(secureValidation);
-                    key = ki.getSecretKey();
-                } catch (KeyResolverException kre) {
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, kre.getMessage(), kre);
-                    }
-                }
-            }
-
-            if (key == null) {
-                log.log(java.util.logging.Level.SEVERE,
-                    "XMLCipher::decryptElement called without a key and unable to resolve"
-                );
-                throw new XMLEncryptionException("encryption.nokey");
-            }
-        }
-
-        // Obtain the encrypted octets
-        XMLCipherInput cipherInput = new XMLCipherInput(encryptedData);
-        cipherInput.setSecureValidation(secureValidation);
-        byte[] encryptedBytes = cipherInput.getBytes();
-
-        // Now create the working cipher
-        String jceAlgorithm =
-            JCEMapper.translateURItoJCEID(encryptedData.getEncryptionMethod().getAlgorithm());
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "JCE Algorithm = " + jceAlgorithm);
-        }
-
-        Cipher c;
-        try {
-            if (requestedJCEProvider == null) {
-                c = Cipher.getInstance(jceAlgorithm);
-            } else {
-                c = Cipher.getInstance(jceAlgorithm, requestedJCEProvider);
-            }
-        } catch (NoSuchAlgorithmException nsae) {
-            throw new XMLEncryptionException("empty", nsae);
-        } catch (NoSuchProviderException nspre) {
-            throw new XMLEncryptionException("empty", nspre);
-        } catch (NoSuchPaddingException nspae) {
-            throw new XMLEncryptionException("empty", nspae);
-        }
-
-        // Calculate the IV length and copy out
-
-        // For now, we only work with Block ciphers, so this will work.
-        // This should probably be put into the JCE mapper.
-
-        int ivLen = c.getBlockSize();
-        String alg = encryptedData.getEncryptionMethod().getAlgorithm();
-        if (AES_128_GCM.equals(alg) || AES_192_GCM.equals(alg) || AES_256_GCM.equals(alg)) {
-            ivLen = 12;
-        }
-        byte[] ivBytes = new byte[ivLen];
-
-        // You may be able to pass the entire piece in to IvParameterSpec
-        // and it will only take the first x bytes, but no way to be certain
-        // that this will work for every JCE provider, so lets copy the
-        // necessary bytes into a dedicated array.
-
-        System.arraycopy(encryptedBytes, 0, ivBytes, 0, ivLen);
-        IvParameterSpec iv = new IvParameterSpec(ivBytes);
-
-        try {
-            c.init(cipherMode, key, iv);
-        } catch (InvalidKeyException ike) {
-            throw new XMLEncryptionException("empty", ike);
-        } catch (InvalidAlgorithmParameterException iape) {
-            throw new XMLEncryptionException("empty", iape);
-        }
-
-        try {
-            return c.doFinal(encryptedBytes, ivLen, encryptedBytes.length - ivLen);
-        } catch (IllegalBlockSizeException ibse) {
-            throw new XMLEncryptionException("empty", ibse);
-        } catch (BadPaddingException bpe) {
-            throw new XMLEncryptionException("empty", bpe);
-        }
-    }
-
-    /*
-     * Expose the interface for creating XML Encryption objects
-     */
-
-    /**
-     * Creates an <code>EncryptedData</code> <code>Element</code>.
-     *
-     * The newEncryptedData and newEncryptedKey methods create fairly complete
-     * elements that are immediately useable.  All the other create* methods
-     * return bare elements that still need to be built upon.
-     *<p>
-     * An EncryptionMethod will still need to be added however
-     *
-     * @param type Either REFERENCE_TYPE or VALUE_TYPE - defines what kind of
-     * CipherData this EncryptedData will contain.
-     * @param value the Base 64 encoded, encrypted text to wrap in the
-     *   <code>EncryptedData</code> or the URI to set in the CipherReference
-     * (usage will depend on the <code>type</code>
-     * @return the <code>EncryptedData</code> <code>Element</code>.
-     *
-     * <!--
-     * <EncryptedData Id[OPT] Type[OPT] MimeType[OPT] Encoding[OPT]>
-     *     <EncryptionMethod/>[OPT]
-     *     <ds:KeyInfo>[OPT]
-     *         <EncryptedKey/>[OPT]
-     *         <AgreementMethod/>[OPT]
-     *         <ds:KeyName/>[OPT]
-     *         <ds:RetrievalMethod/>[OPT]
-     *         <ds:[MUL]/>[OPT]
-     *     </ds:KeyInfo>
-     *     <CipherData>[MAN]
-     *         <CipherValue/> XOR <CipherReference/>
-     *     </CipherData>
-     *     <EncryptionProperties/>[OPT]
-     * </EncryptedData>
-     * -->
-     * @throws XMLEncryptionException
-     */
-    public EncryptedData createEncryptedData(int type, String value) throws XMLEncryptionException {
-        EncryptedData result = null;
-        CipherData data = null;
-
-        switch (type) {
-        case CipherData.REFERENCE_TYPE:
-            CipherReference cipherReference = factory.newCipherReference(value);
-            data = factory.newCipherData(type);
-            data.setCipherReference(cipherReference);
-            result = factory.newEncryptedData(data);
-            break;
-        case CipherData.VALUE_TYPE:
-            CipherValue cipherValue = factory.newCipherValue(value);
-            data = factory.newCipherData(type);
-            data.setCipherValue(cipherValue);
-            result = factory.newEncryptedData(data);
-        }
-
-        return result;
-    }
-
-    /**
-     * Creates an <code>EncryptedKey</code> <code>Element</code>.
-     *
-     * The newEncryptedData and newEncryptedKey methods create fairly complete
-     * elements that are immediately useable.  All the other create* methods
-     * return bare elements that still need to be built upon.
-     *<p>
-     * An EncryptionMethod will still need to be added however
-     *
-     * @param type Either REFERENCE_TYPE or VALUE_TYPE - defines what kind of
-     * CipherData this EncryptedData will contain.
-     * @param value the Base 64 encoded, encrypted text to wrap in the
-     *   <code>EncryptedKey</code> or the URI to set in the CipherReference
-     * (usage will depend on the <code>type</code>
-     * @return the <code>EncryptedKey</code> <code>Element</code>.
-     *
-     * <!--
-     * <EncryptedKey Id[OPT] Type[OPT] MimeType[OPT] Encoding[OPT]>
-     *     <EncryptionMethod/>[OPT]
-     *     <ds:KeyInfo>[OPT]
-     *         <EncryptedKey/>[OPT]
-     *         <AgreementMethod/>[OPT]
-     *         <ds:KeyName/>[OPT]
-     *         <ds:RetrievalMethod/>[OPT]
-     *         <ds:[MUL]/>[OPT]
-     *     </ds:KeyInfo>
-     *     <CipherData>[MAN]
-     *         <CipherValue/> XOR <CipherReference/>
-     *     </CipherData>
-     *     <EncryptionProperties/>[OPT]
-     * </EncryptedData>
-     * -->
-     * @throws XMLEncryptionException
-     */
-    public EncryptedKey createEncryptedKey(int type, String value) throws XMLEncryptionException {
-        EncryptedKey result = null;
-        CipherData data = null;
-
-        switch (type) {
-        case CipherData.REFERENCE_TYPE:
-            CipherReference cipherReference = factory.newCipherReference(value);
-            data = factory.newCipherData(type);
-            data.setCipherReference(cipherReference);
-            result = factory.newEncryptedKey(data);
-            break;
-        case CipherData.VALUE_TYPE:
-            CipherValue cipherValue = factory.newCipherValue(value);
-            data = factory.newCipherData(type);
-            data.setCipherValue(cipherValue);
-            result = factory.newEncryptedKey(data);
-        }
-
-        return result;
-    }
-
-    /**
-     * Create an AgreementMethod object
-     *
-     * @param algorithm Algorithm of the agreement method
-     * @return a new <code>AgreementMethod</code>
-     */
-    public AgreementMethod createAgreementMethod(String algorithm) {
-        return factory.newAgreementMethod(algorithm);
-    }
-
-    /**
-     * Create a CipherData object
-     *
-     * @param type Type of this CipherData (either VALUE_TUPE or
-     * REFERENCE_TYPE)
-     * @return a new <code>CipherData</code>
-     */
-    public CipherData createCipherData(int type) {
-        return factory.newCipherData(type);
-    }
-
-    /**
-     * Create a CipherReference object
-     *
-     * @param uri The URI that the reference will refer
-     * @return a new <code>CipherReference</code>
-     */
-    public CipherReference createCipherReference(String uri) {
-        return factory.newCipherReference(uri);
-    }
-
-    /**
-     * Create a CipherValue element
-     *
-     * @param value The value to set the ciphertext to
-     * @return a new <code>CipherValue</code>
-     */
-    public CipherValue createCipherValue(String value) {
-        return factory.newCipherValue(value);
-    }
-
-    /**
-     * Create an EncryptionMethod object
-     *
-     * @param algorithm Algorithm for the encryption
-     * @return a new <code>EncryptionMethod</code>
-     */
-    public EncryptionMethod createEncryptionMethod(String algorithm) {
-        return factory.newEncryptionMethod(algorithm);
-    }
-
-    /**
-     * Create an EncryptionProperties element
-     * @return a new <code>EncryptionProperties</code>
-     */
-    public EncryptionProperties createEncryptionProperties() {
-        return factory.newEncryptionProperties();
-    }
-
-    /**
-     * Create a new EncryptionProperty element
-     * @return a new <code>EncryptionProperty</code>
-     */
-    public EncryptionProperty createEncryptionProperty() {
-        return factory.newEncryptionProperty();
-    }
-
-    /**
-     * Create a new ReferenceList object
-     * @param type ReferenceList.DATA_REFERENCE or ReferenceList.KEY_REFERENCE
-     * @return a new <code>ReferenceList</code>
-     */
-    public ReferenceList createReferenceList(int type) {
-        return factory.newReferenceList(type);
-    }
-
-    /**
-     * Create a new Transforms object
-     * <p>
-     * <b>Note</b>: A context document <i>must</i> have been set
-     * elsewhere (possibly via a call to doFinal).  If not, use the
-     * createTransforms(Document) method.
-     * @return a new <code>Transforms</code>
-     */
-    public Transforms createTransforms() {
-        return factory.newTransforms();
-    }
-
-    /**
-     * Create a new Transforms object
-     *
-     * Because the handling of Transforms is currently done in the signature
-     * code, the creation of a Transforms object <b>requires</b> a
-     * context document.
-     *
-     * @param doc Document that will own the created Transforms node
-     * @return a new <code>Transforms</code>
-     */
-    public Transforms createTransforms(Document doc) {
-        return factory.newTransforms(doc);
-    }
-
-    /**
-     *
-     * @author Axl Mattheus
-     */
-    private class Factory {
-        /**
-         * @param algorithm
-         * @return a new AgreementMethod
-         */
-        AgreementMethod newAgreementMethod(String algorithm)  {
-            return new AgreementMethodImpl(algorithm);
-        }
-
-        /**
-         * @param type
-         * @return a new CipherData
-         *
-         */
-        CipherData newCipherData(int type) {
-            return new CipherDataImpl(type);
-        }
-
-        /**
-         * @param uri
-         * @return a new CipherReference
-         */
-        CipherReference newCipherReference(String uri)  {
-            return new CipherReferenceImpl(uri);
-        }
-
-        /**
-         * @param value
-         * @return a new CipherValue
-         */
-        CipherValue newCipherValue(String value) {
-            return new CipherValueImpl(value);
-        }
-
-        /*
-        CipherValue newCipherValue(byte[] value) {
-            return new CipherValueImpl(value);
-        }
-         */
-
-        /**
-         * @param data
-         * @return a new EncryptedData
-         */
-        EncryptedData newEncryptedData(CipherData data) {
-            return new EncryptedDataImpl(data);
-        }
-
-        /**
-         * @param data
-         * @return a new EncryptedKey
-         */
-        EncryptedKey newEncryptedKey(CipherData data) {
-            return new EncryptedKeyImpl(data);
-        }
-
-        /**
-         * @param algorithm
-         * @return a new EncryptionMethod
-         */
-        EncryptionMethod newEncryptionMethod(String algorithm) {
-            return new EncryptionMethodImpl(algorithm);
-        }
-
-        /**
-         * @return a new EncryptionProperties
-         */
-        EncryptionProperties newEncryptionProperties() {
-            return new EncryptionPropertiesImpl();
-        }
-
-        /**
-         * @return a new EncryptionProperty
-         */
-        EncryptionProperty newEncryptionProperty() {
-            return new EncryptionPropertyImpl();
-        }
-
-        /**
-         * @param type ReferenceList.DATA_REFERENCE or ReferenceList.KEY_REFERENCE
-         * @return a new ReferenceList
-         */
-        ReferenceList newReferenceList(int type) {
-            return new ReferenceListImpl(type);
-        }
-
-        /**
-         * @return a new Transforms
-         */
-        Transforms newTransforms() {
-            return new TransformsImpl();
-        }
-
-        /**
-         * @param doc
-         * @return a new Transforms
-         */
-        Transforms newTransforms(Document doc) {
-            return new TransformsImpl(doc);
-        }
-
-        /**
-         * @param element
-         * @return a new CipherData
-         * @throws XMLEncryptionException
-         */
-        CipherData newCipherData(Element element) throws XMLEncryptionException {
-            if (null == element) {
-                throw new NullPointerException("element is null");
-            }
-
-            int type = 0;
-            Element e = null;
-            if (element.getElementsByTagNameNS(
-                EncryptionConstants.EncryptionSpecNS,
-                EncryptionConstants._TAG_CIPHERVALUE).getLength() > 0
-            ) {
-                type = CipherData.VALUE_TYPE;
-                e = (Element) element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS,
-                    EncryptionConstants._TAG_CIPHERVALUE).item(0);
-            } else if (element.getElementsByTagNameNS(
-                EncryptionConstants.EncryptionSpecNS,
-                EncryptionConstants._TAG_CIPHERREFERENCE).getLength() > 0) {
-                type = CipherData.REFERENCE_TYPE;
-                e = (Element) element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS,
-                    EncryptionConstants._TAG_CIPHERREFERENCE).item(0);
-            }
-
-            CipherData result = newCipherData(type);
-            if (type == CipherData.VALUE_TYPE) {
-                result.setCipherValue(newCipherValue(e));
-            } else if (type == CipherData.REFERENCE_TYPE) {
-                result.setCipherReference(newCipherReference(e));
-            }
-
-            return result;
-        }
-
-        /**
-         * @param element
-         * @return a new CipherReference
-         * @throws XMLEncryptionException
-         *
-         */
-        CipherReference newCipherReference(Element element) throws XMLEncryptionException {
-
-            Attr uriAttr =
-                element.getAttributeNodeNS(null, EncryptionConstants._ATT_URI);
-            CipherReference result = new CipherReferenceImpl(uriAttr);
-
-            // Find any Transforms
-            NodeList transformsElements =
-                element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_TRANSFORMS);
-            Element transformsElement = (Element) transformsElements.item(0);
-
-            if (transformsElement != null) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Creating a DSIG based Transforms element");
-                }
-                try {
-                    result.setTransforms(new TransformsImpl(transformsElement));
-                } catch (XMLSignatureException xse) {
-                    throw new XMLEncryptionException("empty", xse);
-                } catch (InvalidTransformException ite) {
-                    throw new XMLEncryptionException("empty", ite);
-                } catch (XMLSecurityException xse) {
-                    throw new XMLEncryptionException("empty", xse);
-                }
-            }
-
-            return result;
-        }
-
-        /**
-         * @param element
-         * @return a new CipherValue
-         */
-        CipherValue newCipherValue(Element element) {
-            String value = XMLUtils.getFullTextChildrenFromElement(element);
-
-            return newCipherValue(value);
-        }
-
-        /**
-         * @param element
-         * @return a new EncryptedData
-         * @throws XMLEncryptionException
-         *
-         */
-        EncryptedData newEncryptedData(Element element) throws XMLEncryptionException {
-            EncryptedData result = null;
-
-            NodeList dataElements =
-                element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_CIPHERDATA);
-
-            // Need to get the last CipherData found, as earlier ones will
-            // be for elements in the KeyInfo lists
-
-            Element dataElement =
-                (Element) dataElements.item(dataElements.getLength() - 1);
-
-            CipherData data = newCipherData(dataElement);
-
-            result = newEncryptedData(data);
-
-            result.setId(element.getAttributeNS(null, EncryptionConstants._ATT_ID));
-            result.setType(element.getAttributeNS(null, EncryptionConstants._ATT_TYPE));
-            result.setMimeType(element.getAttributeNS(null, EncryptionConstants._ATT_MIMETYPE));
-            result.setEncoding( element.getAttributeNS(null, Constants._ATT_ENCODING));
-
-            Element encryptionMethodElement =
-                (Element) element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS,
-                    EncryptionConstants._TAG_ENCRYPTIONMETHOD).item(0);
-            if (null != encryptionMethodElement) {
-                result.setEncryptionMethod(newEncryptionMethod(encryptionMethodElement));
-            }
-
-            // BFL 16/7/03 - simple implementation
-            // TODO: Work out how to handle relative URI
-
-            Element keyInfoElement =
-                (Element) element.getElementsByTagNameNS(
-                    Constants.SignatureSpecNS, Constants._TAG_KEYINFO).item(0);
-            if (null != keyInfoElement) {
-                KeyInfo ki = newKeyInfo(keyInfoElement);
-                result.setKeyInfo(ki);
-            }
-
-            // TODO: Implement
-            Element encryptionPropertiesElement =
-                (Element) element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS,
-                    EncryptionConstants._TAG_ENCRYPTIONPROPERTIES).item(0);
-            if (null != encryptionPropertiesElement) {
-                result.setEncryptionProperties(
-                    newEncryptionProperties(encryptionPropertiesElement)
-                );
-            }
-
-            return result;
-        }
-
-        /**
-         * @param element
-         * @return a new EncryptedKey
-         * @throws XMLEncryptionException
-         */
-        EncryptedKey newEncryptedKey(Element element) throws XMLEncryptionException {
-            EncryptedKey result = null;
-            NodeList dataElements =
-                element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_CIPHERDATA);
-            Element dataElement =
-                (Element) dataElements.item(dataElements.getLength() - 1);
-
-            CipherData data = newCipherData(dataElement);
-            result = newEncryptedKey(data);
-
-            result.setId(element.getAttributeNS(null, EncryptionConstants._ATT_ID));
-            result.setType(element.getAttributeNS(null, EncryptionConstants._ATT_TYPE));
-            result.setMimeType(element.getAttributeNS(null, EncryptionConstants._ATT_MIMETYPE));
-            result.setEncoding(element.getAttributeNS(null, Constants._ATT_ENCODING));
-            result.setRecipient(element.getAttributeNS(null, EncryptionConstants._ATT_RECIPIENT));
-
-            Element encryptionMethodElement =
-                (Element) element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS,
-                    EncryptionConstants._TAG_ENCRYPTIONMETHOD).item(0);
-            if (null != encryptionMethodElement) {
-                result.setEncryptionMethod(newEncryptionMethod(encryptionMethodElement));
-            }
-
-            Element keyInfoElement =
-                (Element) element.getElementsByTagNameNS(
-                    Constants.SignatureSpecNS, Constants._TAG_KEYINFO).item(0);
-            if (null != keyInfoElement) {
-                KeyInfo ki = newKeyInfo(keyInfoElement);
-                result.setKeyInfo(ki);
-            }
-
-            // TODO: Implement
-            Element encryptionPropertiesElement =
-                (Element) element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS,
-                    EncryptionConstants._TAG_ENCRYPTIONPROPERTIES).item(0);
-            if (null != encryptionPropertiesElement) {
-                result.setEncryptionProperties(
-                    newEncryptionProperties(encryptionPropertiesElement)
-                );
-            }
-
-            Element referenceListElement =
-                (Element) element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS,
-                    EncryptionConstants._TAG_REFERENCELIST).item(0);
-            if (null != referenceListElement) {
-                result.setReferenceList(newReferenceList(referenceListElement));
-            }
-
-            Element carriedNameElement =
-                (Element) element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS,
-                    EncryptionConstants._TAG_CARRIEDKEYNAME).item(0);
-            if (null != carriedNameElement) {
-                result.setCarriedName(carriedNameElement.getFirstChild().getNodeValue());
-            }
-
-            return result;
-        }
-
-        /**
-         * @param element
-         * @return a new KeyInfo
-         * @throws XMLEncryptionException
-         */
-        KeyInfo newKeyInfo(Element element) throws XMLEncryptionException {
-            try {
-                KeyInfo ki = new KeyInfo(element, null);
-                ki.setSecureValidation(secureValidation);
-                if (internalKeyResolvers != null) {
-                    int size = internalKeyResolvers.size();
-                    for (int i = 0; i < size; i++) {
-                        ki.registerInternalKeyResolver(internalKeyResolvers.get(i));
-                    }
-                }
-                return ki;
-            } catch (XMLSecurityException xse) {
-                throw new XMLEncryptionException("Error loading Key Info", xse);
-            }
-        }
-
-        /**
-         * @param element
-         * @return a new EncryptionMethod
-         */
-        EncryptionMethod newEncryptionMethod(Element element) {
-            String encAlgorithm = element.getAttributeNS(null, EncryptionConstants._ATT_ALGORITHM);
-            EncryptionMethod result = newEncryptionMethod(encAlgorithm);
-
-            Element keySizeElement =
-                (Element) element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS,
-                    EncryptionConstants._TAG_KEYSIZE).item(0);
-            if (null != keySizeElement) {
-                result.setKeySize(
-                    Integer.valueOf(
-                        keySizeElement.getFirstChild().getNodeValue()).intValue());
-            }
-
-            Element oaepParamsElement =
-                (Element) element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS,
-                    EncryptionConstants._TAG_OAEPPARAMS).item(0);
-            if (null != oaepParamsElement) {
-                try {
-                    String oaepParams = oaepParamsElement.getFirstChild().getNodeValue();
-                    result.setOAEPparams(Base64.decode(oaepParams.getBytes("UTF-8")));
-                } catch(UnsupportedEncodingException e) {
-                    throw new RuntimeException("UTF-8 not supported", e);
-                } catch (Base64DecodingException e) {
-                    throw new RuntimeException("BASE-64 decoding error", e);
-                }
-            }
-
-            Element digestElement =
-                (Element) element.getElementsByTagNameNS(
-                    Constants.SignatureSpecNS, Constants._TAG_DIGESTMETHOD).item(0);
-            if (digestElement != null) {
-                String digestAlgorithm = digestElement.getAttributeNS(null, "Algorithm");
-                result.setDigestAlgorithm(digestAlgorithm);
-            }
-
-            Element mgfElement =
-                (Element) element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpec11NS, EncryptionConstants._TAG_MGF).item(0);
-            if (mgfElement != null && !XMLCipher.RSA_OAEP.equals(algorithm)) {
-                String mgfAlgorithm = mgfElement.getAttributeNS(null, "Algorithm");
-                result.setMGFAlgorithm(mgfAlgorithm);
-            }
-
-            // TODO: Make this mess work
-            // <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
-
-            return result;
-        }
-
-        /**
-         * @param element
-         * @return a new EncryptionProperties
-         */
-        EncryptionProperties newEncryptionProperties(Element element) {
-            EncryptionProperties result = newEncryptionProperties();
-
-            result.setId(element.getAttributeNS(null, EncryptionConstants._ATT_ID));
-
-            NodeList encryptionPropertyList =
-                element.getElementsByTagNameNS(
-                    EncryptionConstants.EncryptionSpecNS,
-                    EncryptionConstants._TAG_ENCRYPTIONPROPERTY);
-            for (int i = 0; i < encryptionPropertyList.getLength(); i++) {
-                Node n = encryptionPropertyList.item(i);
-                if (null != n) {
-                    result.addEncryptionProperty(newEncryptionProperty((Element) n));
-                }
-            }
-
-            return result;
-        }
-
-        /**
-         * @param element
-         * @return a new EncryptionProperty
-         */
-        EncryptionProperty newEncryptionProperty(Element element) {
-            EncryptionProperty result = newEncryptionProperty();
-
-            result.setTarget(element.getAttributeNS(null, EncryptionConstants._ATT_TARGET));
-            result.setId(element.getAttributeNS(null, EncryptionConstants._ATT_ID));
-            // TODO: Make this lot work...
-            // <anyAttribute namespace="http://www.w3.org/XML/1998/namespace"/>
-
-            // TODO: Make this work...
-            // <any namespace='##other' processContents='lax'/>
-
-            return result;
-        }
-
-        /**
-         * @param element
-         * @return a new ReferenceList
-         */
-        ReferenceList newReferenceList(Element element) {
-            int type = 0;
-            if (null != element.getElementsByTagNameNS(
-                EncryptionConstants.EncryptionSpecNS,
-                EncryptionConstants._TAG_DATAREFERENCE).item(0)) {
-                type = ReferenceList.DATA_REFERENCE;
-            } else if (null != element.getElementsByTagNameNS(
-                EncryptionConstants.EncryptionSpecNS,
-                EncryptionConstants._TAG_KEYREFERENCE).item(0)) {
-                type = ReferenceList.KEY_REFERENCE;
-            }
-
-            ReferenceList result = new ReferenceListImpl(type);
-            NodeList list = null;
-            switch (type) {
-            case ReferenceList.DATA_REFERENCE:
-                list =
-                    element.getElementsByTagNameNS(
-                        EncryptionConstants.EncryptionSpecNS,
-                        EncryptionConstants._TAG_DATAREFERENCE);
-                for (int i = 0; i < list.getLength() ; i++) {
-                    String uri = ((Element) list.item(i)).getAttribute("URI");
-                    result.add(result.newDataReference(uri));
-                }
-                break;
-            case ReferenceList.KEY_REFERENCE:
-                list =
-                    element.getElementsByTagNameNS(
-                        EncryptionConstants.EncryptionSpecNS,
-                        EncryptionConstants._TAG_KEYREFERENCE);
-                for (int i = 0; i < list.getLength() ; i++) {
-                    String uri = ((Element) list.item(i)).getAttribute("URI");
-                    result.add(result.newKeyReference(uri));
-                }
-            }
-
-            return result;
-        }
-
-        /**
-         * @param encryptedData
-         * @return the XML Element form of that EncryptedData
-         */
-        Element toElement(EncryptedData encryptedData) {
-            return ((EncryptedDataImpl) encryptedData).toElement();
-        }
-
-        /**
-         * @param encryptedKey
-         * @return the XML Element form of that EncryptedKey
-         */
-        Element toElement(EncryptedKey encryptedKey) {
-            return ((EncryptedKeyImpl) encryptedKey).toElement();
-        }
-
-        /**
-         * @param referenceList
-         * @return the XML Element form of that ReferenceList
-         */
-        Element toElement(ReferenceList referenceList) {
-            return ((ReferenceListImpl) referenceList).toElement();
-        }
-
-        private class AgreementMethodImpl implements AgreementMethod {
-            private byte[] kaNonce = null;
-            private List<Element> agreementMethodInformation = null;
-            private KeyInfo originatorKeyInfo = null;
-            private KeyInfo recipientKeyInfo = null;
-            private String algorithmURI = null;
-
-            /**
-             * @param algorithm
-             */
-            public AgreementMethodImpl(String algorithm) {
-                agreementMethodInformation = new LinkedList<Element>();
-                URI tmpAlgorithm = null;
-                try {
-                    tmpAlgorithm = new URI(algorithm);
-                } catch (URISyntaxException ex) {
-                    throw (IllegalArgumentException)
-                    new IllegalArgumentException().initCause(ex);
-                }
-                algorithmURI = tmpAlgorithm.toString();
-            }
-
-            /** @inheritDoc */
-            public byte[] getKANonce() {
-                return kaNonce;
-            }
-
-            /** @inheritDoc */
-            public void setKANonce(byte[] kanonce) {
-                kaNonce = kanonce;
-            }
-
-            /** @inheritDoc */
-            public Iterator<Element> getAgreementMethodInformation() {
-                return agreementMethodInformation.iterator();
-            }
-
-            /** @inheritDoc */
-            public void addAgreementMethodInformation(Element info) {
-                agreementMethodInformation.add(info);
-            }
-
-            /** @inheritDoc */
-            public void revoveAgreementMethodInformation(Element info) {
-                agreementMethodInformation.remove(info);
-            }
-
-            /** @inheritDoc */
-            public KeyInfo getOriginatorKeyInfo() {
-                return originatorKeyInfo;
-            }
-
-            /** @inheritDoc */
-            public void setOriginatorKeyInfo(KeyInfo keyInfo) {
-                originatorKeyInfo = keyInfo;
-            }
-
-            /** @inheritDoc */
-            public KeyInfo getRecipientKeyInfo() {
-                return recipientKeyInfo;
-            }
-
-            /** @inheritDoc */
-            public void setRecipientKeyInfo(KeyInfo keyInfo) {
-                recipientKeyInfo = keyInfo;
-            }
-
-            /** @inheritDoc */
-            public String getAlgorithm() {
-                return algorithmURI;
-            }
-        }
-
-        private class CipherDataImpl implements CipherData {
-            private static final String valueMessage =
-                "Data type is reference type.";
-            private static final String referenceMessage =
-                "Data type is value type.";
-            private CipherValue cipherValue = null;
-            private CipherReference cipherReference = null;
-            private int cipherType = Integer.MIN_VALUE;
-
-            /**
-             * @param type
-             */
-            public CipherDataImpl(int type) {
-                cipherType = type;
-            }
-
-            /** @inheritDoc */
-            public CipherValue getCipherValue() {
-                return cipherValue;
-            }
-
-            /** @inheritDoc */
-            public void setCipherValue(CipherValue value) throws XMLEncryptionException {
-
-                if (cipherType == REFERENCE_TYPE) {
-                    throw new XMLEncryptionException(
-                        "empty", new UnsupportedOperationException(valueMessage)
-                    );
-                }
-
-                cipherValue = value;
-            }
-
-            /** @inheritDoc */
-            public CipherReference getCipherReference() {
-                return cipherReference;
-            }
-
-            /** @inheritDoc */
-            public void setCipherReference(CipherReference reference) throws
-            XMLEncryptionException {
-                if (cipherType == VALUE_TYPE) {
-                    throw new XMLEncryptionException(
-                        "empty", new UnsupportedOperationException(referenceMessage)
-                    );
-                }
-
-                cipherReference = reference;
-            }
-
-            /** @inheritDoc */
-            public int getDataType() {
-                return cipherType;
-            }
-
-            Element toElement() {
-                Element result =
-                    XMLUtils.createElementInEncryptionSpace(
-                        contextDocument, EncryptionConstants._TAG_CIPHERDATA
-                    );
-                if (cipherType == VALUE_TYPE) {
-                    result.appendChild(((CipherValueImpl) cipherValue).toElement());
-                } else if (cipherType == REFERENCE_TYPE) {
-                    result.appendChild(((CipherReferenceImpl) cipherReference).toElement());
-                }
-
-                return result;
-            }
-        }
-
-        private class CipherReferenceImpl implements CipherReference {
-            private String referenceURI = null;
-            private Transforms referenceTransforms = null;
-            private Attr referenceNode = null;
-
-            /**
-             * @param uri
-             */
-            public CipherReferenceImpl(String uri) {
-                /* Don't check validity of URI as may be "" */
-                referenceURI = uri;
-                referenceNode = null;
-            }
-
-            /**
-             * @param uri
-             */
-            public CipherReferenceImpl(Attr uri) {
-                referenceURI = uri.getNodeValue();
-                referenceNode = uri;
-            }
-
-            /** @inheritDoc */
-            public String getURI() {
-                return referenceURI;
-            }
-
-            /** @inheritDoc */
-            public Attr getURIAsAttr() {
-                return referenceNode;
-            }
-
-            /** @inheritDoc */
-            public Transforms getTransforms() {
-                return referenceTransforms;
-            }
-
-            /** @inheritDoc */
-            public void setTransforms(Transforms transforms) {
-                referenceTransforms = transforms;
-            }
-
-            Element toElement() {
-                Element result =
-                    XMLUtils.createElementInEncryptionSpace(
-                        contextDocument, EncryptionConstants._TAG_CIPHERREFERENCE
-                    );
-                result.setAttributeNS(null, EncryptionConstants._ATT_URI, referenceURI);
-                if (null != referenceTransforms) {
-                    result.appendChild(((TransformsImpl) referenceTransforms).toElement());
-                }
-
-                return result;
-            }
-        }
-
-        private class CipherValueImpl implements CipherValue {
-            private String cipherValue = null;
-
-            /**
-             * @param value
-             */
-            public CipherValueImpl(String value) {
-                cipherValue = value;
-            }
-
-            /** @inheritDoc */
-            public String getValue() {
-                return cipherValue;
-            }
-
-            /** @inheritDoc */
-            public void setValue(String value) {
-                cipherValue = value;
-            }
-
-            Element toElement() {
-                Element result =
-                    XMLUtils.createElementInEncryptionSpace(
-                        contextDocument, EncryptionConstants._TAG_CIPHERVALUE
-                    );
-                result.appendChild(contextDocument.createTextNode(cipherValue));
-
-                return result;
-            }
-        }
-
-        private class EncryptedDataImpl extends EncryptedTypeImpl implements EncryptedData {
-
-            /**
-             * @param data
-             */
-            public EncryptedDataImpl(CipherData data) {
-                super(data);
-            }
-
-            Element toElement() {
-                Element result =
-                    ElementProxy.createElementForFamily(
-                        contextDocument, EncryptionConstants.EncryptionSpecNS,
-                        EncryptionConstants._TAG_ENCRYPTEDDATA
-                    );
-
-                if (null != super.getId()) {
-                    result.setAttributeNS(null, EncryptionConstants._ATT_ID, super.getId());
-                }
-                if (null != super.getType()) {
-                    result.setAttributeNS(null, EncryptionConstants._ATT_TYPE, super.getType());
-                }
-                if (null != super.getMimeType()) {
-                    result.setAttributeNS(
-                        null, EncryptionConstants._ATT_MIMETYPE, super.getMimeType()
-                    );
-                }
-                if (null != super.getEncoding()) {
-                    result.setAttributeNS(
-                        null, EncryptionConstants._ATT_ENCODING, super.getEncoding()
-                    );
-                }
-                if (null != super.getEncryptionMethod()) {
-                    result.appendChild(
-                        ((EncryptionMethodImpl)super.getEncryptionMethod()).toElement()
-                    );
-                }
-                if (null != super.getKeyInfo()) {
-                    result.appendChild(super.getKeyInfo().getElement().cloneNode(true));
-                }
-
-                result.appendChild(((CipherDataImpl) super.getCipherData()).toElement());
-                if (null != super.getEncryptionProperties()) {
-                    result.appendChild(((EncryptionPropertiesImpl)
-                        super.getEncryptionProperties()).toElement());
-                }
-
-                return result;
-            }
-        }
-
-        private class EncryptedKeyImpl extends EncryptedTypeImpl implements EncryptedKey {
-            private String keyRecipient = null;
-            private ReferenceList referenceList = null;
-            private String carriedName = null;
-
-            /**
-             * @param data
-             */
-            public EncryptedKeyImpl(CipherData data) {
-                super(data);
-            }
-
-            /** @inheritDoc */
-            public String getRecipient() {
-                return keyRecipient;
-            }
-
-            /** @inheritDoc */
-            public void setRecipient(String recipient) {
-                keyRecipient = recipient;
-            }
-
-            /** @inheritDoc */
-            public ReferenceList getReferenceList() {
-                return referenceList;
-            }
-
-            /** @inheritDoc */
-            public void setReferenceList(ReferenceList list) {
-                referenceList = list;
-            }
-
-            /** @inheritDoc */
-            public String getCarriedName() {
-                return carriedName;
-            }
-
-            /** @inheritDoc */
-            public void setCarriedName(String name) {
-                carriedName = name;
-            }
-
-            Element toElement() {
-                Element result =
-                    ElementProxy.createElementForFamily(
-                        contextDocument, EncryptionConstants.EncryptionSpecNS,
-                        EncryptionConstants._TAG_ENCRYPTEDKEY
-                    );
-
-                if (null != super.getId()) {
-                    result.setAttributeNS(null, EncryptionConstants._ATT_ID, super.getId());
-                }
-                if (null != super.getType()) {
-                    result.setAttributeNS(null, EncryptionConstants._ATT_TYPE, super.getType());
-                }
-                if (null != super.getMimeType()) {
-                    result.setAttributeNS(
-                        null, EncryptionConstants._ATT_MIMETYPE, super.getMimeType()
-                    );
-                }
-                if (null != super.getEncoding()) {
-                    result.setAttributeNS(null, Constants._ATT_ENCODING, super.getEncoding());
-                }
-                if (null != getRecipient()) {
-                    result.setAttributeNS(
-                        null, EncryptionConstants._ATT_RECIPIENT, getRecipient()
-                    );
-                }
-                if (null != super.getEncryptionMethod()) {
-                    result.appendChild(((EncryptionMethodImpl)
-                        super.getEncryptionMethod()).toElement());
-                }
-                if (null != super.getKeyInfo()) {
-                    result.appendChild(super.getKeyInfo().getElement().cloneNode(true));
-                }
-                result.appendChild(((CipherDataImpl) super.getCipherData()).toElement());
-                if (null != super.getEncryptionProperties()) {
-                    result.appendChild(((EncryptionPropertiesImpl)
-                        super.getEncryptionProperties()).toElement());
-                }
-                if (referenceList != null && !referenceList.isEmpty()) {
-                    result.appendChild(((ReferenceListImpl)getReferenceList()).toElement());
-                }
-                if (null != carriedName) {
-                    Element element =
-                        ElementProxy.createElementForFamily(
-                            contextDocument,
-                            EncryptionConstants.EncryptionSpecNS,
-                            EncryptionConstants._TAG_CARRIEDKEYNAME
-                        );
-                    Node node = contextDocument.createTextNode(carriedName);
-                    element.appendChild(node);
-                    result.appendChild(element);
-                }
-
-                return result;
-            }
-        }
-
-        private abstract class EncryptedTypeImpl {
-            private String id =  null;
-            private String type = null;
-            private String mimeType = null;
-            private String encoding = null;
-            private EncryptionMethod encryptionMethod = null;
-            private KeyInfo keyInfo = null;
-            private CipherData cipherData = null;
-            private EncryptionProperties encryptionProperties = null;
-
-            /**
-             * Constructor.
-             * @param data
-             */
-            protected EncryptedTypeImpl(CipherData data) {
-                cipherData = data;
-            }
-
-            /**
-             *
-             * @return the Id
-             */
-            public String getId() {
-                return id;
-            }
-
-            /**
-             *
-             * @param id
-             */
-            public void setId(String id) {
-                this.id = id;
-            }
-
-            /**
-             *
-             * @return the type
-             */
-            public String getType() {
-                return type;
-            }
-
-            /**
-             *
-             * @param type
-             */
-            public void setType(String type) {
-                if (type == null || type.length() == 0) {
-                    this.type = null;
-                } else {
-                    URI tmpType = null;
-                    try {
-                        tmpType = new URI(type);
-                    } catch (URISyntaxException ex) {
-                        throw (IllegalArgumentException)
-                        new IllegalArgumentException().initCause(ex);
-                    }
-                    this.type = tmpType.toString();
-                }
-            }
-
-            /**
-             *
-             * @return the MimeType
-             */
-            public String getMimeType() {
-                return mimeType;
-            }
-            /**
-             *
-             * @param type
-             */
-            public void setMimeType(String type) {
-                mimeType = type;
-            }
-
-            /**
-             *
-             * @return the encoding
-             */
-            public String getEncoding() {
-                return encoding;
-            }
-
-            /**
-             *
-             * @param encoding
-             */
-            public void setEncoding(String encoding) {
-                if (encoding == null || encoding.length() == 0) {
-                    this.encoding = null;
-                } else {
-                    URI tmpEncoding = null;
-                    try {
-                        tmpEncoding = new URI(encoding);
-                    } catch (URISyntaxException ex) {
-                        throw (IllegalArgumentException)
-                        new IllegalArgumentException().initCause(ex);
-                    }
-                    this.encoding = tmpEncoding.toString();
-                }
-            }
-
-            /**
-             *
-             * @return the EncryptionMethod
-             */
-            public EncryptionMethod getEncryptionMethod() {
-                return encryptionMethod;
-            }
-
-            /**
-             *
-             * @param method
-             */
-            public void setEncryptionMethod(EncryptionMethod method) {
-                encryptionMethod = method;
-            }
-
-            /**
-             *
-             * @return the KeyInfo
-             */
-            public KeyInfo getKeyInfo() {
-                return keyInfo;
-            }
-
-            /**
-             *
-             * @param info
-             */
-            public void setKeyInfo(KeyInfo info) {
-                keyInfo = info;
-            }
-
-            /**
-             *
-             * @return the CipherData
-             */
-            public CipherData getCipherData() {
-                return cipherData;
-            }
-
-            /**
-             *
-             * @return the EncryptionProperties
-             */
-            public EncryptionProperties getEncryptionProperties() {
-                return encryptionProperties;
-            }
-
-            /**
-             *
-             * @param properties
-             */
-            public void setEncryptionProperties(EncryptionProperties properties) {
-                encryptionProperties = properties;
-            }
-        }
-
-        private class EncryptionMethodImpl implements EncryptionMethod {
-            private String algorithm = null;
-            private int keySize = Integer.MIN_VALUE;
-            private byte[] oaepParams = null;
-            private List<Element> encryptionMethodInformation = null;
-            private String digestAlgorithm = null;
-            private String mgfAlgorithm = null;
-
-            /**
-             * Constructor.
-             * @param algorithm
-             */
-            public EncryptionMethodImpl(String algorithm) {
-                URI tmpAlgorithm = null;
-                try {
-                    tmpAlgorithm = new URI(algorithm);
-                } catch (URISyntaxException ex) {
-                    throw (IllegalArgumentException)
-                    new IllegalArgumentException().initCause(ex);
-                }
-                this.algorithm = tmpAlgorithm.toString();
-                encryptionMethodInformation = new LinkedList<Element>();
-            }
-
-            /** @inheritDoc */
-            public String getAlgorithm() {
-                return algorithm;
-            }
-
-            /** @inheritDoc */
-            public int getKeySize() {
-                return keySize;
-            }
-
-            /** @inheritDoc */
-            public void setKeySize(int size) {
-                keySize = size;
-            }
-
-            /** @inheritDoc */
-            public byte[] getOAEPparams() {
-                return oaepParams;
-            }
-
-            /** @inheritDoc */
-            public void setOAEPparams(byte[] params) {
-                oaepParams = params;
-            }
-
-            /** @inheritDoc */
-            public void setDigestAlgorithm(String digestAlgorithm) {
-                this.digestAlgorithm = digestAlgorithm;
-            }
-
-            /** @inheritDoc */
-            public String getDigestAlgorithm() {
-                return digestAlgorithm;
-            }
-
-            /** @inheritDoc */
-            public void setMGFAlgorithm(String mgfAlgorithm) {
-                this.mgfAlgorithm = mgfAlgorithm;
-            }
-
-            /** @inheritDoc */
-            public String getMGFAlgorithm() {
-                return mgfAlgorithm;
-            }
-
-            /** @inheritDoc */
-            public Iterator<Element> getEncryptionMethodInformation() {
-                return encryptionMethodInformation.iterator();
-            }
-
-            /** @inheritDoc */
-            public void addEncryptionMethodInformation(Element info) {
-                encryptionMethodInformation.add(info);
-            }
-
-            /** @inheritDoc */
-            public void removeEncryptionMethodInformation(Element info) {
-                encryptionMethodInformation.remove(info);
-            }
-
-            Element toElement() {
-                Element result =
-                    XMLUtils.createElementInEncryptionSpace(
-                        contextDocument, EncryptionConstants._TAG_ENCRYPTIONMETHOD
-                    );
-                result.setAttributeNS(null, EncryptionConstants._ATT_ALGORITHM, algorithm);
-                if (keySize > 0) {
-                    result.appendChild(
-                        XMLUtils.createElementInEncryptionSpace(
-                            contextDocument, EncryptionConstants._TAG_KEYSIZE
-                    ).appendChild(contextDocument.createTextNode(String.valueOf(keySize))));
-                }
-                if (null != oaepParams) {
-                    Element oaepElement =
-                        XMLUtils.createElementInEncryptionSpace(
-                            contextDocument, EncryptionConstants._TAG_OAEPPARAMS
-                        );
-                    oaepElement.appendChild(contextDocument.createTextNode(Base64.encode(oaepParams)));
-                    result.appendChild(oaepElement);
-                }
-                if (digestAlgorithm != null) {
-                    Element digestElement =
-                        XMLUtils.createElementInSignatureSpace(contextDocument, Constants._TAG_DIGESTMETHOD);
-                    digestElement.setAttributeNS(null, "Algorithm", digestAlgorithm);
-                    result.appendChild(digestElement);
-                }
-                if (mgfAlgorithm != null) {
-                    Element mgfElement =
-                        XMLUtils.createElementInEncryption11Space(
-                            contextDocument, EncryptionConstants._TAG_MGF
-                        );
-                    mgfElement.setAttributeNS(null, "Algorithm", mgfAlgorithm);
-                    mgfElement.setAttributeNS(
-                        Constants.NamespaceSpecNS,
-                        "xmlns:" + ElementProxy.getDefaultPrefix(EncryptionConstants.EncryptionSpec11NS),
-                        EncryptionConstants.EncryptionSpec11NS
-                    );
-                    result.appendChild(mgfElement);
-                }
-                Iterator<Element> itr = encryptionMethodInformation.iterator();
-                while (itr.hasNext()) {
-                    result.appendChild(itr.next());
-                }
-
-                return result;
-            }
-        }
-
-        private class EncryptionPropertiesImpl implements EncryptionProperties {
-            private String id = null;
-            private List<EncryptionProperty> encryptionProperties = null;
-
-            /**
-             * Constructor.
-             */
-            public EncryptionPropertiesImpl() {
-                encryptionProperties = new LinkedList<EncryptionProperty>();
-            }
-
-            /** @inheritDoc */
-            public String getId() {
-                return id;
-            }
-
-            /** @inheritDoc */
-            public void setId(String id) {
-                this.id = id;
-            }
-
-            /** @inheritDoc */
-            public Iterator<EncryptionProperty> getEncryptionProperties() {
-                return encryptionProperties.iterator();
-            }
-
-            /** @inheritDoc */
-            public void addEncryptionProperty(EncryptionProperty property) {
-                encryptionProperties.add(property);
-            }
-
-            /** @inheritDoc */
-            public void removeEncryptionProperty(EncryptionProperty property) {
-                encryptionProperties.remove(property);
-            }
-
-            Element toElement() {
-                Element result =
-                    XMLUtils.createElementInEncryptionSpace(
-                        contextDocument, EncryptionConstants._TAG_ENCRYPTIONPROPERTIES
-                    );
-                if (null != id) {
-                    result.setAttributeNS(null, EncryptionConstants._ATT_ID, id);
-                }
-                Iterator<EncryptionProperty> itr = getEncryptionProperties();
-                while (itr.hasNext()) {
-                    result.appendChild(((EncryptionPropertyImpl)itr.next()).toElement());
-                }
-
-                return result;
-            }
-        }
-
-        private class EncryptionPropertyImpl implements EncryptionProperty {
-            private String target = null;
-            private String id = null;
-            private Map<String, String> attributeMap = new HashMap<String, String>();
-            private List<Element> encryptionInformation = null;
-
-            /**
-             * Constructor.
-             */
-            public EncryptionPropertyImpl() {
-                encryptionInformation = new LinkedList<Element>();
-            }
-
-            /** @inheritDoc */
-            public String getTarget() {
-                return target;
-            }
-
-            /** @inheritDoc */
-            public void setTarget(String target) {
-                if (target == null || target.length() == 0) {
-                    this.target = null;
-                } else if (target.startsWith("#")) {
-                    /*
-                     * This is a same document URI reference. Do not parse,
-                     * because it has no scheme.
-                     */
-                    this.target = target;
-                } else {
-                    URI tmpTarget = null;
-                    try {
-                        tmpTarget = new URI(target);
-                    } catch (URISyntaxException ex) {
-                        throw (IllegalArgumentException)
-                        new IllegalArgumentException().initCause(ex);
-                    }
-                    this.target = tmpTarget.toString();
-                }
-            }
-
-            /** @inheritDoc */
-            public String getId() {
-                return id;
-            }
-
-            /** @inheritDoc */
-            public void setId(String id) {
-                this.id = id;
-            }
-
-            /** @inheritDoc */
-            public String getAttribute(String attribute) {
-                return attributeMap.get(attribute);
-            }
-
-            /** @inheritDoc */
-            public void setAttribute(String attribute, String value) {
-                attributeMap.put(attribute, value);
-            }
-
-            /** @inheritDoc */
-            public Iterator<Element> getEncryptionInformation() {
-                return encryptionInformation.iterator();
-            }
-
-            /** @inheritDoc */
-            public void addEncryptionInformation(Element info) {
-                encryptionInformation.add(info);
-            }
-
-            /** @inheritDoc */
-            public void removeEncryptionInformation(Element info) {
-                encryptionInformation.remove(info);
-            }
-
-            Element toElement() {
-                Element result =
-                    XMLUtils.createElementInEncryptionSpace(
-                        contextDocument, EncryptionConstants._TAG_ENCRYPTIONPROPERTY
-                    );
-                if (null != target) {
-                    result.setAttributeNS(null, EncryptionConstants._ATT_TARGET, target);
-                }
-                if (null != id) {
-                    result.setAttributeNS(null, EncryptionConstants._ATT_ID, id);
-                }
-                // TODO: figure out the anyAttribyte stuff...
-                // TODO: figure out the any stuff...
-
-                return result;
-            }
-        }
-
-        private class TransformsImpl extends com.sun.org.apache.xml.internal.security.transforms.Transforms
-            implements Transforms {
-
-            /**
-             * Construct Transforms
-             */
-            public TransformsImpl() {
-                super(contextDocument);
-            }
-
-            /**
-             *
-             * @param doc
-             */
-            public TransformsImpl(Document doc) {
-                if (doc == null) {
-                    throw new RuntimeException("Document is null");
-                }
-
-                this.doc = doc;
-                this.constructionElement =
-                    createElementForFamilyLocal(
-                        this.doc, this.getBaseNamespace(), this.getBaseLocalName()
-                    );
-            }
-
-            /**
-             *
-             * @param element
-             * @throws XMLSignatureException
-             * @throws InvalidTransformException
-             * @throws XMLSecurityException
-             * @throws TransformationException
-             */
-            public TransformsImpl(Element element)
-                throws XMLSignatureException, InvalidTransformException,
-                    XMLSecurityException, TransformationException {
-                super(element, "");
-            }
-
-            /**
-             *
-             * @return the XML Element form of that Transforms
-             */
-            public Element toElement() {
-                if (doc == null) {
-                    doc = contextDocument;
-                }
-
-                return getElement();
-            }
-
-            /** @inheritDoc */
-            public com.sun.org.apache.xml.internal.security.transforms.Transforms getDSTransforms() {
-                return this;
-            }
-
-            // Over-ride the namespace
-            /** @inheritDoc */
-            public String getBaseNamespace() {
-                return EncryptionConstants.EncryptionSpecNS;
-            }
-        }
-
-        private class ReferenceListImpl implements ReferenceList {
-            private Class<?> sentry;
-            private List<Reference> references;
-
-            /**
-             * Constructor.
-             * @param type
-             */
-            public ReferenceListImpl(int type) {
-                if (type == ReferenceList.DATA_REFERENCE) {
-                    sentry = DataReference.class;
-                } else if (type == ReferenceList.KEY_REFERENCE) {
-                    sentry = KeyReference.class;
-                } else {
-                    throw new IllegalArgumentException();
-                }
-                references = new LinkedList<Reference>();
-            }
-
-            /** @inheritDoc */
-            public void add(Reference reference) {
-                if (!reference.getClass().equals(sentry)) {
-                    throw new IllegalArgumentException();
-                }
-                references.add(reference);
-            }
-
-            /** @inheritDoc */
-            public void remove(Reference reference) {
-                if (!reference.getClass().equals(sentry)) {
-                    throw new IllegalArgumentException();
-                }
-                references.remove(reference);
-            }
-
-            /** @inheritDoc */
-            public int size() {
-                return references.size();
-            }
-
-            /** @inheritDoc */
-            public boolean isEmpty() {
-                return references.isEmpty();
-            }
-
-            /** @inheritDoc */
-            public Iterator<Reference> getReferences() {
-                return references.iterator();
-            }
-
-            Element toElement() {
-                Element result =
-                    ElementProxy.createElementForFamily(
-                        contextDocument,
-                        EncryptionConstants.EncryptionSpecNS,
-                        EncryptionConstants._TAG_REFERENCELIST
-                    );
-                Iterator<Reference> eachReference = references.iterator();
-                while (eachReference.hasNext()) {
-                    Reference reference = eachReference.next();
-                    result.appendChild(((ReferenceImpl) reference).toElement());
-                }
-                return result;
-            }
-
-            /** @inheritDoc */
-            public Reference newDataReference(String uri) {
-                return new DataReference(uri);
-            }
-
-            /** @inheritDoc */
-            public Reference newKeyReference(String uri) {
-                return new KeyReference(uri);
-            }
-
-            /**
-             * <code>ReferenceImpl</code> is an implementation of
-             * <code>Reference</code>.
-             *
-             * @see Reference
-             */
-            private abstract class ReferenceImpl implements Reference {
-                private String uri;
-                private List<Element> referenceInformation;
-
-                ReferenceImpl(String uri) {
-                    this.uri = uri;
-                    referenceInformation = new LinkedList<Element>();
-                }
-
-                /** @inheritDoc */
-                public abstract String getType();
-
-                /** @inheritDoc */
-                public String getURI() {
-                    return uri;
-                }
-
-                /** @inheritDoc */
-                public Iterator<Element> getElementRetrievalInformation() {
-                    return referenceInformation.iterator();
-                }
-
-                /** @inheritDoc */
-                public void setURI(String uri) {
-                    this.uri = uri;
-                }
-
-                /** @inheritDoc */
-                public void removeElementRetrievalInformation(Element node) {
-                    referenceInformation.remove(node);
-                }
-
-                /** @inheritDoc */
-                public void addElementRetrievalInformation(Element node) {
-                    referenceInformation.add(node);
-                }
-
-                /**
-                 * @return the XML Element form of that Reference
-                 */
-                public Element toElement() {
-                    String tagName = getType();
-                    Element result =
-                        ElementProxy.createElementForFamily(
-                            contextDocument,
-                            EncryptionConstants.EncryptionSpecNS,
-                            tagName
-                        );
-                    result.setAttribute(EncryptionConstants._ATT_URI, uri);
-
-                    // TODO: Need to martial referenceInformation
-                    // Figure out how to make this work..
-                    // <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
-
-                    return result;
-                }
-            }
-
-            private class DataReference extends ReferenceImpl {
-
-                DataReference(String uri) {
-                    super(uri);
-                }
-
-                /** @inheritDoc */
-                public String getType() {
-                    return EncryptionConstants._TAG_DATAREFERENCE;
-                }
-            }
-
-            private class KeyReference extends ReferenceImpl {
-
-                KeyReference(String uri) {
-                    super(uri);
-                }
-
-                /** @inheritDoc */
-                public String getType() {
-                    return EncryptionConstants._TAG_KEYREFERENCE;
-                }
-            }
-        }
-    }
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipherInput.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +0,0 @@
-/*
- * 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.encryption;
-
-import java.io.IOException;
-
-import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
-import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver;
-import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException;
-import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
-import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
-import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
-import org.w3c.dom.Attr;
-import com.sun.org.apache.xml.internal.security.utils.Base64;
-
-/**
- * <code>XMLCipherInput</code> is used to wrap input passed into the
- * XMLCipher encryption operations.
- *
- * In decryption mode, it takes a <code>CipherData</code> object and allows
- * callers to dereference the CipherData into the encrypted bytes that it
- * actually represents.  This takes care of all base64 encoding etc.
- *
- * While primarily an internal class, this can be used by applications to
- * quickly and easily retrieve the encrypted bytes from an EncryptedType
- * object
- *
- * @author Berin Lautenbach
- */
-public class XMLCipherInput {
-
-    private static java.util.logging.Logger logger =
-        java.util.logging.Logger.getLogger(XMLCipherInput.class.getName());
-
-    /** The data we are working with */
-    private CipherData cipherData;
-
-    /** MODES */
-    private int mode;
-
-    private boolean secureValidation;
-
-    /**
-     * Constructor for processing encrypted octets
-     *
-     * @param data The <code>CipherData</code> object to read the bytes from
-     * @throws XMLEncryptionException {@link XMLEncryptionException}
-     */
-    public XMLCipherInput(CipherData data) throws XMLEncryptionException {
-        cipherData = data;
-        mode = XMLCipher.DECRYPT_MODE;
-        if (cipherData == null) {
-            throw new XMLEncryptionException("CipherData is null");
-        }
-    }
-
-    /**
-     * Constructor for processing encrypted octets
-     *
-     * @param input The <code>EncryptedType</code> object to read
-     * the bytes from.
-     * @throws XMLEncryptionException {@link XMLEncryptionException}
-     */
-    public XMLCipherInput(EncryptedType input) throws XMLEncryptionException {
-        cipherData = ((input == null) ? null : input.getCipherData());
-        mode = XMLCipher.DECRYPT_MODE;
-        if (cipherData == null) {
-            throw new XMLEncryptionException("CipherData is null");
-        }
-    }
-
-    /**
-     * Set whether secure validation is enabled or not. The default is false.
-     */
-    public void setSecureValidation(boolean secureValidation) {
-        this.secureValidation = secureValidation;
-    }
-
-    /**
-     * Dereferences the input and returns it as a single byte array.
-     *
-     * @throws XMLEncryptionException
-     * @return The decripted bytes.
-     */
-    public byte[] getBytes() throws XMLEncryptionException {
-        if (mode == XMLCipher.DECRYPT_MODE) {
-            return getDecryptBytes();
-        }
-        return null;
-    }
-
-    /**
-     * Internal method to get bytes in decryption mode
-     * @return the decrypted bytes
-     * @throws XMLEncryptionException
-     */
-    private byte[] getDecryptBytes() throws XMLEncryptionException {
-        String base64EncodedEncryptedOctets = null;
-
-        if (cipherData.getDataType() == CipherData.REFERENCE_TYPE) {
-            // Fun time!
-            if (logger.isLoggable(java.util.logging.Level.FINE)) {
-                logger.log(java.util.logging.Level.FINE, "Found a reference type CipherData");
-            }
-            CipherReference cr = cipherData.getCipherReference();
-
-            // Need to wrap the uri in an Attribute node so that we can
-            // Pass to the resource resolvers
-
-            Attr uriAttr = cr.getURIAsAttr();
-            XMLSignatureInput input = null;
-
-            try {
-                ResourceResolver resolver =
-                    ResourceResolver.getInstance(uriAttr, null, secureValidation);
-                input = resolver.resolve(uriAttr, null, secureValidation);
-            } catch (ResourceResolverException ex) {
-                throw new XMLEncryptionException("empty", ex);
-            }
-
-            if (input != null) {
-                if (logger.isLoggable(java.util.logging.Level.FINE)) {
-                    logger.log(java.util.logging.Level.FINE, "Managed to resolve URI \"" + cr.getURI() + "\"");
-                }
-            } else {
-                if (logger.isLoggable(java.util.logging.Level.FINE)) {
-                    logger.log(java.util.logging.Level.FINE, "Failed to resolve URI \"" + cr.getURI() + "\"");
-                }
-            }
-
-            // Lets see if there are any transforms
-            Transforms transforms = cr.getTransforms();
-            if (transforms != null) {
-                if (logger.isLoggable(java.util.logging.Level.FINE)) {
-                    logger.log(java.util.logging.Level.FINE, "Have transforms in cipher reference");
-                }
-                try {
-                    com.sun.org.apache.xml.internal.security.transforms.Transforms dsTransforms =
-                        transforms.getDSTransforms();
-                    dsTransforms.setSecureValidation(secureValidation);
-                    input = dsTransforms.performTransforms(input);
-                } catch (TransformationException ex) {
-                    throw new XMLEncryptionException("empty", ex);
-                }
-            }
-
-            try {
-                return input.getBytes();
-            } catch (IOException ex) {
-                throw new XMLEncryptionException("empty", ex);
-            } catch (CanonicalizationException ex) {
-                throw new XMLEncryptionException("empty", ex);
-            }
-
-            // retrieve the cipher text
-        } else if (cipherData.getDataType() == CipherData.VALUE_TYPE) {
-            base64EncodedEncryptedOctets = cipherData.getCipherValue().getValue();
-        } else {
-            throw new XMLEncryptionException("CipherData.getDataType() returned unexpected value");
-        }
-
-        if (logger.isLoggable(java.util.logging.Level.FINE)) {
-            logger.log(java.util.logging.Level.FINE, "Encrypted octets:\n" + base64EncodedEncryptedOctets);
-        }
-
-        try {
-            return Base64.decode(base64EncodedEncryptedOctets);
-        } catch (Base64DecodingException bde) {
-            throw new XMLEncryptionException("empty", bde);
-        }
-    }
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLCipherParameters.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * 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.encryption;
-
-/**
- * Constants
- */
-public interface XMLCipherParameters {
-
-    String AES_128 =
-        "http://www.w3.org/2001/04/xmlenc#aes128-cbc";
-
-    String AES_256 =
-        "http://www.w3.org/2001/04/xmlenc#aes256-cbc";
-
-    String AES_192 =
-        "http://www.w3.org/2001/04/xmlenc#aes192-cbc";
-
-    String RSA_1_5 =
-        "http://www.w3.org/2001/04/xmlenc#rsa-1_5";
-
-    String RSA_OAEP =
-        "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p";
-
-    String DIFFIE_HELLMAN =
-        "http://www.w3.org/2001/04/xmlenc#dh";
-
-    String TRIPLEDES_KEYWRAP =
-        "http://www.w3.org/2001/04/xmlenc#kw-tripledes";
-
-    String AES_128_KEYWRAP =
-        "http://www.w3.org/2001/04/xmlenc#kw-aes128";
-
-    String AES_256_KEYWRAP =
-        "http://www.w3.org/2001/04/xmlenc#kw-aes256";
-
-    String AES_192_KEYWRAP =
-        "http://www.w3.org/2001/04/xmlenc#kw-aes192";
-
-    String SHA1 =
-        "http://www.w3.org/2000/09/xmldsig#sha1";
-
-    String SHA256 =
-        "http://www.w3.org/2001/04/xmlenc#sha256";
-
-    String SHA512 =
-        "http://www.w3.org/2001/04/xmlenc#sha512";
-
-    String RIPEMD_160 =
-        "http://www.w3.org/2001/04/xmlenc#ripemd160";
-
-    String XML_DSIG =
-        "http://www.w3.org/2000/09/xmldsig#";
-
-    String N14C_XML =
-        "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
-
-    String N14C_XML_CMMNTS =
-        "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments";
-
-    String EXCL_XML_N14C =
-        "http://www.w3.org/2001/10/xml-exc-c14n#";
-
-    String EXCL_XML_N14C_CMMNTS =
-        "http://www.w3.org/2001/10/xml-exc-c14n#WithComments";
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/XMLEncryptionException.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * 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.encryption;
-
-import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
-
-/**
- *
- */
-public class XMLEncryptionException extends XMLSecurityException {
-    /**
-     *
-     */
-    private static final long serialVersionUID = 1L;
-
-    /**
-     *
-     *
-     */
-    public XMLEncryptionException() {
-        super();
-    }
-
-    /**
-     *
-     * @param msgID
-     */
-    public XMLEncryptionException(String msgID) {
-        super(msgID);
-    }
-
-    /**
-     *
-     * @param msgID
-     * @param exArgs
-     */
-    public XMLEncryptionException(String msgID, Object exArgs[]) {
-        super(msgID, exArgs);
-    }
-
-    /**
-     *
-     * @param msgID
-     * @param originalException
-     */
-    public XMLEncryptionException(String msgID, Exception originalException) {
-        super(msgID, originalException);
-
-    }
-
-    /**
-     *
-     * @param msgID
-     * @param exArgs
-     * @param originalException
-     */
-    public XMLEncryptionException(String msgID, Object exArgs[], Exception originalException) {
-        super(msgID, exArgs, originalException);
-    }
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/encryption/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <title></title>
-</head>
-<body>
-Provides classes for implementing XML Encryption applications. There are two
-main families of classes in this package. The first group of classes is an
-XML Schema to Java mapping of &nbsp;the complex types and elements of the
-XML Encryption Schema as outllined at <a
- href="http://www.w3.org/Encryption/2001/Drafts/xmlenc-core/">XML Encrtypyion
-Specification</a>. The second group of classes are used to perform encryption
-operations, and to manipulate the first group of classes. The most important
-classes in this second group is <code><a
- href="file://./com/sun/org/apache/xml/internal/security/encryption/XMLCipher.html">XMLCipher</a></code>,
-<code><a
- href="file://./com/sun/org/apache/xml/internal/security/encryption/XMLEncryptionFactory.html">XMLEncryptionFactory</a></code>
-and <code>XMLSerializer</code>. <code>XMLCipher</code> was designed to resemble
-<code>javax.crypto.Cipher</code>. The aforementioned classes were desinged
-with ease-of-use and configurability in mind. Becuase of this, the programmer
-may at times be exposed to lower level programming tasks. This library strives
-to be as simple as possible to use, but no simpler.<br>
-<br>
-</body>
-</html>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/exceptions/AlgorithmAlreadyRegisteredException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/exceptions/AlgorithmAlreadyRegisteredException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -58,24 +58,34 @@
     /**
      * Constructor AlgorithmAlreadyRegisteredException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public AlgorithmAlreadyRegisteredException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public AlgorithmAlreadyRegisteredException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor AlgorithmAlreadyRegisteredException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
     public AlgorithmAlreadyRegisteredException(
-        String msgID, Object exArgs[], Exception originalException
+        Exception originalException, String msgID, Object exArgs[]
     ) {
-        super(msgID, exArgs, originalException);
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public AlgorithmAlreadyRegisteredException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/exceptions/Base64DecodingException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/exceptions/Base64DecodingException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,7 +25,6 @@
 /**
  * This Exception is thrown if decoding of Base64 data fails.
  *
- * @author Christian Geuer-Pollmann
  */
 public class Base64DecodingException extends XMLSecurityException {
 
@@ -61,22 +60,32 @@
     /**
      * Constructor Base64DecodingException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public Base64DecodingException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public Base64DecodingException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor Base64DecodingException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
-    public Base64DecodingException(String msgID, Object exArgs[], Exception originalException) {
-        super(msgID, exArgs, originalException);
+    public Base64DecodingException(Exception originalException, String msgID, Object exArgs[]) {
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public Base64DecodingException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -22,18 +22,15 @@
  */
 package com.sun.org.apache.xml.internal.security.exceptions;
 
-import java.io.PrintStream;
-import java.io.PrintWriter;
 import java.text.MessageFormat;
 
-import com.sun.org.apache.xml.internal.security.utils.Constants;
 import com.sun.org.apache.xml.internal.security.utils.I18n;
 
 /**
  * The mother of all Exceptions in this bundle. It allows exceptions to have
  * their messages translated to the different locales.
  *
- * The <code>xmlsecurity_en.properties</code> file contains this line:
+ * The {@code xmlsecurity_en.properties} file contains this line:
  * <pre>
  * xml.WrongElement = Can't create a {0} from a {1} element
  * </pre>
@@ -47,7 +44,7 @@
  * }
  * </pre>
  *
- * Additionally, if another Exception has been caught, we can supply it, too>
+ * Additionally, if another Exception has been caught, we can supply it, too
  * <pre>
  * try {
  *    ...
@@ -59,7 +56,6 @@
  * </pre>
  *
  *
- * @author Christian Geuer-Pollmann
  */
 public class XMLSecurityException extends Exception {
 
@@ -98,7 +94,7 @@
      * @param msgID
      * @param exArgs
      */
-    public XMLSecurityException(String msgID, Object exArgs[]) {
+    public XMLSecurityException(String msgID, Object[] exArgs) {
 
         super(MessageFormat.format(I18n.getExceptionMessage(msgID), exArgs));
 
@@ -112,11 +108,7 @@
      */
     public XMLSecurityException(Exception originalException) {
 
-        super("Missing message ID to locate message string in resource bundle \""
-              + Constants.exceptionMessagesResourceBundleBase
-              + "\". Original Exception was a "
-              + originalException.getClass().getName() + " and message "
-              + originalException.getMessage(), originalException);
+        super(originalException.getMessage(), originalException);
     }
 
     /**
@@ -125,12 +117,17 @@
      * @param msgID
      * @param originalException
      */
-    public XMLSecurityException(String msgID, Exception originalException) {
+    public XMLSecurityException(Exception originalException, String msgID) {
         super(I18n.getExceptionMessage(msgID, originalException), originalException);
 
         this.msgID = msgID;
     }
 
+    @Deprecated
+    public XMLSecurityException(String msgID, Exception originalException) {
+        this(originalException, msgID);
+    }
+
     /**
      * Constructor XMLSecurityException
      *
@@ -138,12 +135,18 @@
      * @param exArgs
      * @param originalException
      */
-    public XMLSecurityException(String msgID, Object exArgs[], Exception originalException) {
+    public XMLSecurityException(Exception originalException, String msgID, Object[] exArgs) {
         super(MessageFormat.format(I18n.getExceptionMessage(msgID), exArgs), originalException);
 
         this.msgID = msgID;
     }
 
+    @Deprecated
+    public XMLSecurityException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
+    }
+
+
     /**
      * Method getMsgID
      *
@@ -156,7 +159,7 @@
         return msgID;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String toString() {
         String s = this.getClass().getName();
         String message = super.getLocalizedMessage();
@@ -185,24 +188,6 @@
     }
 
     /**
-     * Method printStackTrace
-     *
-     * @param printwriter
-     */
-    public void printStackTrace(PrintWriter printwriter) {
-        super.printStackTrace(printwriter);
-    }
-
-    /**
-     * Method printStackTrace
-     *
-     * @param printstream
-     */
-    public void printStackTrace(PrintStream printstream) {
-        super.printStackTrace(printstream);
-    }
-
-    /**
      * Method getOriginalException
      *
      * @return the original exception
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityRuntimeException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityRuntimeException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -22,8 +22,6 @@
  */
 package com.sun.org.apache.xml.internal.security.exceptions;
 
-import java.io.PrintStream;
-import java.io.PrintWriter;
 import java.text.MessageFormat;
 
 import com.sun.org.apache.xml.internal.security.utils.Constants;
@@ -33,7 +31,7 @@
  * The mother of all runtime Exceptions in this bundle. It allows exceptions to have
  * their messages translated to the different locales.
  *
- * The <code>xmlsecurity_en.properties</code> file contains this line:
+ * The {@code xmlsecurity_en.properties} file contains this line:
  * <pre>
  * xml.WrongElement = Can't create a {0} from a {1} element
  * </pre>
@@ -47,7 +45,7 @@
  * }
  * </pre>
  *
- * Additionally, if another Exception has been caught, we can supply it, too>
+ * Additionally, if another Exception has been caught, we can supply it, too
  * <pre>
  * try {
  *    ...
@@ -59,7 +57,6 @@
  * </pre>
  *
  *
- * @author Christian Geuer-Pollmann
  */
 public class XMLSecurityRuntimeException extends RuntimeException {
 
@@ -134,7 +131,7 @@
      * @param originalException
      */
     public XMLSecurityRuntimeException(String msgID, Object exArgs[], Exception originalException) {
-        super(MessageFormat.format(I18n.getExceptionMessage(msgID), exArgs));
+        super(MessageFormat.format(I18n.getExceptionMessage(msgID), exArgs), originalException);
 
         this.msgID = msgID;
     }
@@ -151,7 +148,7 @@
         return msgID;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String toString() {
         String s = this.getClass().getName();
         String message = super.getLocalizedMessage();
@@ -170,34 +167,6 @@
     }
 
     /**
-     * Method printStackTrace
-     *
-     */
-    public void printStackTrace() {
-        synchronized (System.err) {
-            super.printStackTrace(System.err);
-        }
-    }
-
-    /**
-     * Method printStackTrace
-     *
-     * @param printwriter
-     */
-    public void printStackTrace(PrintWriter printwriter) {
-        super.printStackTrace(printwriter);
-    }
-
-    /**
-     * Method printStackTrace
-     *
-     * @param printstream
-     */
-    public void printStackTrace(PrintStream printstream) {
-        super.printStackTrace(printstream);
-    }
-
-    /**
      * Method getOriginalException
      *
      * @return the original exception
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/exceptions/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-general exceptions used by this library.
-</P></BODY></HTML>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/ContentHandlerAlreadyRegisteredException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/ContentHandlerAlreadyRegisteredException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -61,24 +61,34 @@
     /**
      * Constructor ContentHandlerAlreadyRegisteredException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public ContentHandlerAlreadyRegisteredException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public ContentHandlerAlreadyRegisteredException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor ContentHandlerAlreadyRegisteredException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
     public ContentHandlerAlreadyRegisteredException(
-        String msgID, Object exArgs[], Exception originalException
+        Exception originalException, String msgID, Object exArgs[]
     ) {
-        super(msgID, exArgs, originalException);
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public ContentHandlerAlreadyRegisteredException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java	Sat Oct 24 01:11:51 2020 +0100
@@ -31,9 +31,6 @@
 
 import javax.crypto.SecretKey;
 
-import com.sun.org.apache.xml.internal.security.encryption.EncryptedKey;
-import com.sun.org.apache.xml.internal.security.encryption.XMLCipher;
-import com.sun.org.apache.xml.internal.security.encryption.XMLEncryptionException;
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import com.sun.org.apache.xml.internal.security.keys.content.DEREncodedKeyValue;
 import com.sun.org.apache.xml.internal.security.keys.content.KeyInfoReference;
@@ -52,6 +49,7 @@
 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver;
 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.ElementProxy;
 import com.sun.org.apache.xml.internal.security.utils.EncryptionConstants;
 import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy;
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
@@ -59,55 +57,52 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 
 /**
  * This class stand for KeyInfo Element that may contain keys, names,
  * certificates and other public key management information,
  * such as in-band key distribution or key agreement data.
- * <BR />
+ * <p></p>
  * KeyInfo Element has two basic functions:
  * One is KeyResolve for getting the public key in signature validation processing.
  * the other one is toElement for getting the element in signature generation processing.
- * <BR />
- * The <CODE>lengthXXX()</CODE> methods provide access to the internal Key
+ * <p></p>
+ * The {@code lengthXXX()} methods provide access to the internal Key
  * objects:
  * <UL>
- * <LI>If the <CODE>KeyInfo</CODE> was constructed from an Element
- * (Signature verification), the <CODE>lengthXXX()</CODE> methods searches
- * for child elements of <CODE>ds:KeyInfo</CODE> for known types. </LI>
- * <LI>If the <CODE>KeyInfo</CODE> was constructed from scratch (during
- * Signature generation), the <CODE>lengthXXX()</CODE> methods return the number
- * of <CODE>XXXs</CODE> objects already passed to the KeyInfo</LI>
+ * <LI>If the {@code KeyInfo} was constructed from an Element
+ * (Signature verification), the {@code lengthXXX()} methods searches
+ * for child elements of {@code ds:KeyInfo} for known types. </LI>
+ * <LI>If the {@code KeyInfo} was constructed from scratch (during
+ * Signature generation), the {@code lengthXXX()} methods return the number
+ * of {@code XXXs} objects already passed to the KeyInfo</LI>
  * </UL>
- * <BR />
- * The <CODE>addXXX()</CODE> methods are used for adding Objects of the
- * appropriate type to the <CODE>KeyInfo</CODE>. This is used during signature
+ * <p></p>
+ * The {@code addXXX()} methods are used for adding Objects of the
+ * appropriate type to the {@code KeyInfo}. This is used during signature
  * generation.
- * <BR />
- * The <CODE>itemXXX(int i)</CODE> methods return the i'th object of the
+ * <p></p>
+ * The {@code itemXXX(int i)} methods return the i'th object of the
  * corresponding type.
- * <BR />
- * The <CODE>containsXXX()</CODE> methods return <I>whether</I> the KeyInfo
+ * <p></p>
+ * The {@code containsXXX()} methods return <I>whether</I> the KeyInfo
  * contains the corresponding type.
  *
  */
 public class KeyInfo extends SignatureElementProxy {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(KeyInfo.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(KeyInfo.class);
 
     // We need at least one StorageResolver otherwise
     // the KeyResolvers would not be called.
     // The default StorageResolver is null.
 
-    private List<X509Data> x509Datas = null;
-    private List<EncryptedKey> encryptedKeys = null;
+    private List<X509Data> x509Datas;
 
     private static final List<StorageResolver> nullList;
     static {
-        List<StorageResolver> list = new ArrayList<StorageResolver>(1);
+        List<StorageResolver> list = new ArrayList<>(1);
         list.add(null);
         nullList = java.util.Collections.unmodifiableList(list);
     }
@@ -118,7 +113,7 @@
     /**
      * Stores the individual (per-KeyInfo) {@link KeyResolverSpi}s
      */
-    private List<KeyResolverSpi> internalKeyResolvers = new ArrayList<KeyResolverSpi>();
+    private List<KeyResolverSpi> internalKeyResolvers = new ArrayList<>();
 
     private boolean secureValidation;
 
@@ -128,8 +123,14 @@
      */
     public KeyInfo(Document doc) {
         super(doc);
+        addReturnToSelf();
 
-        XMLUtils.addReturnToElement(this.constructionElement);
+        String prefix = ElementProxy.getDefaultPrefix(this.getBaseNamespace());
+        if (prefix != null && prefix.length() > 0) {
+            getElement().setAttributeNS(Constants.NamespaceSpecNS, "xmlns:" + prefix,
+                                        this.getBaseNamespace());
+        }
+
     }
 
     /**
@@ -156,24 +157,23 @@
     }
 
     /**
-     * Sets the <code>Id</code> attribute
+     * Sets the {@code Id} attribute
      *
-     * @param Id ID
+     * @param id ID
      */
     public void setId(String id) {
         if (id != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_ID, id);
-            this.constructionElement.setIdAttributeNS(null, Constants._ATT_ID, true);
+            setLocalIdAttribute(Constants._ATT_ID, id);
         }
     }
 
     /**
-     * Returns the <code>Id</code> attribute
+     * Returns the {@code Id} attribute
      *
-     * @return the <code>Id</code> attribute
+     * @return the {@code Id} attribute
      */
     public String getId() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_ID);
+        return getLocalAttribute(Constants._ATT_ID);
     }
 
     /**
@@ -182,7 +182,7 @@
      * @param keynameString
      */
     public void addKeyName(String keynameString) {
-        this.add(new KeyName(this.doc, keynameString));
+        this.add(new KeyName(getDocument(), keynameString));
     }
 
     /**
@@ -191,8 +191,8 @@
      * @param keyname
      */
     public void add(KeyName keyname) {
-        this.constructionElement.appendChild(keyname.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(keyname);
+        addReturnToSelf();
     }
 
     /**
@@ -201,7 +201,7 @@
      * @param pk
      */
     public void addKeyValue(PublicKey pk) {
-        this.add(new KeyValue(this.doc, pk));
+        this.add(new KeyValue(getDocument(), pk));
     }
 
     /**
@@ -210,7 +210,7 @@
      * @param unknownKeyValueElement
      */
     public void addKeyValue(Element unknownKeyValueElement) {
-        this.add(new KeyValue(this.doc, unknownKeyValueElement));
+        this.add(new KeyValue(getDocument(), unknownKeyValueElement));
     }
 
     /**
@@ -219,7 +219,7 @@
      * @param dsakeyvalue
      */
     public void add(DSAKeyValue dsakeyvalue) {
-        this.add(new KeyValue(this.doc, dsakeyvalue));
+        this.add(new KeyValue(getDocument(), dsakeyvalue));
     }
 
     /**
@@ -228,7 +228,7 @@
      * @param rsakeyvalue
      */
     public void add(RSAKeyValue rsakeyvalue) {
-        this.add(new KeyValue(this.doc, rsakeyvalue));
+        this.add(new KeyValue(getDocument(), rsakeyvalue));
     }
 
     /**
@@ -237,7 +237,7 @@
      * @param pk
      */
     public void add(PublicKey pk) {
-        this.add(new KeyValue(this.doc, pk));
+        this.add(new KeyValue(getDocument(), pk));
     }
 
     /**
@@ -246,8 +246,8 @@
      * @param keyvalue
      */
     public void add(KeyValue keyvalue) {
-        this.constructionElement.appendChild(keyvalue.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(keyvalue);
+        addReturnToSelf();
     }
 
     /**
@@ -256,7 +256,7 @@
      * @param mgmtdata
      */
     public void addMgmtData(String mgmtdata) {
-        this.add(new MgmtData(this.doc, mgmtdata));
+        this.add(new MgmtData(getDocument(), mgmtdata));
     }
 
     /**
@@ -265,8 +265,8 @@
      * @param mgmtdata
      */
     public void add(MgmtData mgmtdata) {
-        this.constructionElement.appendChild(mgmtdata.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(mgmtdata);
+        addReturnToSelf();
     }
 
     /**
@@ -275,8 +275,8 @@
      * @param pgpdata
      */
     public void add(PGPData pgpdata) {
-        this.constructionElement.appendChild(pgpdata.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(pgpdata);
+        addReturnToSelf();
     }
 
     /**
@@ -287,7 +287,7 @@
      * @param Type
      */
     public void addRetrievalMethod(String uri, Transforms transforms, String Type) {
-        this.add(new RetrievalMethod(this.doc, uri, transforms, Type));
+        this.add(new RetrievalMethod(getDocument(), uri, transforms, Type));
     }
 
     /**
@@ -296,8 +296,8 @@
      * @param retrievalmethod
      */
     public void add(RetrievalMethod retrievalmethod) {
-        this.constructionElement.appendChild(retrievalmethod.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(retrievalmethod);
+        addReturnToSelf();
     }
 
     /**
@@ -306,8 +306,8 @@
      * @param spkidata
      */
     public void add(SPKIData spkidata) {
-        this.constructionElement.appendChild(spkidata.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(spkidata);
+        addReturnToSelf();
     }
 
     /**
@@ -317,27 +317,11 @@
      */
     public void add(X509Data x509data) {
         if (x509Datas == null) {
-            x509Datas = new ArrayList<X509Data>();
+            x509Datas = new ArrayList<>();
         }
         x509Datas.add(x509data);
-        this.constructionElement.appendChild(x509data.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
-    }
-
-    /**
-     * Method addEncryptedKey
-     *
-     * @param encryptedKey
-     * @throws XMLEncryptionException
-     */
-
-    public void add(EncryptedKey encryptedKey) throws XMLEncryptionException {
-        if (encryptedKeys == null) {
-            encryptedKeys = new ArrayList<EncryptedKey>();
-        }
-        encryptedKeys.add(encryptedKey);
-        XMLCipher cipher = XMLCipher.getInstance();
-        this.constructionElement.appendChild(cipher.martial(encryptedKey));
+        appendSelf(x509data);
+        addReturnToSelf();
     }
 
     /**
@@ -347,7 +331,7 @@
      * @throws XMLSecurityException
      */
     public void addDEREncodedKeyValue(PublicKey pk) throws XMLSecurityException {
-        this.add(new DEREncodedKeyValue(this.doc, pk));
+        this.add(new DEREncodedKeyValue(getDocument(), pk));
     }
 
     /**
@@ -356,8 +340,8 @@
      * @param derEncodedKeyValue
      */
     public void add(DEREncodedKeyValue derEncodedKeyValue) {
-        this.constructionElement.appendChild(derEncodedKeyValue.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(derEncodedKeyValue);
+        addReturnToSelf();
     }
 
     /**
@@ -367,7 +351,7 @@
      * @throws XMLSecurityException
      */
     public void addKeyInfoReference(String URI) throws XMLSecurityException {
-        this.add(new KeyInfoReference(this.doc, URI));
+        this.add(new KeyInfoReference(getDocument(), URI));
     }
 
     /**
@@ -376,8 +360,8 @@
      * @param keyInfoReference
      */
     public void add(KeyInfoReference keyInfoReference) {
-        this.constructionElement.appendChild(keyInfoReference.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(keyInfoReference);
+        addReturnToSelf();
     }
 
     /**
@@ -386,8 +370,8 @@
      * @param element
      */
     public void addUnknownElement(Element element) {
-        this.constructionElement.appendChild(element);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(element);
+        addReturnToSelf();
     }
 
     /**
@@ -481,19 +465,17 @@
      */
     public int lengthUnknownElement() {
         int res = 0;
-        NodeList nl = this.constructionElement.getChildNodes();
-
-        for (int i = 0; i < nl.getLength(); i++) {
-            Node current = nl.item(i);
-
+        Node childNode = getElement().getFirstChild();
+        while (childNode != null) {
             /**
              * $todo$ using this method, we don't see unknown Elements
              *  from Signature NS; revisit
              */
-            if ((current.getNodeType() == Node.ELEMENT_NODE)
-                && current.getNamespaceURI().equals(Constants.SignatureSpecNS)) {
+            if (childNode.getNodeType() == Node.ELEMENT_NODE
+                && childNode.getNamespaceURI().equals(Constants.SignatureSpecNS)) {
                 res++;
             }
+            childNode = childNode.getNextSibling();
         }
 
         return res;
@@ -509,7 +491,7 @@
     public KeyName itemKeyName(int i) throws XMLSecurityException {
         Element e =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_KEYNAME, i);
+                getFirstChild(), Constants._TAG_KEYNAME, i);
 
         if (e != null) {
             return new KeyName(e, this.baseURI);
@@ -527,7 +509,7 @@
     public KeyValue itemKeyValue(int i) throws XMLSecurityException {
         Element e =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_KEYVALUE, i);
+                getFirstChild(), Constants._TAG_KEYVALUE, i);
 
         if (e != null) {
             return new KeyValue(e, this.baseURI);
@@ -545,7 +527,7 @@
     public MgmtData itemMgmtData(int i) throws XMLSecurityException {
         Element e =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_MGMTDATA, i);
+                getFirstChild(), Constants._TAG_MGMTDATA, i);
 
         if (e != null) {
             return new MgmtData(e, this.baseURI);
@@ -563,7 +545,7 @@
     public PGPData itemPGPData(int i) throws XMLSecurityException {
         Element e =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_PGPDATA, i);
+                getFirstChild(), Constants._TAG_PGPDATA, i);
 
         if (e != null) {
             return new PGPData(e, this.baseURI);
@@ -581,7 +563,7 @@
     public RetrievalMethod itemRetrievalMethod(int i) throws XMLSecurityException {
         Element e =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_RETRIEVALMETHOD, i);
+                getFirstChild(), Constants._TAG_RETRIEVALMETHOD, i);
 
         if (e != null) {
             return new RetrievalMethod(e, this.baseURI);
@@ -599,7 +581,7 @@
     public SPKIData itemSPKIData(int i) throws XMLSecurityException {
         Element e =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_SPKIDATA, i);
+                getFirstChild(), Constants._TAG_SPKIDATA, i);
 
         if (e != null) {
             return new SPKIData(e, this.baseURI);
@@ -620,7 +602,7 @@
         }
         Element e =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_X509DATA, i);
+                getFirstChild(), Constants._TAG_X509DATA, i);
 
         if (e != null) {
             return new X509Data(e, this.baseURI);
@@ -629,29 +611,6 @@
     }
 
     /**
-     * Method itemEncryptedKey
-     *
-     * @param i
-     * @return the asked EncryptedKey element, null if the index is too big
-     * @throws XMLSecurityException
-     */
-    public EncryptedKey itemEncryptedKey(int i) throws XMLSecurityException {
-        if (encryptedKeys != null) {
-            return encryptedKeys.get(i);
-        }
-        Element e =
-            XMLUtils.selectXencNode(
-                this.constructionElement.getFirstChild(), EncryptionConstants._TAG_ENCRYPTEDKEY, i);
-
-        if (e != null) {
-            XMLCipher cipher = XMLCipher.getInstance();
-            cipher.init(XMLCipher.UNWRAP_MODE, null);
-            return cipher.loadEncryptedKey(e);
-        }
-        return null;
-    }
-
-    /**
      * Method itemDEREncodedKeyValue
      *
      * @param i
@@ -661,7 +620,7 @@
     public DEREncodedKeyValue itemDEREncodedKeyValue(int i) throws XMLSecurityException {
         Element e =
             XMLUtils.selectDs11Node(
-                this.constructionElement.getFirstChild(), Constants._TAG_DERENCODEDKEYVALUE, i);
+                getFirstChild(), Constants._TAG_DERENCODEDKEYVALUE, i);
 
         if (e != null) {
             return new DEREncodedKeyValue(e, this.baseURI);
@@ -679,7 +638,7 @@
     public KeyInfoReference itemKeyInfoReference(int i) throws XMLSecurityException {
         Element e =
             XMLUtils.selectDs11Node(
-                this.constructionElement.getFirstChild(), Constants._TAG_KEYINFOREFERENCE, i);
+                getFirstChild(), Constants._TAG_KEYINFOREFERENCE, i);
 
         if (e != null) {
             return new KeyInfoReference(e, this.baseURI);
@@ -694,24 +653,22 @@
      * @return the element number of the unknown elements
      */
     public Element itemUnknownElement(int i) {
-        NodeList nl = this.constructionElement.getChildNodes();
         int res = 0;
-
-        for (int j = 0; j < nl.getLength(); j++) {
-            Node current = nl.item(j);
-
+        Node childNode = getElement().getFirstChild();
+        while (childNode != null) {
             /**
              * $todo$ using this method, we don't see unknown Elements
              *  from Signature NS; revisit
              */
-            if ((current.getNodeType() == Node.ELEMENT_NODE)
-                && current.getNamespaceURI().equals(Constants.SignatureSpecNS)) {
+            if (childNode.getNodeType() == Node.ELEMENT_NODE
+                && childNode.getNamespaceURI().equals(Constants.SignatureSpecNS)) {
                 res++;
 
                 if (res == i) {
-                    return (Element) current;
+                    return (Element) childNode;
                 }
             }
+            childNode = childNode.getNextSibling();
         }
 
         return null;
@@ -723,7 +680,7 @@
      * @return true if the element has no descendants.
      */
     public boolean isEmpty() {
-        return this.constructionElement.getFirstChild() == null;
+        return getFirstChild() == null;
     }
 
     /**
@@ -826,28 +783,20 @@
         PublicKey pk = this.getPublicKeyFromInternalResolvers();
 
         if (pk != null) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I could find a key using the per-KeyInfo key resolvers");
-            }
+            LOG.debug("I could find a key using the per-KeyInfo key resolvers");
 
             return pk;
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "I couldn't find a key using the per-KeyInfo key resolvers");
-        }
+        LOG.debug("I couldn't find a key using the per-KeyInfo key resolvers");
 
         pk = this.getPublicKeyFromStaticResolvers();
 
         if (pk != null) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I could find a key using the system-wide key resolvers");
-            }
+            LOG.debug("I could find a key using the system-wide key resolvers");
 
             return pk;
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "I couldn't find a key using the system-wide key resolvers");
-        }
+        LOG.debug("I couldn't find a key using the system-wide key resolvers");
 
         return null;
     }
@@ -863,7 +812,7 @@
         while (it.hasNext()) {
             KeyResolverSpi keyResolver = it.next();
             keyResolver.setSecureValidation(secureValidation);
-            Node currentChild = this.constructionElement.getFirstChild();
+            Node currentChild = getFirstChild();
             String uri = this.getBaseURI();
             while (currentChild != null) {
                 if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
@@ -892,11 +841,9 @@
      */
     PublicKey getPublicKeyFromInternalResolvers() throws KeyResolverException {
         for (KeyResolverSpi keyResolver : internalKeyResolvers) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Try " + keyResolver.getClass().getName());
-            }
+            LOG.debug("Try {}", keyResolver.getClass().getName());
             keyResolver.setSecureValidation(secureValidation);
-            Node currentChild = this.constructionElement.getFirstChild();
+            Node currentChild = getFirstChild();
             String uri = this.getBaseURI();
             while (currentChild != null)      {
                 if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
@@ -929,29 +876,21 @@
         X509Certificate cert = this.getX509CertificateFromInternalResolvers();
 
         if (cert != null) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I could find a X509Certificate using the per-KeyInfo key resolvers");
-            }
+            LOG.debug("I could find a X509Certificate using the per-KeyInfo key resolvers");
 
             return cert;
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "I couldn't find a X509Certificate using the per-KeyInfo key resolvers");
-        }
+        LOG.debug("I couldn't find a X509Certificate using the per-KeyInfo key resolvers");
 
         // Then use the system-wide Resolvers
         cert = this.getX509CertificateFromStaticResolvers();
 
         if (cert != null) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I could find a X509Certificate using the system-wide key resolvers");
-            }
+            LOG.debug("I could find a X509Certificate using the system-wide key resolvers");
 
             return cert;
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "I couldn't find a X509Certificate using the system-wide key resolvers");
-        }
+        LOG.debug("I couldn't find a X509Certificate using the system-wide key resolvers");
 
         return null;
     }
@@ -966,12 +905,9 @@
      */
     X509Certificate getX509CertificateFromStaticResolvers()
         throws KeyResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE,
-                "Start getX509CertificateFromStaticResolvers() with " + KeyResolver.length()
-                + " resolvers"
-            );
-        }
+        LOG.debug(
+            "Start getX509CertificateFromStaticResolvers() with {} resolvers", KeyResolver.length()
+        );
         String uri = this.getBaseURI();
         Iterator<KeyResolverSpi> it = KeyResolver.iterator();
         while (it.hasNext()) {
@@ -988,7 +924,7 @@
     private X509Certificate applyCurrentResolver(
         String uri, KeyResolverSpi keyResolver
     ) throws KeyResolverException {
-        Node currentChild = this.constructionElement.getFirstChild();
+        Node currentChild = getFirstChild();
         while (currentChild != null)      {
             if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
                 for (StorageResolver storage : storageResolvers) {
@@ -1015,17 +951,13 @@
      */
     X509Certificate getX509CertificateFromInternalResolvers()
         throws KeyResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE,
-                "Start getX509CertificateFromInternalResolvers() with "
-                + this.lengthInternalKeyResolver() + " resolvers"
-            );
-        }
+        LOG.debug(
+            "Start getX509CertificateFromInternalResolvers() with {} resolvers",
+            + this.lengthInternalKeyResolver()
+        );
         String uri = this.getBaseURI();
         for (KeyResolverSpi keyResolver : internalKeyResolvers) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Try " + keyResolver.getClass().getName());
-            }
+            LOG.debug("Try {}", keyResolver.getClass().getName());
             keyResolver.setSecureValidation(secureValidation);
             X509Certificate cert = applyCurrentResolver(uri, keyResolver);
             if (cert != null) {
@@ -1045,28 +977,20 @@
         SecretKey sk = this.getSecretKeyFromInternalResolvers();
 
         if (sk != null) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I could find a secret key using the per-KeyInfo key resolvers");
-            }
+            LOG.debug("I could find a secret key using the per-KeyInfo key resolvers");
 
             return sk;
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "I couldn't find a secret key using the per-KeyInfo key resolvers");
-        }
+        LOG.debug("I couldn't find a secret key using the per-KeyInfo key resolvers");
 
         sk = this.getSecretKeyFromStaticResolvers();
 
         if (sk != null) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I could find a secret key using the system-wide key resolvers");
-            }
+            LOG.debug("I could find a secret key using the system-wide key resolvers");
 
             return sk;
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "I couldn't find a secret key using the system-wide key resolvers");
-        }
+        LOG.debug("I couldn't find a secret key using the system-wide key resolvers");
 
         return null;
     }
@@ -1083,7 +1007,7 @@
             KeyResolverSpi keyResolver = it.next();
             keyResolver.setSecureValidation(secureValidation);
 
-            Node currentChild = this.constructionElement.getFirstChild();
+            Node currentChild = getFirstChild();
             String uri = this.getBaseURI();
             while (currentChild != null)      {
                 if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
@@ -1113,11 +1037,9 @@
 
     SecretKey getSecretKeyFromInternalResolvers() throws KeyResolverException {
         for (KeyResolverSpi keyResolver : internalKeyResolvers) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Try " + keyResolver.getClass().getName());
-            }
+            LOG.debug("Try {}", keyResolver.getClass().getName());
             keyResolver.setSecureValidation(secureValidation);
-            Node currentChild = this.constructionElement.getFirstChild();
+            Node currentChild = getFirstChild();
             String uri = this.getBaseURI();
             while (currentChild != null)      {
                 if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
@@ -1148,25 +1070,17 @@
         PrivateKey pk = this.getPrivateKeyFromInternalResolvers();
 
         if (pk != null) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I could find a private key using the per-KeyInfo key resolvers");
-            }
+            LOG.debug("I could find a private key using the per-KeyInfo key resolvers");
             return pk;
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "I couldn't find a secret key using the per-KeyInfo key resolvers");
-        }
+        LOG.debug("I couldn't find a secret key using the per-KeyInfo key resolvers");
 
         pk = this.getPrivateKeyFromStaticResolvers();
         if (pk != null) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I could find a private key using the system-wide key resolvers");
-            }
+            LOG.debug("I could find a private key using the system-wide key resolvers");
             return pk;
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "I couldn't find a private key using the system-wide key resolvers");
-        }
+        LOG.debug("I couldn't find a private key using the system-wide key resolvers");
 
         return null;
     }
@@ -1183,7 +1097,7 @@
             KeyResolverSpi keyResolver = it.next();
             keyResolver.setSecureValidation(secureValidation);
 
-            Node currentChild = this.constructionElement.getFirstChild();
+            Node currentChild = getFirstChild();
             String uri = this.getBaseURI();
             while (currentChild != null)      {
                 if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
@@ -1212,11 +1126,9 @@
      */
     PrivateKey getPrivateKeyFromInternalResolvers() throws KeyResolverException {
         for (KeyResolverSpi keyResolver : internalKeyResolvers) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Try " + keyResolver.getClass().getName());
-            }
+            LOG.debug("Try {}", keyResolver.getClass().getName());
             keyResolver.setSecureValidation(secureValidation);
-            Node currentChild = this.constructionElement.getFirstChild();
+            Node currentChild = getFirstChild();
             String uri = this.getBaseURI();
             while (currentChild != null) {
                 if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
@@ -1274,13 +1186,13 @@
     public void addStorageResolver(StorageResolver storageResolver) {
         if (storageResolvers == nullList) {
             // Replace the default null StorageResolver
-            storageResolvers = new ArrayList<StorageResolver>();
+            storageResolvers = new ArrayList<>();
         }
         this.storageResolvers.add(storageResolver);
     }
 
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_KEYINFO;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyUtils.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyUtils.java	Sat Oct 24 01:11:51 2020 +0100
@@ -32,11 +32,10 @@
 import com.sun.org.apache.xml.internal.security.keys.content.X509Data;
 
 /**
- * Utility class for for <CODE>com.sun.org.apache.xml.internal.security.keys</CODE> package.
+ * Utility class for {@code com.sun.org.apache.xml.internal.security.keys} package.
  *
- * @author $Author: coheigea $
  */
-public class KeyUtils {
+public final class KeyUtils {
 
     private KeyUtils() {
         // no instantiation
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/DEREncodedKeyValue.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/DEREncodedKeyValue.java	Sat Oct 24 01:11:51 2020 +0100
@@ -35,9 +35,8 @@
 import org.w3c.dom.Element;
 
 /**
- * Provides content model support for the <code>dsig11:DEREncodedKeyvalue</code> element.
+ * Provides content model support for the {@code dsig11:DEREncodedKeyvalue} element.
  *
- * @author Brent Putman (putmanb@georgetown.edu)
  */
 public class DEREncodedKeyValue extends Signature11ElementProxy implements KeyInfoContent {
 
@@ -48,11 +47,11 @@
      * Constructor DEREncodedKeyValue
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public DEREncodedKeyValue(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public DEREncodedKeyValue(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
     }
 
     /**
@@ -72,7 +71,7 @@
      * Constructor DEREncodedKeyValue
      *
      * @param doc
-     * @param base64EncodedKey
+     * @param encodedKey
      */
     public DEREncodedKeyValue(Document doc, byte[] encodedKey) {
         super(doc);
@@ -81,29 +80,24 @@
     }
 
     /**
-     * Sets the <code>Id</code> attribute
+     * Sets the {@code Id} attribute
      *
-     * @param Id ID
+     * @param id ID
      */
     public void setId(String id) {
-        if (id != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_ID, id);
-            this.constructionElement.setIdAttributeNS(null, Constants._ATT_ID, true);
-        } else {
-            this.constructionElement.removeAttributeNS(null, Constants._ATT_ID);
-        }
+        setLocalIdAttribute(Constants._ATT_ID, id);
     }
 
     /**
-     * Returns the <code>Id</code> attribute
+     * Returns the {@code Id} attribute
      *
-     * @return the <code>Id</code> attribute
+     * @return the {@code Id} attribute
      */
     public String getId() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_ID);
+        return getLocalAttribute(Constants._ATT_ID);
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_DERENCODEDKEYVALUE;
     }
@@ -126,9 +120,9 @@
                 if (publicKey != null) {
                     return publicKey;
                 }
-            } catch (NoSuchAlgorithmException e) {
+            } catch (NoSuchAlgorithmException e) { //NOPMD
                 // Do nothing, try the next type
-            } catch (InvalidKeySpecException e) {
+            } catch (InvalidKeySpecException e) { //NOPMD
                 // Do nothing, try the next type
             }
         }
@@ -148,10 +142,10 @@
             return keySpec.getEncoded();
         } catch (NoSuchAlgorithmException e) {
             Object exArgs[] = { publicKey.getAlgorithm(), publicKey.getFormat(), publicKey.getClass().getName() };
-            throw new XMLSecurityException("DEREncodedKeyValue.UnsupportedPublicKey", exArgs, e);
+            throw new XMLSecurityException(e, "DEREncodedKeyValue.UnsupportedPublicKey", exArgs);
         } catch (InvalidKeySpecException e) {
             Object exArgs[] = { publicKey.getAlgorithm(), publicKey.getFormat(), publicKey.getClass().getName() };
-            throw new XMLSecurityException("DEREncodedKeyValue.UnsupportedPublicKey", exArgs, e);
+            throw new XMLSecurityException(e, "DEREncodedKeyValue.UnsupportedPublicKey", exArgs);
         }
     }
 
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyInfoContent.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyInfoContent.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,7 +25,6 @@
 /**
  * Empty interface just to identify Elements that can be children of ds:KeyInfo.
  *
- * @author $Author: coheigea $
  */
 public interface KeyInfoContent {
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyInfoReference.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyInfoReference.java	Sat Oct 24 01:11:51 2020 +0100
@@ -30,9 +30,8 @@
 import org.w3c.dom.Element;
 
 /**
- * Provides content model support for the <code>dsig11:KeyInfoReference</code> element.
+ * Provides content model support for the {@code dsig11:KeyInfoReference} element.
  *
- * @author Brent Putman (putmanb@georgetown.edu)
  */
 public class KeyInfoReference extends Signature11ElementProxy implements KeyInfoContent {
 
@@ -40,7 +39,7 @@
      * Constructor RetrievalMethod
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
     public KeyInfoReference(Element element, String baseURI) throws XMLSecurityException {
@@ -51,12 +50,12 @@
      * Constructor RetrievalMethod
      *
      * @param doc
-     * @param URI
+     * @param uri
      */
-    public KeyInfoReference(Document doc, String URI) {
+    public KeyInfoReference(Document doc, String uri) {
         super(doc);
 
-        this.constructionElement.setAttributeNS(null, Constants._ATT_URI, URI);
+        setLocalAttribute(Constants._ATT_URI, uri);
     }
 
     /**
@@ -65,7 +64,7 @@
      * @return the URI attribute
      */
     public Attr getURIAttr() {
-        return this.constructionElement.getAttributeNodeNS(null, Constants._ATT_URI);
+        return getElement().getAttributeNodeNS(null, Constants._ATT_URI);
     }
 
     /**
@@ -78,29 +77,24 @@
     }
 
     /**
-     * Sets the <code>Id</code> attribute
+     * Sets the {@code Id} attribute
      *
-     * @param Id ID
+     * @param id ID
      */
     public void setId(String id) {
-        if (id != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_ID, id);
-            this.constructionElement.setIdAttributeNS(null, Constants._ATT_ID, true);
-        } else {
-            this.constructionElement.removeAttributeNS(null, Constants._ATT_ID);
-        }
+        setLocalIdAttribute(Constants._ATT_ID, id);
     }
 
     /**
-     * Returns the <code>Id</code> attribute
+     * Returns the {@code Id} attribute
      *
-     * @return the <code>Id</code> attribute
+     * @return the {@code Id} attribute
      */
     public String getId() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_ID);
+        return getLocalAttribute(Constants._ATT_ID);
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_KEYINFOREFERENCE;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyName.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyName.java	Sat Oct 24 01:11:51 2020 +0100
@@ -29,7 +29,6 @@
 import org.w3c.dom.Element;
 
 /**
- * @author $Author: coheigea $
  */
 public class KeyName extends SignatureElementProxy implements KeyInfoContent {
 
@@ -37,11 +36,11 @@
      * Constructor KeyName
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public KeyName(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public KeyName(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
     }
 
     /**
@@ -65,7 +64,7 @@
         return this.getTextFromTextChild();
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_KEYNAME;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java	Sat Oct 24 01:11:51 2020 +0100
@@ -41,7 +41,6 @@
  * keys values represented as PCDATA or element types from an external
  * namespace.
  *
- * @author $Author: coheigea $
  */
 public class KeyValue extends SignatureElementProxy implements KeyInfoContent {
 
@@ -54,9 +53,9 @@
     public KeyValue(Document doc, DSAKeyValue dsaKeyValue) {
         super(doc);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
-        this.constructionElement.appendChild(dsaKeyValue.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
+        appendSelf(dsaKeyValue);
+        addReturnToSelf();
     }
 
     /**
@@ -68,9 +67,9 @@
     public KeyValue(Document doc, RSAKeyValue rsaKeyValue) {
         super(doc);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
-        this.constructionElement.appendChild(rsaKeyValue.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
+        appendSelf(rsaKeyValue);
+        addReturnToSelf();
     }
 
     /**
@@ -82,9 +81,9 @@
     public KeyValue(Document doc, Element unknownKeyValue) {
         super(doc);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
-        this.constructionElement.appendChild(unknownKeyValue);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
+        appendSelf(unknownKeyValue);
+        addReturnToSelf();
     }
 
     /**
@@ -96,18 +95,22 @@
     public KeyValue(Document doc, PublicKey pk) {
         super(doc);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
 
         if (pk instanceof java.security.interfaces.DSAPublicKey) {
-            DSAKeyValue dsa = new DSAKeyValue(this.doc, pk);
+            DSAKeyValue dsa = new DSAKeyValue(getDocument(), pk);
 
-            this.constructionElement.appendChild(dsa.getElement());
-            XMLUtils.addReturnToElement(this.constructionElement);
+            appendSelf(dsa);
+            addReturnToSelf();
         } else if (pk instanceof java.security.interfaces.RSAPublicKey) {
-            RSAKeyValue rsa = new RSAKeyValue(this.doc, pk);
+            RSAKeyValue rsa = new RSAKeyValue(getDocument(), pk);
 
-            this.constructionElement.appendChild(rsa.getElement());
-            XMLUtils.addReturnToElement(this.constructionElement);
+            appendSelf(rsa);
+            addReturnToSelf();
+        } else {
+            String error = "The given PublicKey type " + pk + " is not supported. Only DSAPublicKey and "
+                + "RSAPublicKey types are currently supported";
+            throw new IllegalArgumentException(error);
         }
     }
 
@@ -115,11 +118,11 @@
      * Constructor KeyValue
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public KeyValue(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public KeyValue(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
     }
 
     /**
@@ -131,7 +134,7 @@
     public PublicKey getPublicKey() throws XMLSecurityException {
         Element rsa =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_RSAKEYVALUE, 0);
+                getFirstChild(), Constants._TAG_RSAKEYVALUE, 0);
 
         if (rsa != null) {
             RSAKeyValue kv = new RSAKeyValue(rsa, this.baseURI);
@@ -140,7 +143,7 @@
 
         Element dsa =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_DSAKEYVALUE, 0);
+                getFirstChild(), Constants._TAG_DSAKEYVALUE, 0);
 
         if (dsa != null) {
             DSAKeyValue kv = new DSAKeyValue(dsa, this.baseURI);
@@ -150,7 +153,7 @@
         return null;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_KEYVALUE;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/MgmtData.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/MgmtData.java	Sat Oct 24 01:11:51 2020 +0100
@@ -29,7 +29,6 @@
 import org.w3c.dom.Element;
 
 /**
- * @author $Author: coheigea $
  */
 public class MgmtData extends SignatureElementProxy implements KeyInfoContent {
 
@@ -37,12 +36,12 @@
      * Constructor MgmtData
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public MgmtData(Element element, String BaseURI)
+    public MgmtData(Element element, String baseURI)
         throws XMLSecurityException {
-        super(element, BaseURI);
+        super(element, baseURI);
     }
 
     /**
@@ -66,7 +65,7 @@
         return this.getTextFromTextChild();
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_MGMTDATA;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/PGPData.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/PGPData.java	Sat Oct 24 01:11:51 2020 +0100
@@ -28,7 +28,6 @@
 import org.w3c.dom.Element;
 
 /**
- * @author $Author: coheigea $
  * $todo$ Implement
  */
 public class PGPData extends SignatureElementProxy implements KeyInfoContent {
@@ -37,14 +36,14 @@
      * Constructor PGPData
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public PGPData(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public PGPData(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_PGPDATA;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/RetrievalMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/RetrievalMethod.java	Sat Oct 24 01:11:51 2020 +0100
@@ -35,17 +35,17 @@
 public class RetrievalMethod extends SignatureElementProxy implements KeyInfoContent {
 
     /** DSA retrieval */
-    public static final String TYPE_DSA     = Constants.SignatureSpecNS + "DSAKeyValue";
+    public static final String TYPE_DSA = Constants.SignatureSpecNS + "DSAKeyValue";
     /** RSA retrieval */
-    public static final String TYPE_RSA     = Constants.SignatureSpecNS + "RSAKeyValue";
+    public static final String TYPE_RSA = Constants.SignatureSpecNS + "RSAKeyValue";
     /** PGP retrieval */
-    public static final String TYPE_PGP     = Constants.SignatureSpecNS + "PGPData";
+    public static final String TYPE_PGP = Constants.SignatureSpecNS + "PGPData";
     /** SPKI retrieval */
-    public static final String TYPE_SPKI    = Constants.SignatureSpecNS + "SPKIData";
+    public static final String TYPE_SPKI = Constants.SignatureSpecNS + "SPKIData";
     /** MGMT retrieval */
-    public static final String TYPE_MGMT    = Constants.SignatureSpecNS + "MgmtData";
+    public static final String TYPE_MGMT = Constants.SignatureSpecNS + "MgmtData";
     /** X509 retrieval */
-    public static final String TYPE_X509    = Constants.SignatureSpecNS + "X509Data";
+    public static final String TYPE_X509 = Constants.SignatureSpecNS + "X509Data";
     /** RAWX509 retrieval */
     public static final String TYPE_RAWX509 = Constants.SignatureSpecNS + "rawX509Certificate";
 
@@ -53,11 +53,11 @@
      * Constructor RetrievalMethod
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public RetrievalMethod(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public RetrievalMethod(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
     }
 
     /**
@@ -71,15 +71,15 @@
     public RetrievalMethod(Document doc, String URI, Transforms transforms, String Type) {
         super(doc);
 
-        this.constructionElement.setAttributeNS(null, Constants._ATT_URI, URI);
+        setLocalAttribute(Constants._ATT_URI, URI);
 
         if (Type != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_TYPE, Type);
+            setLocalAttribute(Constants._ATT_TYPE, Type);
         }
 
         if (transforms != null) {
-            this.constructionElement.appendChild(transforms.getElement());
-            XMLUtils.addReturnToElement(this.constructionElement);
+            appendSelf(transforms);
+            addReturnToSelf();
         }
     }
 
@@ -89,7 +89,7 @@
      * @return the URI attribute
      */
     public Attr getURIAttr() {
-        return this.constructionElement.getAttributeNodeNS(null, Constants._ATT_URI);
+        return getElement().getAttributeNodeNS(null, Constants._ATT_URI);
     }
 
     /**
@@ -98,12 +98,12 @@
      * @return URI string
      */
     public String getURI() {
-        return this.getURIAttr().getNodeValue();
+        return getLocalAttribute(Constants._ATT_URI);
     }
 
     /** @return the type*/
     public String getType() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_TYPE);
+        return getLocalAttribute(Constants._ATT_TYPE);
     }
 
     /**
@@ -116,7 +116,7 @@
         try {
             Element transformsElem =
                 XMLUtils.selectDsNode(
-                    this.constructionElement.getFirstChild(), Constants._TAG_TRANSFORMS, 0);
+                    getFirstChild(), Constants._TAG_TRANSFORMS, 0);
 
             if (transformsElem != null) {
                 return new Transforms(transformsElem, this.baseURI);
@@ -124,11 +124,11 @@
 
             return null;
         } catch (XMLSignatureException ex) {
-            throw new XMLSecurityException("empty", ex);
+            throw new XMLSecurityException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_RETRIEVALMETHOD;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/SPKIData.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/SPKIData.java	Sat Oct 24 01:11:51 2020 +0100
@@ -28,7 +28,6 @@
 import org.w3c.dom.Element;
 
 /**
- * @author $Author: coheigea $
  * $todo$ implement
  */
 public class SPKIData extends SignatureElementProxy implements KeyInfoContent {
@@ -37,15 +36,15 @@
      * Constructor SPKIData
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public SPKIData(Element element, String BaseURI)
+    public SPKIData(Element element, String baseURI)
         throws XMLSecurityException {
-        super(element, BaseURI);
+        super(element, baseURI);
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_SPKIDATA;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/X509Data.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/X509Data.java	Sat Oct 24 01:11:51 2020 +0100
@@ -41,9 +41,8 @@
 
 public class X509Data extends SignatureElementProxy implements KeyInfoContent {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(X509Data.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(X509Data.class);
 
     /**
      * Constructor X509Data
@@ -53,7 +52,7 @@
     public X509Data(Document doc) {
         super(doc);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
     }
 
     /**
@@ -66,17 +65,15 @@
     public X509Data(Element element, String baseURI) throws XMLSecurityException {
         super(element, baseURI);
 
-        Node sibling = this.constructionElement.getFirstChild();
-        while (sibling != null) {
-            if (sibling.getNodeType() != Node.ELEMENT_NODE) {
-                sibling = sibling.getNextSibling();
-                continue;
-            }
-            return;
+        Node sibling = getFirstChild();
+        while (sibling != null && sibling.getNodeType() != Node.ELEMENT_NODE) {
+            sibling = sibling.getNextSibling();
         }
-        /* No Elements found */
-        Object exArgs[] = { "Elements", Constants._TAG_X509DATA };
-        throw new XMLSecurityException("xml.WrongContent", exArgs);
+        if (sibling == null || sibling.getNodeType() != Node.ELEMENT_NODE) {
+            /* No Elements found */
+            Object exArgs[] = { "Elements", Constants._TAG_X509DATA };
+            throw new XMLSecurityException("xml.WrongContent", exArgs);
+        }
     }
 
     /**
@@ -86,7 +83,7 @@
      * @param X509SerialNumber
      */
     public void addIssuerSerial(String X509IssuerName, BigInteger X509SerialNumber) {
-        this.add(new XMLX509IssuerSerial(this.doc, X509IssuerName, X509SerialNumber));
+        this.add(new XMLX509IssuerSerial(getDocument(), X509IssuerName, X509SerialNumber));
     }
 
     /**
@@ -96,7 +93,7 @@
      * @param X509SerialNumber
      */
     public void addIssuerSerial(String X509IssuerName, String X509SerialNumber) {
-        this.add(new XMLX509IssuerSerial(this.doc, X509IssuerName, X509SerialNumber));
+        this.add(new XMLX509IssuerSerial(getDocument(), X509IssuerName, X509SerialNumber));
     }
 
     /**
@@ -106,7 +103,7 @@
      * @param X509SerialNumber
      */
     public void addIssuerSerial(String X509IssuerName, int X509SerialNumber) {
-        this.add(new XMLX509IssuerSerial(this.doc, X509IssuerName, X509SerialNumber));
+        this.add(new XMLX509IssuerSerial(getDocument(), X509IssuerName, X509SerialNumber));
     }
 
     /**
@@ -116,8 +113,8 @@
      */
     public void add(XMLX509IssuerSerial xmlX509IssuerSerial) {
 
-        this.constructionElement.appendChild(xmlX509IssuerSerial.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(xmlX509IssuerSerial);
+        addReturnToSelf();
     }
 
     /**
@@ -126,7 +123,7 @@
      * @param skiBytes
      */
     public void addSKI(byte[] skiBytes) {
-        this.add(new XMLX509SKI(this.doc, skiBytes));
+        this.add(new XMLX509SKI(getDocument(), skiBytes));
     }
 
     /**
@@ -137,7 +134,7 @@
      */
     public void addSKI(X509Certificate x509certificate)
         throws XMLSecurityException {
-        this.add(new XMLX509SKI(this.doc, x509certificate));
+        this.add(new XMLX509SKI(getDocument(), x509certificate));
     }
 
     /**
@@ -146,8 +143,8 @@
      * @param xmlX509SKI
      */
     public void add(XMLX509SKI xmlX509SKI) {
-        this.constructionElement.appendChild(xmlX509SKI.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(xmlX509SKI);
+        addReturnToSelf();
     }
 
     /**
@@ -156,7 +153,7 @@
      * @param subjectName
      */
     public void addSubjectName(String subjectName) {
-        this.add(new XMLX509SubjectName(this.doc, subjectName));
+        this.add(new XMLX509SubjectName(getDocument(), subjectName));
     }
 
     /**
@@ -165,7 +162,7 @@
      * @param x509certificate
      */
     public void addSubjectName(X509Certificate x509certificate) {
-        this.add(new XMLX509SubjectName(this.doc, x509certificate));
+        this.add(new XMLX509SubjectName(getDocument(), x509certificate));
     }
 
     /**
@@ -174,8 +171,8 @@
      * @param xmlX509SubjectName
      */
     public void add(XMLX509SubjectName xmlX509SubjectName) {
-        this.constructionElement.appendChild(xmlX509SubjectName.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(xmlX509SubjectName);
+        addReturnToSelf();
     }
 
     /**
@@ -186,7 +183,7 @@
      */
     public void addCertificate(X509Certificate x509certificate)
         throws XMLSecurityException {
-        this.add(new XMLX509Certificate(this.doc, x509certificate));
+        this.add(new XMLX509Certificate(getDocument(), x509certificate));
     }
 
     /**
@@ -195,7 +192,7 @@
      * @param x509certificateBytes
      */
     public void addCertificate(byte[] x509certificateBytes) {
-        this.add(new XMLX509Certificate(this.doc, x509certificateBytes));
+        this.add(new XMLX509Certificate(getDocument(), x509certificateBytes));
     }
 
     /**
@@ -204,8 +201,8 @@
      * @param xmlX509Certificate
      */
     public void add(XMLX509Certificate xmlX509Certificate) {
-        this.constructionElement.appendChild(xmlX509Certificate.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(xmlX509Certificate);
+        addReturnToSelf();
     }
 
     /**
@@ -214,7 +211,7 @@
      * @param crlBytes
      */
     public void addCRL(byte[] crlBytes) {
-        this.add(new XMLX509CRL(this.doc, crlBytes));
+        this.add(new XMLX509CRL(getDocument(), crlBytes));
     }
 
     /**
@@ -223,8 +220,8 @@
      * @param xmlX509CRL
      */
     public void add(XMLX509CRL xmlX509CRL) {
-        this.constructionElement.appendChild(xmlX509CRL.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(xmlX509CRL);
+        addReturnToSelf();
     }
 
     /**
@@ -236,27 +233,27 @@
      */
     public void addDigest(X509Certificate x509certificate, String algorithmURI)
         throws XMLSecurityException {
-        this.add(new XMLX509Digest(this.doc, x509certificate, algorithmURI));
+        this.add(new XMLX509Digest(getDocument(), x509certificate, algorithmURI));
     }
 
     /**
      * Method addDigest
      *
-     * @param x509CertificateDigestByes
+     * @param x509CertificateDigestBytes
      * @param algorithmURI
      */
-    public void addDigest(byte[] x509certificateDigestBytes, String algorithmURI) {
-        this.add(new XMLX509Digest(this.doc, x509certificateDigestBytes, algorithmURI));
+    public void addDigest(byte[] x509CertificateDigestBytes, String algorithmURI) {
+        this.add(new XMLX509Digest(getDocument(), x509CertificateDigestBytes, algorithmURI));
     }
 
     /**
      * Method add
      *
-     * @param XMLX509Digest
+     * @param xmlX509Digest
      */
     public void add(XMLX509Digest xmlX509Digest) {
-        this.constructionElement.appendChild(xmlX509Digest.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(xmlX509Digest);
+        addReturnToSelf();
     }
 
     /**
@@ -265,8 +262,8 @@
      * @param element
      */
     public void addUnknownElement(Element element) {
-        this.constructionElement.appendChild(element);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(element);
+        addReturnToSelf();
     }
 
     /**
@@ -330,9 +327,9 @@
      */
     public int lengthUnknownElement() {
         int result = 0;
-        Node n = this.constructionElement.getFirstChild();
-        while (n != null){
-            if ((n.getNodeType() == Node.ELEMENT_NODE)
+        Node n = getFirstChild();
+        while (n != null) {
+            if (n.getNodeType() == Node.ELEMENT_NODE
                 && !n.getNamespaceURI().equals(Constants.SignatureSpecNS)) {
                 result++;
             }
@@ -352,7 +349,7 @@
     public XMLX509IssuerSerial itemIssuerSerial(int i) throws XMLSecurityException {
         Element e =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_X509ISSUERSERIAL, i);
+                getFirstChild(), Constants._TAG_X509ISSUERSERIAL, i);
 
         if (e != null) {
             return new XMLX509IssuerSerial(e, this.baseURI);
@@ -371,7 +368,7 @@
 
         Element e =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_X509SKI, i);
+                getFirstChild(), Constants._TAG_X509SKI, i);
 
         if (e != null) {
             return new XMLX509SKI(e, this.baseURI);
@@ -390,7 +387,7 @@
 
         Element e =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_X509SUBJECTNAME, i);
+                getFirstChild(), Constants._TAG_X509SUBJECTNAME, i);
 
         if (e != null) {
             return new XMLX509SubjectName(e, this.baseURI);
@@ -402,14 +399,14 @@
      * Method itemCertificate
      *
      * @param i
-     * @return the X509Certifacte, null if not present
+     * @return the X509Certificate, null if not present
      * @throws XMLSecurityException
      */
     public XMLX509Certificate itemCertificate(int i) throws XMLSecurityException {
 
         Element e =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_X509CERTIFICATE, i);
+                getFirstChild(), Constants._TAG_X509CERTIFICATE, i);
 
         if (e != null) {
             return new XMLX509Certificate(e, this.baseURI);
@@ -428,7 +425,7 @@
 
         Element e =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_X509CRL, i);
+                getFirstChild(), Constants._TAG_X509CRL, i);
 
         if (e != null) {
             return new XMLX509CRL(e, this.baseURI);
@@ -447,7 +444,7 @@
 
         Element e =
             XMLUtils.selectDs11Node(
-                this.constructionElement.getFirstChild(), Constants._TAG_X509DIGEST, i);
+                getFirstChild(), Constants._TAG_X509DIGEST, i);
 
         if (e != null) {
             return new XMLX509Digest(e, this.baseURI);
@@ -463,9 +460,7 @@
      * TODO implement
      **/
     public Element itemUnknownElement(int i) {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "itemUnknownElement not implemented:" + i);
-        }
+        LOG.debug("itemUnknownElement not implemented: {}", i);
         return null;
     }
 
@@ -532,7 +527,7 @@
         return this.lengthUnknownElement() > 0;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_X509DATA;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/DSAKeyValue.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/DSAKeyValue.java	Sat Oct 24 01:11:51 2020 +0100
@@ -27,6 +27,7 @@
 import java.security.KeyFactory;
 import java.security.NoSuchAlgorithmException;
 import java.security.PublicKey;
+import java.security.interfaces.DSAParams;
 import java.security.interfaces.DSAPublicKey;
 import java.security.spec.DSAPublicKeySpec;
 import java.security.spec.InvalidKeySpecException;
@@ -35,7 +36,6 @@
 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.SignatureElementProxy;
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -64,7 +64,7 @@
     public DSAKeyValue(Document doc, BigInteger P, BigInteger Q, BigInteger G, BigInteger Y) {
         super(doc);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
         this.addBigIntegerElement(P, Constants._TAG_P);
         this.addBigIntegerElement(Q, Constants._TAG_Q);
         this.addBigIntegerElement(G, Constants._TAG_G);
@@ -81,12 +81,13 @@
     public DSAKeyValue(Document doc, Key key) throws IllegalArgumentException {
         super(doc);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
 
-        if (key instanceof java.security.interfaces.DSAPublicKey) {
-            this.addBigIntegerElement(((DSAPublicKey) key).getParams().getP(), Constants._TAG_P);
-            this.addBigIntegerElement(((DSAPublicKey) key).getParams().getQ(), Constants._TAG_Q);
-            this.addBigIntegerElement(((DSAPublicKey) key).getParams().getG(), Constants._TAG_G);
+        if (key instanceof DSAPublicKey) {
+            DSAParams params = ((DSAPublicKey) key).getParams();
+            this.addBigIntegerElement(params.getP(), Constants._TAG_P);
+            this.addBigIntegerElement(params.getQ(), Constants._TAG_Q);
+            this.addBigIntegerElement(params.getG(), Constants._TAG_G);
             this.addBigIntegerElement(((DSAPublicKey) key).getY(), Constants._TAG_Y);
         } else {
             Object exArgs[] = { Constants._TAG_DSAKEYVALUE, key.getClass().getName() };
@@ -95,7 +96,7 @@
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public PublicKey getPublicKey() throws XMLSecurityException {
         try {
             DSAPublicKeySpec pkspec =
@@ -118,13 +119,13 @@
 
             return pk;
         } catch (NoSuchAlgorithmException ex) {
-            throw new XMLSecurityException("empty", ex);
+            throw new XMLSecurityException(ex);
         } catch (InvalidKeySpecException ex) {
-            throw new XMLSecurityException("empty", ex);
+            throw new XMLSecurityException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_DSAKEYVALUE;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/RSAKeyValue.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/RSAKeyValue.java	Sat Oct 24 01:11:51 2020 +0100
@@ -35,7 +35,6 @@
 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.SignatureElementProxy;
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -45,11 +44,11 @@
      * Constructor RSAKeyValue
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public RSAKeyValue(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public RSAKeyValue(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
     }
 
     /**
@@ -62,7 +61,7 @@
     public RSAKeyValue(Document doc, BigInteger modulus, BigInteger exponent) {
         super(doc);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
         this.addBigIntegerElement(modulus, Constants._TAG_MODULUS);
         this.addBigIntegerElement(exponent, Constants._TAG_EXPONENT);
     }
@@ -77,9 +76,9 @@
     public RSAKeyValue(Document doc, Key key) throws IllegalArgumentException {
         super(doc);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
 
-        if (key instanceof java.security.interfaces.RSAPublicKey ) {
+        if (key instanceof RSAPublicKey ) {
             this.addBigIntegerElement(
                 ((RSAPublicKey) key).getModulus(), Constants._TAG_MODULUS
             );
@@ -93,7 +92,7 @@
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public PublicKey getPublicKey() throws XMLSecurityException {
         try {
             KeyFactory rsaFactory = KeyFactory.getInstance("RSA");
@@ -111,13 +110,13 @@
 
             return pk;
         } catch (NoSuchAlgorithmException ex) {
-            throw new XMLSecurityException("empty", ex);
+            throw new XMLSecurityException(ex);
         } catch (InvalidKeySpecException ex) {
-            throw new XMLSecurityException("empty", ex);
+            throw new XMLSecurityException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_RSAKEYVALUE;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-basic handlers for elements that can occur inside <CODE>ds:KeyValue</CODE>.
-</P></BODY></HTML>
\ No newline at end of file
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-basic handlers for elements that can occur inside <CODE>ds:KeyInfo</CODE>.
-</P></BODY></HTML>
\ No newline at end of file
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509CRL.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509CRL.java	Sat Oct 24 01:11:51 2020 +0100
@@ -34,11 +34,11 @@
      * Constructor XMLX509CRL
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public XMLX509CRL(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public XMLX509CRL(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
     }
 
     /**
@@ -63,7 +63,7 @@
         return this.getBytesFromTextChild();
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_X509CRL;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Certificate.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Certificate.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,6 +23,8 @@
 package com.sun.org.apache.xml.internal.security.keys.content.x509;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.security.PublicKey;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
@@ -44,11 +46,11 @@
      * Constructor X509Certificate
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public XMLX509Certificate(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public XMLX509Certificate(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
     }
 
     /**
@@ -77,7 +79,7 @@
         try {
             this.addBase64Text(x509certificate.getEncoded());
         } catch (java.security.cert.CertificateEncodingException ex) {
-            throw new XMLSecurityException("empty", ex);
+            throw new XMLSecurityException(ex);
         }
     }
 
@@ -98,22 +100,20 @@
      * @throws XMLSecurityException
      */
     public X509Certificate getX509Certificate() throws XMLSecurityException {
-        try {
-            byte certbytes[] = this.getCertificateBytes();
+        byte certbytes[] = this.getCertificateBytes();
+        try (InputStream is = new ByteArrayInputStream(certbytes)) {
             CertificateFactory certFact =
                 CertificateFactory.getInstance(XMLX509Certificate.JCA_CERT_ID);
             X509Certificate cert =
-                (X509Certificate) certFact.generateCertificate(
-                    new ByteArrayInputStream(certbytes)
-                );
+                (X509Certificate) certFact.generateCertificate(is);
 
             if (cert != null) {
                 return cert;
             }
 
             return null;
-        } catch (CertificateException ex) {
-            throw new XMLSecurityException("empty", ex);
+        } catch (CertificateException | IOException ex) {
+            throw new XMLSecurityException(ex);
         }
     }
 
@@ -123,7 +123,7 @@
      * @return the publickey
      * @throws XMLSecurityException
      */
-    public PublicKey getPublicKey() throws XMLSecurityException {
+    public PublicKey getPublicKey() throws XMLSecurityException, IOException {
         X509Certificate cert = this.getX509Certificate();
 
         if (cert != null) {
@@ -133,7 +133,7 @@
         return null;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public boolean equals(Object obj) {
         if (!(obj instanceof XMLX509Certificate)) {
             return false;
@@ -154,14 +154,12 @@
                 result = 31 * result + bytes[i];
             }
         } catch (XMLSecurityException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
+            LOG.debug(e.getMessage(), e);
         }
         return result;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_X509CERTIFICATE;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509DataContent.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509DataContent.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,7 +25,6 @@
 /**
  * Just used for tagging contents that are allowed inside a ds:X509Data Element.
  *
- * @author $Author: coheigea $
  */
 public interface XMLX509DataContent {
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Digest.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Digest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -34,9 +34,8 @@
 import org.w3c.dom.Element;
 
 /**
- * Provides content model support for the <code>dsig11:X509Digest</code> element.
+ * Provides content model support for the {@code dsig11:X509Digest} element.
  *
- * @author Brent Putman (putmanb@georgetown.edu)
  */
 public class XMLX509Digest extends Signature11ElementProxy implements XMLX509DataContent {
 
@@ -44,11 +43,11 @@
      * Constructor XMLX509Digest
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public XMLX509Digest(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public XMLX509Digest(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
     }
 
     /**
@@ -61,7 +60,7 @@
     public XMLX509Digest(Document doc, byte[] digestBytes, String algorithmURI) {
         super(doc);
         this.addBase64Text(digestBytes);
-        this.constructionElement.setAttributeNS(null, Constants._ATT_ALGORITHM, algorithmURI);
+        setLocalAttribute(Constants._ATT_ALGORITHM, algorithmURI);
     }
 
     /**
@@ -75,7 +74,7 @@
     public XMLX509Digest(Document doc, X509Certificate x509certificate, String algorithmURI) throws XMLSecurityException {
         super(doc);
         this.addBase64Text(getDigestBytesFromCert(x509certificate, algorithmURI));
-        this.constructionElement.setAttributeNS(null, Constants._ATT_ALGORITHM, algorithmURI);
+        setLocalAttribute(Constants._ATT_ALGORITHM, algorithmURI);
     }
 
     /**
@@ -84,7 +83,7 @@
      * @return the Algorithm attribute
      */
     public Attr getAlgorithmAttr() {
-        return this.constructionElement.getAttributeNodeNS(null, Constants._ATT_ALGORITHM);
+        return getElement().getAttributeNodeNS(null, Constants._ATT_ALGORITHM);
     }
 
     /**
@@ -118,21 +117,21 @@
     public static byte[] getDigestBytesFromCert(X509Certificate cert, String algorithmURI) throws XMLSecurityException {
         String jcaDigestAlgorithm = JCEMapper.translateURItoJCEID(algorithmURI);
         if (jcaDigestAlgorithm == null) {
-            Object exArgs[] = { algorithmURI };
-            throw new XMLSecurityException("XMLX509Digest.UnknownDigestAlgorithm", exArgs);
+                Object exArgs[] = { algorithmURI };
+                throw new XMLSecurityException("XMLX509Digest.UnknownDigestAlgorithm", exArgs);
         }
 
         try {
-            MessageDigest md = MessageDigest.getInstance(jcaDigestAlgorithm);
-            return md.digest(cert.getEncoded());
-        } catch (Exception e) {
-            Object exArgs[] = { jcaDigestAlgorithm };
-            throw new XMLSecurityException("XMLX509Digest.FailedDigest", exArgs);
-        }
+                        MessageDigest md = MessageDigest.getInstance(jcaDigestAlgorithm);
+                        return md.digest(cert.getEncoded());
+                } catch (Exception e) {
+                Object exArgs[] = { jcaDigestAlgorithm };
+                        throw new XMLSecurityException("XMLX509Digest.FailedDigest", exArgs);
+                }
 
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_X509DIGEST;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509IssuerSerial.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509IssuerSerial.java	Sat Oct 24 01:11:51 2020 +0100
@@ -29,15 +29,13 @@
 import com.sun.org.apache.xml.internal.security.utils.Constants;
 import com.sun.org.apache.xml.internal.security.utils.RFC2253Parser;
 import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy;
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 public class XMLX509IssuerSerial extends SignatureElementProxy implements XMLX509DataContent {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(XMLX509IssuerSerial.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(XMLX509IssuerSerial.class);
 
     /**
      * Constructor XMLX509IssuerSerial
@@ -59,7 +57,7 @@
      */
     public XMLX509IssuerSerial(Document doc, String x509IssuerName, BigInteger x509SerialNumber) {
         super(doc);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
         addTextElement(x509IssuerName, Constants._TAG_X509ISSUERNAME);
         addTextElement(x509SerialNumber.toString(), Constants._TAG_X509SERIALNUMBER);
     }
@@ -108,9 +106,7 @@
     public BigInteger getSerialNumber() {
         String text =
             this.getTextFromChildElement(Constants._TAG_X509SERIALNUMBER, Constants.SignatureSpecNS);
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "X509SerialNumber text: " + text);
-        }
+        LOG.debug("X509SerialNumber text: {}", text);
 
         return new BigInteger(text);
     }
@@ -135,7 +131,7 @@
         );
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public boolean equals(Object obj) {
         if (!(obj instanceof XMLX509IssuerSerial)) {
             return false;
@@ -154,7 +150,7 @@
         return result;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_X509ISSUERSERIAL;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java	Sat Oct 24 01:11:51 2020 +0100
@@ -24,9 +24,9 @@
 
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
+import java.util.Base64;
 
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
-import com.sun.org.apache.xml.internal.security.utils.Base64;
 import com.sun.org.apache.xml.internal.security.utils.Constants;
 import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy;
 import org.w3c.dom.Document;
@@ -40,20 +40,19 @@
  */
 public class XMLX509SKI extends SignatureElementProxy implements XMLX509DataContent {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(XMLX509SKI.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(XMLX509SKI.class);
 
     /**
-     * <CODE>SubjectKeyIdentifier (id-ce-subjectKeyIdentifier) (2.5.29.14)</CODE>:
+     * {@code SubjectKeyIdentifier (id-ce-subjectKeyIdentifier) (2.5.29.14)}:
      * This extension identifies the public key being certified. It enables
      * distinct keys used by the same subject to be differentiated
      * (e.g., as key updating occurs).
-     * <BR />
+     * <p></p>
      * A key identifier shall be unique with respect to all key identifiers
      * for the subject with which it is used. This extension is always non-critical.
      */
-    public static final String SKI_OID = "2.5.29.14";
+    public static final String SKI_OID = "2.5.29.14"; //NOPMD
 
     /**
      * Constructor X509SKI
@@ -83,11 +82,11 @@
      * Constructor XMLX509SKI
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public XMLX509SKI(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public XMLX509SKI(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
     }
 
     /**
@@ -113,7 +112,7 @@
         throws XMLSecurityException {
 
         if (cert.getVersion() < 3) {
-            Object exArgs[] = { Integer.valueOf(cert.getVersion()) };
+            Object exArgs[] = { cert.getVersion() };
             throw new XMLSecurityException("certificate.noSki.lowVersion", exArgs);
         }
 
@@ -138,14 +137,14 @@
 
         System.arraycopy(extensionValue, 4, skidValue, 0, skidValue.length);
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Base64 of SKI is " + Base64.encode(skidValue));
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Base64 of SKI is " + Base64.getMimeEncoder().encodeToString(skidValue));
         }
 
         return skidValue;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public boolean equals(Object obj) {
         if (!(obj instanceof XMLX509SKI)) {
             return false;
@@ -168,15 +167,13 @@
                 result = 31 * result + bytes[i];
             }
         } catch (XMLSecurityException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
+            LOG.debug(e.getMessage(), e);
         }
         return result;
 
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_X509SKI;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SubjectName.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SubjectName.java	Sat Oct 24 01:11:51 2020 +0100
@@ -32,7 +32,6 @@
 import org.w3c.dom.Element;
 
 /**
- * @author $Author: coheigea $
  */
 public class XMLX509SubjectName extends SignatureElementProxy implements XMLX509DataContent {
 
@@ -40,12 +39,12 @@
      * Constructor X509SubjectName
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public XMLX509SubjectName(Element element, String BaseURI)
+    public XMLX509SubjectName(Element element, String baseURI)
         throws XMLSecurityException {
-        super(element, BaseURI);
+        super(element, baseURI);
     }
 
     /**
@@ -80,7 +79,7 @@
         return RFC2253Parser.normalize(this.getTextFromTextChild());
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public boolean equals(Object obj) {
         if (!(obj instanceof XMLX509SubjectName)) {
             return false;
@@ -99,7 +98,7 @@
         return result;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_X509SUBJECTNAME;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-basic handlers for elements that can occur inside <CODE>ds:X509Data</CODE>.
-</P></BODY></HTML>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/ClassLoaderUtils.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,84 @@
+/*
+ * 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.keys.keyresolver;
+
+// NOTE! This is a duplicate of utils.ClassLoaderUtils with public
+// modifiers changed to package-private. Make sure to integrate any future
+// changes to utils.ClassLoaderUtils to this file.
+final class ClassLoaderUtils {
+
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ClassLoaderUtils.class);
+
+    private ClassLoaderUtils() {
+    }
+
+    /**
+     * Load a class with a given name. <p></p> It will try to load the class in the
+     * following order:
+     * <ul>
+     * <li>From Thread.currentThread().getContextClassLoader()
+     * <li>Using the basic Class.forName()
+     * <li>From ClassLoaderUtil.class.getClassLoader()
+     * <li>From the callingClass.getClassLoader()
+     * </ul>
+     *
+     * @param className The name of the class to load
+     * @param callingClass The Class object of the calling object
+     * @throws ClassNotFoundException If the class cannot be found anywhere.
+     */
+    static Class<?> loadClass(String className, Class<?> callingClass)
+        throws ClassNotFoundException {
+        try {
+            ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
+            if (cl != null) {
+                return cl.loadClass(className);
+            }
+        } catch (ClassNotFoundException e) {
+            LOG.debug(e.getMessage(), e);
+            //ignore
+        }
+        return loadClass2(className, callingClass);
+    }
+
+    private static Class<?> loadClass2(String className, Class<?> callingClass)
+        throws ClassNotFoundException {
+        try {
+            return Class.forName(className);
+        } catch (ClassNotFoundException ex) {
+            try {
+                if (ClassLoaderUtils.class.getClassLoader() != null) {
+                    return ClassLoaderUtils.class.getClassLoader().loadClass(className);
+                }
+            } catch (ClassNotFoundException exc) {
+                if (callingClass != null && callingClass.getClassLoader() != null) {
+                    return callingClass.getClassLoader().loadClass(className);
+                }
+            }
+            LOG.debug(ex.getMessage(), ex);
+            throw ex;
+        }
+    }
+}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/InvalidKeyResolverException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/InvalidKeyResolverException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -61,21 +61,31 @@
     /**
      * Constructor InvalidKeyResolverException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public InvalidKeyResolverException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public InvalidKeyResolverException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor InvalidKeyResolverException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
-    public InvalidKeyResolverException(String msgID, Object exArgs[], Exception originalException) {
-        super(msgID, exArgs, originalException);
+    public InvalidKeyResolverException(Exception originalException, String msgID, Object exArgs[]) {
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public InvalidKeyResolverException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -52,9 +52,8 @@
  */
 public class KeyResolver {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(KeyResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(KeyResolver.class);
 
     /** Field resolverVector */
     private static List<KeyResolver> resolverVector = new CopyOnWriteArrayList<KeyResolver>();
@@ -96,16 +95,14 @@
         for (KeyResolver resolver : resolverVector) {
             if (resolver == null) {
                 Object exArgs[] = {
-                                   (((element != null)
-                                       && (element.getNodeType() == Node.ELEMENT_NODE))
-                                       ? element.getTagName() : "null")
+                                   element != null
+                                       && element.getNodeType() == Node.ELEMENT_NODE
+                                       ? element.getTagName() : "null"
                 };
 
                 throw new KeyResolverException("utils.resolver.noClass", exArgs);
             }
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "check resolvability by class " + resolver.getClass());
-            }
+            LOG.debug("check resolvability by class {}", resolver.getClass());
 
             X509Certificate cert = resolver.resolveX509Certificate(element, baseURI, storage);
             if (cert != null) {
@@ -114,8 +111,8 @@
         }
 
         Object exArgs[] = {
-                           (((element != null) && (element.getNodeType() == Node.ELEMENT_NODE))
-                           ? element.getTagName() : "null")
+                           element != null && element.getNodeType() == Node.ELEMENT_NODE
+                           ? element.getTagName() : "null"
                           };
 
         throw new KeyResolverException("utils.resolver.noClass", exArgs);
@@ -137,16 +134,14 @@
         for (KeyResolver resolver : resolverVector) {
             if (resolver == null) {
                 Object exArgs[] = {
-                                   (((element != null)
-                                       && (element.getNodeType() == Node.ELEMENT_NODE))
-                                       ? element.getTagName() : "null")
+                                   element != null
+                                       && element.getNodeType() == Node.ELEMENT_NODE
+                                       ? element.getTagName() : "null"
                 };
 
                 throw new KeyResolverException("utils.resolver.noClass", exArgs);
             }
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "check resolvability by class " + resolver.getClass());
-            }
+            LOG.debug("check resolvability by class {}", resolver.getClass());
 
             PublicKey cert = resolver.resolvePublicKey(element, baseURI, storage);
             if (cert != null) {
@@ -155,8 +150,8 @@
         }
 
         Object exArgs[] = {
-                           (((element != null) && (element.getNodeType() == Node.ELEMENT_NODE))
-                           ? element.getTagName() : "null")
+                           element != null && element.getNodeType() == Node.ELEMENT_NODE
+                           ? element.getTagName() : "null"
                           };
 
         throw new KeyResolverException("utils.resolver.noClass", exArgs);
@@ -183,7 +178,7 @@
         throws ClassNotFoundException, IllegalAccessException, InstantiationException {
         JavaUtils.checkRegisterPermission();
         KeyResolverSpi keyResolverSpi =
-            (KeyResolverSpi) Class.forName(className).newInstance();
+            (KeyResolverSpi) ClassLoaderUtils.loadClass(className, KeyResolver.class).newInstance();
         keyResolverSpi.setGlobalResolver(globalResolver);
         register(keyResolverSpi, false);
     }
@@ -207,7 +202,10 @@
         KeyResolverSpi keyResolverSpi = null;
         Exception ex = null;
         try {
-            keyResolverSpi = (KeyResolverSpi) Class.forName(className).newInstance();
+            KeyResolverSpi tmp = (KeyResolverSpi) ClassLoaderUtils.loadClass(className, KeyResolver.class).newInstance();
+            keyResolverSpi = tmp;
+            keyResolverSpi.setGlobalResolver(globalResolver);
+            register(keyResolverSpi, true);
         } catch (ClassNotFoundException e) {
             ex = e;
         } catch (IllegalAccessException e) {
@@ -220,8 +218,6 @@
             throw (IllegalArgumentException) new
             IllegalArgumentException("Invalid KeyResolver class name").initCause(ex);
         }
-        keyResolverSpi.setGlobalResolver(globalResolver);
-        register(keyResolverSpi, true);
     }
 
     /**
@@ -270,10 +266,10 @@
     public static void registerClassNames(List<String> classNames)
         throws ClassNotFoundException, IllegalAccessException, InstantiationException {
         JavaUtils.checkRegisterPermission();
-        List<KeyResolver> keyResolverList = new ArrayList<KeyResolver>(classNames.size());
+        List<KeyResolver> keyResolverList = new ArrayList<>(classNames.size());
         for (String className : classNames) {
             KeyResolverSpi keyResolverSpi =
-                (KeyResolverSpi) Class.forName(className).newInstance();
+                (KeyResolverSpi)ClassLoaderUtils.loadClass(className, KeyResolver.class).newInstance();
             keyResolverSpi.setGlobalResolver(false);
             keyResolverList.add(new KeyResolver(keyResolverSpi));
         }
@@ -285,7 +281,7 @@
      */
     public static void registerDefaultResolvers() {
 
-        List<KeyResolver> keyResolverList = new ArrayList<KeyResolver>();
+        List<KeyResolver> keyResolverList = new ArrayList<>();
         keyResolverList.add(new KeyResolver(new RSAKeyValueResolver()));
         keyResolverList.add(new KeyResolver(new DSAKeyValueResolver()));
         keyResolverList.add(new KeyResolver(new X509CertificateResolver()));
@@ -414,7 +410,7 @@
         public void remove() {
             throw new UnsupportedOperationException("Can't remove resolvers using the iterator");
         }
-    };
+    }
 
     public static Iterator<KeyResolverSpi> iterator() {
         return new ResolverIterator(resolverVector);
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -39,6 +39,10 @@
         super();
     }
 
+    public KeyResolverException(Exception ex) {
+        super(ex);
+    }
+
     /**
      * Constructor KeyResolverException
      *
@@ -61,21 +65,31 @@
     /**
      * Constructor KeyResolverException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public KeyResolverException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public KeyResolverException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor KeyResolverException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
-    public KeyResolverException(String msgID, Object exArgs[], Exception originalException) {
-        super(msgID, exArgs, originalException);
+    public KeyResolverException(Exception originalException, String msgID, Object exArgs[]) {
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public KeyResolverException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverSpi.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolverSpi.java	Sat Oct 24 01:11:51 2020 +0100
@@ -22,15 +22,23 @@
  */
 package com.sun.org.apache.xml.internal.security.keys.keyresolver;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
 import java.util.HashMap;
 
 import javax.crypto.SecretKey;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
 
 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
 
 /**
  * This class is an abstract class for a child KeyInfo Element.
@@ -45,7 +53,7 @@
 public abstract class KeyResolverSpi {
 
     /** Field properties */
-    protected java.util.Map<String, String> properties = null;
+    protected java.util.Map<String, String> properties;
 
     protected boolean globalResolver = false;
 
@@ -84,7 +92,7 @@
         Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
         throw new UnsupportedOperationException();
-    };
+    }
 
     /**
      * Method engineLookupAndResolvePublicKey
@@ -107,17 +115,17 @@
     }
 
     private KeyResolverSpi cloneIfNeeded() throws KeyResolverException {
-        KeyResolverSpi tmp = this;
         if (globalResolver) {
             try {
-                tmp = getClass().newInstance();
+                KeyResolverSpi tmp = getClass().newInstance();
+                return tmp;
             } catch (InstantiationException e) {
-                throw new KeyResolverException("", e);
+                throw new KeyResolverException(e, "");
             } catch (IllegalAccessException e) {
-                throw new KeyResolverException("", e);
+                throw new KeyResolverException(e, "");
             }
         }
-        return tmp;
+        return this;
     }
 
     /**
@@ -134,7 +142,7 @@
         Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException{
         throw new UnsupportedOperationException();
-    };
+    }
 
     /**
      * Method engineLookupResolveX509Certificate
@@ -170,7 +178,7 @@
         Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException{
         throw new UnsupportedOperationException();
-    };
+    }
 
     /**
      * Method engineLookupAndResolveSecretKey
@@ -221,7 +229,7 @@
      */
     public void engineSetProperty(String key, String value) {
         if (properties == null) {
-            properties = new HashMap<String, String>();
+            properties = new HashMap<>();
         }
         properties.put(key, value);
     }
@@ -258,4 +266,27 @@
         this.globalResolver = globalResolver;
     }
 
+
+    /**
+     * Parses a byte array and returns the parsed Element.
+     *
+     * @param bytes
+     * @return the Document Element after parsing bytes
+     * @throws KeyResolverException if something goes wrong
+     */
+    protected static Element getDocFromBytes(byte[] bytes, boolean secureValidation) throws KeyResolverException {
+        DocumentBuilder db = null;
+        try (InputStream is = new ByteArrayInputStream(bytes)) {
+            db = XMLUtils.createDocumentBuilder(false, secureValidation);
+            Document doc = db.parse(is);
+            return doc.getDocumentElement();
+        } catch (SAXException ex) {
+            throw new KeyResolverException(ex);
+        } catch (IOException ex) {
+            throw new KeyResolverException(ex);
+        } catch (ParserConfigurationException ex) {
+            throw new KeyResolverException(ex);
+        }
+    }
+
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/DEREncodedKeyValueResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/DEREncodedKeyValueResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -2,6 +2,24 @@
  * 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.keys.keyresolver.implementations;
 
 import java.security.PrivateKey;
@@ -21,28 +39,24 @@
 
 /**
  * KeyResolverSpi implementation which resolves public keys from a
- * <code>dsig11:DEREncodedKeyValue</code> element.
+ * {@code dsig11:DEREncodedKeyValue} element.
  *
- * @author Brent Putman (putmanb@georgetown.edu)
  */
 public class DEREncodedKeyValueResolver extends KeyResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(DEREncodedKeyValueResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(DEREncodedKeyValueResolver.class);
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public boolean engineCanResolve(Element element, String baseURI, StorageResolver storage) {
         return XMLUtils.elementIsInSignature11Space(element, Constants._TAG_DERENCODEDKEYVALUE);
     }
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public PublicKey engineLookupAndResolvePublicKey(Element element, String baseURI, StorageResolver storage)
         throws KeyResolverException {
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName());
-        }
+        LOG.debug("Can I resolve {}", element.getTagName());
 
         if (!engineCanResolve(element, baseURI, storage)) {
             return null;
@@ -52,27 +66,25 @@
             DEREncodedKeyValue derKeyValue = new DEREncodedKeyValue(element, baseURI);
             return derKeyValue.getPublicKey();
         } catch (XMLSecurityException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "XMLSecurityException", e);
-            }
+            LOG.debug("XMLSecurityException", e);
         }
 
         return null;
     }
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public X509Certificate engineLookupResolveX509Certificate(Element element, String baseURI, StorageResolver storage)
         throws KeyResolverException {
         return null;
     }
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public SecretKey engineLookupAndResolveSecretKey(Element element, String baseURI, StorageResolver storage)
         throws KeyResolverException {
         return null;
     }
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public PrivateKey engineLookupAndResolvePrivateKey(Element element, String baseURI, StorageResolver storage)
         throws KeyResolverException {
         return null;
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/DSAKeyValueResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/DSAKeyValueResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -35,21 +35,20 @@
 
 public class DSAKeyValueResolver extends KeyResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(DSAKeyValueResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(DSAKeyValueResolver.class);
 
 
     /**
      * Method engineResolvePublicKey
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @param storage
      * @return null if no {@link PublicKey} could be obtained
      */
     public PublicKey engineLookupAndResolvePublicKey(
-        Element element, String BaseURI, StorageResolver storage
+        Element element, String baseURI, StorageResolver storage
     ) {
         if (element == null) {
             return null;
@@ -71,14 +70,12 @@
         }
 
         try {
-            DSAKeyValue dsaKeyValue = new DSAKeyValue(dsaKeyElement, BaseURI);
+            DSAKeyValue dsaKeyValue = new DSAKeyValue(dsaKeyElement, baseURI);
             PublicKey pk = dsaKeyValue.getPublicKey();
 
             return pk;
         } catch (XMLSecurityException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-            }
+            LOG.debug(ex.getMessage(), ex);
             //do nothing
         }
 
@@ -86,16 +83,16 @@
     }
 
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public X509Certificate engineLookupResolveX509Certificate(
-        Element element, String BaseURI, StorageResolver storage
+        Element element, String baseURI, StorageResolver storage
     ) {
         return null;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public javax.crypto.SecretKey engineLookupAndResolveSecretKey(
-        Element element, String BaseURI, StorageResolver storage
+        Element element, String baseURI, StorageResolver storage
     ) {
         return null;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/EncryptedKeyResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/*
- * 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.keys.keyresolver.implementations;
-
-import java.security.Key;
-import java.security.PublicKey;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.crypto.SecretKey;
-
-import com.sun.org.apache.xml.internal.security.encryption.EncryptedKey;
-import com.sun.org.apache.xml.internal.security.encryption.XMLCipher;
-import com.sun.org.apache.xml.internal.security.encryption.XMLEncryptionException;
-import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverSpi;
-import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver;
-import com.sun.org.apache.xml.internal.security.utils.EncryptionConstants;
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
-import org.w3c.dom.Element;
-
-/**
- * The <code>EncryptedKeyResolver</code> is not a generic resolver.  It can
- * only be for specific instantiations, as the key being unwrapped will
- * always be of a particular type and will always have been wrapped by
- * another key which needs to be recursively resolved.
- *
- * The <code>EncryptedKeyResolver</code> can therefore only be instantiated
- * with an algorithm.  It can also be instantiated with a key (the KEK) or
- * will search the static KeyResolvers to find the appropriate key.
- *
- * @author Berin Lautenbach
- */
-public class EncryptedKeyResolver extends KeyResolverSpi {
-
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(EncryptedKeyResolver.class.getName());
-
-    private Key kek;
-    private String algorithm;
-    private List<KeyResolverSpi> internalKeyResolvers;
-
-    /**
-     * Constructor for use when a KEK needs to be derived from a KeyInfo
-     * list
-     * @param algorithm
-     */
-    public EncryptedKeyResolver(String algorithm) {
-        kek = null;
-        this.algorithm = algorithm;
-    }
-
-    /**
-     * Constructor used for when a KEK has been set
-     * @param algorithm
-     * @param kek
-     */
-    public EncryptedKeyResolver(String algorithm, Key kek) {
-        this.algorithm = algorithm;
-        this.kek = kek;
-    }
-
-    /**
-     * This method is used to add a custom {@link KeyResolverSpi} to help
-     * resolve the KEK.
-     *
-     * @param realKeyResolver
-     */
-    public void registerInternalKeyResolver(KeyResolverSpi realKeyResolver) {
-        if (internalKeyResolvers == null) {
-            internalKeyResolvers = new ArrayList<KeyResolverSpi>();
-        }
-        internalKeyResolvers.add(realKeyResolver);
-    }
-
-    /** @inheritDoc */
-    public PublicKey engineLookupAndResolvePublicKey(
-        Element element, String BaseURI, StorageResolver storage
-    ) {
-        return null;
-    }
-
-    /** @inheritDoc */
-    public X509Certificate engineLookupResolveX509Certificate(
-        Element element, String BaseURI, StorageResolver storage
-    ) {
-        return null;
-    }
-
-    /** @inheritDoc */
-    public javax.crypto.SecretKey engineLookupAndResolveSecretKey(
-        Element element, String BaseURI, StorageResolver storage
-    ) {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "EncryptedKeyResolver - Can I resolve " + element.getTagName());
-        }
-
-        if (element == null) {
-            return null;
-        }
-
-        SecretKey key = null;
-        boolean isEncryptedKey =
-            XMLUtils.elementIsInEncryptionSpace(element, EncryptionConstants._TAG_ENCRYPTEDKEY);
-        if (isEncryptedKey) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Passed an Encrypted Key");
-            }
-            try {
-                XMLCipher cipher = XMLCipher.getInstance();
-                cipher.init(XMLCipher.UNWRAP_MODE, kek);
-                if (internalKeyResolvers != null) {
-                    int size = internalKeyResolvers.size();
-                    for (int i = 0; i < size; i++) {
-                        cipher.registerInternalKeyResolver(internalKeyResolvers.get(i));
-                    }
-                }
-                EncryptedKey ek = cipher.loadEncryptedKey(element);
-                key = (SecretKey) cipher.decryptKey(ek, algorithm);
-            } catch (XMLEncryptionException e) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                }
-            }
-        }
-
-        return key;
-    }
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -2,19 +2,33 @@
  * 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.keys.keyresolver.implementations;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
 
 import javax.crypto.SecretKey;
-import javax.xml.XMLConstants;
 import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
@@ -29,34 +43,29 @@
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver;
 import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.xml.sax.SAXException;
 
 /**
  * KeyResolverSpi implementation which resolves public keys, private keys, secret keys, and X.509 certificates from a
- * <code>dsig11:KeyInfoReference</code> element.
+ * {@code dsig11:KeyInfoReference} element.
  *
- * @author Brent Putman (putmanb@georgetown.edu)
  */
 public class KeyInfoReferenceResolver extends KeyResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(KeyInfoReferenceResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(KeyInfoReferenceResolver.class);
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public boolean engineCanResolve(Element element, String baseURI, StorageResolver storage) {
         return XMLUtils.elementIsInSignature11Space(element, Constants._TAG_KEYINFOREFERENCE);
     }
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public PublicKey engineLookupAndResolvePublicKey(Element element, String baseURI, StorageResolver storage)
         throws KeyResolverException {
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName());
-        }
+        LOG.debug("Can I resolve {}", element.getTagName());
 
         if (!engineCanResolve(element, baseURI, storage)) {
             return null;
@@ -68,21 +77,17 @@
                 return referent.getPublicKey();
             }
         } catch (XMLSecurityException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "XMLSecurityException", e);
-            }
+            LOG.debug("XMLSecurityException", e);
         }
 
         return null;
     }
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public X509Certificate engineLookupResolveX509Certificate(Element element, String baseURI, StorageResolver storage)
         throws KeyResolverException {
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName());
-        }
+        LOG.debug("Can I resolve {}", element.getTagName());
 
         if (!engineCanResolve(element, baseURI, storage)) {
             return null;
@@ -94,21 +99,17 @@
                 return referent.getX509Certificate();
             }
         } catch (XMLSecurityException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "XMLSecurityException", e);
-            }
+            LOG.debug("XMLSecurityException", e);
         }
 
         return null;
     }
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public SecretKey engineLookupAndResolveSecretKey(Element element, String baseURI, StorageResolver storage)
         throws KeyResolverException {
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName());
-        }
+        LOG.debug("Can I resolve {}", element.getTagName());
 
         if (!engineCanResolve(element, baseURI, storage)) {
             return null;
@@ -120,21 +121,17 @@
                 return referent.getSecretKey();
             }
         } catch (XMLSecurityException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "XMLSecurityException", e);
-            }
+            LOG.debug("XMLSecurityException", e);
         }
 
         return null;
     }
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public PrivateKey engineLookupAndResolvePrivateKey(Element element, String baseURI, StorageResolver storage)
         throws KeyResolverException {
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName());
-        }
+        LOG.debug("Can I resolve " + element.getTagName());
 
         if (!engineCanResolve(element, baseURI, storage)) {
             return null;
@@ -146,9 +143,7 @@
                 return referent.getPrivateKey();
             }
         } catch (XMLSecurityException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "XMLSecurityException", e);
-            }
+            LOG.debug("XMLSecurityException", e);
         }
 
         return null;
@@ -173,14 +168,12 @@
         try {
             referentElement = obtainReferenceElement(resource);
         } catch (Exception e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "XMLSecurityException", e);
-            }
+            LOG.debug("XMLSecurityException", e);
             return null;
         }
 
         if (referentElement == null) {
-            log.log(java.util.logging.Level.FINE, "De-reference of KeyInfoReference URI returned null: " + uriAttr.getValue());
+            LOG.debug("De-reference of KeyInfoReference URI returned null: {}", uriAttr.getValue());
             return null;
         }
 
@@ -224,21 +217,20 @@
      * @param uri
      * @param baseURI
      * @param secureValidation
-     * @return
+     * @return the XML signature input represented by the specified URI.
      * @throws XMLSecurityException
      */
     private XMLSignatureInput resolveInput(Attr uri, String baseURI, boolean secureValidation)
         throws XMLSecurityException {
         ResourceResolver resRes = ResourceResolver.getInstance(uri, baseURI, secureValidation);
-        XMLSignatureInput resource = resRes.resolve(uri, baseURI, secureValidation);
-        return resource;
+        return resRes.resolve(uri, baseURI, secureValidation);
     }
 
     /**
      * Resolve the Element effectively represented by the XML signature input source.
      *
      * @param resource
-     * @return
+     * @return the Element effectively represented by the XML signature input source.
      * @throws CanonicalizationException
      * @throws ParserConfigurationException
      * @throws IOException
@@ -253,38 +245,13 @@
         if (resource.isElement()){
             e = (Element) resource.getSubNode();
         } else if (resource.isNodeSet()) {
-            log.log(java.util.logging.Level.FINE, "De-reference of KeyInfoReference returned an unsupported NodeSet");
+            LOG.debug("De-reference of KeyInfoReference returned an unsupported NodeSet");
             return null;
         } else {
             // Retrieved resource is a byte stream
             byte inputBytes[] = resource.getBytes();
-            e = getDocFromBytes(inputBytes);
+            e = getDocFromBytes(inputBytes, this.secureValidation);
         }
         return e;
     }
-
-    /**
-     * Parses a byte array and returns the parsed Element.
-     *
-     * @param bytes
-     * @return the Document Element after parsing bytes
-     * @throws KeyResolverException if something goes wrong
-     */
-    private Element getDocFromBytes(byte[] bytes) throws KeyResolverException {
-        try {
-            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-            dbf.setNamespaceAware(true);
-            dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
-            DocumentBuilder db = dbf.newDocumentBuilder();
-            Document doc = db.parse(new ByteArrayInputStream(bytes));
-            return doc.getDocumentElement();
-        } catch (SAXException ex) {
-            throw new KeyResolverException("empty", ex);
-        } catch (IOException ex) {
-            throw new KeyResolverException("empty", ex);
-        } catch (ParserConfigurationException ex) {
-            throw new KeyResolverException("empty", ex);
-        }
-    }
-
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/PrivateKeyResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/PrivateKeyResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -2,6 +2,24 @@
  * 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.keys.keyresolver.implementations;
 
 import java.security.Key;
@@ -34,9 +52,9 @@
  * For a KeyName hint, the KeyName must match the alias of a PrivateKey entry within the KeyStore.
  */
 public class PrivateKeyResolver extends KeyResolverSpi {
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(PrivateKeyResolver.class.getName());
+
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(PrivateKeyResolver.class);
 
     private KeyStore keyStore;
     private char[] password;
@@ -53,11 +71,11 @@
      * This method returns whether the KeyResolverSpi is able to perform the requested action.
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @param storage
      * @return whether the KeyResolverSpi is able to perform the requested action.
      */
-    public boolean engineCanResolve(Element element, String BaseURI, StorageResolver storage) {
+    public boolean engineCanResolve(Element element, String baseURI, StorageResolver storage) {
         if (XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_X509DATA)
             || XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_KEYNAME)) {
             return true;
@@ -70,27 +88,27 @@
      * Method engineLookupAndResolvePublicKey
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @param storage
      * @return null if no {@link PublicKey} could be obtained
      * @throws KeyResolverException
      */
     public PublicKey engineLookupAndResolvePublicKey(
-        Element element, String BaseURI, StorageResolver storage
+        Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
         return null;
     }
 
     /**
      * Method engineResolveX509Certificate
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @param storage
      * @throws KeyResolverException
      */
     public X509Certificate engineLookupResolveX509Certificate(
-        Element element, String BaseURI, StorageResolver storage
+        Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
         return null;
     }
@@ -99,21 +117,21 @@
      * Method engineResolveSecretKey
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @param storage
      * @return resolved SecretKey key or null if no {@link SecretKey} could be obtained
      *
      * @throws KeyResolverException
      */
     public SecretKey engineResolveSecretKey(
-        Element element, String BaseURI, StorageResolver storage
+        Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
         return null;
     }
 
     /**
      * Method engineResolvePrivateKey
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
      * @param baseURI
      * @param storage
@@ -123,9 +141,7 @@
     public PrivateKey engineLookupAndResolvePrivateKey(
         Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?");
-        }
+        LOG.debug("Can I resolve {}?", element.getTagName());
 
         if (XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_X509DATA)) {
             PrivateKey privKey = resolveX509Data(element, baseURI);
@@ -133,7 +149,7 @@
                 return privKey;
             }
         } else if (XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_KEYNAME)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve KeyName?");
+            LOG.debug("Can I resolve KeyName?");
             String keyName = element.getFirstChild().getNodeValue();
 
             try {
@@ -142,16 +158,16 @@
                     return (PrivateKey) key;
                 }
             } catch (Exception e) {
-                log.log(java.util.logging.Level.FINE, "Cannot recover the key", e);
+                LOG.debug("Cannot recover the key", e);
             }
         }
 
-        log.log(java.util.logging.Level.FINE, "I can't");
+        LOG.debug("I can't");
         return null;
     }
 
     private PrivateKey resolveX509Data(Element element, String baseURI) {
-        log.log(java.util.logging.Level.FINE, "Can I resolve X509Data?");
+        LOG.debug("Can I resolve X509Data?");
 
         try {
             X509Data x509Data = new X509Data(element, baseURI);
@@ -192,9 +208,9 @@
                 }
             }
         } catch (XMLSecurityException e) {
-            log.log(java.util.logging.Level.FINE, "XMLSecurityException", e);
+            LOG.debug("XMLSecurityException", e);
         } catch (KeyStoreException e) {
-            log.log(java.util.logging.Level.FINE, "KeyStoreException", e);
+            LOG.debug("KeyStoreException", e);
         }
 
         return null;
@@ -204,7 +220,7 @@
      * Search for a private key entry in the KeyStore with the same Subject Key Identifier
      */
     private PrivateKey resolveX509SKI(XMLX509SKI x509SKI) throws XMLSecurityException, KeyStoreException {
-        log.log(java.util.logging.Level.FINE, "Can I resolve X509SKI?");
+        LOG.debug("Can I resolve X509SKI?");
 
         Enumeration<String> aliases = keyStore.aliases();
         while (aliases.hasMoreElements()) {
@@ -216,7 +232,7 @@
                     XMLX509SKI certSKI = new XMLX509SKI(x509SKI.getDocument(), (X509Certificate) cert);
 
                     if (certSKI.equals(x509SKI)) {
-                        log.log(java.util.logging.Level.FINE, "match !!! ");
+                        LOG.debug("match !!! ");
 
                         try {
                             Key key = keyStore.getKey(alias, password);
@@ -224,7 +240,7 @@
                                 return (PrivateKey) key;
                             }
                         } catch (Exception e) {
-                            log.log(java.util.logging.Level.FINE, "Cannot recover the key", e);
+                            LOG.debug("Cannot recover the key", e);
                             // Keep searching
                         }
                     }
@@ -239,7 +255,7 @@
      * Search for a private key entry in the KeyStore with the same Issuer/Serial Number pair.
      */
     private PrivateKey resolveX509IssuerSerial(XMLX509IssuerSerial x509Serial) throws KeyStoreException {
-        log.log(java.util.logging.Level.FINE, "Can I resolve X509IssuerSerial?");
+        LOG.debug("Can I resolve X509IssuerSerial?");
 
         Enumeration<String> aliases = keyStore.aliases();
         while (aliases.hasMoreElements()) {
@@ -252,7 +268,7 @@
                         new XMLX509IssuerSerial(x509Serial.getDocument(), (X509Certificate) cert);
 
                     if (certSerial.equals(x509Serial)) {
-                        log.log(java.util.logging.Level.FINE, "match !!! ");
+                        LOG.debug("match !!! ");
 
                         try {
                             Key key = keyStore.getKey(alias, password);
@@ -260,7 +276,7 @@
                                 return (PrivateKey) key;
                             }
                         } catch (Exception e) {
-                            log.log(java.util.logging.Level.FINE, "Cannot recover the key", e);
+                            LOG.debug("Cannot recover the key", e);
                             // Keep searching
                         }
                     }
@@ -275,7 +291,7 @@
      * Search for a private key entry in the KeyStore with the same Subject Name.
      */
     private PrivateKey resolveX509SubjectName(XMLX509SubjectName x509SubjectName) throws KeyStoreException {
-        log.log(java.util.logging.Level.FINE, "Can I resolve X509SubjectName?");
+        LOG.debug("Can I resolve X509SubjectName?");
 
         Enumeration<String> aliases = keyStore.aliases();
         while (aliases.hasMoreElements()) {
@@ -288,7 +304,7 @@
                         new XMLX509SubjectName(x509SubjectName.getDocument(), (X509Certificate) cert);
 
                     if (certSN.equals(x509SubjectName)) {
-                        log.log(java.util.logging.Level.FINE, "match !!! ");
+                        LOG.debug("match !!! ");
 
                         try {
                             Key key = keyStore.getKey(alias, password);
@@ -296,7 +312,7 @@
                                 return (PrivateKey) key;
                             }
                         } catch (Exception e) {
-                            log.log(java.util.logging.Level.FINE, "Cannot recover the key", e);
+                            LOG.debug("Cannot recover the key", e);
                             // Keep searching
                         }
                     }
@@ -313,7 +329,7 @@
     private PrivateKey resolveX509Certificate(
         XMLX509Certificate x509Cert
     ) throws XMLSecurityException, KeyStoreException {
-        log.log(java.util.logging.Level.FINE, "Can I resolve X509Certificate?");
+        LOG.debug("Can I resolve X509Certificate?");
         byte[] x509CertBytes = x509Cert.getCertificateBytes();
 
         Enumeration<String> aliases = keyStore.aliases();
@@ -328,10 +344,11 @@
                     try {
                         certBytes = cert.getEncoded();
                     } catch (CertificateEncodingException e1) {
+                        LOG.debug("Cannot recover the key", e1);
                     }
 
                     if (certBytes != null && Arrays.equals(certBytes, x509CertBytes)) {
-                        log.log(java.util.logging.Level.FINE, "match !!! ");
+                        LOG.debug("match !!! ");
 
                         try {
                             Key key = keyStore.getKey(alias, password);
@@ -340,7 +357,7 @@
                             }
                         }
                         catch (Exception e) {
-                            log.log(java.util.logging.Level.FINE, "Cannot recover the key", e);
+                            LOG.debug("Cannot recover the key", e);
                             // Keep searching
                         }
                     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RSAKeyValueResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RSAKeyValueResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -36,18 +36,15 @@
 
 public class RSAKeyValueResolver extends KeyResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(RSAKeyValueResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(RSAKeyValueResolver.class);
 
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public PublicKey engineLookupAndResolvePublicKey(
-        Element element, String BaseURI, StorageResolver storage
+        Element element, String baseURI, StorageResolver storage
     ) {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName());
-        }
+        LOG.debug("Can I resolve {}", element.getTagName());
         if (element == null) {
             return null;
         }
@@ -68,28 +65,26 @@
         }
 
         try {
-            RSAKeyValue rsaKeyValue = new RSAKeyValue(rsaKeyElement, BaseURI);
+            RSAKeyValue rsaKeyValue = new RSAKeyValue(rsaKeyElement, baseURI);
 
             return rsaKeyValue.getPublicKey();
         } catch (XMLSecurityException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex);
-            }
+            LOG.debug("XMLSecurityException", ex);
         }
 
         return null;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public X509Certificate engineLookupResolveX509Certificate(
-        Element element, String BaseURI, StorageResolver storage
+        Element element, String baseURI, StorageResolver storage
     ) {
         return null;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public javax.crypto.SecretKey engineLookupAndResolveSecretKey(
-        Element element, String BaseURI, StorageResolver storage
+        Element element, String baseURI, StorageResolver storage
     ) {
         return null;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RetrievalMethodResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RetrievalMethodResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -24,6 +24,7 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.security.PublicKey;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
@@ -34,9 +35,6 @@
 import java.util.ListIterator;
 import java.util.Set;
 
-import javax.xml.XMLConstants;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
@@ -53,7 +51,6 @@
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver;
 import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.xml.sax.SAXException;
@@ -67,17 +64,15 @@
  * RetrievalMethodResolver cannot handle itself, resolving of the extracted
  * element is delegated back to the KeyResolver mechanism.
  *
- * @author $Author: raul $ modified by Dave Garcia
  */
 public class RetrievalMethodResolver extends KeyResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(RetrievalMethodResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(RetrievalMethodResolver.class);
 
     /**
      * Method engineResolvePublicKey
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
      * @param baseURI
      * @param storage
@@ -102,58 +97,46 @@
                 }
                 return null;
              }
-             Element e = obtainReferenceElement(resource);
+             Element e = obtainReferenceElement(resource, secureValidation);
 
              // Check to make sure that the reference is not to another RetrievalMethod
              // which points to this element
              if (XMLUtils.elementIsInSignatureSpace(e, Constants._TAG_RETRIEVALMETHOD)) {
                  if (secureValidation) {
-                     String error = "Error: It is forbidden to have one RetrievalMethod "
-                         + "point to another with secure validation";
-                     if (log.isLoggable(java.util.logging.Level.FINE)) {
-                         log.log(java.util.logging.Level.FINE, error);
+                     if (LOG.isDebugEnabled()) {
+                         String error = "Error: It is forbidden to have one RetrievalMethod "
+                             + "point to another with secure validation";
+                         LOG.debug(error);
                      }
                      return null;
                  }
                  RetrievalMethod rm2 = new RetrievalMethod(e, baseURI);
                  XMLSignatureInput resource2 = resolveInput(rm2, baseURI, secureValidation);
-                 Element e2 = obtainReferenceElement(resource2);
+                 Element e2 = obtainReferenceElement(resource2, secureValidation);
                  if (e2 == element) {
-                     if (log.isLoggable(java.util.logging.Level.FINE)) {
-                         log.log(java.util.logging.Level.FINE, "Error: Can't have RetrievalMethods pointing to each other");
-                     }
+                     LOG.debug("Error: Can't have RetrievalMethods pointing to each other");
                      return null;
                  }
              }
 
              return resolveKey(e, baseURI, storage);
          } catch (XMLSecurityException ex) {
-             if (log.isLoggable(java.util.logging.Level.FINE)) {
-                 log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex);
-             }
+             LOG.debug("XMLSecurityException", ex);
          } catch (CertificateException ex) {
-             if (log.isLoggable(java.util.logging.Level.FINE)) {
-                 log.log(java.util.logging.Level.FINE, "CertificateException", ex);
-             }
+             LOG.debug("CertificateException", ex);
          } catch (IOException ex) {
-             if (log.isLoggable(java.util.logging.Level.FINE)) {
-                 log.log(java.util.logging.Level.FINE, "IOException", ex);
-             }
+             LOG.debug("IOException", ex);
          } catch (ParserConfigurationException e) {
-             if (log.isLoggable(java.util.logging.Level.FINE)) {
-                 log.log(java.util.logging.Level.FINE, "ParserConfigurationException", e);
-             }
+             LOG.debug("ParserConfigurationException", e);
          } catch (SAXException e) {
-             if (log.isLoggable(java.util.logging.Level.FINE)) {
-                 log.log(java.util.logging.Level.FINE, "SAXException", e);
-             }
+             LOG.debug("SAXException", e);
          }
          return null;
     }
 
     /**
      * Method engineResolveX509Certificate
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
      * @param baseURI
      * @param storage
@@ -172,51 +155,39 @@
                 return getRawCertificate(resource);
             }
 
-            Element e = obtainReferenceElement(resource);
+            Element e = obtainReferenceElement(resource, secureValidation);
 
             // Check to make sure that the reference is not to another RetrievalMethod
             // which points to this element
             if (XMLUtils.elementIsInSignatureSpace(e, Constants._TAG_RETRIEVALMETHOD)) {
                 if (secureValidation) {
-                    String error = "Error: It is forbidden to have one RetrievalMethod "
-                        + "point to another with secure validation";
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, error);
+                    if (LOG.isDebugEnabled()) {
+                        String error = "Error: It is forbidden to have one RetrievalMethod "
+                            + "point to another with secure validation";
+                        LOG.debug(error);
                     }
                     return null;
                 }
                 RetrievalMethod rm2 = new RetrievalMethod(e, baseURI);
                 XMLSignatureInput resource2 = resolveInput(rm2, baseURI, secureValidation);
-                Element e2 = obtainReferenceElement(resource2);
+                Element e2 = obtainReferenceElement(resource2, secureValidation);
                 if (e2 == element) {
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, "Error: Can't have RetrievalMethods pointing to each other");
-                    }
+                    LOG.debug("Error: Can't have RetrievalMethods pointing to each other");
                     return null;
                 }
             }
 
             return resolveCertificate(e, baseURI, storage);
         } catch (XMLSecurityException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex);
-            }
+            LOG.debug("XMLSecurityException", ex);
         } catch (CertificateException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "CertificateException", ex);
-            }
+            LOG.debug("CertificateException", ex);
         } catch (IOException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "IOException", ex);
-            }
+            LOG.debug("IOException", ex);
         } catch (ParserConfigurationException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "ParserConfigurationException", e);
-            }
+            LOG.debug("ParserConfigurationException", e);
         } catch (SAXException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "SAXException", e);
-            }
+            LOG.debug("SAXException", e);
         }
         return null;
     }
@@ -226,14 +197,14 @@
      * @param e
      * @param baseURI
      * @param storage
-     * @return
+     * @return a x509Certificate from the given information
      * @throws KeyResolverException
      */
     private static X509Certificate resolveCertificate(
         Element e, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Now we have a {" + e.getNamespaceURI() + "}"
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Now we have a {" + e.getNamespaceURI() + "}"
                 + e.getLocalName() + " Element");
         }
         // An element has been provided
@@ -248,14 +219,14 @@
      * @param e
      * @param baseURI
      * @param storage
-     * @return
+     * @return a PublicKey from the given information
      * @throws KeyResolverException
      */
     private static PublicKey resolveKey(
         Element e, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Now we have a {" + e.getNamespaceURI() + "}"
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Now we have a {" + e.getNamespaceURI() + "}"
                 + e.getLocalName() + " Element");
         }
         // An element has been provided
@@ -265,7 +236,7 @@
         return null;
     }
 
-    private static Element obtainReferenceElement(XMLSignatureInput resource)
+    private static Element obtainReferenceElement(XMLSignatureInput resource, boolean secureValidation)
         throws CanonicalizationException, ParserConfigurationException,
         IOException, SAXException, KeyResolverException {
         Element e;
@@ -277,11 +248,9 @@
         } else {
             // Retrieved resource is an inputStream
             byte inputBytes[] = resource.getBytes();
-            e = getDocFromBytes(inputBytes);
+            e = getDocFromBytes(inputBytes, secureValidation);
             // otherwise, we parse the resource, create an Element and delegate
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "we have to parse " + inputBytes.length + " bytes");
-            }
+            LOG.debug("we have to parse {} bytes", inputBytes.length);
         }
         return e;
     }
@@ -292,14 +261,14 @@
         // if the resource stores a raw certificate, we have to handle it
         CertificateFactory certFact =
             CertificateFactory.getInstance(XMLX509Certificate.JCA_CERT_ID);
-        X509Certificate cert = (X509Certificate)
-            certFact.generateCertificate(new ByteArrayInputStream(inputBytes));
-        return cert;
+        try (InputStream is = new ByteArrayInputStream(inputBytes)) {
+            return (X509Certificate) certFact.generateCertificate(is);
+        }
     }
 
     /**
      * Resolves the input from the given retrieval method
-     * @return
+     * @return the input from the given retrieval method
      * @throws XMLSecurityException
      */
     private static XMLSignatureInput resolveInput(
@@ -311,41 +280,15 @@
         ResourceResolver resRes = ResourceResolver.getInstance(uri, baseURI, secureValidation);
         XMLSignatureInput resource = resRes.resolve(uri, baseURI, secureValidation);
         if (transforms != null) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "We have Transforms");
-            }
+            LOG.debug("We have Transforms");
             resource = transforms.performTransforms(resource);
         }
         return resource;
     }
 
     /**
-     * Parses a byte array and returns the parsed Element.
-     *
-     * @param bytes
-     * @return the Document Element after parsing bytes
-     * @throws KeyResolverException if something goes wrong
-     */
-    private static Element getDocFromBytes(byte[] bytes) throws KeyResolverException {
-        try {
-            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-            dbf.setNamespaceAware(true);
-            dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
-            DocumentBuilder db = dbf.newDocumentBuilder();
-            Document doc = db.parse(new ByteArrayInputStream(bytes));
-            return doc.getDocumentElement();
-        } catch (SAXException ex) {
-            throw new KeyResolverException("empty", ex);
-        } catch (IOException ex) {
-            throw new KeyResolverException("empty", ex);
-        } catch (ParserConfigurationException ex) {
-            throw new KeyResolverException("empty", ex);
-        }
-    }
-
-    /**
      * Method engineResolveSecretKey
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
      * @param baseURI
      * @param storage
@@ -366,7 +309,7 @@
                 break;
             }
         }
-        List<Node> parents = new ArrayList<Node>();
+        List<Node> parents = new ArrayList<>();
 
         // Obtain all the parents of the elemnt
         while (e != null) {
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/SecretKeyResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/SecretKeyResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -2,6 +2,24 @@
  * 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.keys.keyresolver.implementations;
 
 import java.security.Key;
@@ -23,9 +41,8 @@
  */
 public class SecretKeyResolver extends KeyResolverSpi
 {
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(SecretKeyResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(SecretKeyResolver.class);
 
     private KeyStore keyStore;
     private char[] password;
@@ -67,7 +84,7 @@
 
     /**
      * Method engineResolveX509Certificate
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
      * @param baseURI
      * @param storage
@@ -92,9 +109,7 @@
     public SecretKey engineResolveSecretKey(
         Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?");
-        }
+        LOG.debug("Can I resolve {}?", element.getTagName());
 
         if (XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_KEYNAME)) {
             String keyName = element.getFirstChild().getNodeValue();
@@ -104,17 +119,17 @@
                     return (SecretKey) key;
                 }
             } catch (Exception e) {
-                log.log(java.util.logging.Level.FINE, "Cannot recover the key", e);
+                LOG.debug("Cannot recover the key", e);
             }
         }
 
-        log.log(java.util.logging.Level.FINE, "I can't");
+        LOG.debug("I can't");
         return null;
     }
 
     /**
      * Method engineResolvePrivateKey
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
      * @param baseURI
      * @param storage
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/SingleKeyResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/SingleKeyResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -2,6 +2,24 @@
  * 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.keys.keyresolver.implementations;
 
 import java.security.PrivateKey;
@@ -18,11 +36,9 @@
 /**
  * Resolves a single Key based on the KeyName.
  */
-public class SingleKeyResolver extends KeyResolverSpi
-{
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(SingleKeyResolver.class.getName());
+public class SingleKeyResolver extends KeyResolverSpi {
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(SingleKeyResolver.class);
 
     private String keyName;
     private PublicKey publicKey;
@@ -63,7 +79,7 @@
      * This method returns whether the KeyResolverSpi is able to perform the requested action.
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @param storage
      * @return whether the KeyResolverSpi is able to perform the requested action.
      */
@@ -83,9 +99,7 @@
     public PublicKey engineLookupAndResolvePublicKey(
         Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?");
-        }
+        LOG.debug("Can I resolve {}?", element.getTagName());
 
         if (publicKey != null
             && XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_KEYNAME)) {
@@ -95,13 +109,13 @@
             }
         }
 
-        log.log(java.util.logging.Level.FINE, "I can't");
+        LOG.debug("I can't");
         return null;
     }
 
     /**
      * Method engineResolveX509Certificate
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
      * @param baseURI
      * @param storage
@@ -126,9 +140,7 @@
     public SecretKey engineResolveSecretKey(
         Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?");
-        }
+        LOG.debug("Can I resolve {}?", element.getTagName());
 
         if (secretKey != null
             && XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_KEYNAME)) {
@@ -138,13 +150,13 @@
             }
         }
 
-        log.log(java.util.logging.Level.FINE, "I can't");
+        LOG.debug("I can't");
         return null;
     }
 
     /**
      * Method engineResolvePrivateKey
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
      * @param baseURI
      * @param storage
@@ -154,9 +166,7 @@
     public PrivateKey engineLookupAndResolvePrivateKey(
         Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?");
-        }
+        LOG.debug("Can I resolve {}?", element.getTagName());
 
         if (privateKey != null
             && XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_KEYNAME)) {
@@ -166,7 +176,7 @@
             }
         }
 
-        log.log(java.util.logging.Level.FINE, "I can't");
+        LOG.debug("I can't");
         return null;
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509CertificateResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509CertificateResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -36,31 +36,29 @@
 
 /**
  * Resolves Certificates which are directly contained inside a
- * <CODE>ds:X509Certificate</CODE> Element.
+ * {@code ds:X509Certificate} Element.
  *
- * @author $Author: coheigea $
  */
 public class X509CertificateResolver extends KeyResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(X509CertificateResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(X509CertificateResolver.class);
 
     /**
      * Method engineResolvePublicKey
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @param storage
      *
      * @throws KeyResolverException
      */
     public PublicKey engineLookupAndResolvePublicKey(
-        Element element, String BaseURI, StorageResolver storage
+        Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
 
         X509Certificate cert =
-            this.engineLookupResolveX509Certificate(element, BaseURI, storage);
+            this.engineLookupResolveX509Certificate(element, baseURI, storage);
 
         if (cert != null) {
             return cert.getPublicKey();
@@ -71,32 +69,32 @@
 
     /**
      * Method engineResolveX509Certificate
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @param storage
      *
      * @throws KeyResolverException
      */
     public X509Certificate engineLookupResolveX509Certificate(
-        Element element, String BaseURI, StorageResolver storage
+        Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
 
         try {
             Element[] els =
                 XMLUtils.selectDsNodes(element.getFirstChild(), Constants._TAG_X509CERTIFICATE);
-            if ((els == null) || (els.length == 0)) {
+            if (els == null || els.length == 0) {
                 Element el =
                     XMLUtils.selectDsNode(element.getFirstChild(), Constants._TAG_X509DATA, 0);
                 if (el != null) {
-                    return engineLookupResolveX509Certificate(el, BaseURI, storage);
+                    return engineLookupResolveX509Certificate(el, baseURI, storage);
                 }
                 return null;
             }
 
             // populate Object array
             for (int i = 0; i < els.length; i++) {
-                XMLX509Certificate xmlCert = new XMLX509Certificate(els[i], BaseURI);
+                XMLX509Certificate xmlCert = new XMLX509Certificate(els[i], baseURI);
                 X509Certificate cert = xmlCert.getX509Certificate();
                 if (cert != null) {
                     return cert;
@@ -104,22 +102,20 @@
             }
             return null;
         } catch (XMLSecurityException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex);
-            }
-            throw new KeyResolverException("generic.EmptyMessage", ex);
+            LOG.debug("Security Exception", ex);
+            throw new KeyResolverException(ex);
         }
     }
 
     /**
      * Method engineResolveSecretKey
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @param storage
      */
     public javax.crypto.SecretKey engineLookupAndResolveSecretKey(
-        Element element, String BaseURI, StorageResolver storage
+        Element element, String baseURI, StorageResolver storage
     ) {
         return null;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509DigestResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509DigestResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -2,6 +2,24 @@
  * 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.keys.keyresolver.implementations;
 
 import java.security.PublicKey;
@@ -24,17 +42,15 @@
 
 /**
  * KeyResolverSpi implementation which resolves public keys and X.509 certificates from a
- * <code>dsig11:X509Digest</code> element.
+ * {@code dsig11:X509Digest} element.
  *
- * @author Brent Putman (putmanb@georgetown.edu)
  */
 public class X509DigestResolver extends KeyResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(X509DigestResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(X509DigestResolver.class);
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public boolean engineCanResolve(Element element, String baseURI, StorageResolver storage) {
         if (XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_X509DATA)) {
             try {
@@ -48,7 +64,7 @@
         }
     }
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public PublicKey engineLookupAndResolvePublicKey(Element element, String baseURI, StorageResolver storage)
         throws KeyResolverException {
 
@@ -61,13 +77,11 @@
         return null;
     }
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public X509Certificate engineLookupResolveX509Certificate(Element element, String baseURI, StorageResolver storage)
         throws KeyResolverException {
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName());
-        }
+        LOG.debug("Can I resolve {}", element.getTagName());
 
         if (!engineCanResolve(element, baseURI, storage)) {
             return null;
@@ -76,15 +90,13 @@
         try {
             return resolveCertificate(element, baseURI, storage);
         } catch (XMLSecurityException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "XMLSecurityException", e);
-            }
+            LOG.debug("XMLSecurityException", e);
         }
 
         return null;
     }
 
-    /** {@inheritDoc}. */
+    /** {{@inheritDoc}}. */
     public SecretKey engineLookupAndResolveSecretKey(Element element, String baseURI, StorageResolver storage)
         throws KeyResolverException {
         return null;
@@ -96,7 +108,7 @@
      * @param element
      * @param baseURI
      * @param storage
-     * @return
+     * @return the certificate represented by the digest.
      * @throws XMLSecurityException
      */
     private X509Certificate resolveCertificate(Element element, String baseURI, StorageResolver storage)
@@ -128,9 +140,7 @@
                     byte[] certDigestBytes = XMLX509Digest.getDigestBytesFromCert(cert, keyInfoDigest.getAlgorithm());
 
                     if (Arrays.equals(keyInfoDigest.getDigestBytes(), certDigestBytes)) {
-                        if (log.isLoggable(java.util.logging.Level.FINE)) {
-                            log.log(java.util.logging.Level.FINE, "Found certificate with: " + cert.getSubjectX500Principal().getName());
-                        }
+                        LOG.debug("Found certificate with: {}", cert.getSubjectX500Principal().getName());
                         return cert;
                     }
 
@@ -138,7 +148,7 @@
             }
 
         } catch (XMLSecurityException ex) {
-            throw new KeyResolverException("empty", ex);
+            throw new KeyResolverException(ex);
         }
 
         return null;
@@ -154,9 +164,7 @@
         if (storage == null) {
             Object exArgs[] = { Constants._TAG_X509DIGEST };
             KeyResolverException ex = new KeyResolverException("KeyResolver.needStorageResolver", exArgs);
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "", ex);
-            }
+            LOG.debug("", ex);
             throw ex;
         }
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509IssuerSerialResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509IssuerSerialResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -39,12 +39,11 @@
 
 public class X509IssuerSerialResolver extends KeyResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(X509IssuerSerialResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(X509IssuerSerialResolver.class);
 
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public PublicKey engineLookupAndResolvePublicKey(
         Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
@@ -59,26 +58,20 @@
         return null;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public X509Certificate engineLookupResolveX509Certificate(
         Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?");
-        }
+        LOG.debug("Can I resolve {}?", element.getTagName());
 
         X509Data x509data = null;
         try {
             x509data = new X509Data(element, baseURI);
         } catch (XMLSignatureException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I can't");
-            }
+            LOG.debug("I can't");
             return null;
         } catch (XMLSecurityException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I can't");
-            }
+            LOG.debug("I can't");
             return null;
         }
 
@@ -91,9 +84,7 @@
                 KeyResolverException ex =
                     new KeyResolverException("KeyResolver.needStorageResolver", exArgs);
 
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "", ex);
-                }
+                LOG.debug("", ex);
                 throw ex;
             }
 
@@ -104,44 +95,32 @@
                 X509Certificate cert = (X509Certificate)storageIterator.next();
                 XMLX509IssuerSerial certSerial = new XMLX509IssuerSerial(element.getOwnerDocument(), cert);
 
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Found Certificate Issuer: " + certSerial.getIssuerName());
-                    log.log(java.util.logging.Level.FINE, "Found Certificate Serial: " + certSerial.getSerialNumber().toString());
-                }
+                LOG.debug("Found Certificate Issuer: {}", certSerial.getIssuerName());
+                LOG.debug("Found Certificate Serial: {}", certSerial.getSerialNumber().toString());
 
                 for (int i = 0; i < noOfISS; i++) {
                     XMLX509IssuerSerial xmliss = x509data.itemIssuerSerial(i);
 
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, "Found Element Issuer:     "
-                                  + xmliss.getIssuerName());
-                        log.log(java.util.logging.Level.FINE, "Found Element Serial:     "
-                                  + xmliss.getSerialNumber().toString());
-                    }
+                    LOG.debug("Found Element Issuer:     {}", xmliss.getIssuerName());
+                    LOG.debug("Found Element Serial:     {}", xmliss.getSerialNumber().toString());
 
                     if (certSerial.equals(xmliss)) {
-                        if (log.isLoggable(java.util.logging.Level.FINE)) {
-                            log.log(java.util.logging.Level.FINE, "match !!! ");
-                        }
+                        LOG.debug("match !!! ");
                         return cert;
                     }
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, "no match...");
-                    }
+                    LOG.debug("no match...");
                 }
             }
 
             return null;
         } catch (XMLSecurityException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex);
-            }
+            LOG.debug("XMLSecurityException", ex);
 
-            throw new KeyResolverException("generic.EmptyMessage", ex);
+            throw new KeyResolverException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public javax.crypto.SecretKey engineLookupAndResolveSecretKey(
         Element element, String baseURI, StorageResolver storage
     ) {
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SKIResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SKIResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -39,9 +39,8 @@
 
 public class X509SKIResolver extends KeyResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(X509SKIResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(X509SKIResolver.class);
 
 
     /**
@@ -69,7 +68,7 @@
 
     /**
      * Method engineResolveX509Certificate
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
      * @param baseURI
      * @param storage
@@ -79,13 +78,9 @@
     public X509Certificate engineLookupResolveX509Certificate(
         Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?");
-        }
+        LOG.debug("Can I resolve {}?", element.getTagName());
         if (!XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_X509DATA)) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I can't");
-            }
+            LOG.debug("I can't");
             return null;
         }
         /** Field _x509childObject[] */
@@ -94,10 +89,8 @@
         Element x509childNodes[] = null;
         x509childNodes = XMLUtils.selectDsNodes(element.getFirstChild(), Constants._TAG_X509SKI);
 
-        if (!((x509childNodes != null) && (x509childNodes.length > 0))) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I can't");
-            }
+        if (!(x509childNodes != null && x509childNodes.length > 0)) {
+            LOG.debug("I can't");
             return null;
         }
         try {
@@ -106,9 +99,7 @@
                 KeyResolverException ex =
                     new KeyResolverException("KeyResolver.needStorageResolver", exArgs);
 
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "", ex);
-                }
+                LOG.debug("", ex);
 
                 throw ex;
             }
@@ -126,16 +117,14 @@
 
                 for (int i = 0; i < x509childObject.length; i++) {
                     if (certSKI.equals(x509childObject[i])) {
-                        if (log.isLoggable(java.util.logging.Level.FINE)) {
-                            log.log(java.util.logging.Level.FINE, "Return PublicKey from " + cert.getSubjectX500Principal().getName());
-                        }
+                        LOG.debug("Return PublicKey from {}", cert.getSubjectX500Principal().getName());
 
                         return cert;
                     }
                 }
             }
         } catch (XMLSecurityException ex) {
-            throw new KeyResolverException("empty", ex);
+            throw new KeyResolverException(ex);
         }
 
         return null;
@@ -143,7 +132,7 @@
 
     /**
      * Method engineResolveSecretKey
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
      * @param baseURI
      * @param storage
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SubjectNameResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SubjectNameResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -39,16 +39,15 @@
 
 public class X509SubjectNameResolver extends KeyResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(X509SubjectNameResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(X509SubjectNameResolver.class);
 
 
     /**
      * Method engineResolvePublicKey
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @param storage
      * @return null if no {@link PublicKey} could be obtained
      * @throws KeyResolverException
@@ -69,7 +68,7 @@
 
     /**
      * Method engineResolveX509Certificate
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
      * @param baseURI
      * @param storage
@@ -79,26 +78,19 @@
     public X509Certificate engineLookupResolveX509Certificate(
         Element element, String baseURI, StorageResolver storage
     ) throws KeyResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Can I resolve " + element.getTagName() + "?");
-        }
+        LOG.debug("Can I resolve {}?", element.getTagName());
         Element[] x509childNodes = null;
         XMLX509SubjectName x509childObject[] = null;
 
         if (!XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_X509DATA)) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I can't");
-            }
+            LOG.debug("I can't");
             return null;
         }
         x509childNodes =
             XMLUtils.selectDsNodes(element.getFirstChild(), Constants._TAG_X509SUBJECTNAME);
 
-        if (!((x509childNodes != null)
-            && (x509childNodes.length > 0))) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I can't");
-            }
+        if (!(x509childNodes != null && x509childNodes.length > 0)) {
+            LOG.debug("I can't");
             return null;
         }
 
@@ -108,9 +100,7 @@
                 KeyResolverException ex =
                     new KeyResolverException("KeyResolver.needStorageResolver", exArgs);
 
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "", ex);
-                }
+                LOG.debug("", ex);
 
                 throw ex;
             }
@@ -127,42 +117,31 @@
                 XMLX509SubjectName certSN =
                     new XMLX509SubjectName(element.getOwnerDocument(), cert);
 
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Found Certificate SN: " + certSN.getSubjectName());
-                }
+                LOG.debug("Found Certificate SN: {}", certSN.getSubjectName());
 
                 for (int i = 0; i < x509childObject.length; i++) {
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, "Found Element SN:     "
-                              + x509childObject[i].getSubjectName());
-                    }
+                    LOG.debug("Found Element SN:     {}", x509childObject[i].getSubjectName());
 
                     if (certSN.equals(x509childObject[i])) {
-                        if (log.isLoggable(java.util.logging.Level.FINE)) {
-                            log.log(java.util.logging.Level.FINE, "match !!! ");
-                        }
+                        LOG.debug("match !!! ");
 
                         return cert;
                     }
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, "no match...");
-                    }
+                    LOG.debug("no match...");
                 }
             }
 
             return null;
         } catch (XMLSecurityException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex);
-            }
+            LOG.debug("XMLSecurityException", ex);
 
-            throw new KeyResolverException("generic.EmptyMessage", ex);
+            throw new KeyResolverException(ex);
         }
     }
 
     /**
      * Method engineResolveSecretKey
-     * @inheritDoc
+     * {@inheritDoc}
      * @param element
      * @param baseURI
      * @param storage
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-implementations for retrieval of certificates and public keys from elements.
-</P></BODY></HTML>
\ No newline at end of file
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-the resolver framework for retrieval of certificates and public keys from elements.
-</P></BODY></HTML>
\ No newline at end of file
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-general key related material.
-</P></BODY></HTML>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -38,12 +38,11 @@
  */
 public class StorageResolver {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(StorageResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(StorageResolver.class);
 
     /** Field storageResolvers */
-    private List<StorageResolverSpi> storageResolvers = null;
+    private List<StorageResolverSpi> storageResolvers;
 
     /**
      * Constructor StorageResolver
@@ -67,7 +66,7 @@
      */
     public void add(StorageResolverSpi resolver) {
         if (storageResolvers == null) {
-            storageResolvers = new ArrayList<StorageResolverSpi>();
+            storageResolvers = new ArrayList<>();
         }
         this.storageResolvers.add(resolver);
     }
@@ -90,7 +89,7 @@
         try {
             this.add(new KeyStoreResolver(keyStore));
         } catch (StorageResolverException ex) {
-            log.log(java.util.logging.Level.SEVERE, "Could not add KeyStore because of: ", ex);
+            LOG.error("Could not add KeyStore because of: ", ex);
         }
     }
 
@@ -142,7 +141,7 @@
             currentResolver = findNextResolver();
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public boolean hasNext() {
             if (currentResolver == null) {
                 return false;
@@ -153,10 +152,10 @@
             }
 
             currentResolver = findNextResolver();
-            return (currentResolver != null);
+            return currentResolver != null;
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public Certificate next() {
             if (hasNext()) {
                 return currentResolver.next();
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolverException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolverException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -40,6 +40,10 @@
         super();
     }
 
+    public StorageResolverException(Exception ex) {
+        super(ex);
+    }
+
     /**
      * Constructor StorageResolverException
      *
@@ -62,22 +66,31 @@
     /**
      * Constructor StorageResolverException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public StorageResolverException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public StorageResolverException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor StorageResolverException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
-    public StorageResolverException(String msgID, Object exArgs[],
-                                    Exception originalException) {
-        super(msgID, exArgs, originalException);
+    public StorageResolverException(Exception originalException, String msgID, Object exArgs[]) {
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public StorageResolverException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/CertsInFilesystemDirectoryResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/CertsInFilesystemDirectoryResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,9 +23,11 @@
 package com.sun.org.apache.xml.internal.security.keys.storage.implementations;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateExpiredException;
@@ -33,12 +35,12 @@
 import java.security.cert.CertificateNotYetValidException;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
+import java.util.Base64;
 import java.util.Iterator;
 import java.util.List;
 
 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolverException;
 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolverSpi;
-import com.sun.org.apache.xml.internal.security.utils.Base64;
 
 /**
  * This {@link StorageResolverSpi} makes all raw (binary) {@link X509Certificate}s
@@ -47,17 +49,16 @@
  */
 public class CertsInFilesystemDirectoryResolver extends StorageResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(
-            CertsInFilesystemDirectoryResolver.class.getName()
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(
+            CertsInFilesystemDirectoryResolver.class
         );
 
     /** Field merlinsCertificatesDir */
-    private String merlinsCertificatesDir = null;
+    private String merlinsCertificatesDir;
 
     /** Field certs */
-    private List<X509Certificate> certs = new ArrayList<X509Certificate>();
+    private List<X509Certificate> certs = new ArrayList<>();
 
     /**
      * @param directoryName
@@ -78,14 +79,16 @@
     private void readCertsFromHarddrive() throws StorageResolverException {
 
         File certDir = new File(this.merlinsCertificatesDir);
-        List<String> al = new ArrayList<String>();
+        List<String> al = new ArrayList<>();
         String[] names = certDir.list();
 
-        for (int i = 0; i < names.length; i++) {
-            String currentFileName = names[i];
+        if (names != null) {
+            for (int i = 0; i < names.length; i++) {
+                String currentFileName = names[i];
 
-            if (currentFileName.endsWith(".crt")) {
-                al.add(names[i]);
+                if (currentFileName.endsWith(".crt")) {
+                    al.add(names[i]);
+                }
             }
         }
 
@@ -94,24 +97,17 @@
         try {
             cf = CertificateFactory.getInstance("X.509");
         } catch (CertificateException ex) {
-            throw new StorageResolverException("empty", ex);
-        }
-
-        if (cf == null) {
-            throw new StorageResolverException("empty");
+            throw new StorageResolverException(ex);
         }
 
         for (int i = 0; i < al.size(); i++) {
             String filename = certDir.getAbsolutePath() + File.separator + al.get(i);
-            File file = new File(filename);
             boolean added = false;
             String dn = null;
 
-            FileInputStream fis = null;
-            try {
-                fis = new FileInputStream(file);
+            try (InputStream inputStream = Files.newInputStream(Paths.get(filename))) {
                 X509Certificate cert =
-                    (X509Certificate) cf.generateCertificate(fis);
+                    (X509Certificate) cf.generateCertificate(inputStream);
 
                 //add to ArrayList
                 cert.checkValidity();
@@ -120,40 +116,34 @@
                 dn = cert.getSubjectX500Principal().getName();
                 added = true;
             } catch (FileNotFoundException ex) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex);
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Could not add certificate from file " + filename, ex);
                 }
             } catch (CertificateNotYetValidException ex) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex);
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Could not add certificate from file " + filename, ex);
                 }
             } catch (CertificateExpiredException ex) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex);
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Could not add certificate from file " + filename, ex);
                 }
             } catch (CertificateException ex) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex);
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Could not add certificate from file " + filename, ex);
                 }
-            } finally {
-                try {
-                    if (fis != null) {
-                        fis.close();
-                    }
-                } catch (IOException ex) {
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, "Could not add certificate from file " + filename, ex);
-                    }
+            } catch (IOException ex) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Could not add certificate from file " + filename, ex);
                 }
             }
 
-            if (added && log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Added certificate: " + dn);
+            if (added) {
+                LOG.debug("Added certificate: {}", dn);
             }
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public Iterator<Certificate> getIterator() {
         return new FilesystemIterator(this.certs);
     }
@@ -164,10 +154,10 @@
     private static class FilesystemIterator implements Iterator<Certificate> {
 
         /** Field certs */
-        List<X509Certificate> certs = null;
+        private List<X509Certificate> certs;
 
         /** Field i */
-        int i;
+        private int i;
 
         /**
          * Constructor FilesystemIterator
@@ -179,12 +169,12 @@
             this.i = 0;
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public boolean hasNext() {
-            return (this.i < this.certs.size());
+            return this.i < this.certs.size();
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public Certificate next() {
             return this.certs.get(this.i++);
         }
@@ -217,7 +207,7 @@
 
             System.out.println();
             System.out.println("Base64(SKI())=                 \""
-                               + Base64.encode(ski) + "\"");
+                               + Base64.getMimeEncoder().encodeToString(ski) + "\"");
             System.out.println("cert.getSerialNumber()=        \""
                                + cert.getSerialNumber().toString() + "\"");
             System.out.println("cert.getSubjectX500Principal().getName()= \""
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/KeyStoreResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/KeyStoreResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -39,7 +39,7 @@
 public class KeyStoreResolver extends StorageResolverSpi {
 
     /** Field keyStore */
-    private KeyStore keyStore = null;
+    private KeyStore keyStore;
 
     /**
      * Constructor KeyStoreResolver
@@ -53,11 +53,11 @@
         try {
             keyStore.aliases();
         } catch (KeyStoreException ex) {
-            throw new StorageResolverException("generic.EmptyMessage", ex);
+            throw new StorageResolverException(ex);
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public Iterator<Certificate> getIterator() {
         return new KeyStoreIterator(this.keyStore);
     }
@@ -98,16 +98,16 @@
             }
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public boolean hasNext() {
             if (nextCert == null) {
                 nextCert = findNextCert();
             }
 
-            return (nextCert != null);
+            return nextCert != null;
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public Certificate next() {
             if (nextCert == null) {
                 // maybe caller did not call hasNext()
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/SingleCertificateResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/SingleCertificateResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -36,7 +36,7 @@
 public class SingleCertificateResolver extends StorageResolverSpi {
 
     /** Field certificate */
-    private X509Certificate certificate = null;
+    private X509Certificate certificate;
 
     /**
      * @param x509cert the single {@link X509Certificate}
@@ -45,7 +45,7 @@
         this.certificate = x509cert;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public Iterator<Certificate> getIterator() {
         return new InternalIterator(this.certificate);
     }
@@ -70,12 +70,12 @@
             this.certificate = x509cert;
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public boolean hasNext() {
             return !this.alreadyReturned;
         }
 
-        /** @inheritDoc */
+        /** {@inheritDoc} */
         public Certificate next() {
             if (this.alreadyReturned) {
                 throw new NoSuchElementException();
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-implementations of resolvers for retrieval for certificates and public keys from user-specified locations.
-</P></BODY></HTML>
\ No newline at end of file
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-a resolver framework for certificates and public keys from user-specified locations.
-</P></BODY></HTML>
\ No newline at end of file
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-<HTML>
-  <HEAD> 
-	 <TITLE>com.sun.org.apache.xml.internal.security</TITLE> 
-  </HEAD> 
-  <BODY> 
-	 <H1>Canonical XML and XML Signature Implementation</H1> 
-	 <H2>Needs the following packages</H2> 
-	 <UL> 
-		<LI>Xerces v2.0.0 <A HREF="http://xml.apache.org/dist/xerces-j/">http://xml.apache.org/dist/xerces-j/</A></LI>
-		<LI>Xalan 2.2.0 <A HREF="http://xml.apache.org/dist/xalan-j/">http://xml.apache.org/dist/xalan-j/</A></LI>
-		<LI>JUnit 3.7 <A HREF="http://download.sourceforge.net/junit/junit3.7.zip">http://download.sourceforge.net/junit/junit3.5.zip</A></LI>
-		<LI>Jakarta Log4J 1.1.2 <A HREF="http://jakarta.apache.org/log4j/">http://jakarta.apache.org/log4j/</A></LI>
-		<LI>ANT <A HREF="http://jakarta.apache.org/builds/jakarta-ant/release/">http://jakarta.apache.org/builds/jakarta-ant/release/</A></LI> 
-	 </UL>
-	 <H1>Packages</H1> 
-	 <UL> 
-		<LI>{@link com.sun.org.apache.xml.internal.security.algorithms} contains algorithm factories </LI> 
-		<LI>{@link com.sun.org.apache.xml.internal.security.c14n} contains Canonicalization related material and algorithms </LI> 
-		<LI>{@link com.sun.org.apache.xml.internal.security.exceptions} contains all exceptions used by this library </LI> 
-		<LI>{@link com.sun.org.apache.xml.internal.security.keys} contains key related material </LI> 
-		<LI>{@link com.sun.org.apache.xml.internal.security.samples} contains some sample applications and non-standard transforms </LI> 
-		<LI>{@link com.sun.org.apache.xml.internal.security.signature} contains the XML Signature specific classes </LI> 
-		<LI>{@link com.sun.org.apache.xml.internal.security.transforms} XML Signature transformations </LI> 
-		<LI>{@link com.sun.org.apache.xml.internal.security.utils} contains all utility classes </LI> 
-		<LI>{@link com.sun.org.apache.xml.internal.security.test} JUnit test cases </LI> 
-		<LI>{@link com.sun.org.apache.xml.internal.security.temp} is the playground for messing around </LI> 
-	 </UL> 
-	 <H2>Support</H2> 
-	 <P>See <A HREF="http://xml.apache.org/security/">the xml-security project</A> for further assistence</P> 
-	 <H2>Author</H2> 
-	 <P>Christian Geuer-Pollmann geuer-pollmann@nue.et-inf.uni-siegen.de<BR> 
-	    University of Siegen<BR> 
-	    Institute for Data Communications Systems<BR> 
-	 </P> 
-     </BODY>
-</HTML>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,23 @@
 <?xml version="1.0"?>
 <!--
+  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.
+-->
+<!--
 <!DOCTYPE Configuration SYSTEM "config.dtd">
 -->
 <!-- This configuration file is used for configuration of the com.sun.org.apache.xml.internal.security package -->
@@ -14,10 +32,12 @@
                               JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315ExclOmitComments"/>
       <CanonicalizationMethod URI="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"
                               JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315ExclWithComments"/>
-      <CanonicalizationMethod URI="http://www.w3.org/2006/12/xml-c14n11"
-                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_OmitComments"/>
-      <CanonicalizationMethod URI="http://www.w3.org/2006/12/xml-c14n11#WithComments"
-                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_WithComments"/>
+      <CanonicalizationMethod URI="http://www.w3.org/2006/12/xml-c14n11"
+                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_OmitComments"/>
+      <CanonicalizationMethod URI="http://www.w3.org/2006/12/xml-c14n11#WithComments"
+                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_WithComments"/>
+      <CanonicalizationMethod URI="http://santuario.apache.org/c14n/physical"
+                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.CanonicalizerPhysical"/>
    </CanonicalizationMethods>
    <TransformAlgorithms>
       <!-- Base64 -->
@@ -67,21 +87,41 @@
                           JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSAMD5" />
       <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160"
                           JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSARIPEMD160" />
+      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha224"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA224" />
       <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
                           JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA256" />
       <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
                           JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA384" />
       <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
                           JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA512" />
+                          
+      <SignatureAlgorithm URI="http://www.w3.org/2007/05/xmldsig-more#ripemd160-rsa-MGF1"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSARIPEMD160MGF1" />
+      <SignatureAlgorithm URI="http://www.w3.org/2007/05/xmldsig-more#sha1-rsa-MGF1"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA1MGF1" />
+      <SignatureAlgorithm URI="http://www.w3.org/2007/05/xmldsig-more#sha224-rsa-MGF1"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA224MGF1" />
+      <SignatureAlgorithm URI="http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA256MGF1" />
+      <SignatureAlgorithm URI="http://www.w3.org/2007/05/xmldsig-more#sha384-rsa-MGF1"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA384MGF1" />
+      <SignatureAlgorithm URI="http://www.w3.org/2007/05/xmldsig-more#sha512-rsa-MGF1"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA512MGF1" />
+                          
       <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"
                           JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA$SignatureECDSASHA1" />
+      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA$SignatureECDSASHA224" />
       <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"
                           JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA$SignatureECDSASHA256" />
       <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"
                           JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA$SignatureECDSASHA384" />
       <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"
                           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/2001/04/xmldsig-more#hmac-md5"
                           JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacMD5" />
       <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160"
@@ -114,6 +154,12 @@
                     AlgorithmClass="MessageDigest"
                     RequirementLevel="REQUIRED"
                     JCEName="SHA-1"/>
+                    
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#sha224"
+                    Description="SHA-224 message digest"
+                    AlgorithmClass="MessageDigest"
+                    RequirementLevel="OPTIONAL"
+                    JCEName="SHA-224"/>
 
          <Algorithm URI="http://www.w3.org/2001/04/xmlenc#sha256"
                     Description="SHA-1 message digest with 256 bit"
@@ -139,6 +185,7 @@
                     Description="Digital Signature Algorithm with SHA-1 message digest"
                     AlgorithmClass="Signature"
                     RequirementLevel="REQUIRED"
+                    RequiredKey="DSA"
                     JCEName="SHA1withDSA"/>
 
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-md5"
@@ -146,6 +193,7 @@
                     AlgorithmClass="Signature"
                     RequirementLevel="NOT RECOMMENDED"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="RSA"
                     JCEName="MD5withRSA"/>
 
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160"
@@ -153,19 +201,30 @@
                     AlgorithmClass="Signature"
                     RequirementLevel="OPTIONAL"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="RSA"
                     JCEName="RIPEMD160withRSA"/>
 
          <Algorithm URI="http://www.w3.org/2000/09/xmldsig#rsa-sha1"
                     Description="RSA Signature with SHA-1 message digest"
                     AlgorithmClass="Signature"
                     RequirementLevel="RECOMMENDED"
+                    RequiredKey="RSA"
                     JCEName="SHA1withRSA"/>
 
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha2224"
+                    Description="RSA Signature with SHA-2224 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="RSA"
+                    JCEName="SHA224withRSA"/>
+                    
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
                     Description="RSA Signature with SHA-256 message digest"
                     AlgorithmClass="Signature"
                     RequirementLevel="OPTIONAL"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="RSA"
                     JCEName="SHA256withRSA"/>
 
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
@@ -173,6 +232,7 @@
                     AlgorithmClass="Signature"
                     RequirementLevel="OPTIONAL"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="RSA"
                     JCEName="SHA384withRSA"/>
 
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
@@ -180,8 +240,48 @@
                     AlgorithmClass="Signature"
                     RequirementLevel="OPTIONAL"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="RSA"
                     JCEName="SHA512withRSA"/>
                     
+         <Algorithm URI="http://www.w3.org/2007/05/xmldsig-more#sha1-rsa-MGF1"
+                    Description="RSASSA-PSS Signature with SHA-1 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="RECOMMENDED"
+                    RequiredKey="RSA"
+                    JCEName="SHA1withRSAandMGF1"/>
+
+         <Algorithm URI="http://www.w3.org/2007/05/xmldsig-more#sha224-rsa-MGF1"
+                    Description="RSASSA-PSS Signature with SHA-224 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/rfc/rfc6931.txt"
+                    RequiredKey="RSA"
+                    JCEName="SHA224withRSAandMGF1"/>
+
+         <Algorithm URI="http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1"
+                    Description="RSASSA-PSS Signature with SHA-256 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/rfc/rfc6931.txt"
+                    RequiredKey="RSA"
+                    JCEName="SHA256withRSAandMGF1"/>
+
+         <Algorithm URI="http://www.w3.org/2007/05/xmldsig-more#sha384-rsa-MGF1"
+                    Description="RSASSA-PSS Signature with SHA-384 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/rfc/rfc6931.txt"
+                    RequiredKey="RSA"
+                    JCEName="SHA384withRSAandMGF1"/>
+
+         <Algorithm URI="http://www.w3.org/2007/05/xmldsig-more#sha512-rsa-MGF1"
+                    Description="RSASSA-PSS Signature with SHA-512 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/rfc/rfc6931.txt"
+                    RequiredKey="RSA"
+                    JCEName="SHA512withRSAandMGF1"/>
+                    
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"
                     Description="ECDSA Signature with SHA-1 message digest"
                     AlgorithmClass="Signature"
@@ -189,11 +289,20 @@
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
                     JCEName="SHA1withECDSA"/>
 
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224"
+                    Description="ECDSA Signature with SHA-224 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="EC"
+                    JCEName="SHA224withECDSA"/>
+                    
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"
                     Description="ECDSA Signature with SHA-256 message digest"
                     AlgorithmClass="Signature"
                     RequirementLevel="OPTIONAL"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="EC"
                     JCEName="SHA256withECDSA"/>
 
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"
@@ -201,6 +310,7 @@
                     AlgorithmClass="Signature"
                     RequirementLevel="OPTIONAL"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="EC"
                     JCEName="SHA384withECDSA"/>
 
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"
@@ -209,13 +319,22 @@
                     RequirementLevel="OPTIONAL"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
                     JCEName="SHA512withECDSA"/>
-
+                    
+         <Algorithm URI="http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160"
+                    Description="ECDSA Signature with RIPEMD-160 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="https://tools.ietf.org/html/rfc6931"
+                    RequiredKey="EC"
+                    JCEName="RIPEMD160withECDSA"/>
+                    
          <!-- MAC Algorithms -->
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-md5"
                     Description="Message Authentication code using MD5"
                     AlgorithmClass="Mac"
                     RequirementLevel="NOT RECOMMENDED"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    KeyLength="0"
                     JCEName="HmacMD5"/>
 
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160"
@@ -223,19 +342,30 @@
                     AlgorithmClass="Mac"
                     RequirementLevel="OPTIONAL"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    KeyLength="0"
                     JCEName="HMACRIPEMD160"/>
 
          <Algorithm URI="http://www.w3.org/2000/09/xmldsig#hmac-sha1"
                     Description="Message Authentication code using SHA1"
                     AlgorithmClass="Mac"
                     RequirementLevel="REQUIRED"
+                    KeyLength="0"
                     JCEName="HmacSHA1"/>
+                    
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha224"
+                    Description="Message Authentication code using SHA-224"
+                    AlgorithmClass="Mac"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    KeyLength="0"
+                    JCEName="HmacSHA224"/>
 
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"
                     Description="Message Authentication code using SHA-256"
                     AlgorithmClass="Mac"
                     RequirementLevel="OPTIONAL"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    KeyLength="0"
                     JCEName="HmacSHA256"/>
 
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha384"
@@ -243,6 +373,7 @@
                     AlgorithmClass="Mac"
                     RequirementLevel="OPTIONAL"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    KeyLength="0"
                     JCEName="HmacSHA384"/>
 
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha512"
@@ -250,6 +381,7 @@
                     AlgorithmClass="Mac"
                     RequirementLevel="OPTIONAL"
                     SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    KeyLength="0"
                     JCEName="HmacSHA512"/>
 
          <!-- Block encryption Algorithms -->
@@ -258,6 +390,7 @@
                     AlgorithmClass="BlockEncryption"
                     RequirementLevel="REQUIRED"
                     KeyLength="192"
+                    IVLength="64"
                     RequiredKey="DESede"
                     JCEName="DESede/CBC/ISO10126Padding"/>
 
@@ -266,6 +399,7 @@
                     AlgorithmClass="BlockEncryption"
                     RequirementLevel="REQUIRED"
                     KeyLength="128"
+                    IVLength="128"
                     RequiredKey="AES"
                     JCEName="AES/CBC/ISO10126Padding"/>
 
@@ -274,6 +408,7 @@
                     AlgorithmClass="BlockEncryption"
                     RequirementLevel="OPTIONAL"
                     KeyLength="192"
+                    IVLength="128"
                     RequiredKey="AES"
                     JCEName="AES/CBC/ISO10126Padding"/>
 
@@ -282,6 +417,7 @@
                     AlgorithmClass="BlockEncryption"
                     RequirementLevel="REQUIRED"
                     KeyLength="256"
+                    IVLength="128"
                     RequiredKey="AES"
                     JCEName="AES/CBC/ISO10126Padding"/>
                     
@@ -290,6 +426,7 @@
                    AlgorithmClass="BlockEncryption"
                    RequirementLevel="OPTIONAL"
                    KeyLength="128"
+                   IVLength="96"
                    RequiredKey="AES"
                    JCEName="AES/GCM/NoPadding"/>
                    
@@ -298,6 +435,7 @@
                    AlgorithmClass="BlockEncryption"
                    RequirementLevel="OPTIONAL"
                    KeyLength="192"
+                   IVLength="96"
                    RequiredKey="AES"
                    JCEName="AES/GCM/NoPadding"/>
 
@@ -306,8 +444,45 @@
                    AlgorithmClass="BlockEncryption"
                    RequirementLevel="OPTIONAL"
                    KeyLength="256"
+                   IVLength="96"
                    RequiredKey="AES"
                    JCEName="AES/GCM/NoPadding"/>
+                   
+         <Algorithm URI="http://www.w3.org/2007/05/xmldsig-more#seed128-cbc"
+                    Description="Block encryption using SEED with a key length of 128 bit"
+                    AlgorithmClass="BlockEncryption"
+                    RequirementLevel="OPTIONAL"
+                    KeyLength="128"
+                    IVLength="128"
+                    RequiredKey="SEED"
+                    JCEName="SEED/CBC/ISO10126Padding"/>
+                    
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#camellia128-cbc"
+                    Description="Block encryption using Camellia with a key length of 128 bit"
+                    AlgorithmClass="BlockEncryption"
+                    RequirementLevel="OPTIONAL"
+                    KeyLength="128"
+                    IVLength="128"
+                    RequiredKey="Camellia"
+                    JCEName="Camellia/CBC/ISO10126Padding"/>
+                    
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#camellia192-cbc"
+                    Description="Block encryption using Camellia with a key length of 192 bit"
+                    AlgorithmClass="BlockEncryption"
+                    RequirementLevel="OPTIONAL"
+                    KeyLength="192"
+                    IVLength="128"
+                    RequiredKey="Camellia"
+                    JCEName="Camellia/CBC/ISO10126Padding"/>
+                    
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#camellia256-cbc"
+                    Description="Block encryption using Camellia with a key length of 256 bit"
+                    AlgorithmClass="BlockEncryption"
+                    RequirementLevel="OPTIONAL"
+                    KeyLength="256"
+                    IVLength="128"
+                    RequiredKey="Camellia"
+                    JCEName="Camellia/CBC/ISO10126Padding"/>
          
          <Algorithm URI="http://www.w3.org/2001/04/xmlenc#rsa-1_5"
                     Description="Key Transport RSA-v1.5"
@@ -366,6 +541,38 @@
                     KeyLength="256"
                     RequiredKey="AES"
                     JCEName="AESWrap"/>
+                    
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#kw-camellia128"
+                    Description="Symmetric Key Wrap using CAMELLIA with a key length of 128 bit"
+                    AlgorithmClass="SymmetricKeyWrap"
+                    RequirementLevel="OPTIONAL"
+                    KeyLength="128"
+                    RequiredKey="Camellia"
+                    JCEName="CamelliaWrap"/>
+                    
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#kw-camellia192"
+                    Description="Symmetric Key Wrap using CAMELLIA with a key length of 192 bit"
+                    AlgorithmClass="SymmetricKeyWrap"
+                    RequirementLevel="OPTIONAL"
+                    KeyLength="192"
+                    RequiredKey="Camellia"
+                    JCEName="CamelliaWrap"/>
+                    
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#kw-camellia256"
+                    Description="Symmetric Key Wrap using CAMELLIA with a key length of 256 bit"
+                    AlgorithmClass="SymmetricKeyWrap"
+                    RequirementLevel="OPTIONAL"
+                    KeyLength="256"
+                    RequiredKey="Camellia"
+                    JCEName="CamelliaWrap"/>
+                    
+         <Algorithm URI="http://www.w3.org/2007/05/xmldsig-more#kw-seed128"
+                    Description="Symmetric Key Wrap using SEED with a key length of 128 bit"
+                    AlgorithmClass="SymmetricKeyWrap"
+                    RequirementLevel="OPTIONAL"
+                    KeyLength="128"
+                    RequiredKey="SEED"
+                    JCEName="SEEDWrap"/>
 
       </Algorithms>
    </JCEAlgorithmMappings>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML> <HEAD> </HEAD> <BODY> <P>
-software configuration and internationalization ({@link com.sun.org.apache.xml.internal.security.utils.I18n}).
-</P></BODY> </HTML>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_de.properties	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_de.properties	Sat Oct 24 01:11:51 2020 +0100
@@ -1,126 +1,196 @@
+#
+#
+#    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.
+#
+#
+
 algorithm.alreadyRegistered = URI {0} wurde bereits an die Klasse {1} gebunden
-algorithm.classDoesNotExist = Kann URI {0} nicht für Klasse {1} registrieren weil sie nicht existiert
+algorithm.classDoesNotExist = Kann URI {0} nicht f\u00fcr Klasse {1} registrieren weil sie nicht existiert
 algorithm.ClassDoesNotExist = Klasse {0} existiert nicht
-algorithm.extendsWrongClass = Kann URI {0} nicht für Klasse {1} registrieren weil sie nicht {2} extended
-algorithms.CannotUseAlgorithmParameterSpecOnDSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating DSA signatures.
-algorithms.CannotUseAlgorithmParameterSpecOnRSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating RSA signatures.
-algorithms.CannotUseSecureRandomOnMAC = Sorry, but you cannot use a SecureRandom object for creating MACs.
-algorithms.HMACOutputLengthMin = HMACOutputLength must not be less than {0}
-algorithms.HMACOutputLengthOnlyForHMAC = A HMACOutputLength can only be specified for HMAC integrity algorithms
-algorithms.NoSuchAlgorithm = Der Algorithmus {0} ist nicht verfügbar. Original Nachricht war: {1}
-algorithms.NoSuchMap = The algorithm URI "{0}" could not be mapped to a JCE algorithm
-algorithms.NoSuchProvider = The specified Provider {0} does not exist. Original Message was: {1}
-algorithms.operationOnlyVerification = A public key can only used for verification of a signature.
-algorithms.WrongKeyForThisOperation = Sorry, you supplied the wrong key type for this operation! You supplied a {0} but a {1} is needed.
-attributeValueIllegal = The attribute {0} has value {1} but must be {2}
-c14n.Canonicalizer.Exception = Exception während Kanonisierung:  Original Nachricht war {0}
-c14n.Canonicalizer.IllegalNode = Unzulässiger NodeType {0}, NodeName lautete {1}
-c14n.Canonicalizer.NoSuchCanonicalizer = Kein Canonicalizer mit dem URI {0} gefunden
-c14n.Canonicalizer.ParserConfigurationException = ParserConfigurationException während Kanonisierung:  Original Nachricht war {0}
+algorithm.extendsWrongClass = Kann URI {0} nicht f\u00fcr Klasse {1} registrieren weil sie nicht von {2} abgeleitet ist
+algorithms.CannotUseAlgorithmParameterSpecOnDSA = AlgorithmParameterSpec kann nicht f\u00fcr DSA Signaturen benutzt werden.
+algorithms.CannotUseAlgorithmParameterSpecOnRSA = AlgorithmParameterSpec kann nicht f\u00fcr RSA Signaturen benutzt werden.
+algorithms.CannotUseSecureRandomOnMAC = SecureRandom kann nicht f\u00fcr MAC's angewandt werden.
+algorithms.HMACOutputLengthMin = HMACOutputLength darf nicht kleiner als {0} sein
+algorithms.HMACOutputLengthOnlyForHMAC = Die HMACOutputLength kann nur bei HMAC integrit\u00e4ts Algorithmen angegeben werden
+algorithms.NoSuchAlgorithm = Der Algorithmus {0} ist nicht verf\u00fcgbar.
+algorithms.NoSuchAlgorithm = Der Algorithmus {0} ist nicht verf\u00fcgbar. Original Nachricht war\: {1}
+algorithms.NoSuchMap = Algorithmus URI "{0}" konnte auf keinen JCE Algorithmus gemappt werden
+algorithms.NoSuchProvider = Der angegebene Provider {0} existiert nicht. Original Nachricht war\: {1}
+algorithms.operationOnlyVerification = Ein \u00f6ffentlicher Schl\u00fcssel (public key) kann nur zur Verifizierung einer Signatur verwendet werden.
+algorithms.WrongKeyForThisOperation = Der angegebene Schl\u00fcssel-Typ kann nicht f\u00fcr diese Operation verwendet werden. Angegeben wurde {0} aber ein {1} wird ben\u00f6tigt.
+attributeValueIllegal = Das Attribut {0} hat den Wert {1} muss aber {2} sein.
+c14n.Canonicalizer.Exception = Fehler w\u00e4hrend der Kanonisierung\:  Original Nachricht war {0}
+c14n.Canonicalizer.IllegalNode = Unzul\u00e4ssiger NodeType {0}, NodeName lautete {1}
+c14n.Canonicalizer.NoSuchCanonicalizer = Kein Kanonisierer mit dem URI {0} gefunden
+c14n.Canonicalizer.ParserConfigurationException = ParserConfigurationException w\u00e4hrend der Kanonisierung\:  Original Nachricht war {0}
 c14n.Canonicalizer.RelativeNamespace = Das Element {0} hat einen relativen Namespace: {1}="{2}"
-c14n.Canonicalizer.SAXException = SAXException während Kanonisierung:  Original Nachricht war {0}
-c14n.Canonicalizer.TraversalNotSupported = Das DOM Dokument unterstützt keine Traversal {0}
-c14n.Canonicalizer.UnsupportedEncoding = Unbekannte Kodierung {0}
-c14n.Canonicalizer.UnsupportedOperation = This canonicalizer does not support this operation
-c14n.XMLUtils.circumventBug2650forgotten = The tree has not been prepared for canonicalization using XMLUtils#circumventBug2650(Document)
-certificate.noSki.lowVersion = Certificate cannot contain a SubjectKeyIdentifier because it is only X509v{0}
-certificate.noSki.notOctetString = Certificates SubjectKeyIdentifier is not a OctetString
-certificate.noSki.null = Certificate does not contain a SubjectKeyIdentifier
-defaultNamespaceCannotBeSetHere = Default namespace cannot be set here
-ElementProxy.nullElement = Kann einen ElementProxy aus einem null Argument erzeugen
+c14n.Canonicalizer.SAXException = SAXException w\u00e4hrend der Kanonisierung\:  Original Nachricht war {0}
+c14n.Canonicalizer.TraversalNotSupported = Das DOM Dokument unterst\u00fctzt keine Traversal {0}
+c14n.Canonicalizer.UnsupportedEncoding = Nicht unterst\u00fctzte Kodierung {0}
+c14n.Canonicalizer.UnsupportedOperation = Der Kanonisierer unterst\u00fctzt diese Operation nicht
+c14n.XMLUtils.circumventBug2650forgotten = Die Baumstruktur wurde nicht vorbereitet f\u00fcr die Kanonisierung mit XMLUtils\#circumventBug2650(Document)
+certificate.noSki.lowVersion = Das Zertifikat dard kein SubjectKeyIdentifier enthalten da es nur ein X509v{0} ist
+certificate.noSki.notOctetString = Der SubjectKeyIdentifier des Zertifikates ist kein "OctetString"
+certificate.noSki.null = Das Zertifikat enth\u00e4lt kein SubjectKeyIdentifier
+defaultNamespaceCannotBeSetHere = Standard Namespace kann hier nicht gesetzt werden
+ElementProxy.nullElement = Kann keinen ElementProxy aus einem null Argument erzeugen
 empty = {0}
 encryption.algorithmCannotBeUsedForEncryptedData = encryption.algorithmCannotBeUsedForEncryptedData {0}
 encryption.algorithmCannotEatInitParams = encryption.algorithmCannotEatInitParams
 encryption.algorithmCannotEncryptDecrypt = encryption.algorithmCannotEncryptDecrypt
 encryption.algorithmCannotWrapUnWrap = encryption.algorithmCannotWrapUnWrap
-encryption.ExplicitKeySizeMismatch = The xenc:KeySize element requests a key size of {0} bit but the algorithm implements {1} bit
-encryption.nonceLongerThanDecryptedPlaintext = The given nonce is longer than the available plaintext. I Cannot strip away this.
-encryption.RSAOAEP.dataHashWrong = data hash wrong
-encryption.RSAOAEP.dataStartWrong = data wrong start {0}
-encryption.RSAOAEP.dataTooShort = data too short
-encryption.RSAPKCS15.blockTruncated = block truncated
-encryption.RSAPKCS15.noDataInBlock = no data in block
-encryption.RSAPKCS15.unknownBlockType = unknown block type
-encryption.nokey = No Key Encryption Key loaded and cannot determine using key resolvers
-endorsed.jdk1.4.0 = Since it seems that nobody reads our installation notes, we must do it in the exception messages. Hope you read them. You did NOT use the endorsed mechanism from JDK 1.4 properly; look at <http://xml.apache.org/security/Java/installation.html> how to solve this problem.
-errorMessages.InvalidDigestValueException = Ungültige Signatur: Reference Validation fehlgeschlagen.
-errorMessages.InvalidSignatureValueException = Ungültige Signatur: Core Validation fehlgeschlagen.
+encryption.ExplicitKeySizeMismatch = Das xenc\:KeySize Element fordert eine Schl\u00fcssel-L\u00e4nge von {0} bits aber der Algorithmus besitzt {1} bits
+encryption.nonceLongerThanDecryptedPlaintext = Das angegebene "Nonce" ist l\u00e4nger als der verf\u00fcgbare Plaintext.
+encryption.RSAOAEP.dataHashWrong = Falscher Hash-Wert
+encryption.RSAOAEP.dataStartWrong = Falscher Start Input {0}
+encryption.RSAOAEP.dataTooShort = Zu wenig Input
+encryption.RSAPKCS15.blockTruncated = Block abgeschnitten
+encryption.RSAPKCS15.noDataInBlock = Im Block sind keine Daten enthalten
+encryption.RSAPKCS15.unknownBlockType = Unbekannter Block Typ
+encryption.nokey = Es ist kein verschl\u00fcsselungs Schl\u00fcssel geladen und es konnte kein Schl\u00fcssel mit Hilfe der "key resolvers" gefunden werden.
+endorsed.jdk1.4.0 = Leider scheint niemand unsere Installations-Anleitung zu lesen, deshalb m\u00fcssen wir es \u00fcber die Exception machen\: Du hast den "endorsing" Mechanismus vom JDK 1.4 nicht richtig angewandt. Schaue unter <http\://xml.apache.org/security/Java/installation.html> nach wie man das Problem l\u00f6st.
+errorMessages.InvalidDigestValueException = Ung\u00fcltige Signatur\: Referen-Validierung fehlgeschlagen.
+errorMessages.InvalidSignatureValueException = Ung\u00fcltige Signatur\: Core Validierung fehlgeschlagen.
 errorMessages.IOException = Datei oder Resource kann nicht gelesen werden.
-errorMessages.MissingKeyFailureException = Verifizieren fehlgeschlagen, weil der öffentliche Schlüssel (public key) nicht verfügbar ist. Resourcen via addResource() hinzufügen und erneut verifizieren.
-errorMessages.MissingResourceFailureException = Verifizieren fehlgeschlagen, weil Resourcen nicht verfügbar sind. Resourcen via addResource() hinzufügen und erneut verifizieren.
+errorMessages.MissingKeyFailureException = Verifizierung fehlgeschlagen, weil der \u00f6ffentliche Schl\u00fcssel (public key) nicht verf\u00fcgbar ist. Resourcen via addResource() hinzuf\u00fcgen und erneut versuchen.
+errorMessages.MissingResourceFailureException = Verifizierung fehlgeschlagen, weil Resourcen nicht verf\u00fcgbar sind. Resourcen via addResource() hinzuf\u00fcgen und erneut versuchen.
 errorMessages.NoSuchAlgorithmException = Unbekannter Algorithmus {0}
-errorMessages.NotYetImplementedException = Funktionalität noch nicht implementiert.
-errorMessages.XMLSignatureException = Verifizieren aus unbekanntem Grund fehlgeschlagen.
+errorMessages.NotYetImplementedException = Funktionalit\u00e4t noch nicht implementiert.
+errorMessages.XMLSignatureException = Verifizierung aus unbekanntem Grund fehlgeschlagen.
 decoding.divisible.four = It should be divisible by four
-decoding.general = Error while decoding
-FileKeyStorageImpl.addToDefaultFromRemoteNotImplemented = Method addToDefaultFromRemote() not yet implemented.
-FileKeyStorageImpl.NoCert.Context = Not found such a X509Certificate including context {0}
-FileKeyStorageImpl.NoCert.IssNameSerNo = Not found such a X509Certificate with IssuerName {0} and serial number {1}
-FileKeyStorageImpl.NoCert.SubjName = Not found such a X509Certificate including SubjectName {0}
-generic.dontHaveConstructionElement = I do not have a construction Element
+decoding.general = Fehler beim Decodieren
+FileKeyStorageImpl.addToDefaultFromRemoteNotImplemented = Methode addToDefaultFromRemote() wurde noch nicht implementiert.
+FileKeyStorageImpl.NoCert.Context = Kein X509-Zertifikat mit Kontext {0} gefunden
+FileKeyStorageImpl.NoCert.IssNameSerNo = Kein X509-Zertifikat mit IssuerName {0} und serial number {1} gefunden
+FileKeyStorageImpl.NoCert.SubjName = Kein X509-Zertifikat mit SubjectName {0} gefunden
+generic.dontHaveConstructionElement = Konstruktions-Element fehlt
 generic.EmptyMessage = {0}
 generic.NotYetImplemented = {0} Leider noch nicht implementiert ;-((
-java.security.InvalidKeyException = Ungültiger Schlüssel
-java.security.NoSuchProviderException = Unbekannter oder nicht unterstützter Provider
-java.security.UnknownKeyType = Unbekannter oder nicht unterstützter Key type {0}
-KeyInfo.needKeyResolver = Es müssen mehrere KeyResolver registriert sein
-KeyInfo.nokey = Kann keinen Schlüssel aus {0} gewinnen
-KeyInfo.noKey = Kann keinen öffentlichen Schlüssel finden
-KeyInfo.wrongNumberOfObject = Benötige {0} keyObjects
+java.security.InvalidKeyException = Ung\u00fcltiger Schl\u00fcssel
+java.security.NoSuchProviderException = Unbekannter oder nicht unterst\u00fctzter Provider
+java.security.UnknownKeyType = Unbekannter oder nicht unterst\u00fctzter Schl\u00fcssel-Typ {0}
+KeyInfo.error = Error loading Key Info
+KeyInfo.needKeyResolver = Es m\u00fcssen mehrere KeyResolver registriert sein
+KeyInfo.nokey = Kann keinen Schl\u00fcssel aus {0} gewinnen
+KeyInfo.noKey = Kann keinen \u00f6ffentlichen Schl\u00fcssel finden
+KeyInfo.wrongNumberOfObject = Ben\u00f6tige {0} keyObjects
 KeyInfo.wrongUse = Dieses Objekt wird verwendet, um {0} zu gewinnen
-keyResolver.alreadyRegistered = Die Klasse {1} wurde bereits registriert für {0}
-KeyResolver.needStorageResolver = Need a StorageResolver to retrieve a Certificate from a {0}
+keyResolver.alreadyRegistered = Die Klasse {1} wurde bereits registriert f\u00fcr {0}
+KeyResolver.needStorageResolver = Es wird ein StorageResolver ben\u00f6tigt um ein Zertifikat aus {0} zu holen
 KeyResoverSpiImpl.cannotGetCert = Cannot get the Certificate that include or in {1} in implement class {0}
 KeyResoverSpiImpl.elementGeneration = Cannot make {1} element in implement class {0}
 KeyResoverSpiImpl.getPoublicKey = Cannot get the public key from implement class {0}
 KeyResoverSpiImpl.InvalidElement = Cannot set (2) Element in implement class {0}
-KeyResoverSpiImpl.keyStore = KeyStorage error in implement class {0}
-KeyResoverSpiImpl.need.Element = {1} type of Element is needed in implement class {0}
+KeyResoverSpiImpl.keyStore = KeyStorage Fehler in der implementierenden Klasse {0}
+KeyResoverSpiImpl.need.Element = Es wird der Typ {1} ben\u00f6tigt in der implementierenden Klasse {0}
 KeyResoverSpiImpl.wrongCRLElement = Cannot make CRL from {1} in implement class {0}
 KeyResoverSpiImpl.wrongKeyObject =  Need {1} type of KeyObject for generation Element in implement class{0}
 KeyResoverSpiImpl.wrongNumberOfObject = Need {1} keyObject in implement class {0}
-KeyStore.alreadyRegistered = {0} Class has already been registered for {1}
-KeyStore.register = {1} type class register error  in class {0}
-KeyStore.registerStore.register = Registeration error for type {0}
-KeyValue.IllegalArgument = Cannot create a {0} from {1}
-namespacePrefixAlreadyUsedByOtherURI = Namespace {0} already used by other URI {1}
+KeyStore.alreadyRegistered = Klasse {0} bereits registriert f\u00fcr {1}
+KeyStore.register = {1} type class register error in class {0}
+KeyStore.registerStore.register = Registrierungsfehler f\u00fcr Typ {0}
+KeyValue.IllegalArgument = Kann kein {0} aus {1} erzeugen
+namespacePrefixAlreadyUsedByOtherURI = Namespace {0} wird bereits von einer anderen URI {1} gebraucht
 notYetInitialized = Das Modul {0} ist noch nicht initialisiert
 prefix.AlreadyAssigned = Sie binden den Prefix {0} an den Namespace {1} aber er ist bereits an {2} zugewiesen
-signature.Canonicalizer.UnknownCanonicalizer = Unbekannter Canonicalizer. Kein Handler installiert für URI {0}
-signature.DSA.invalidFormat = Invalid ASN.1 encoding of the DSA signature
-signature.Generation.signBeforeGetValue = You have to XMLSignature.sign(java.security.PrivateKey) first
-signature.Reference.ForbiddenResolver = It is forbidden to access resolver {0} when secure validation is enabled
-signature.signatureAlgorithm = It is forbidden to use algorithm {0} when secure validation is enabled
+signature.Canonicalizer.UnknownCanonicalizer = Unbekannter Kanonisierer. Kein Handler installiert f\u00fcr URI {0}
+signature.DSA.invalidFormat = Ung\u00fcltige ASN.1 Kodierung der DSA Signatur
+signature.Generation.signBeforeGetValue = Es muss zuerst XMLSignature.sign(java.security.PrivateKey) aufgerufen werden
+signature.Reference.ForbiddenResolver = Der "Resolver" {0} ist bei aktivierter "secure validation" nicht erlaubt
+signature.Reference.NoDigestMethod = A Signature Reference Element must contain a DigestMethod child
+signature.Reference.NoDigestValue = A Signature Reference Element must contain a DigestValue child
+signature.signatureAlgorithm = Der Algorithmus {0} ist bei aktivierter "secure validation" nicht erlaubt
 signature.signaturePropertyHasNoTarget = Das Target Attribut der SignatureProperty muss gesetzt sein
-signature.tooManyReferences = {0} references are contained in the Manifest, maximum {1} are allowed with secure validation
-signature.tooManyTransforms = {0} transforms are contained in the Reference, maximum {1} are allowed with secure validation
-signature.Transform.ErrorDuringTransform = Während der Transformation {0} trat eine {1} auf.
-signature.Transform.ForbiddenTransform = Transform {0} is forbidden when secure validation is enabled
+signature.tooManyReferences = Das Manifest enth\u00e4lt {0} Referenzen, bei aktivierter "secure validation" sind aber maximal {1} erlaubt
+signature.tooManyTransforms = Die Referenz enth\u00e4lt {0} Transformationen, bei aktivierter "secure validation" sind aber maximal {1} erlaubt
+signature.Transform.ErrorDuringTransform = W\u00e4hrend der Transformation {0} trat eine {1} auf.
+signature.Transform.ForbiddenTransform = Die Transformation {0} ist bei aktivierter "secure validation" nicht erlaubt
 signature.Transform.NotYetImplemented = Transform {0} noch nicht implementiert
-signature.Transform.NullPointerTransform = Null pointer als URI übergeben. Programmierfehler?
-signature.Transform.UnknownTransform = Unbekannte Transformation. Kein Handler installiert für URI {0}
-signature.Util.BignumNonPositive = bigInteger.signum() muß positiv sein
-signature.Util.NonTextNode = Kein Text Node
-signature.Util.TooManyChilds = Zu viele Child-Elemente vom Type {0} in {1}
+signature.Transform.NullPointerTransform = Null pointer als URI \u00fcbergeben. Programmierfehler?
+signature.Transform.UnknownTransform = Unbekannte Transformation. Kein Handler installiert f\u00fcr URI {0}
+signature.Util.BignumNonPositive = bigInteger.signum() muss positiv sein
+signature.Util.NonTextNode = Keine Text Node
+signature.Util.TooManyChilds = Zu viele Kind-Elemente vom Typ {0} in {1}
 signature.Verification.certificateError = Zertifikatsfehler
-signature.Verification.IndexOutOfBounds = Index {0} illegal. We only have {1} References
+signature.Verification.IndexOutOfBounds = Index {0} illegal. Es sind nur {1} Referenzen vorhanden
 signature.Verification.internalError = Interner Fehler
-signature.Verification.InvalidDigestOrReference = Ungültiger Digest Wert oder Reference Element {0}
-signature.Verification.keyStore = Öffnen des KeyStore fehlgeschlagen
-signature.Verification.MissingID = Cannot resolve element with ID {0}
-signature.Verification.MissingResources = Kann die externe Resource {0} nicht auflösen
-signature.Verification.MultipleIDs = Multiple Elements with the same ID {0} were detected
-signature.Verification.NoSignatureElement = Input Dokument enthält kein {0} Element mit dem Namespace {1}
-signature.Verification.Reference.NoInput = Die Reference für den URI {0} hat keinen XMLSignatureInput erhalten.
+signature.Verification.InvalidDigestOrReference = Ung\u00fcltiger Digest Wert der Referenz {0}
+signature.Verification.keyStore = \u00d6ffnen des KeyStore fehlgeschlagen
+signature.Verification.MissingID = Element mit der ID {0} nicht gefunden
+signature.Verification.MissingResources = Kann die externe Resource {0} nicht aufl\u00f6sen
+signature.Verification.MultipleIDs = Mehrere Elemente mit der ID {0} gefunden
+signature.Verification.NoSignatureElement = Input Dokument enth\u00e4lt kein {0} Element mit dem Namespace {1}
+signature.Verification.Reference.NoInput = Die Referenz f\u00fcr den URI {0} hat keinen XMLSignatureInput erhalten.
 signature.Verification.SignatureError = Signatur Fehler
 signature.XMLSignatureInput.MissingConstuctor = Kann aus der Klasse {0} keinen XMLSignatureInput erzeugen
-signature.XMLSignatureInput.SerializeDOM = Input mit einem DOM Dokument initialisiert. Muß mit C14N serialisiert werden
-transform.Init.IllegalContextArgument = Unzulässiges Kontext Argument der Klasse {0}. Muss String, org.w3c.dom.NodeList oder java.io.InputStream sein.
+signature.XMLSignatureInput.SerializeDOM = Input mit einem DOM Dokument initialisiert. Muss mit C14N serialisiert werden
+transform.Init.IllegalContextArgument = Unzul\u00e4ssiges Kontext Argument der Klasse {0}. Muss String, org.w3c.dom.NodeList oder java.io.InputStream sein.
 transform.init.NotInitialized =
 transform.init.wrongURI = Initialisiert mit dem falschen URI. Das sollte nie passieren. Die Transformation implementiert {0} aber {1} wurde bei der Instantiierung verwendet.
-utils.Base64.IllegalBitlength = Ungültige Bytelänge; Muss ein vielfaches von 4 sein
-utils.resolver.noClass = Could not find a resolver for URI {0} and Base {1}
+utils.Base64.IllegalBitlength = Ung\u00fcltige Byte-L\u00e4nge; Muss ein vielfaches von 4 sein
+utils.resolver.noClass = Keinen Resolver f\u00fcr URI {0} und Base {1} gefunden
 xml.WrongContent = Kann {0} nicht finden in {1}
 xml.WrongElement = Kann kein {0} aus einem {1} Element erzeugen
 xpath.funcHere.documentsDiffer = Der XPath ist nicht im selben Dokument wie der Kontext Node
-xpath.funcHere.noXPathContext = Try to evaluate an XPath which uses the here() function but XPath is not inside an ds:XPath Element. XPath was : {0}
+xpath.funcHere.noXPathContext = Versuch einer XPath-Evaluierung welcher die Funktion here() benutzt aber der XPath ist nicht innerhalb eines ds\:XPath Elements. XPath \: {0}
+signature.Transform.node = Aktuelle Node\: {0}
+signature.Transform.nodeAndType = Aktuelle Node\: {0}, Typ\: {1}
+signature.XMLSignatureInput.nodesetReference = Das Node-Set der Referenz konnte nicht konvertieren werden
+transform.envelopedSignatureTransformNotInSignatureElement = Enveloped Transform konnte kein Signatur Element finden
+Base64Decoding = Fehler bei der Decodierung
+secureProcessing.MaximumAllowedTransformsPerReference = Die Referenz enth\u00e4lt {0} Transformationen. Es sind aber maximal {1} erlaubt. Die Limite kann \u00fcber das Konfigurations-Property "MaximumAllowedTransformsPerReference" erh\u00f6ht werden.
+secureProcessing.MaximumAllowedReferencesPerManifest = Das Manifest enh\u00e4lt {0} Referenzen. Es sind aber maximal {1} erlaubt. Die Limite kann \u00fcber das Konfigurations-Property "MaximumAllowedReferencesPerManifest" erh\u00f6ht werden.
+secureProcessing.DoNotThrowExceptionForManifests = Signatur-Manifests werden nicht unterst\u00fctzt. Das werfen dieser Exception kann durch das Konfigurations-Property "DoNotThrowExceptionForManifests" verhindert werden.
+secureProcessing.AllowMD5Algorithm = Vom Einsatz des MD5 Algorithmus wird strengstens abgeraten. Trotzdem kann er \u00fcber das Konfigurations-Property "AllowMD5Algorithm" erlaubt werden.
+secureProcessing.AllowNotSameDocumentReferences = Externe Referenzen gefunden. Die Verarbeitung von externen Referenzen ist standardm\u00e4ssig ausgeschaltet. Es kann \u00fcber das Konfigurations-Property "AllowNotSameDocumentReferences" aktiviert werden.
+secureProcessing.MaximumAllowedXMLStructureDepth = Die Maximum erlaubte Dokumenten-Tiefe von ({0}) wurde erreicht. Die Limite kann \u00fcber das Konfigurations-Property "MaximumAllowedXMLStructureDepth" erh\u00f6ht werden.
+secureProcessing.inputStreamLimitReached = Maximal erlaubte Anzahl bytes ({0}) erreicht.
+stax.duplicateActions=Doppelte Actions sind nicht erlaubt.
+stax.missingSecurityProperties = SecurityProperties darf nicht null sein\!
+stax.noOutputAction = Keine ausgehenden "Actions" definiert.
+stax.noKey = Kein Schl\u00fcssel geladen und es konnte kein Schl\u00fcssel gefunden werden f\u00fcr {0}
+stax.keyNotFound = Schl\u00fcssel nicht gefunden.
+stax.unsupportedKeyValue = Kein oder ung\u00fcltiger KeyValue.
+stax.emptyReferenceURI = Referenz enth\u00e4lt kein URI Attribut.
+stax.encryption.unprocessedReferences = Es wurden nicht alle Verschl\u00fcsselungs-Referenzen verarbeitet...
+stax.signature.unprocessedReferences = Es wurden nicht alle Signatur-Referenzen verarbeitet...
+stax.unsupportedToken = {0} nicht unterst\u00fctzt.
+stax.xmlStructureSizeExceeded = Maximal erlaubte ({0}) XML-Struktur Tiefe erreicht.
+stax.unexpectedXMLEvent = Unerwarteter StAX-Event\: {0}
+stax.encryption.noEncAlgo = xenc\:EncryptedKey enth\u00e4lt kein xenc\:EncryptionMethod/@Algorithm.
+stax.encryption.noCipherValue = EncryptedKey enth\u00e4lt kein xenc\:CipherData/xenc\:CipherValue.
+stax.unsecuredMessage = Ungesicherte Nachricht. Weder ein Signatur- noch ein EncryptedData- Element wurde gefunden.
+stax.signature.signedInfoMissing = SignedInfo Element fehlt.
+stax.signature.signatureMethodMissing = Signature method fehlt.
+stax.signature.canonicalizationMethodMissing = Signature canonicalization method fehlt.
+stax.signature.signatureValueMissing = Signature value fehlt.
+stax.signature.publicKeyOrCertificateMissing = Weder ein Zertifikat noch ein public-key wurde konfiguriert.
+stax.encryption.encryptionKeyMissing = Kein Schl\u00fcssel f\u00fcr die Verschl\u00fcsselung wurde konfiguriert.
+stax.unsupportedKeyTransp = Der public-key Algorithmus ist zu kurz um den symmetrischen Schl\u00fcssel zu verschl\u00fcsseln.
+stax.recursiveKeyReference = Rekursive Schl\u00fcssel referenzierung detektiert.
+stax.ecParametersNotSupported = ECParameters werden nicht unterst\u00fctzt.
+stax.namedCurveMissing = NamedCurve fehlt.
+stax.encryption.securePartNotFound = Part zum Verschl\u00fcsseln nicht gefunden: {0}
+stax.signature.securePartNotFound = Part zum Signieren nicht gefunden: {0}
+stax.multipleSignaturesNotSupported = Mehrere Signaturen werden nicht unterstützt.
+stax.signature.keyNameMissing = KeyName nicht konfiguriert.
+stax.keyNotFoundForName = Kein Schl\u00fcssel für Schl\u00fcsselname konfiguriert: {0}
+stax.keyTypeNotSupported = Key vom Typ {0} nicht f\u00fcr einen Key-Namenssuche unterst\u00fctzt
+stax.idsetbutnotgenerated = An Id attribute is specified, but Id generation is disabled
+stax.idgenerationdisablewithmultipleparts = Id generation must not be disabled when multiple parts need signing
\ No newline at end of file
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties	Sat Oct 24 01:11:51 2020 +0100
@@ -1,3 +1,24 @@
+#
+#
+#    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.
+#
+#
+
 algorithm.alreadyRegistered = URI {0} already assigned to class {1}
 algorithm.classDoesNotExist = Cannot register URI {0} to class {1} because this class does not exist in CLASSPATH
 algorithm.ClassDoesNotExist = Class {0} does not exist
@@ -5,8 +26,9 @@
 algorithms.CannotUseAlgorithmParameterSpecOnDSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating DSA signatures.
 algorithms.CannotUseAlgorithmParameterSpecOnRSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating RSA signatures.
 algorithms.CannotUseSecureRandomOnMAC = Sorry, but you cannot use a SecureRandom object for creating MACs.
-algorithms.HMACOutputLengthMin = HMACOutputLength must not be less than {0}
+algorithms.HMACOutputLengthMin = HMACOutputLength must not be less than {0}
 algorithms.HMACOutputLengthOnlyForHMAC = A HMACOutputLength can only be specified for HMAC integrity algorithms
+algorithms.NoSuchAlgorithmNoEx = The requested algorithm {0} does not exist.
 algorithms.NoSuchAlgorithm = The requested algorithm {0} does not exist. Original Message was: {1}
 algorithms.NoSuchMap = The algorithm URI "{0}" could not be mapped to a JCE algorithm
 algorithms.NoSuchProvider = The specified Provider {0} does not exist. Original Message was: {1}
@@ -63,7 +85,8 @@
 java.security.InvalidKeyException = Invalid key
 java.security.NoSuchProviderException = Unknown or unsupported provider
 java.security.UnknownKeyType = Unknown or unsupported key type {0}
-KeyInfo.needKeyResolver = More than one keyResovler have to be registered
+KeyInfo.error = Error loading Key Info
+KeyInfo.needKeyResolver = More than one keyResolver have to be registered
 KeyInfo.nokey = Cannot get key from {0}
 KeyInfo.noKey = Cannot get the public key
 KeyInfo.wrongNumberOfObject = Need {0} keyObjects
@@ -80,8 +103,8 @@
 KeyResoverSpiImpl.wrongKeyObject =  Need {1} type of KeyObject for generation Element in implement class{0}
 KeyResoverSpiImpl.wrongNumberOfObject = Need {1} keyObject in implement class {0}
 KeyStore.alreadyRegistered = {0} Class has already been registered for {1}
-KeyStore.register = {1} type class register error  in class {0}
-KeyStore.registerStore.register = Registeration error for type {0}
+KeyStore.register = {1} type class register error in class {0}
+KeyStore.registerStore.register = Registration error for type {0}
 KeyValue.IllegalArgument = Cannot create a {0} from {1}
 namespacePrefixAlreadyUsedByOtherURI = Namespace prefix {0} already used by other URI {1}
 notYetInitialized = The module {0} is not yet initialized
@@ -90,6 +113,8 @@
 signature.DSA.invalidFormat = Invalid ASN.1 encoding of the DSA signature
 signature.Generation.signBeforeGetValue = You have to XMLSignature.sign(java.security.PrivateKey) first
 signature.Reference.ForbiddenResolver = It is forbidden to access resolver {0} when secure validation is enabled
+signature.Reference.NoDigestMethod = A Signature Reference Element must contain a DigestMethod child
+signature.Reference.NoDigestValue = A Signature Reference Element must contain a DigestValue child
 signature.signatureAlgorithm = It is forbidden to use algorithm {0} when secure validation is enabled
 signature.signaturePropertyHasNoTarget = The Target attribute of the SignatureProperty must be set
 signature.tooManyReferences = {0} references are contained in the Manifest, maximum {1} are allowed with secure validation
@@ -121,7 +146,7 @@
 transform.Init.IllegalContextArgument = Invalid context argument of class {0}. Must be String, org.w3c.dom.NodeList or java.io.InputStream.
 transform.init.NotInitialized =
 transform.init.wrongURI = Initialized with wrong URI. How could this happen? We implement {0} but {1} was used during initialization
-transform.envelopedSignatureTransformNotInSignatureElement = Enveloped Transform cannot find Signature element
+transform.envelopedSignatureTransformNotInSignatureElement = Enveloped Transform cannot find Signature element
 utils.Base64.IllegalBitlength = Illegal byte length; Data to be decoded must be a multiple of 4
 Base64Decoding = Error while decoding
 utils.resolver.noClass = Could not find a resolver for URI {0} and Base {1}
@@ -129,3 +154,43 @@
 xml.WrongElement = Cannot create a {0} from a {1} element
 xpath.funcHere.documentsDiffer = The XPath is not in the same document as the context node
 xpath.funcHere.noXPathContext = Try to evaluate an XPath which uses the here() function but XPath is not inside an ds:XPath Element. XPath was : {0}
+secureProcessing.MaximumAllowedTransformsPerReference = {0} transforms are contained in the Reference, maximum {1} are allowed. You can raise the maximum via the \"MaximumAllowedTransformsPerReference\" property in the configuration.
+secureProcessing.MaximumAllowedReferencesPerManifest = {0} references are contained in the Manifest, maximum {1} are allowed. You can raise the maximum via the \"MaximumAllowedReferencesPerManifest\" property in the configuration.
+secureProcessing.DoNotThrowExceptionForManifests = Signature Manifests are not supported. You can disable throwing of an exception via the \"DoNotThrowExceptionForManifests\" property in the configuration.
+secureProcessing.AllowMD5Algorithm = The use of MD5 algorithm is strongly discouraged. Nonetheless can it be enabled via the \"AllowMD5Algorithm\" property in the configuration.
+secureProcessing.AllowNotSameDocumentReferences = External references found. Processing of external references is disabled by default. You can enable it via the \"AllowNotSameDocumentReferences\" property in the configuration.
+secureProcessing.MaximumAllowedXMLStructureDepth = Maximum depth ({0}) of the XML structure reached. You can raise the maximum via the \"MaximumAllowedXMLStructureDepth\" property in the configuration.
+secureProcessing.inputStreamLimitReached = Maximum byte count ({0}) reached.
+stax.duplicateActions = Duplicate Actions are not allowed.
+stax.missingSecurityProperties = SecurityProperties must not be null!
+stax.noOutputAction = No outgoing actions specified.
+stax.noKey = Key could not be resolved and no key was loaded for {0}
+stax.keyNotFound = Key not found.
+stax.unsupportedKeyValue = No or unsupported key in KeyValue.
+stax.emptyReferenceURI = Reference is missing an URI attribute.
+stax.encryption.unprocessedReferences = Some encryption references were not processed...
+stax.signature.unprocessedReferences = Some signature references were not processed...
+stax.unsupportedToken = {0} not supported.
+stax.xmlStructureSizeExceeded = Maximum ({0}) allowed XML Structure size exceeded.
+stax.unexpectedXMLEvent = Unexpected StAX-Event\: {0}
+stax.encryption.noEncAlgo = xenc:EncryptedKey does not contain xenc:EncryptionMethod/@Algorithm.
+stax.encryption.noCipherValue = EncryptedKey does not contain xenc:CipherData/xenc:CipherValue.
+stax.unsecuredMessage = Unsecured message. Neither a Signature nor a EncryptedData element found.
+stax.signature.signedInfoMissing = SignedInfo Element is missing.
+stax.signature.signatureMethodMissing = Signature method is missing.
+stax.signature.canonicalizationMethodMissing = Signature canonicalization method is missing.
+stax.signature.signatureValueMissing = Signature value is missing.
+stax.signature.publicKeyOrCertificateMissing = Certificate or public key not configured.
+stax.encryption.encryptionKeyMissing = Key for encryption not configured.
+stax.unsupportedKeyTransp = public key algorithm too weak to encrypt symmetric key.
+stax.recursiveKeyReference = Recursive key reference detected.
+stax.ecParametersNotSupported = ECParameters not supported.
+stax.namedCurveMissing = NamedCurve is missing.
+stax.encryption.securePartNotFound = Part to encrypt not found: {0}
+stax.signature.securePartNotFound = Part to sign not found: {0}
+stax.multipleSignaturesNotSupported = Multiple signatures are not supported.
+stax.signature.keyNameMissing = KeyName not configured.
+stax.keyNotFoundForName = No key configured for KeyName: {0}
+stax.keyTypeNotSupported = Key of type {0} not supported for a KeyName lookup
+stax.idsetbutnotgenerated = An Id attribute is specified, but Id generation is disabled
+stax.idgenerationdisablewithmultipleparts = Id generation must not be disabled when multiple parts need signing
\ No newline at end of file
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/InvalidDigestValueException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/InvalidDigestValueException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -27,7 +27,6 @@
  * Additional human readable info is passed to the constructor -- this being the benefit
  * of raising an exception or returning a value.
  *
- * @author Christian Geuer-Pollmann
  */
 public class InvalidDigestValueException extends XMLSignatureException {
 
@@ -66,21 +65,31 @@
     /**
      * Constructor InvalidDigestValueException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public InvalidDigestValueException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public InvalidDigestValueException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor InvalidDigestValueException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
-    public InvalidDigestValueException(String msgID, Object exArgs[], Exception originalException) {
-        super(msgID, exArgs, originalException);
+    public InvalidDigestValueException(Exception originalException, String msgID, Object exArgs[]) {
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public InvalidDigestValueException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/InvalidSignatureValueException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/InvalidSignatureValueException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -26,7 +26,6 @@
  * Raised if testing the signature value over <i>DigestValue</i> fails because of invalid signature.
  *
  * @see InvalidDigestValueException  MissingKeyFailureException  MissingResourceFailureException
- * @author Christian Geuer-Pollmann
  */
 public class InvalidSignatureValueException extends XMLSignatureException {
 
@@ -65,21 +64,31 @@
     /**
      * Constructor InvalidSignatureValueException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public InvalidSignatureValueException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public InvalidSignatureValueException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor InvalidSignatureValueException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
-    public InvalidSignatureValueException(String msgID, Object exArgs[], Exception originalException) {
-        super(msgID, exArgs, originalException);
+    public InvalidSignatureValueException(Exception originalException, String msgID, Object exArgs[]) {
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public InvalidSignatureValueException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/Manifest.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/Manifest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -50,8 +50,8 @@
 import org.xml.sax.SAXException;
 
 /**
- * Handles <code>&lt;ds:Manifest&gt;</code> elements.
- * <p> This element holds the <code>Reference</code> elements</p>
+ * Handles {@code &lt;ds:Manifest&gt;} elements.
+ * <p> This element holds the {@code Reference} elements</p>
  */
 public class Manifest extends SignatureElementProxy {
 
@@ -60,36 +60,35 @@
      */
     public static final int MAXIMUM_REFERENCE_COUNT = 30;
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(Manifest.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(Manifest.class);
 
     /** Field references */
     private List<Reference> references;
     private Element[] referencesEl;
 
     /** Field verificationResults[] */
-    private boolean verificationResults[] = null;
+    private boolean[] verificationResults;
 
     /** Field resolverProperties */
-    private Map<String, String> resolverProperties = null;
+    private Map<String, String> resolverProperties;
 
     /** Field perManifestResolvers */
-    private List<ResourceResolver> perManifestResolvers = null;
+    private List<ResourceResolver> perManifestResolvers;
 
     private boolean secureValidation;
 
     /**
      * Constructs {@link Manifest}
      *
-     * @param doc the {@link Document} in which <code>XMLsignature</code> is placed
+     * @param doc the {@link Document} in which {@code XMLsignature} is placed
      */
     public Manifest(Document doc) {
         super(doc);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
 
-        this.references = new ArrayList<Reference>();
+        this.references = new ArrayList<>();
     }
 
     /**
@@ -100,7 +99,7 @@
      * @throws XMLSecurityException
      */
     public Manifest(Element element, String baseURI) throws XMLSecurityException {
-        this(element, baseURI, false);
+        this(element, baseURI, true);
 
     }
     /**
@@ -125,7 +124,7 @@
         // check out Reference children
         this.referencesEl =
             XMLUtils.selectDsNodes(
-                this.constructionElement.getFirstChild(), Constants._TAG_REFERENCE
+                getFirstChild(), Constants._TAG_REFERENCE
             );
         int le = this.referencesEl.length;
         if (le == 0) {
@@ -143,7 +142,7 @@
         }
 
         // create List
-        this.references = new ArrayList<Reference>(le);
+        this.references = new ArrayList<>(le);
 
         for (int i = 0; i < le; i++) {
             Element refElem = referencesEl[i];
@@ -156,12 +155,12 @@
     }
 
     /**
-     * This <code>addDocument</code> method is used to add a new resource to the
+     * This {@code addDocument} method is used to add a new resource to the
      * signed info. A {@link com.sun.org.apache.xml.internal.security.signature.Reference} is built
      * from the supplied values.
      *
      * @param baseURI the URI of the resource where the XML instance was stored
-     * @param referenceURI <code>URI</code> attribute in <code>Reference</code> for specifying
+     * @param referenceURI {@code URI} attribute in {@code Reference} for specifying
      * where data is
      * @param transforms com.sun.org.apache.xml.internal.security.signature.Transforms object with an ordered
      * list of transformations to be performed.
@@ -176,7 +175,7 @@
     ) throws XMLSignatureException {
         // the this.doc is handed implicitly by the this.getOwnerDocument()
         Reference ref =
-            new Reference(this.doc, baseURI, referenceURI, this, transforms, digestURI);
+            new Reference(getDocument(), baseURI, referenceURI, this, transforms, digestURI);
 
         if (referenceId != null) {
             ref.setId(referenceId);
@@ -190,8 +189,8 @@
         this.references.add(ref);
 
         // add the Element of the Reference object to the Manifest/SignedInfo
-        this.constructionElement.appendChild(ref.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(ref);
+        addReturnToSelf();
     }
 
     /**
@@ -221,11 +220,11 @@
     }
 
     /**
-     * Return the <it>i</it><sup>th</sup> reference. Valid <code>i</code>
-     * values are 0 to <code>{link@ getSize}-1</code>.
+     * Return the <i>i</i><sup>th</sup> reference. Valid {@code i}
+     * values are 0 to {@code {link@ getSize}-1}.
      *
      * @param i Index of the requested {@link Reference}
-     * @return the <it>i</it><sup>th</sup> reference
+     * @return the <i>i</i><sup>th</sup> reference
      * @throws XMLSecurityException
      */
     public Reference item(int i) throws XMLSecurityException {
@@ -241,24 +240,23 @@
     }
 
     /**
-     * Sets the <code>Id</code> attribute
+     * Sets the {@code Id} attribute
      *
-     * @param Id the <code>Id</code> attribute in <code>ds:Manifest</code>
+     * @param Id the {@code Id} attribute in {@code ds:Manifest}
      */
     public void setId(String Id) {
         if (Id != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_ID, Id);
-            this.constructionElement.setIdAttributeNS(null, Constants._ATT_ID, true);
+            setLocalIdAttribute(Constants._ATT_ID, Id);
         }
     }
 
     /**
-     * Returns the <code>Id</code> attribute
+     * Returns the {@code Id} attribute
      *
-     * @return the <code>Id</code> attribute in <code>ds:Manifest</code>
+     * @return the {@code Id} attribute in {@code ds:Manifest}
      */
     public String getId() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_ID);
+        return getLocalAttribute(Constants._ATT_ID);
     }
 
     /**
@@ -267,8 +265,8 @@
      *
      * <p>This step loops through all {@link Reference}s and does verify the hash
      * values. If one or more verifications fail, the method returns
-     * <code>false</code>. If <i>all</i> verifications are successful,
-     * it returns <code>true</code>. The results of the individual reference
+     * {@code false}. If <i>all</i> verifications are successful,
+     * it returns {@code true}. The results of the individual reference
      * validations are available by using the {@link #getVerificationResult(int)} method
      *
      * @return true if all References verify, false if one or more do not verify.
@@ -291,8 +289,8 @@
      *
      * <p>This step loops through all {@link Reference}s and does verify the hash
      * values. If one or more verifications fail, the method returns
-     * <code>false</code>. If <i>all</i> verifications are successful,
-     * it returns <code>true</code>. The results of the individual reference
+     * {@code false}. If <i>all</i> verifications are successful,
+     * it returns {@code true}. The results of the individual reference
      * validations are available by using the {@link #getVerificationResult(int)} method
      *
      * @param followManifests
@@ -310,16 +308,14 @@
         if (referencesEl == null) {
             this.referencesEl =
                 XMLUtils.selectDsNodes(
-                    this.constructionElement.getFirstChild(), Constants._TAG_REFERENCE
+                    getFirstChild(), Constants._TAG_REFERENCE
                 );
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "verify " + referencesEl.length + " References");
-            log.log(java.util.logging.Level.FINE, "I am " + (followManifests
-                ? "" : "not") + " requested to follow nested Manifests");
-        }
+        LOG.debug("verify {} References", referencesEl.length);
+        LOG.debug("I am {} requested to follow nested Manifests", (followManifests
+            ? "" : "not"));
         if (referencesEl.length == 0) {
-            throw new XMLSecurityException("empty");
+            throw new XMLSecurityException("empty", new Object[]{"References are empty"});
         }
         if (secureValidation && referencesEl.length > MAXIMUM_REFERENCE_COUNT) {
             Object exArgs[] = { referencesEl.length, MAXIMUM_REFERENCE_COUNT };
@@ -344,15 +340,11 @@
                 if (!currentRefVerified) {
                     verify = false;
                 }
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "The Reference has Type " + currentRef.getType());
-                }
+                LOG.debug("The Reference has Type {}", currentRef.getType());
 
                 // was verification successful till now and do we want to verify the Manifest?
                 if (verify && followManifests && currentRef.typeIsReferenceToManifest()) {
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, "We have to follow a nested Manifest");
-                    }
+                    LOG.debug("We have to follow a nested Manifest");
 
                     try {
                         XMLSignatureInput signedManifestNodes =
@@ -361,10 +353,10 @@
                         Manifest referencedManifest = null;
                         Iterator<Node> nlIterator = nl.iterator();
 
-                        findManifest: while (nlIterator.hasNext()) {
+                        while (nlIterator.hasNext()) {
                             Node n = nlIterator.next();
 
-                            if ((n.getNodeType() == Node.ELEMENT_NODE)
+                            if (n.getNodeType() == Node.ELEMENT_NODE
                                 && ((Element) n).getNamespaceURI().equals(Constants.SignatureSpecNS)
                                 && ((Element) n).getLocalName().equals(Constants._TAG_MANIFEST)
                             ) {
@@ -373,11 +365,9 @@
                                         new Manifest(
                                              (Element)n, signedManifestNodes.getSourceURI(), secureValidation
                                         );
-                                    break findManifest;
+                                    break;
                                 } catch (XMLSecurityException ex) {
-                                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                                        log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-                                    }
+                                    LOG.debug(ex.getMessage(), ex);
                                     // Hm, seems not to be a ds:Manifest
                                 }
                             }
@@ -386,7 +376,8 @@
                         if (referencedManifest == null) {
                             // The Reference stated that it points to a ds:Manifest
                             // but we did not find a ds:Manifest in the signed area
-                            throw new MissingResourceFailureException("empty", currentRef);
+                            throw new MissingResourceFailureException(currentRef, "empty",
+                                                                      new Object[]{"No Manifest found"});
                         }
 
                         referencedManifest.perManifestResolvers = this.perManifestResolvers;
@@ -398,25 +389,23 @@
                         if (!referencedManifestValid) {
                             verify = false;
 
-                            log.log(java.util.logging.Level.WARNING, "The nested Manifest was invalid (bad)");
+                            LOG.warn("The nested Manifest was invalid (bad)");
                         } else {
-                            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                                log.log(java.util.logging.Level.FINE, "The nested Manifest was valid (good)");
-                            }
+                            LOG.debug("The nested Manifest was valid (good)");
                         }
                     } catch (IOException ex) {
-                        throw new ReferenceNotInitializedException("empty", ex);
+                        throw new ReferenceNotInitializedException(ex);
                     } catch (ParserConfigurationException ex) {
-                        throw new ReferenceNotInitializedException("empty", ex);
+                        throw new ReferenceNotInitializedException(ex);
                     } catch (SAXException ex) {
-                        throw new ReferenceNotInitializedException("empty", ex);
+                        throw new ReferenceNotInitializedException(ex);
                     }
                 }
             } catch (ReferenceNotInitializedException ex) {
                 Object exArgs[] = { currentRef.getURI() };
 
                 throw new MissingResourceFailureException(
-                    "signature.Verification.Reference.NoInput", exArgs, ex, currentRef
+                    ex, currentRef, "signature.Verification.Reference.NoInput", exArgs
                 );
             }
         }
@@ -448,21 +437,21 @@
      * @throws XMLSecurityException
      */
     public boolean getVerificationResult(int index) throws XMLSecurityException {
-        if ((index < 0) || (index > this.getLength() - 1)) {
+        if (index < 0 || index > this.getLength() - 1) {
             Object exArgs[] = { Integer.toString(index), Integer.toString(this.getLength()) };
             Exception e =
                 new IndexOutOfBoundsException(
                     I18n.translate("signature.Verification.IndexOutOfBounds", exArgs)
                 );
 
-            throw new XMLSecurityException("generic.EmptyMessage", e);
+            throw new XMLSecurityException(e);
         }
 
         if (this.verificationResults == null) {
             try {
                 this.verifyReferences();
             } catch (Exception ex) {
-                throw new XMLSecurityException("generic.EmptyMessage", ex);
+                throw new XMLSecurityException(ex);
             }
         }
 
@@ -470,8 +459,8 @@
     }
 
     /**
-     * Adds Resource Resolver for retrieving resources at specified <code>URI</code> attribute
-     * in <code>reference</code> element
+     * Adds Resource Resolver for retrieving resources at specified {@code URI} attribute
+     * in {@code reference} element
      *
      * @param resolver {@link ResourceResolver} can provide the implemenatin subclass of
      * {@link ResourceResolverSpi} for retrieving resource.
@@ -481,14 +470,14 @@
             return;
         }
         if (perManifestResolvers == null) {
-            perManifestResolvers = new ArrayList<ResourceResolver>();
+            perManifestResolvers = new ArrayList<>();
         }
         this.perManifestResolvers.add(resolver);
     }
 
     /**
-     * Adds Resource Resolver for retrieving resources at specified <code>URI</code> attribute
-     * in <code>reference</code> element
+     * Adds Resource Resolver for retrieving resources at specified {@code URI} attribute
+     * in {@code reference} element
      *
      * @param resolverSpi the implementation subclass of {@link ResourceResolverSpi} for
      * retrieving the resource.
@@ -498,7 +487,7 @@
             return;
         }
         if (perManifestResolvers == null) {
-            perManifestResolvers = new ArrayList<ResourceResolver>();
+            perManifestResolvers = new ArrayList<>();
         }
         perManifestResolvers.add(new ResourceResolver(resolverSpi));
     }
@@ -528,7 +517,7 @@
      */
     public void setResolverProperty(String key, String value) {
         if (resolverProperties == null) {
-            resolverProperties = new HashMap<String, String>(10);
+            resolverProperties = new HashMap<>(10);
         }
         this.resolverProperties.put(key, value);
     }
@@ -555,13 +544,13 @@
         try {
             return this.getReferencedContentAfterTransformsItem(i).getBytes();
         } catch (IOException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (CanonicalizationException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (InvalidCanonicalizerException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (XMLSecurityException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
@@ -601,9 +590,13 @@
     /**
      * Method getBaseLocalName
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     public String getBaseLocalName() {
         return Constants._TAG_MANIFEST;
     }
+
+    public boolean isSecureValidation() {
+        return secureValidation;
+    }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/MissingResourceFailureException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/MissingResourceFailureException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -27,7 +27,6 @@
  * testing the signature fails because of uninitialized
  * {@link com.sun.org.apache.xml.internal.security.signature.Reference}s.
  *
- * @author Christian Geuer-Pollmann
  * @see ReferenceNotInitializedException
  */
 public class MissingResourceFailureException extends XMLSignatureException {
@@ -38,65 +37,89 @@
     private static final long serialVersionUID = 1L;
 
     /** Field uninitializedReference */
-    private Reference uninitializedReference = null;
+    private Reference uninitializedReference;
 
     /**
      * MissingKeyResourceFailureException constructor.
+     * @param reference
      * @param msgID
-     * @param reference
      * @see #getReference
      */
-    public MissingResourceFailureException(String msgID, Reference reference) {
+    public MissingResourceFailureException(Reference reference, String msgID) {
         super(msgID);
 
         this.uninitializedReference = reference;
     }
 
+    @Deprecated
+    public MissingResourceFailureException(String msgID, Reference reference) {
+        this(reference, msgID);
+    }
+
     /**
      * Constructor MissingResourceFailureException
      *
+     * @param reference
      * @param msgID
      * @param exArgs
-     * @param reference
      * @see #getReference
      */
-    public MissingResourceFailureException(String msgID, Object exArgs[], Reference reference) {
+    public MissingResourceFailureException(Reference reference, String msgID, Object exArgs[]) {
         super(msgID, exArgs);
 
         this.uninitializedReference = reference;
     }
 
-    /**
-     * Constructor MissingResourceFailureException
-     *
-     * @param msgID
-     * @param originalException
-     * @param reference
-     * @see #getReference
-     */
-    public MissingResourceFailureException(
-        String msgID, Exception originalException, Reference reference
-    ) {
-        super(msgID, originalException);
-
-        this.uninitializedReference = reference;
+    @Deprecated
+    public MissingResourceFailureException(String msgID, Object exArgs[], Reference reference) {
+        this(reference, msgID, exArgs);
     }
 
     /**
      * Constructor MissingResourceFailureException
      *
-     * @param msgID
-     * @param exArgs
      * @param originalException
      * @param reference
+     * @param msgID
      * @see #getReference
      */
     public MissingResourceFailureException(
+        Exception originalException, Reference reference, String msgID
+    ) {
+        super(originalException, msgID);
+
+        this.uninitializedReference = reference;
+    }
+
+    @Deprecated
+    public MissingResourceFailureException(
+        String msgID, Exception originalException, Reference reference
+    ) {
+        this(originalException, reference, msgID);
+    }
+
+    /**
+     * Constructor MissingResourceFailureException
+     *
+     * @param originalException
+     * @param reference
+     * @param msgID
+     * @param exArgs
+     * @see #getReference
+     */
+    public MissingResourceFailureException(
+        Exception originalException, Reference reference, String msgID, Object exArgs[]
+    ) {
+        super(originalException, msgID, exArgs);
+
+        this.uninitializedReference = reference;
+    }
+
+    @Deprecated
+    public MissingResourceFailureException(
         String msgID, Object exArgs[], Exception originalException, Reference reference
     ) {
-        super(msgID, exArgs, originalException);
-
-        this.uninitializedReference = reference;
+        this(originalException, reference, msgID, exArgs);
     }
 
     /**
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/NodeFilter.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/NodeFilter.java	Sat Oct 24 01:11:51 2020 +0100
@@ -33,8 +33,8 @@
      * Tells if a node must be output in c14n.
      * @param n
      * @return 1 if the node should be output.
-     *         0 if node must not be output,
-     *         -1 if the node and all it's child must not be output.
+     *            0 if node must not be output,
+     *           -1 if the node and all it's child must not be output.
      *
      */
     int isNodeInclude(Node n);
@@ -47,8 +47,8 @@
      * @param n
      * @param level the relative level in the tree
      * @return 1 if the node should be output.
-     *         0 if node must not be output,
-     *         -1 if the node and all it's child must not be output.
+     *            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);
 
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/ObjectContainer.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/ObjectContainer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -31,10 +31,9 @@
 
 
 /**
- * Handles <code>&lt;ds:Object&gt;</code> elements
- * <code>Object<code> {@link Element} supply facility which can contain any kind data
+ * Handles {@code &lt;ds:Object&gt;} elements
+ * {@code Object} {@link Element} supply facility which can contain any kind data
  *
- * @author Christian Geuer-Pollmann
  * $todo$ if we remove childen, the boolean values are not updated
  */
 public class ObjectContainer extends SignatureElementProxy {
@@ -42,7 +41,7 @@
     /**
      * Constructs {@link ObjectContainer}
      *
-     * @param doc the {@link Document} in which <code>Object</code> element is placed
+     * @param doc the {@link Document} in which {@code Object} element is placed
      */
     public ObjectContainer(Document doc) {
         super(doc);
@@ -51,7 +50,7 @@
     /**
      * Constructs {@link ObjectContainer} from {@link Element}
      *
-     * @param element is <code>Object</code> element
+     * @param element is {@code Object} element
      * @param baseURI the URI of the resource where the XML instance was stored
      * @throws XMLSecurityException
      */
@@ -60,64 +59,63 @@
     }
 
     /**
-     * Sets the <code>Id</code> attribute
+     * Sets the {@code Id} attribute
      *
-     * @param Id <code>Id</code> attribute
+     * @param Id {@code Id} attribute
      */
     public void setId(String Id) {
         if (Id != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_ID, Id);
-            this.constructionElement.setIdAttributeNS(null, Constants._ATT_ID, true);
+            setLocalIdAttribute(Constants._ATT_ID, Id);
         }
     }
 
     /**
-     * Returns the <code>Id</code> attribute
+     * Returns the {@code Id} attribute
      *
-     * @return the <code>Id</code> attribute
+     * @return the {@code Id} attribute
      */
     public String getId() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_ID);
+        return getLocalAttribute(Constants._ATT_ID);
     }
 
     /**
-     * Sets the <code>MimeType</code> attribute
+     * Sets the {@code MimeType} attribute
      *
-     * @param MimeType the <code>MimeType</code> attribute
+     * @param MimeType the {@code MimeType} attribute
      */
     public void setMimeType(String MimeType) {
         if (MimeType != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_MIMETYPE, MimeType);
+            setLocalAttribute(Constants._ATT_MIMETYPE, MimeType);
         }
     }
 
     /**
-     * Returns the <code>MimeType</code> attribute
+     * Returns the {@code MimeType} attribute
      *
-     * @return the <code>MimeType</code> attribute
+     * @return the {@code MimeType} attribute
      */
     public String getMimeType() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_MIMETYPE);
+        return getLocalAttribute(Constants._ATT_MIMETYPE);
     }
 
     /**
-     * Sets the <code>Encoding</code> attribute
+     * Sets the {@code Encoding} attribute
      *
-     * @param Encoding the <code>Encoding</code> attribute
+     * @param Encoding the {@code Encoding} attribute
      */
     public void setEncoding(String Encoding) {
         if (Encoding != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_ENCODING, Encoding);
+            setLocalAttribute(Constants._ATT_ENCODING, Encoding);
         }
     }
 
     /**
-     * Returns the <code>Encoding</code> attribute
+     * Returns the {@code Encoding} attribute
      *
-     * @return the <code>Encoding</code> attribute
+     * @return the {@code Encoding} attribute
      */
     public String getEncoding() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_ENCODING);
+        return getLocalAttribute(Constants._ATT_ENCODING);
     }
 
     /**
@@ -127,10 +125,11 @@
      * @return the new node in the tree.
      */
     public Node appendChild(Node node) {
-        return this.constructionElement.appendChild(node);
+        appendSelf(node);
+        return node;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_OBJECT;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/Reference.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/Reference.java	Sat Oct 24 01:11:51 2020 +0100
@@ -26,14 +26,15 @@
 import java.io.OutputStream;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Base64;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 
+import com.sun.org.apache.xml.internal.security.algorithms.Algorithm;
 import com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm;
 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
-import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import com.sun.org.apache.xml.internal.security.signature.reference.ReferenceData;
 import com.sun.org.apache.xml.internal.security.signature.reference.ReferenceNodeSetData;
@@ -44,7 +45,6 @@
 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.InclusiveNamespaces;
-import com.sun.org.apache.xml.internal.security.utils.Base64;
 import com.sun.org.apache.xml.internal.security.utils.Constants;
 import com.sun.org.apache.xml.internal.security.utils.DigesterOutputStream;
 import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy;
@@ -59,11 +59,11 @@
 import org.w3c.dom.Text;
 
 /**
- * Handles <code>&lt;ds:Reference&gt;</code> elements.
+ * Handles {@code &lt;ds:Reference&gt;} elements.
  *
  * This includes:
  *
- * Constructs a <CODE>ds:Reference</CODE> from an {@link org.w3c.dom.Element}.
+ * Construct a {@code ds:Reference} from an {@link org.w3c.dom.Element}.
  *
  * <p>Create a new reference</p>
  * <pre>
@@ -100,7 +100,6 @@
  *  &lt;/complexType&gt;
  * </pre>
  *
- * @author Christian Geuer-Pollmann
  * @see ObjectContainer
  * @see Manifest
  */
@@ -124,16 +123,12 @@
      * will be added if necessary when generating the signature. See section
      * 3.1.1 of http://www.w3.org/2007/xmlsec/Drafts/xmldsig-core/ for more info.
      */
-    private static boolean useC14N11 = (
-        AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
-            public Boolean run() {
-                return Boolean.valueOf(Boolean.getBoolean("com.sun.org.apache.xml.internal.security.useC14N11"));
-            }
-        })).booleanValue();
+    private static boolean useC14N11 =
+        AccessController.doPrivileged((PrivilegedAction<Boolean>)
+            () -> Boolean.getBoolean("com.sun.org.apache.xml.internal.security.useC14N11"));
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static final java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(Reference.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(Reference.class);
 
     private Manifest manifest;
     private XMLSignatureInput transformsOutput;
@@ -149,7 +144,7 @@
     /**
      * Constructor Reference
      *
-     * @param doc the {@link Document} in which <code>XMLsignature</code> is placed
+     * @param doc the {@link Document} in which {@code XMLsignature} is placed
      * @param baseURI the URI of the resource where the XML instance will be stored
      * @param referenceURI URI indicate where is data which will digested
      * @param manifest
@@ -165,7 +160,7 @@
     ) throws XMLSignatureException {
         super(doc);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
 
         this.baseURI = baseURI;
         this.manifest = manifest;
@@ -178,29 +173,39 @@
         // this.manifest.appendChild(this.doc.createTextNode("\n"));
 
         if (transforms != null) {
-            this.transforms=transforms;
-            this.constructionElement.appendChild(transforms.getElement());
-            XMLUtils.addReturnToElement(this.constructionElement);
+            this.transforms = transforms;
+            appendSelf(transforms);
+            addReturnToSelf();
         }
-        MessageDigestAlgorithm mda =
-            MessageDigestAlgorithm.getInstance(this.doc, messageDigestAlgorithm);
+
+        // Create DigestMethod Element without actually instantiating a MessageDigest Object
+        Algorithm digestAlgorithm = new Algorithm(getDocument(), messageDigestAlgorithm) {
+            public String getBaseNamespace() {
+                return Constants.SignatureSpecNS;
+            }
 
-        digestMethodElem = mda.getElement();
-        this.constructionElement.appendChild(digestMethodElem);
-        XMLUtils.addReturnToElement(this.constructionElement);
+            public String getBaseLocalName() {
+                return Constants._TAG_DIGESTMETHOD;
+            }
+        };
+
+        digestMethodElem = digestAlgorithm.getElement();
+
+        appendSelf(digestMethodElem);
+        addReturnToSelf();
 
         digestValueElement =
-            XMLUtils.createElementInSignatureSpace(this.doc, Constants._TAG_DIGESTVALUE);
+            XMLUtils.createElementInSignatureSpace(getDocument(), Constants._TAG_DIGESTVALUE);
 
-        this.constructionElement.appendChild(digestValueElement);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(digestValueElement);
+        addReturnToSelf();
     }
 
 
     /**
      * Build a {@link Reference} from an {@link Element}
      *
-     * @param element <code>Reference</code> element
+     * @param element {@code Reference} element
      * @param baseURI the URI of the resource where the XML instance was stored
      * @param manifest is the {@link Manifest} of {@link SignedInfo} in which the Reference occurs.
      * We need this because the Manifest has the individual {@link ResourceResolver}s which have
@@ -208,13 +213,13 @@
      * @throws XMLSecurityException
      */
     protected Reference(Element element, String baseURI, Manifest manifest) throws XMLSecurityException {
-        this(element, baseURI, manifest, false);
+        this(element, baseURI, manifest, true);
     }
 
     /**
      * Build a {@link Reference} from an {@link Element}
      *
-     * @param element <code>Reference</code> element
+     * @param element {@code Reference} element
      * @param baseURI the URI of the resource where the XML instance was stored
      * @param manifest is the {@link Manifest} of {@link SignedInfo} in which the Reference occurs.
      * @param secureValidation whether secure validation is enabled or not
@@ -228,7 +233,8 @@
         this.secureValidation = secureValidation;
         this.baseURI = baseURI;
         Element el = XMLUtils.getNextElement(element.getFirstChild());
-        if (Constants._TAG_TRANSFORMS.equals(el.getLocalName())
+
+        if (el != null && Constants._TAG_TRANSFORMS.equals(el.getLocalName())
             && Constants.SignatureSpecNS.equals(el.getNamespaceURI())) {
             transforms = new Transforms(el, this.baseURI);
             transforms.setSecureValidation(secureValidation);
@@ -239,8 +245,16 @@
             }
             el = XMLUtils.getNextElement(el.getNextSibling());
         }
+
         digestMethodElem = el;
+        if (digestMethodElem == null) {
+            throw new XMLSecurityException("signature.Reference.NoDigestMethod");
+        }
+
         digestValueElement = XMLUtils.getNextElement(digestMethodElem.getNextSibling());
+        if (digestValueElement == null) {
+            throw new XMLSecurityException("signature.Reference.NoDigestValue");
+        }
         this.manifest = manifest;
     }
 
@@ -259,7 +273,7 @@
 
         String uri = digestMethodElem.getAttributeNS(null, Constants._ATT_ALGORITHM);
 
-        if (uri == null) {
+        if ("".equals(uri)) {
             return null;
         }
 
@@ -269,82 +283,81 @@
             throw new XMLSignatureException("signature.signatureAlgorithm", exArgs);
         }
 
-        return MessageDigestAlgorithm.getInstance(this.doc, uri);
+        return MessageDigestAlgorithm.getInstance(getDocument(), uri);
     }
 
     /**
-     * Sets the <code>URI</code> of this <code>Reference</code> element
+     * Sets the {@code URI} of this {@code Reference} element
      *
-     * @param uri the <code>URI</code> of this <code>Reference</code> element
+     * @param uri the {@code URI} of this {@code Reference} element
      */
     public void setURI(String uri) {
         if (uri != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_URI, uri);
+            setLocalAttribute(Constants._ATT_URI, uri);
         }
     }
 
     /**
-     * Returns the <code>URI</code> of this <code>Reference</code> element
+     * Returns the {@code URI} of this {@code Reference} element
      *
-     * @return URI the <code>URI</code> of this <code>Reference</code> element
+     * @return URI the {@code URI} of this {@code Reference} element
      */
     public String getURI() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_URI);
+        return getLocalAttribute(Constants._ATT_URI);
     }
 
     /**
-     * Sets the <code>Id</code> attribute of this <code>Reference</code> element
+     * Sets the {@code Id} attribute of this {@code Reference} element
      *
-     * @param id the <code>Id</code> attribute of this <code>Reference</code> element
+     * @param id the {@code Id} attribute of this {@code Reference} element
      */
     public void setId(String id) {
         if (id != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_ID, id);
-            this.constructionElement.setIdAttributeNS(null, Constants._ATT_ID, true);
+            setLocalIdAttribute(Constants._ATT_ID, id);
         }
     }
 
     /**
-     * Returns the <code>Id</code> attribute of this <code>Reference</code> element
+     * Returns the {@code Id} attribute of this {@code Reference} element
      *
-     * @return Id the <code>Id</code> attribute of this <code>Reference</code> element
+     * @return Id the {@code Id} attribute of this {@code Reference} element
      */
     public String getId() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_ID);
+        return getLocalAttribute(Constants._ATT_ID);
     }
 
     /**
-     * Sets the <code>type</code> atttibute of the Reference indicate whether an
-     * <code>ds:Object</code>, <code>ds:SignatureProperty</code>, or <code>ds:Manifest</code>
+     * Sets the {@code type} atttibute of the Reference indicate whether an
+     * {@code ds:Object}, {@code ds:SignatureProperty}, or {@code ds:Manifest}
      * element.
      *
-     * @param type the <code>type</code> attribute of the Reference
+     * @param type the {@code type} attribute of the Reference
      */
     public void setType(String type) {
         if (type != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_TYPE, type);
+            setLocalAttribute(Constants._ATT_TYPE, type);
         }
     }
 
     /**
-     * Return the <code>type</code> atttibute of the Reference indicate whether an
-     * <code>ds:Object</code>, <code>ds:SignatureProperty</code>, or <code>ds:Manifest</code>
+     * Return the {@code type} atttibute of the Reference indicate whether an
+     * {@code ds:Object}, {@code ds:SignatureProperty}, or {@code ds:Manifest}
      * element
      *
-     * @return the <code>type</code> attribute of the Reference
+     * @return the {@code type} attribute of the Reference
      */
     public String getType() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_TYPE);
+        return getLocalAttribute(Constants._ATT_TYPE);
     }
 
     /**
      * Method isReferenceToObject
      *
-     * This returns true if the <CODE>Type</CODE> attribute of the
-     * <CODE>Reference</CODE> element points to a <CODE>#Object</CODE> element
+     * This returns true if the {@code Type} attribute of the
+     * {@code Reference} element points to a {@code #Object} element
      *
      * @return true if the Reference type indicates that this Reference points to an
-     * <code>Object</code>
+     * {@code Object}
      */
     public boolean typeIsReferenceToObject() {
         if (Reference.OBJECT_URI.equals(this.getType())) {
@@ -357,8 +370,8 @@
     /**
      * Method isReferenceToManifest
      *
-     * This returns true if the <CODE>Type</CODE> attribute of the
-     * <CODE>Reference</CODE> element points to a <CODE>#Manifest</CODE> element
+     * This returns true if the {@code Type} attribute of the
+     * {@code Reference} element points to a {@code #Manifest} element
      *
      * @return true if the Reference type indicates that this Reference points to a
      * {@link Manifest}
@@ -383,8 +396,8 @@
             n = n.getNextSibling();
         }
 
-        String base64codedValue = Base64.encode(digestValue);
-        Text t = this.doc.createTextNode(base64codedValue);
+        String base64codedValue = Base64.getMimeEncoder().encodeToString(digestValue);
+        Text t = createText(base64codedValue);
 
         digestValueElement.appendChild(t);
     }
@@ -410,7 +423,7 @@
         throws ReferenceNotInitializedException {
         try {
             Attr uriAttr =
-                this.constructionElement.getAttributeNodeNS(null, Constants._ATT_URI);
+                getElement().getAttributeNodeNS(null, Constants._ATT_URI);
 
             ResourceResolver resolver =
                 ResourceResolver.getInstance(
@@ -420,7 +433,7 @@
 
             return resolver.resolve(uriAttr, this.baseURI, secureValidation);
         }  catch (ResourceResolverException ex) {
-            throw new ReferenceNotInitializedException("empty", ex);
+            throw new ReferenceNotInitializedException(ex);
         }
     }
 
@@ -442,15 +455,15 @@
 
             return output;
         } catch (ResourceResolverException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (CanonicalizationException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (InvalidCanonicalizerException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (TransformationException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (XMLSecurityException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
@@ -483,35 +496,37 @@
             Transforms transforms = this.getTransforms();
 
             if (transforms != null) {
-                doTransforms: for (int i = 0; i < transforms.getLength(); i++) {
+                for (int i = 0; i < transforms.getLength(); i++) {
                     Transform t = transforms.item(i);
                     String uri = t.getURI();
 
                     if (uri.equals(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS)
                         || uri.equals(Transforms.TRANSFORM_C14N_EXCL_WITH_COMMENTS)
                         || uri.equals(Transforms.TRANSFORM_C14N_OMIT_COMMENTS)
-                        || uri.equals(Transforms.TRANSFORM_C14N_WITH_COMMENTS)) {
-                        break doTransforms;
+                        || uri.equals(Transforms.TRANSFORM_C14N_WITH_COMMENTS)
+                        || uri.equals(Transforms.TRANSFORM_C14N11_OMIT_COMMENTS)
+                        || uri.equals(Transforms.TRANSFORM_C14N11_WITH_COMMENTS)) {
+                        break;
                     }
 
                     output = t.performTransform(output, null);
                 }
 
-            output.setSourceURI(input.getSourceURI());
+                output.setSourceURI(input.getSourceURI());
             }
             return output;
         } catch (IOException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (ResourceResolverException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (CanonicalizationException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (InvalidCanonicalizerException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (TransformationException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (XMLSecurityException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
@@ -528,23 +543,23 @@
             Transform c14nTransform = null;
 
             if (transforms != null) {
-                doTransforms: for (int i = 0; i < transforms.getLength(); i++) {
+                for (int i = 0; i < transforms.getLength(); i++) {
                     Transform t = transforms.item(i);
                     String uri = t.getURI();
 
                     if (uri.equals(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS)
                         || uri.equals(Transforms.TRANSFORM_C14N_EXCL_WITH_COMMENTS)) {
                         c14nTransform = t;
-                        break doTransforms;
+                        break;
                     }
                 }
             }
 
-            Set<String> inclusiveNamespaces = new HashSet<String>();
+            Set<String> inclusiveNamespaces = new HashSet<>();
             if (c14nTransform != null
-                && (c14nTransform.length(
+                && c14nTransform.length(
                     InclusiveNamespaces.ExclusiveCanonicalizationNamespace,
-                    InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES) == 1)) {
+                    InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES) == 1) {
 
                 // there is one InclusiveNamespaces element
                 InclusiveNamespaces in =
@@ -562,11 +577,11 @@
 
             return nodes.getHTMLRepresentation(inclusiveNamespaces);
         } catch (TransformationException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (InvalidTransformException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (XMLSecurityException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
@@ -588,7 +603,7 @@
 
     /**
      * This method returns the {@link XMLSignatureInput} which is referenced by the
-     * <CODE>URI</CODE> Attribute.
+     * {@code URI} Attribute.
      * @param os where to write the transformation can be null.
      * @return the element to digest
      *
@@ -605,7 +620,7 @@
             this.transformsOutput = output;
             return output;
         } catch (XMLSecurityException ex) {
-            throw new ReferenceNotInitializedException("empty", ex);
+            throw new ReferenceNotInitializedException(ex);
         }
     }
 
@@ -622,14 +637,17 @@
 
                             Iterator<Node> sIterator = s.iterator();
 
+                            @Override
                             public boolean hasNext() {
                                 return sIterator.hasNext();
                             }
 
+                            @Override
                             public Node next() {
                                 return sIterator.next();
                             }
 
+                            @Override
                             public void remove() {
                                 throw new UnsupportedOperationException();
                             }
@@ -637,8 +655,8 @@
                     }
                 };
             } catch (Exception e) {
-                // log a warning
-                log.log(java.util.logging.Level.WARNING, "cannot cache dereferenced data: " + e);
+                // LOG a warning
+                LOG.warn("cannot cache dereferenced data: " + e);
             }
         } else if (input.isElement()) {
             referenceData = new ReferenceSubTreeData
@@ -649,8 +667,8 @@
                     (input.getOctetStream(), input.getSourceURI(),
                         input.getMIMEType());
             } catch (IOException ioe) {
-                // log a warning
-                log.log(java.util.logging.Level.WARNING, "cannot cache dereferenced data: " + ioe);
+                // LOG a warning
+                LOG.warn("cannot cache dereferenced data: " + ioe);
             }
         }
     }
@@ -683,9 +701,9 @@
             XMLSignatureInput output = this.dereferenceURIandPerformTransforms(null);
             return output.getBytes();
         } catch (IOException ex) {
-            throw new ReferenceNotInitializedException("empty", ex);
+            throw new ReferenceNotInitializedException(ex);
         } catch (CanonicalizationException ex) {
-            throw new ReferenceNotInitializedException("empty", ex);
+            throw new ReferenceNotInitializedException(ex);
         }
     }
 
@@ -700,22 +718,25 @@
      */
     private byte[] calculateDigest(boolean validating)
         throws ReferenceNotInitializedException, XMLSignatureException {
-        OutputStream os = null;
-        try {
-            MessageDigestAlgorithm mda = this.getMessageDigestAlgorithm();
+        XMLSignatureInput input = this.getContentsBeforeTransformation();
+        if (input.isPreCalculatedDigest()) {
+            return getPreCalculatedDigest(input);
+        }
 
-            mda.reset();
-            DigesterOutputStream diOs = new DigesterOutputStream(mda);
-            os = new UnsyncBufferedOutputStream(diOs);
+        MessageDigestAlgorithm mda = this.getMessageDigestAlgorithm();
+        mda.reset();
+
+        try (DigesterOutputStream diOs = new DigesterOutputStream(mda);
+            OutputStream os = new UnsyncBufferedOutputStream(diOs)) {
             XMLSignatureInput output = this.dereferenceURIandPerformTransforms(os);
             // if signing and c14n11 property == true explicitly add
             // C14N11 transform if needed
             if (Reference.useC14N11 && !validating && !output.isOutputStreamSet()
                 && !output.isOctetStream()) {
                 if (transforms == null) {
-                    transforms = new Transforms(this.doc);
+                    transforms = new Transforms(getDocument());
                     transforms.setSecureValidation(secureValidation);
-                    this.constructionElement.insertBefore(transforms.getElement(), digestMethodElem);
+                    getElement().insertBefore(transforms.getElement(), digestMethodElem);
                 }
                 transforms.addTransform(Transforms.TRANSFORM_C14N11_OMIT_COMMENTS);
                 output.updateOutputStream(os, true);
@@ -733,28 +754,34 @@
 
             return diOs.getDigestValue();
         } catch (XMLSecurityException ex) {
-            throw new ReferenceNotInitializedException("empty", ex);
+            throw new ReferenceNotInitializedException(ex);
         } catch (IOException ex) {
-            throw new ReferenceNotInitializedException("empty", ex);
-        } finally {
-            if (os != null) {
-                try {
-                    os.close();
-                } catch (IOException ex) {
-                    throw new ReferenceNotInitializedException("empty", ex);
-                }
-            }
+            throw new ReferenceNotInitializedException(ex);
         }
     }
 
     /**
+     * Get the pre-calculated digest value from the XMLSignatureInput.
+     *
+     * @param input XMLSignature
+     * @return a pre-calculated digest value.
+     * @throws ReferenceNotInitializedException if there is an error decoding digest value
+     * in Base64. Properly encoded pre-calculated digest value must be set.
+     */
+    private byte[] getPreCalculatedDigest(XMLSignatureInput input)
+            throws ReferenceNotInitializedException {
+        LOG.debug("Verifying element with pre-calculated digest");
+        String preCalculatedDigest = input.getPreCalculatedDigest();
+        return Base64.getMimeDecoder().decode(preCalculatedDigest);
+    }
+
+    /**
      * Returns the digest value.
      *
      * @return the digest value.
-     * @throws Base64DecodingException if Reference contains no proper base64 encoded data.
      * @throws XMLSecurityException if the Reference does not contain a DigestValue element
      */
-    public byte[] getDigestValue() throws Base64DecodingException, XMLSecurityException {
+    public byte[] getDigestValue() throws XMLSecurityException {
         if (digestValueElement == null) {
             // The required element is not in the XML!
             Object[] exArgs ={ Constants._TAG_DIGESTVALUE, Constants.SignatureSpecNS };
@@ -762,7 +789,8 @@
                 "signature.Verification.NoSignatureElement", exArgs
             );
         }
-        return Base64.decode(digestValueElement);
+        String content = XMLUtils.getFullTextChildrenFromElement(digestValueElement);
+        return Base64.getMimeDecoder().decode(content);
     }
 
 
@@ -780,13 +808,11 @@
         boolean equal = MessageDigestAlgorithm.isEqual(elemDig, calcDig);
 
         if (!equal) {
-            log.log(java.util.logging.Level.WARNING, "Verification failed for URI \"" + this.getURI() + "\"");
-            log.log(java.util.logging.Level.WARNING, "Expected Digest: " + Base64.encode(elemDig));
-            log.log(java.util.logging.Level.WARNING, "Actual Digest: " + Base64.encode(calcDig));
+            LOG.warn("Verification failed for URI \"" + this.getURI() + "\"");
+            LOG.warn("Expected Digest: " + Base64.getMimeEncoder().encodeToString(elemDig));
+            LOG.warn("Actual Digest: " + Base64.getMimeEncoder().encodeToString(calcDig));
         } else {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Verification successful for URI \"" + this.getURI() + "\"");
-            }
+            LOG.debug("Verification successful for URI \"{}\"", this.getURI());
         }
 
         return equal;
@@ -794,7 +820,7 @@
 
     /**
      * Method getBaseLocalName
-     * @inheritDoc
+     * {@inheritDoc}
      */
     public String getBaseLocalName() {
         return Constants._TAG_REFERENCE;
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/ReferenceNotInitializedException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/ReferenceNotInitializedException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -26,7 +26,6 @@
  * Raised if verifying a {@link com.sun.org.apache.xml.internal.security.signature.Reference} fails
  * because of an uninitialized {@link com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput}
  *
- * @author Christian Geuer-Pollmann
  */
 public class ReferenceNotInitializedException extends XMLSignatureException {
 
@@ -43,6 +42,10 @@
         super();
     }
 
+    public ReferenceNotInitializedException(Exception ex) {
+        super(ex);
+    }
+
     /**
      * Constructor ReferenceNotInitializedException
      *
@@ -65,21 +68,31 @@
     /**
      * Constructor ReferenceNotInitializedException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public ReferenceNotInitializedException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public ReferenceNotInitializedException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor ReferenceNotInitializedException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
-    public ReferenceNotInitializedException(String msgID, Object exArgs[], Exception originalException) {
-        super(msgID, exArgs, originalException);
+    public ReferenceNotInitializedException(Exception originalException, String msgID, Object exArgs[]) {
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public ReferenceNotInitializedException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperties.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperties.java	Sat Oct 24 01:11:51 2020 +0100
@@ -31,12 +31,11 @@
 import org.w3c.dom.Element;
 
 /**
- * Handles <code>&lt;ds:SignatureProperties&gt;</code> elements
- * This Element holds {@link SignatureProperty} that contian additional information items
+ * Handles {@code &lt;ds:SignatureProperties&gt;} elements
+ * This Element holds {@link SignatureProperty} properties that contain additional information items
  * concerning the generation of the signature.
  * for example, data-time stamp, serial number of cryptographic hardware.
  *
- * @author Christian Geuer-Pollmann
  */
 public class SignatureProperties extends SignatureElementProxy {
 
@@ -48,17 +47,17 @@
     public SignatureProperties(Document doc) {
         super(doc);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
     }
 
     /**
      * Constructs {@link SignatureProperties} from {@link Element}
-     * @param element <code>SignatureProperties</code> element
-     * @param BaseURI the URI of the resource where the XML instance was stored
+     * @param element {@code SignatureProperties} element
+     * @param baseURI the URI of the resource where the XML instance was stored
      * @throws XMLSecurityException
      */
-    public SignatureProperties(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public SignatureProperties(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
 
         Attr attr = element.getAttributeNodeNS(null, "Id");
         if (attr != null) {
@@ -68,7 +67,7 @@
         int length = getLength();
         for (int i = 0; i < length; i++) {
             Element propertyElem =
-                XMLUtils.selectDsNode(this.constructionElement, Constants._TAG_SIGNATUREPROPERTY, i);
+                XMLUtils.selectDsNode(getElement(), Constants._TAG_SIGNATUREPROPERTY, i);
             Attr propertyAttr = propertyElem.getAttributeNodeNS(null, "Id");
             if (propertyAttr != null) {
                 propertyElem.setIdAttributeNode(propertyAttr, true);
@@ -83,52 +82,51 @@
      */
     public int getLength() {
         Element[] propertyElems =
-            XMLUtils.selectDsNodes(this.constructionElement, Constants._TAG_SIGNATUREPROPERTY);
+            XMLUtils.selectDsNodes(getElement(), Constants._TAG_SIGNATUREPROPERTY);
 
         return propertyElems.length;
     }
 
     /**
-     * Return the <it>i</it><sup>th</sup> SignatureProperty. Valid <code>i</code>
-     * values are 0 to <code>{link@ getSize}-1</code>.
+     * Return the <i>i</i><sup>th</sup> SignatureProperty. Valid {@code i}
+     * values are 0 to {@code {link@ getSize}-1}.
      *
      * @param i Index of the requested {@link SignatureProperty}
-     * @return the <it>i</it><sup>th</sup> SignatureProperty
+     * @return the <i>i</i><sup>th</sup> SignatureProperty
      * @throws XMLSignatureException
      */
     public SignatureProperty item(int i) throws XMLSignatureException {
         try {
             Element propertyElem =
-                XMLUtils.selectDsNode(this.constructionElement, Constants._TAG_SIGNATUREPROPERTY, i);
+                XMLUtils.selectDsNode(getElement(), Constants._TAG_SIGNATUREPROPERTY, i);
 
             if (propertyElem == null) {
                 return null;
             }
             return new SignatureProperty(propertyElem, this.baseURI);
         } catch (XMLSecurityException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
     /**
-     * Sets the <code>Id</code> attribute
+     * Sets the {@code Id} attribute
      *
-     * @param Id the <code>Id</code> attribute
+     * @param Id the {@code Id} attribute
      */
     public void setId(String Id) {
         if (Id != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_ID, Id);
-            this.constructionElement.setIdAttributeNS(null, Constants._ATT_ID, true);
+            setLocalIdAttribute(Constants._ATT_ID, Id);
         }
     }
 
     /**
-     * Returns the <code>Id</code> attribute
+     * Returns the {@code Id} attribute
      *
-     * @return the <code>Id</code> attribute
+     * @return the {@code Id} attribute
      */
     public String getId() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_ID);
+        return getLocalAttribute(Constants._ATT_ID);
     }
 
     /**
@@ -137,11 +135,11 @@
      * @param sp
      */
     public void addSignatureProperty(SignatureProperty sp) {
-        this.constructionElement.appendChild(sp.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(sp);
+        addReturnToSelf();
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_SIGNATUREPROPERTIES;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperty.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperty.java	Sat Oct 24 01:11:51 2020 +0100
@@ -30,19 +30,18 @@
 import org.w3c.dom.Node;
 
 /**
- * Handles <code>&lt;ds:SignatureProperty&gt;</code> elements
+ * Handles {@code &lt;ds:SignatureProperty&gt;} elements
  * Additional information item concerning the generation of the signature(s) can
  * be placed in this Element
  *
- * @author Christian Geuer-Pollmann
  */
 public class SignatureProperty extends SignatureElementProxy {
 
     /**
-     * Constructs{@link SignatureProperty} using specified <code>target</code> attribute
+     * Constructs{@link SignatureProperty} using specified {@code target} attribute
      *
-     * @param doc the {@link Document} in which <code>XMLsignature</code> is placed
-     * @param target the <code>target</code> attribute references the <code>Signature</code>
+     * @param doc the {@link Document} in which {@code XMLsignature} is placed
+     * @param target the {@code target} attribute references the {@code Signature}
      * element to which the property applies SignatureProperty
      */
     public SignatureProperty(Document doc, String target) {
@@ -50,13 +49,13 @@
     }
 
     /**
-     * Constructs {@link SignatureProperty} using sepcified <code>target</code> attribute and
-     * <code>id</code> attribute
+     * Constructs {@link SignatureProperty} using sepcified {@code target} attribute and
+     * {@code id} attribute
      *
-     * @param doc the {@link Document} in which <code>XMLsignature</code> is placed
-     * @param target the <code>target</code> attribute references the <code>Signature</code>
+     * @param doc the {@link Document} in which {@code XMLsignature} is placed
+     * @param target the {@code target} attribute references the {@code Signature}
      *  element to which the property applies
-     * @param id the <code>id</code> will be specified by {@link Reference#getURI} in validation
+     * @param id the {@code id} will be specified by {@link Reference#getURI} in validation
      */
     public SignatureProperty(Document doc, String target, String id) {
         super(doc);
@@ -67,53 +66,52 @@
 
     /**
      * Constructs a {@link SignatureProperty} from an {@link Element}
-     * @param element <code>SignatureProperty</code> element
-     * @param BaseURI the URI of the resource where the XML instance was stored
+     * @param element {@code SignatureProperty} element
+     * @param baseURI the URI of the resource where the XML instance was stored
      * @throws XMLSecurityException
      */
-    public SignatureProperty(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public SignatureProperty(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
     }
 
     /**
-     *   Sets the <code>id</code> attribute
+     *   Sets the {@code id} attribute
      *
-     *   @param id the <code>id</code> attribute
+     *   @param id the {@code id} attribute
      */
     public void setId(String id) {
         if (id != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_ID, id);
-            this.constructionElement.setIdAttributeNS(null, Constants._ATT_ID, true);
+            setLocalIdAttribute(Constants._ATT_ID, id);
         }
     }
 
     /**
-     * Returns the <code>id</code> attribute
+     * Returns the {@code id} attribute
      *
-     * @return the <code>id</code> attribute
+     * @return the {@code id} attribute
      */
     public String getId() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_ID);
+        return getLocalAttribute(Constants._ATT_ID);
     }
 
     /**
-     * Sets the <code>target</code> attribute
+     * Sets the {@code target} attribute
      *
-     * @param target the <code>target</code> attribute
+     * @param target the {@code target} attribute
      */
     public void setTarget(String target) {
         if (target != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_TARGET, target);
+            setLocalAttribute(Constants._ATT_TARGET, target);
         }
     }
 
     /**
-     * Returns the <code>target</code> attribute
+     * Returns the {@code target} attribute
      *
-     * @return the <code>target</code> attribute
+     * @return the {@code target} attribute
      */
     public String getTarget() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_TARGET);
+        return getLocalAttribute(Constants._ATT_TARGET);
     }
 
     /**
@@ -123,10 +121,11 @@
      * @return the node in this element.
      */
     public Node appendChild(Node node) {
-        return this.constructionElement.appendChild(node);
+        appendSelf(node);
+        return node;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_SIGNATUREPROPERTY;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/SignedInfo.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/SignedInfo.java	Sat Oct 24 01:11:51 2020 +0100
@@ -24,10 +24,11 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
+
 import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
-import javax.xml.XMLConstants;
 import javax.xml.parsers.ParserConfigurationException;
 
 import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm;
@@ -35,28 +36,27 @@
 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
+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 com.sun.org.apache.xml.internal.security.transforms.params.InclusiveNamespaces;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.xml.sax.SAXException;
 
 /**
- * Handles <code>&lt;ds:SignedInfo&gt;</code> elements
- * This <code>SignedInfo<code> element includes the canonicalization algorithm,
+ * Handles {@code &lt;ds:SignedInfo&gt;} elements
+ * This {@code SignedInfo} element includes the canonicalization algorithm,
  * a signature algorithm, and one or more references.
  *
- * @author Christian Geuer-Pollmann
  */
 public class SignedInfo extends Manifest {
 
     /** Field signatureAlgorithm */
-    private SignatureAlgorithm signatureAlgorithm = null;
+    private SignatureAlgorithm signatureAlgorithm;
 
     /** Field c14nizedBytes           */
-    private byte[] c14nizedBytes = null;
+    private byte[] c14nizedBytes;
 
     private Element c14nMethod;
     private Element signatureMethod;
@@ -65,7 +65,7 @@
      * Overwrites {@link Manifest#addDocument} because it creates another
      * Element.
      *
-     * @param doc the {@link Document} in which <code>XMLsignature</code> will
+     * @param doc the {@link Document} in which {@code XMLsignature} will
      *    be placed
      * @throws XMLSecurityException
      */
@@ -78,7 +78,7 @@
      * Constructs {@link SignedInfo} using given Canonicalization algorithm and
      * Signature algorithm.
      *
-     * @param doc <code>SignedInfo</code> is placed in this document
+     * @param doc {@code SignedInfo} is placed in this document
      * @param signatureMethodURI URI representation of the Digest and
      *    Signature algorithm
      * @param canonicalizationMethodURI URI representation of the
@@ -94,7 +94,7 @@
     /**
      * Constructor SignedInfo
      *
-     * @param doc <code>SignedInfo</code> is placed in this document
+     * @param doc {@code SignedInfo} is placed in this document
      * @param signatureMethodURI URI representation of the Digest and
      *    Signature algorithm
      * @param hMACOutputLength
@@ -109,22 +109,22 @@
         super(doc);
 
         c14nMethod =
-            XMLUtils.createElementInSignatureSpace(this.doc, Constants._TAG_CANONICALIZATIONMETHOD);
+            XMLUtils.createElementInSignatureSpace(getDocument(), Constants._TAG_CANONICALIZATIONMETHOD);
 
         c14nMethod.setAttributeNS(null, Constants._ATT_ALGORITHM, canonicalizationMethodURI);
-        this.constructionElement.appendChild(c14nMethod);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(c14nMethod);
+        addReturnToSelf();
 
         if (hMACOutputLength > 0) {
             this.signatureAlgorithm =
-                new SignatureAlgorithm(this.doc, signatureMethodURI, hMACOutputLength);
+                new SignatureAlgorithm(getDocument(), signatureMethodURI, hMACOutputLength);
         } else {
-            this.signatureAlgorithm = new SignatureAlgorithm(this.doc, signatureMethodURI);
+            this.signatureAlgorithm = new SignatureAlgorithm(getDocument(), signatureMethodURI);
         }
 
         signatureMethod = this.signatureAlgorithm.getElement();
-        this.constructionElement.appendChild(signatureMethod);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(signatureMethod);
+        addReturnToSelf();
     }
 
     /**
@@ -139,22 +139,22 @@
         super(doc);
         // Check this?
         this.c14nMethod = canonicalizationMethodElem;
-        this.constructionElement.appendChild(c14nMethod);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(c14nMethod);
+        addReturnToSelf();
 
         this.signatureAlgorithm =
             new SignatureAlgorithm(signatureMethodElem, null);
 
         signatureMethod = this.signatureAlgorithm.getElement();
-        this.constructionElement.appendChild(signatureMethod);
+        appendSelf(signatureMethod);
 
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
     }
 
     /**
      * Build a {@link SignedInfo} from an {@link Element}
      *
-     * @param element <code>SignedInfo</code>
+     * @param element {@code SignedInfo}
      * @param baseURI the URI of the resource where the XML instance was stored
      * @throws XMLSecurityException
      * @see <A HREF="http://lists.w3.org/Archives/Public/w3c-ietf-xmldsig/2001OctDec/0033.html">
@@ -163,13 +163,13 @@
      * Answer</A>
      */
     public SignedInfo(Element element, String baseURI) throws XMLSecurityException {
-        this(element, baseURI, false);
+        this(element, baseURI, true);
     }
 
     /**
      * Build a {@link SignedInfo} from an {@link Element}
      *
-     * @param element <code>SignedInfo</code>
+     * @param element {@code SignedInfo}
      * @param baseURI the URI of the resource where the XML instance was stored
      * @param secureValidation whether secure validation is enabled or not
      * @throws XMLSecurityException
@@ -182,7 +182,7 @@
         Element element, String baseURI, boolean secureValidation
     ) throws XMLSecurityException {
         // Parse the Reference children and Id attribute in the Manifest
-        super(reparseSignedInfoElem(element), baseURI, secureValidation);
+        super(reparseSignedInfoElem(element, secureValidation), baseURI, secureValidation);
 
         c14nMethod = XMLUtils.getNextElement(element.getFirstChild());
         signatureMethod = XMLUtils.getNextElement(c14nMethod.getNextSibling());
@@ -190,7 +190,7 @@
             new SignatureAlgorithm(signatureMethod, this.getBaseURI(), secureValidation);
     }
 
-    private static Element reparseSignedInfoElem(Element element)
+    private static Element reparseSignedInfoElem(Element element, boolean secureValidation)
         throws XMLSecurityException {
         /*
          * If a custom canonicalizationMethod is used, canonicalize
@@ -212,27 +212,24 @@
             try {
                 Canonicalizer c14nizer =
                     Canonicalizer.getInstance(c14nMethodURI);
+                c14nizer.setSecureValidation(secureValidation);
 
                 byte[] c14nizedBytes = c14nizer.canonicalizeSubtree(element);
-                javax.xml.parsers.DocumentBuilderFactory dbf =
-                    javax.xml.parsers.DocumentBuilderFactory.newInstance();
-                dbf.setNamespaceAware(true);
-                dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
-                javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
-                Document newdoc =
-                    db.parse(new ByteArrayInputStream(c14nizedBytes));
-                Node imported =
-                    element.getOwnerDocument().importNode(newdoc.getDocumentElement(), true);
-
-                element.getParentNode().replaceChild(imported, element);
-
-                return (Element) imported;
+                javax.xml.parsers.DocumentBuilder db =
+                    XMLUtils.createDocumentBuilder(false, secureValidation);
+                try (InputStream is = new ByteArrayInputStream(c14nizedBytes)) {
+                    Document newdoc = db.parse(is);
+                    Node imported = element.getOwnerDocument().importNode(
+                            newdoc.getDocumentElement(), true);
+                    element.getParentNode().replaceChild(imported, element);
+                    return (Element) imported;
+                }
             } catch (ParserConfigurationException ex) {
-                throw new XMLSecurityException("empty", ex);
+                throw new XMLSecurityException(ex);
             } catch (IOException ex) {
-                throw new XMLSecurityException("empty", ex);
+                throw new XMLSecurityException(ex);
             } catch (SAXException ex) {
-                throw new XMLSecurityException("empty", ex);
+                throw new XMLSecurityException(ex);
             }
         }
         return element;
@@ -253,7 +250,7 @@
     /**
      * Tests core validation process
      *
-     * @param followManifests defines whether the verification process has to verify referenced <CODE>ds:Manifest</CODE>s, too
+     * @param followManifests defines whether the verification process has to verify referenced {@code ds:Manifest}s, too
      * @return true if verification was successful
      * @throws MissingResourceFailureException
      * @throws XMLSecurityException
@@ -266,7 +263,7 @@
     /**
      * Returns getCanonicalizedOctetStream
      *
-     * @return the canonicalization result octet stream of <code>SignedInfo</code> element
+     * @return the canonicalization result octet stream of {@code SignedInfo} element
      * @throws CanonicalizationException
      * @throws InvalidCanonicalizerException
      * @throws XMLSecurityException
@@ -276,9 +273,14 @@
         if (this.c14nizedBytes == null) {
             Canonicalizer c14nizer =
                 Canonicalizer.getInstance(this.getCanonicalizationMethodURI());
+            c14nizer.setSecureValidation(isSecureValidation());
 
-            this.c14nizedBytes =
-                c14nizer.canonicalizeSubtree(this.constructionElement);
+            String inclusiveNamespaces = this.getInclusiveNamespaces();
+            if (inclusiveNamespaces == null) {
+                this.c14nizedBytes = c14nizer.canonicalizeSubtree(getElement());
+            } else {
+                this.c14nizedBytes = c14nizer.canonicalizeSubtree(getElement(), inclusiveNamespaces);
+            }
         }
 
         // make defensive copy
@@ -297,13 +299,14 @@
         if (this.c14nizedBytes == null) {
             Canonicalizer c14nizer =
                 Canonicalizer.getInstance(this.getCanonicalizationMethodURI());
+            c14nizer.setSecureValidation(isSecureValidation());
             c14nizer.setWriter(os);
             String inclusiveNamespaces = this.getInclusiveNamespaces();
 
             if (inclusiveNamespaces == null) {
-                c14nizer.canonicalizeSubtree(this.constructionElement);
+                c14nizer.canonicalizeSubtree(getElement());
             } else {
-                c14nizer.canonicalizeSubtree(this.constructionElement, inclusiveNamespaces);
+                c14nizer.canonicalizeSubtree(getElement(), inclusiveNamespaces);
             }
         } else {
             try {
@@ -358,13 +361,13 @@
         return new SecretKeySpec(secretKeyBytes, this.signatureAlgorithm.getJCEAlgorithmString());
     }
 
-    protected SignatureAlgorithm getSignatureAlgorithm() {
+    public SignatureAlgorithm getSignatureAlgorithm() {
         return signatureAlgorithm;
     }
 
     /**
      * Method getBaseLocalName
-     * @inheritDoc
+     * {@inheritDoc}
      *
      */
     public String getBaseLocalName() {
@@ -372,7 +375,7 @@
     }
 
     public String getInclusiveNamespaces() {
-        String c14nMethodURI = c14nMethod.getAttributeNS(null, Constants._ATT_ALGORITHM);
+        String c14nMethodURI = getCanonicalizationMethodURI();
         if (!(c14nMethodURI.equals("http://www.w3.org/2001/10/xml-exc-c14n#") ||
             c14nMethodURI.equals("http://www.w3.org/2001/10/xml-exc-c14n#WithComments"))) {
             return null;
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java	Sat Oct 24 01:11:51 2020 +0100
@@ -27,6 +27,7 @@
 import java.security.Key;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
+import java.util.Base64;
 
 import javax.crypto.SecretKey;
 
@@ -34,12 +35,10 @@
 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
-import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import com.sun.org.apache.xml.internal.security.keys.KeyInfo;
 import com.sun.org.apache.xml.internal.security.keys.content.X509Data;
 import com.sun.org.apache.xml.internal.security.transforms.Transforms;
-import com.sun.org.apache.xml.internal.security.utils.Base64;
 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.SignatureElementProxy;
@@ -52,11 +51,10 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 import org.w3c.dom.Text;
 
 /**
- * Handles <code>&lt;ds:Signature&gt;</code> elements.
+ * Handles {@code &lt;ds:Signature&gt;} elements.
  * This is the main class that deals with creating and verifying signatures.
  *
  * <p>There are 2 types of constructors for this class. The ones that take a
@@ -105,6 +103,10 @@
     public static final String ALGO_ID_SIGNATURE_RSA_RIPEMD160 =
         Constants.MoreAlgorithmsSpecNS + "rsa-ripemd160";
 
+    /** Signature - Optional RSAwithSHA224 */
+    public static final String ALGO_ID_SIGNATURE_RSA_SHA224 =
+        Constants.MoreAlgorithmsSpecNS + "rsa-sha224";
+
     /** Signature - Optional RSAwithSHA256 */
     public static final String ALGO_ID_SIGNATURE_RSA_SHA256 =
         Constants.MoreAlgorithmsSpecNS + "rsa-sha256";
@@ -117,6 +119,26 @@
     public static final String ALGO_ID_SIGNATURE_RSA_SHA512 =
         Constants.MoreAlgorithmsSpecNS + "rsa-sha512";
 
+    /** Signature - Optional RSAwithSHA1andMGF1 */
+    public static final String ALGO_ID_SIGNATURE_RSA_SHA1_MGF1 =
+        Constants.XML_DSIG_NS_MORE_07_05 + "sha1-rsa-MGF1";
+
+    /** Signature - Optional RSAwithSHA224andMGF1 */
+    public static final String ALGO_ID_SIGNATURE_RSA_SHA224_MGF1 =
+        Constants.XML_DSIG_NS_MORE_07_05 + "sha224-rsa-MGF1";
+
+    /** Signature - Optional RSAwithSHA256andMGF1 */
+    public static final String ALGO_ID_SIGNATURE_RSA_SHA256_MGF1 =
+        Constants.XML_DSIG_NS_MORE_07_05 + "sha256-rsa-MGF1";
+
+    /** Signature - Optional RSAwithSHA384andMGF1 */
+    public static final String ALGO_ID_SIGNATURE_RSA_SHA384_MGF1 =
+        Constants.XML_DSIG_NS_MORE_07_05 + "sha384-rsa-MGF1";
+
+    /** Signature - Optional RSAwithSHA512andMGF1 */
+    public static final String ALGO_ID_SIGNATURE_RSA_SHA512_MGF1 =
+        Constants.XML_DSIG_NS_MORE_07_05 + "sha512-rsa-MGF1";
+
     /** HMAC - NOT Recommended HMAC-MD5 */
     public static final String ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5 =
         Constants.MoreAlgorithmsSpecNS + "hmac-md5";
@@ -125,6 +147,10 @@
     public static final String ALGO_ID_MAC_HMAC_RIPEMD160 =
         Constants.MoreAlgorithmsSpecNS + "hmac-ripemd160";
 
+    /** HMAC - Optional HMAC-SHA2224 */
+    public static final String ALGO_ID_MAC_HMAC_SHA224 =
+        Constants.MoreAlgorithmsSpecNS + "hmac-sha224";
+
     /** HMAC - Optional HMAC-SHA256 */
     public static final String ALGO_ID_MAC_HMAC_SHA256 =
         Constants.MoreAlgorithmsSpecNS + "hmac-sha256";
@@ -141,6 +167,10 @@
     public static final String ALGO_ID_SIGNATURE_ECDSA_SHA1 =
         "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1";
 
+    /**Signature - Optional ECDSAwithSHA224 */
+    public static final String ALGO_ID_SIGNATURE_ECDSA_SHA224 =
+        "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224";
+
     /**Signature - Optional ECDSAwithSHA256 */
     public static final String ALGO_ID_SIGNATURE_ECDSA_SHA256 =
         "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256";
@@ -153,9 +183,12 @@
     public static final String ALGO_ID_SIGNATURE_ECDSA_SHA512 =
         "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512";
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(XMLSignature.class.getName());
+    /**Signature - Optional ECDSAwithRIPEMD160 */
+    public static final String ALGO_ID_SIGNATURE_ECDSA_RIPEMD160 =
+        "http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160";
+
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(XMLSignature.class);
 
     /** ds:Signature.ds:SignedInfo element */
     private SignedInfo signedInfo;
@@ -177,9 +210,9 @@
     private int state = MODE_SIGN;
 
     /**
-     * This creates a new <CODE>ds:Signature</CODE> Element and adds an empty
-     * <CODE>ds:SignedInfo</CODE>.
-     * The <code>ds:SignedInfo</code> is initialized with the specified Signature
+     * This creates a new {@code ds:Signature} Element and adds an empty
+     * {@code ds:SignedInfo}.
+     * The {@code ds:SignedInfo} is initialized with the specified Signature
      * algorithm and Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS which is REQUIRED
      * by the spec. This method's main use is for creating a new signature.
      *
@@ -250,31 +283,31 @@
 
         String xmlnsDsPrefix = getDefaultPrefix(Constants.SignatureSpecNS);
         if (xmlnsDsPrefix == null || xmlnsDsPrefix.length() == 0) {
-            this.constructionElement.setAttributeNS(
+            getElement().setAttributeNS(
                 Constants.NamespaceSpecNS, "xmlns", Constants.SignatureSpecNS
             );
         } else {
-            this.constructionElement.setAttributeNS(
+            getElement().setAttributeNS(
                 Constants.NamespaceSpecNS, "xmlns:" + xmlnsDsPrefix, Constants.SignatureSpecNS
             );
         }
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
 
         this.baseURI = baseURI;
         this.signedInfo =
             new SignedInfo(
-                this.doc, signatureMethodURI, hmacOutputLength, canonicalizationMethodURI
+                getDocument(), signatureMethodURI, hmacOutputLength, canonicalizationMethodURI
             );
 
-        this.constructionElement.appendChild(this.signedInfo.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(this.signedInfo);
+        addReturnToSelf();
 
         // create an empty SignatureValue; this is filled by setSignatureValueElement
         signatureValueElement =
-            XMLUtils.createElementInSignatureSpace(this.doc, Constants._TAG_SIGNATUREVALUE);
+            XMLUtils.createElementInSignatureSpace(getDocument(), Constants._TAG_SIGNATUREVALUE);
 
-        this.constructionElement.appendChild(signatureValueElement);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(signatureValueElement);
+        addReturnToSelf();
     }
 
     /**
@@ -295,29 +328,29 @@
 
         String xmlnsDsPrefix = getDefaultPrefix(Constants.SignatureSpecNS);
         if (xmlnsDsPrefix == null || xmlnsDsPrefix.length() == 0) {
-            this.constructionElement.setAttributeNS(
+            getElement().setAttributeNS(
                 Constants.NamespaceSpecNS, "xmlns", Constants.SignatureSpecNS
             );
         } else {
-            this.constructionElement.setAttributeNS(
+            getElement().setAttributeNS(
                 Constants.NamespaceSpecNS, "xmlns:" + xmlnsDsPrefix, Constants.SignatureSpecNS
             );
         }
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
 
         this.baseURI = baseURI;
         this.signedInfo =
-            new SignedInfo(this.doc, SignatureMethodElem, CanonicalizationMethodElem);
+            new SignedInfo(getDocument(), SignatureMethodElem, CanonicalizationMethodElem);
 
-        this.constructionElement.appendChild(this.signedInfo.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(this.signedInfo);
+        addReturnToSelf();
 
         // create an empty SignatureValue; this is filled by setSignatureValueElement
         signatureValueElement =
-            XMLUtils.createElementInSignatureSpace(this.doc, Constants._TAG_SIGNATUREVALUE);
+            XMLUtils.createElementInSignatureSpace(getDocument(), Constants._TAG_SIGNATUREVALUE);
 
-        this.constructionElement.appendChild(signatureValueElement);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(signatureValueElement);
+        addReturnToSelf();
     }
 
     /**
@@ -331,7 +364,7 @@
      */
     public XMLSignature(Element element, String baseURI)
         throws XMLSignatureException, XMLSecurityException {
-        this(element, baseURI, false);
+        this(element, baseURI, true);
     }
 
     /**
@@ -382,8 +415,8 @@
 
         // If it exists use it, but it's not mandatory
         if (keyInfoElem != null
-            && keyInfoElem.getNamespaceURI().equals(Constants.SignatureSpecNS)
-            && keyInfoElem.getLocalName().equals(Constants._TAG_KEYINFO)) {
+            && Constants.SignatureSpecNS.equals(keyInfoElem.getNamespaceURI())
+            && Constants._TAG_KEYINFO.equals(keyInfoElem.getLocalName())) {
             this.keyInfo = new KeyInfo(keyInfoElem, baseURI);
             this.keyInfo.setSecureValidation(secureValidation);
         }
@@ -397,20 +430,19 @@
                 objectElem.setIdAttributeNode(objectAttr, true);
             }
 
-            NodeList nodes = objectElem.getChildNodes();
-            int length = nodes.getLength();
+            Node firstChild = objectElem.getFirstChild();
             // Register Ids of the Object child elements
-            for (int i = 0; i < length; i++) {
-                Node child = nodes.item(i);
-                if (child.getNodeType() == Node.ELEMENT_NODE) {
-                    Element childElem = (Element)child;
+            while (firstChild != null) {
+                if (firstChild.getNodeType() == Node.ELEMENT_NODE) {
+                    Element childElem = (Element)firstChild;
                     String tag = childElem.getLocalName();
-                    if (tag.equals("Manifest")) {
+                    if ("Manifest".equals(tag)) {
                         new Manifest(childElem, baseURI);
-                    } else if (tag.equals("SignatureProperties")) {
+                    } else if ("SignatureProperties".equals(tag)) {
                         new SignatureProperties(childElem, baseURI);
                     }
                 }
+                firstChild = firstChild.getNextSibling();
             }
 
             objectElem = XMLUtils.getNextElement(objectElem.getNextSibling());
@@ -420,30 +452,29 @@
     }
 
     /**
-     * Sets the <code>Id</code> attribute
+     * Sets the {@code Id} attribute
      *
      * @param id Id value for the id attribute on the Signature Element
      */
     public void setId(String id) {
         if (id != null) {
-            this.constructionElement.setAttributeNS(null, Constants._ATT_ID, id);
-            this.constructionElement.setIdAttributeNS(null, Constants._ATT_ID, true);
+            setLocalIdAttribute(Constants._ATT_ID, id);
         }
     }
 
     /**
-     * Returns the <code>Id</code> attribute
+     * Returns the {@code Id} attribute
      *
-     * @return the <code>Id</code> attribute
+     * @return the {@code Id} attribute
      */
     public String getId() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_ID);
+        return getLocalAttribute(Constants._ATT_ID);
     }
 
     /**
-     * Returns the completely parsed <code>SignedInfo</code> object.
+     * Returns the completely parsed {@code SignedInfo} object.
      *
-     * @return the completely parsed <code>SignedInfo</code> object.
+     * @return the completely parsed {@code SignedInfo} object.
      */
     public SignedInfo getSignedInfo() {
         return this.signedInfo;
@@ -457,11 +488,8 @@
      * @throws XMLSignatureException If there is no content
      */
     public byte[] getSignatureValue() throws XMLSignatureException {
-        try {
-            return Base64.decode(signatureValueElement);
-        } catch (Base64DecodingException ex) {
-            throw new XMLSignatureException("empty", ex);
-        }
+        String content = XMLUtils.getFullTextChildrenFromElement(signatureValueElement);
+        return Base64.getMimeDecoder().decode(content);
     }
 
     /**
@@ -476,13 +504,13 @@
             signatureValueElement.removeChild(signatureValueElement.getFirstChild());
         }
 
-        String base64codedValue = Base64.encode(bytes);
+        String base64codedValue = Base64.getMimeEncoder().encodeToString(bytes);
 
         if (base64codedValue.length() > 76 && !XMLUtils.ignoreLineBreaks()) {
             base64codedValue = "\n" + base64codedValue + "\n";
         }
 
-        Text t = this.doc.createTextNode(base64codedValue);
+        Text t = createText(base64codedValue);
         signatureValueElement.appendChild(t);
     }
 
@@ -499,23 +527,23 @@
         if (this.state == MODE_SIGN && this.keyInfo == null) {
 
             // create the KeyInfo
-            this.keyInfo = new KeyInfo(this.doc);
+            this.keyInfo = new KeyInfo(getDocument());
 
             // get the Element from KeyInfo
             Element keyInfoElement = this.keyInfo.getElement();
             Element firstObject =
                 XMLUtils.selectDsNode(
-                    this.constructionElement.getFirstChild(), Constants._TAG_OBJECT, 0
+                    getElement().getFirstChild(), Constants._TAG_OBJECT, 0
                 );
 
             if (firstObject != null) {
                 // add it before the object
-                this.constructionElement.insertBefore(keyInfoElement, firstObject);
-                XMLUtils.addReturnBeforeChild(this.constructionElement, firstObject);
+                getElement().insertBefore(keyInfoElement, firstObject);
+                XMLUtils.addReturnBeforeChild(getElement(), firstObject);
             } else {
                 // add it as the last element to the signature
-                this.constructionElement.appendChild(keyInfoElement);
-                XMLUtils.addReturnToElement(this.constructionElement);
+                appendSelf(keyInfoElement);
+                addReturnToSelf();
             }
         }
 
@@ -523,7 +551,7 @@
     }
 
     /**
-     * Appends an Object (not a <code>java.lang.Object</code> but an Object
+     * Appends an Object (not a {@code java.lang.Object} but an Object
      * element) to the Signature. Please note that this is only possible
      * when signing.
      *
@@ -537,25 +565,25 @@
         //  "signature.operationOnlyBeforeSign");
         //}
 
-        this.constructionElement.appendChild(object.getElement());
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(object);
+        addReturnToSelf();
         //} catch (XMLSecurityException ex) {
-        // throw new XMLSignatureException("empty", ex);
+        // throw new XMLSignatureException(ex);
         //}
     }
 
     /**
-     * Returns the <code>i<code>th <code>ds:Object</code> child of the signature
-     * or null if no such <code>ds:Object</code> element exists.
+     * Returns the {@code i}th {@code ds:Object} child of the signature
+     * or null if no such {@code ds:Object} element exists.
      *
      * @param i
-     * @return the <code>i<code>th <code>ds:Object</code> child of the signature
-     * or null if no such <code>ds:Object</code> element exists.
+     * @return the {@code i}th {@code ds:Object} child of the signature
+     * or null if no such {@code ds:Object} element exists.
      */
     public ObjectContainer getObjectItem(int i) {
         Element objElem =
             XMLUtils.selectDsNode(
-                this.constructionElement.getFirstChild(), Constants._TAG_OBJECT, i
+                getFirstChild(), Constants._TAG_OBJECT, i
             );
 
         try {
@@ -566,9 +594,9 @@
     }
 
     /**
-     * Returns the number of all <code>ds:Object</code> elements.
+     * Returns the number of all {@code ds:Object} elements.
      *
-     * @return the number of all <code>ds:Object</code> elements.
+     * @return the number of all {@code ds:Object} elements.
      */
     public int getObjectLength() {
         return this.length(Constants.SignatureSpecNS, Constants._TAG_OBJECT);
@@ -590,44 +618,33 @@
             );
         }
 
-        try {
-            //Create a SignatureAlgorithm object
-            SignedInfo si = this.getSignedInfo();
-            SignatureAlgorithm sa = si.getSignatureAlgorithm();
-            OutputStream so = null;
-            try {
-                // initialize SignatureAlgorithm for signing
-                sa.initSign(signingKey);
+        //Create a SignatureAlgorithm object
+        SignedInfo si = this.getSignedInfo();
+        SignatureAlgorithm sa = si.getSignatureAlgorithm();
+        try (SignerOutputStream output = new SignerOutputStream(sa);
+            OutputStream so = new UnsyncBufferedOutputStream(output)) {
 
-                // generate digest values for all References in this SignedInfo
-                si.generateDigestValues();
-                so = new UnsyncBufferedOutputStream(new SignerOutputStream(sa));
-                // get the canonicalized bytes from SignedInfo
-                si.signInOctetStream(so);
-            } catch (XMLSecurityException ex) {
-                throw ex;
-            } finally {
-                if (so != null) {
-                    try {
-                        so.close();
-                    } catch (IOException ex) {
-                        if (log.isLoggable(java.util.logging.Level.FINE)) {
-                            log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-                        }
-                    }
-                }
-            }
+            // generate digest values for all References in this SignedInfo
+            si.generateDigestValues();
+
+            // initialize SignatureAlgorithm for signing
+            sa.initSign(signingKey);
+
+            // get the canonicalized bytes from SignedInfo
+            si.signInOctetStream(so);
 
             // set them on the SignatureValue element
             this.setSignatureValueElement(sa.sign());
         } catch (XMLSignatureException ex) {
             throw ex;
         } catch (CanonicalizationException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (InvalidCanonicalizerException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } catch (XMLSecurityException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
+        } catch (IOException ex) {
+            throw new XMLSignatureException(ex);
         }
     }
 
@@ -699,28 +716,23 @@
             //create a SignatureAlgorithms from the SignatureMethod inside
             //SignedInfo. This is used to validate the signature.
             SignatureAlgorithm sa = si.getSignatureAlgorithm();
+            LOG.debug("signatureMethodURI = {}", sa.getAlgorithmURI());
+            LOG.debug("jceSigAlgorithm = {}", sa.getJCEAlgorithmString());
+            LOG.debug("jceSigProvider = {}", sa.getJCEProviderName());
+            LOG.debug("PublicKey = {}", pk);
+
             byte sigBytes[] = null;
-            try {
+            try (SignerOutputStream so = new SignerOutputStream(sa);
+                OutputStream bos = new UnsyncBufferedOutputStream(so)) {
+
                 sa.initVerify(pk);
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "signatureMethodURI = " + sa.getAlgorithmURI());
-                    log.log(java.util.logging.Level.FINE, "jceSigAlgorithm    = " + sa.getJCEAlgorithmString());
-                    log.log(java.util.logging.Level.FINE, "jceSigProvider     = " + sa.getJCEProviderName());
-                    log.log(java.util.logging.Level.FINE, "PublicKey = " + pk);
-                }
 
                 // Get the canonicalized (normalized) SignedInfo
-                SignerOutputStream so = new SignerOutputStream(sa);
-                OutputStream bos = new UnsyncBufferedOutputStream(so);
-
                 si.signInOctetStream(bos);
-                bos.close();
                 // retrieve the byte[] from the stored signature
                 sigBytes = this.getSignatureValue();
             } catch (IOException ex) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-                }
+                LOG.debug(ex.getMessage(), ex);
                 // Impossible...
             } catch (XMLSecurityException ex) {
                 throw ex;
@@ -729,7 +741,7 @@
             // have SignatureAlgorithm sign the input bytes and compare them to
             // the bytes that were stored in the signature.
             if (!sa.verify(sigBytes)) {
-                log.log(java.util.logging.Level.WARNING, "Signature verification failed.");
+                LOG.warn("Signature verification failed.");
                 return false;
             }
 
@@ -737,7 +749,7 @@
         } catch (XMLSignatureException ex) {
             throw ex;
         } catch (XMLSecurityException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         }
     }
 
@@ -820,7 +832,7 @@
      * @throws XMLSecurityException
      */
     public void addKeyInfo(X509Certificate cert) throws XMLSecurityException {
-        X509Data x509data = new X509Data(this.doc);
+        X509Data x509data = new X509Data(getDocument());
 
         x509data.addCertificate(cert);
         this.getKeyInfo().add(x509data);
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -28,7 +28,6 @@
  * All XML Signature related exceptions inherit herefrom.
  *
  * @see MissingResourceFailureException InvalidDigestValueException InvalidSignatureValueException
- * @author Christian Geuer-Pollmann
  */
 public class XMLSignatureException extends XMLSecurityException {
 
@@ -45,6 +44,10 @@
         super();
     }
 
+    public XMLSignatureException(Exception ex) {
+        super(ex);
+    }
+
     /**
      * Constructor XMLSignatureException
      *
@@ -67,21 +70,31 @@
     /**
      * Constructor XMLSignatureException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public XMLSignatureException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public XMLSignatureException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor XMLSignatureException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
-    public XMLSignatureException(String msgID, Object exArgs[], Exception originalException) {
-        super(msgID, exArgs, originalException);
+    public XMLSignatureException(Exception originalException, String msgID, Object exArgs[]) {
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public XMLSignatureException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInput.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInput.java	Sat Oct 24 01:11:51 2020 +0100
@@ -27,20 +27,19 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 
-import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
-import com.sun.org.apache.xml.internal.security.c14n.implementations.CanonicalizerBase;
+import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_OmitComments;
 import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315OmitComments;
-import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_OmitComments;
+import com.sun.org.apache.xml.internal.security.c14n.implementations.CanonicalizerBase;
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityRuntimeException;
 import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
@@ -51,7 +50,6 @@
 /**
  * Class XMLSignatureInput
  *
- * @author Christian Geuer-Pollmann
  * $todo$ check whether an XMLSignatureInput can be _both_, octet stream _and_ node set?
  */
 public class XMLSignatureInput {
@@ -68,19 +66,19 @@
      * Some InputStreams do not support the {@link java.io.InputStream#reset}
      * method, so we read it in completely and work on our Proxy.
      */
-    private InputStream inputOctetStreamProxy = null;
+    private InputStream inputOctetStreamProxy;
     /**
      * The original NodeSet for this XMLSignatureInput
      */
-    private Set<Node> inputNodeSet = null;
+    private Set<Node> inputNodeSet;
     /**
      * The original Element
      */
-    private Node subNode = null;
+    private Node subNode;
     /**
      * Exclude Node *for enveloped transformations*
      */
-    private Node excludeNode = null;
+    private Node excludeNode;
     /**
      *
      */
@@ -90,7 +88,8 @@
     /**
      * A cached bytes
      */
-    private byte[] bytes = null;
+    private byte[] bytes;
+    private boolean secureValidation;
 
     /**
      * Some Transforms may require explicit MIME type, charset (IANA registered
@@ -101,22 +100,25 @@
      * Transform algorithm and should be described in the specification for the
      * algorithm.
      */
-    private String mimeType = null;
+    private String mimeType;
 
     /**
      * Field sourceURI
      */
-    private String sourceURI = null;
+    private String sourceURI;
 
     /**
      * Node Filter list.
      */
-    private List<NodeFilter> nodeFilters = new ArrayList<NodeFilter>();
+    private List<NodeFilter> nodeFilters = new ArrayList<>();
 
     private boolean needsToBeExpanded = false;
-    private OutputStream outputStream = null;
+    private OutputStream outputStream;
 
-    private DocumentBuilderFactory dfactory;
+    /**
+     * Pre-calculated digest value of the object in base64.
+     */
+    private String preCalculatedDigest;
 
     /**
      * Construct a XMLSignatureInput from an octet array.
@@ -132,7 +134,7 @@
     }
 
     /**
-     * Constructs a <code>XMLSignatureInput</code> from an octet stream. The
+     * Constructs a {@code XMLSignatureInput} from an octet stream. The
      * stream is directly read.
      *
      * @param inputOctetStream
@@ -161,6 +163,15 @@
     }
 
     /**
+     * Construct a {@code XMLSignatureInput} from a known digest value in Base64.
+     * This makes it possible to compare the element digest with the provided digest value.
+     * @param preCalculatedDigest digest value in base64.
+     */
+    public XMLSignatureInput(String preCalculatedDigest) {
+        this.preCalculatedDigest = preCalculatedDigest;
+    }
+
+    /**
      * Check if the structure needs to be expanded.
      * @return true if so.
      */
@@ -286,8 +297,7 @@
      * @return true if the object has been set up with a Node set
      */
     public boolean isNodeSet() {
-        return ((inputOctetStreamProxy == null
-            && inputNodeSet != null) || isNodeSet);
+        return inputOctetStreamProxy == null && inputNodeSet != null || isNodeSet;
     }
 
     /**
@@ -296,8 +306,8 @@
      * @return true if the object has been set up with an Element
      */
     public boolean isElement() {
-        return (inputOctetStreamProxy == null && subNode != null
-            && inputNodeSet == null && !isNodeSet);
+        return inputOctetStreamProxy == null && subNode != null
+            && inputNodeSet == null && !isNodeSet;
     }
 
     /**
@@ -306,8 +316,8 @@
      * @return true if the object has been set up with an octet stream
      */
     public boolean isOctetStream() {
-        return ((inputOctetStreamProxy != null || bytes != null)
-          && (inputNodeSet == null && subNode == null));
+        return (inputOctetStreamProxy != null || bytes != null)
+          && inputNodeSet == null && subNode == null;
     }
 
     /**
@@ -327,7 +337,15 @@
      * @return true is the object has been set up with an octet stream
      */
     public boolean isByteArray() {
-        return (bytes != null && (this.inputNodeSet == null && subNode == null));
+        return bytes != null && this.inputNodeSet == null && subNode == null;
+    }
+
+    /**
+     * Determines if the object has been set up with a pre-calculated digest.
+     * @return
+     */
+    public boolean isPreCalculatedDigest() {
+        return preCalculatedDigest != null;
     }
 
     /**
@@ -377,7 +395,7 @@
 
     /**
      * Method toString
-     * @inheritDoc
+     * {@inheritDoc}
      */
     public String toString() {
         if (isNodeSet()) {
@@ -556,13 +574,7 @@
 
     void convertToNodes() throws CanonicalizationException,
         ParserConfigurationException, IOException, SAXException {
-        if (dfactory == null) {
-            dfactory = DocumentBuilderFactory.newInstance();
-            dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
-            dfactory.setValidating(false);
-            dfactory.setNamespaceAware(true);
-        }
-        DocumentBuilder db = dfactory.newDocumentBuilder();
+        DocumentBuilder db = XMLUtils.createDocumentBuilder(false, secureValidation);
         // select all nodes, also the comments.
         try {
             db.setErrorHandler(new com.sun.org.apache.xml.internal.security.utils.IgnoreAllErrorHandler());
@@ -570,16 +582,20 @@
             Document doc = db.parse(this.getOctetStream());
             this.subNode = doc;
         } catch (SAXException ex) {
+            byte[] result = null;
             // if a not-wellformed nodeset exists, put a container around it...
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
 
-            baos.write("<container>".getBytes("UTF-8"));
-            baos.write(this.getBytes());
-            baos.write("</container>".getBytes("UTF-8"));
+                baos.write("<container>".getBytes(StandardCharsets.UTF_8));
+                baos.write(this.getBytes());
+                baos.write("</container>".getBytes(StandardCharsets.UTF_8));
 
-            byte result[] = baos.toByteArray();
-            Document document = db.parse(new ByteArrayInputStream(result));
-            this.subNode = document.getDocumentElement().getFirstChild().getFirstChild();
+                result = baos.toByteArray();
+            }
+            try (InputStream is = new ByteArrayInputStream(result)) {
+                Document document = db.parse(is);
+                this.subNode = document.getDocumentElement().getFirstChild().getFirstChild();
+            }
         } finally {
             if (this.inputOctetStreamProxy != null) {
                 this.inputOctetStreamProxy.close();
@@ -589,4 +605,15 @@
         }
     }
 
+    public boolean isSecureValidation() {
+        return secureValidation;
+    }
+
+    public void setSecureValidation(boolean secureValidation) {
+        this.secureValidation = secureValidation;
+    }
+
+    public String getPreCalculatedDigest() {
+        return preCalculatedDigest;
+    }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInputDebugger.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInputDebugger.java	Sat Oct 24 01:11:51 2020 +0100
@@ -48,11 +48,8 @@
 
     private Set<String> inclusiveNamespaces;
 
-    /** Field doc */
-    private Document doc = null;
-
     /** Field writer */
-    private Writer writer = null;
+    private Writer writer;
 
     /** The HTML Prefix* */
     static final String HTMLPrefix =
@@ -148,27 +145,26 @@
      * @throws XMLSignatureException
      */
     public String getHTMLRepresentation() throws XMLSignatureException {
-        if ((this.xpathNodeSet == null) || (this.xpathNodeSet.size() == 0)) {
+        if (this.xpathNodeSet == null || this.xpathNodeSet.isEmpty()) {
             return HTMLPrefix + "<blink>no node set, sorry</blink>" + HTMLSuffix;
         }
 
         // get only a single node as anchor to fetch the owner document
         Node n = this.xpathNodeSet.iterator().next();
 
-        this.doc = XMLUtils.getOwnerDocument(n);
+        Document doc = XMLUtils.getOwnerDocument(n);
 
         try {
             this.writer = new StringWriter();
 
-            this.canonicalizeXPathNodeSet(this.doc);
+            this.canonicalizeXPathNodeSet(doc);
             this.writer.close();
 
             return this.writer.toString();
         } catch (IOException ex) {
-            throw new XMLSignatureException("empty", ex);
+            throw new XMLSignatureException(ex);
         } finally {
             this.xpathNodeSet = null;
-            this.doc = null;
             this.writer = null;
         }
     }
@@ -191,7 +187,7 @@
         case Node.NOTATION_NODE:
         case Node.DOCUMENT_FRAGMENT_NODE:
         case Node.ATTRIBUTE_NODE:
-            throw new XMLSignatureException("empty");
+            throw new XMLSignatureException("empty", new Object[]{"An incorrect node was provided for c14n: " + currentNodeType});
         case Node.DOCUMENT_NODE:
             this.writer.write(HTMLPrefix);
 
@@ -258,9 +254,9 @@
             outputTextToWriter(currentNode.getNodeValue());
 
             for (Node nextSibling = currentNode.getNextSibling();
-                (nextSibling != null)
-                && ((nextSibling.getNodeType() == Node.TEXT_NODE)
-                    || (nextSibling.getNodeType() == Node.CDATA_SECTION_NODE));
+                nextSibling != null
+                && (nextSibling.getNodeType() == Node.TEXT_NODE
+                    || nextSibling.getNodeType() == Node.CDATA_SECTION_NODE);
                 nextSibling = nextSibling.getNextSibling()) {
                 /*
                  * The XPath data model allows to select only the first of a
@@ -412,13 +408,13 @@
      *
      * The string value of the node is modified by replacing
      * <UL>
-     * <LI>all ampersands (&) with <CODE>&amp;amp;</CODE></LI>
-     * <LI>all open angle brackets (<) with <CODE>&amp;lt;</CODE></LI>
-     * <LI>all quotation mark characters with <CODE>&amp;quot;</CODE></LI>
-     * <LI>and the whitespace characters <CODE>#x9</CODE>, #xA, and #xD,
+     * <LI>all ampersands (&) with {@code &amp;amp;}</LI>
+     * <LI>all open angle brackets (<) with {@code &amp;lt;}</LI>
+     * <LI>all quotation mark characters with {@code &amp;quot;}</LI>
+     * <LI>and the whitespace characters {@code #x9}, #xA, and #xD,
      * with character references. The character references are written in
-     * uppercase hexadecimal with no leading zeroes (for example, <CODE>#xD</CODE>
-     * is represented by the character reference <CODE>&amp;#xD;</CODE>)</LI>
+     * uppercase hexadecimal with no leading zeroes (for example, {@code #xD}
+     * is represented by the character reference {@code &amp;#xD;})</LI>
      * </UL>
      *
      * @param name
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-XML Signature specific classes.
-</P></BODY></HTML>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/reference/ReferenceData.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/reference/ReferenceData.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,7 +21,7 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * $Id$
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/reference/ReferenceNodeSetData.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/reference/ReferenceNodeSetData.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,7 +21,7 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * $Id$
@@ -33,20 +33,20 @@
 import org.w3c.dom.Node;
 
 /**
- * An abstract representation of a <code>ReferenceData</code> type containing a node-set.
+ * An abstract representation of a {@code ReferenceData} type containing a node-set.
  */
 public interface ReferenceNodeSetData extends ReferenceData {
 
     /**
      * Returns a read-only iterator over the nodes contained in this
-     * <code>NodeSetData</code> in
+     * {@code NodeSetData} in
      * <a href="http://www.w3.org/TR/1999/REC-xpath-19991116#dt-document-order">
      * document order</a>. Attempts to modify the returned iterator
-     * via the <code>remove</code> method throw
-     * <code>UnsupportedOperationException</code>.
+     * via the {@code remove} method throw
+     * {@code UnsupportedOperationException}.
      *
-     * @return an <code>Iterator</code> over the nodes in this
-     *    <code>NodeSetData</code> in document order
+     * @return an {@code Iterator} over the nodes in this
+     *    {@code NodeSetData} in document order
      */
     Iterator<Node> iterator();
 
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/reference/ReferenceOctetStreamData.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/reference/ReferenceOctetStreamData.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,7 +21,7 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * $Id$
@@ -31,7 +31,7 @@
 import java.io.InputStream;
 
 /**
- * A representation of a <code>ReferenceData</code> type containing an OctetStream.
+ * A representation of a {@code ReferenceData} type containing an OctetStream.
  */
 public class ReferenceOctetStreamData implements ReferenceData {
     private InputStream octetStream;
@@ -39,11 +39,11 @@
     private String mimeType;
 
     /**
-     * Creates a new <code>ReferenceOctetStreamData</code>.
+     * Creates a new {@code ReferenceOctetStreamData}.
      *
      * @param octetStream the input stream containing the octets
-     * @throws NullPointerException if <code>octetStream</code> is
-     *    <code>null</code>
+     * @throws NullPointerException if {@code octetStream} is
+     *    {@code null}
      */
     public ReferenceOctetStreamData(InputStream octetStream) {
         if (octetStream == null) {
@@ -53,15 +53,15 @@
     }
 
     /**
-     * Creates a new <code>ReferenceOctetStreamData</code>.
+     * Creates a new {@code ReferenceOctetStreamData}.
      *
      * @param octetStream the input stream containing the octets
      * @param uri the URI String identifying the data object (may be
-     *    <code>null</code>)
+     *    {@code null})
      * @param mimeType the MIME type associated with the data object (may be
-     *    <code>null</code>)
-     * @throws NullPointerException if <code>octetStream</code> is
-     *    <code>null</code>
+     *    {@code null})
+     * @throws NullPointerException if {@code octetStream} is
+     *    {@code null}
      */
     public ReferenceOctetStreamData(InputStream octetStream, String uri,
         String mimeType) {
@@ -74,9 +74,9 @@
     }
 
     /**
-     * Returns the input stream of this <code>ReferenceOctetStreamData</code>.
+     * Returns the input stream of this {@code ReferenceOctetStreamData}.
      *
-     * @return the input stream of this <code>ReferenceOctetStreamData</code>.
+     * @return the input stream of this {@code ReferenceOctetStreamData}.
      */
     public InputStream getOctetStream() {
         return octetStream;
@@ -84,9 +84,9 @@
 
     /**
      * Returns the URI String identifying the data object represented by this
-     * <code>ReferenceOctetStreamData</code>.
+     * {@code ReferenceOctetStreamData}.
      *
-     * @return the URI String or <code>null</code> if not applicable
+     * @return the URI String or {@code null} if not applicable
      */
     public String getURI() {
         return uri;
@@ -94,9 +94,9 @@
 
     /**
      * Returns the MIME type associated with the data object represented by this
-     * <code>ReferenceOctetStreamData</code>.
+     * {@code ReferenceOctetStreamData}.
      *
-     * @return the MIME type or <code>null</code> if not applicable
+     * @return the MIME type or {@code null} if not applicable
      */
     public String getMimeType() {
         return mimeType;
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/signature/reference/ReferenceSubTreeData.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/signature/reference/ReferenceSubTreeData.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,7 +21,7 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * $Id$
@@ -37,7 +37,7 @@
 import org.w3c.dom.Node;
 
 /**
- * A representation of a <code>ReferenceNodeSetData</code> type containing a node-set.
+ * A representation of a {@code ReferenceNodeSetData} type containing a node-set.
  * This is a subtype of NodeSetData that represents a dereferenced
  * same-document URI as the root of a subdocument. The main reason is
  * for efficiency and performance, as some transforms can operate
@@ -109,11 +109,11 @@
          * Dereferences a same-document URI fragment.
          *
          * @param node the node (document or element) referenced by the
-         *        URI fragment. If null, returns an empty set.
+         *     URI fragment. If null, returns an empty set.
          * @return a set of nodes (minus any comment nodes)
          */
         private List<Node> dereferenceSameDocumentURI(Node node) {
-            List<Node> nodeSet = new ArrayList<Node>();
+            List<Node> nodeSet = new ArrayList<>();
             if (node != null) {
                 nodeSetMinusCommentNodes(node, nodeSet, null);
             }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/ClassLoaderUtils.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/ClassLoaderUtils.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,211 +23,19 @@
 
 package com.sun.org.apache.xml.internal.security.transforms;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-
-/**
- * This class is extremely useful for loading resources and classes in a fault
- * tolerant manner that works across different applications servers. Do not
- * touch this unless you're a grizzled classloading guru veteran who is going to
- * verify any change on 6 different application servers.
- */
 // NOTE! This is a duplicate of utils.ClassLoaderUtils with public
 // modifiers changed to package-private. Make sure to integrate any future
 // changes to utils.ClassLoaderUtils to this file.
 final class ClassLoaderUtils {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static final java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(ClassLoaderUtils.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ClassLoaderUtils.class);
 
     private ClassLoaderUtils() {
     }
 
     /**
-     * Load a given resource. <p/> This method will try to load the resource
-     * using the following methods (in order):
-     * <ul>
-     * <li>From Thread.currentThread().getContextClassLoader()
-     * <li>From ClassLoaderUtil.class.getClassLoader()
-     * <li>callingClass.getClassLoader()
-     * </ul>
-     *
-     * @param resourceName The name of the resource to load
-     * @param callingClass The Class object of the calling object
-     */
-    static URL getResource(String resourceName, Class<?> callingClass) {
-        URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
-        if (url == null && resourceName.startsWith("/")) {
-            //certain classloaders need it without the leading /
-            url =
-                Thread.currentThread().getContextClassLoader().getResource(
-                    resourceName.substring(1)
-                );
-        }
-
-        ClassLoader cluClassloader = ClassLoaderUtils.class.getClassLoader();
-        if (cluClassloader == null) {
-            cluClassloader = ClassLoader.getSystemClassLoader();
-        }
-        if (url == null) {
-            url = cluClassloader.getResource(resourceName);
-        }
-        if (url == null && resourceName.startsWith("/")) {
-            //certain classloaders need it without the leading /
-            url = cluClassloader.getResource(resourceName.substring(1));
-        }
-
-        if (url == null) {
-            ClassLoader cl = callingClass.getClassLoader();
-
-            if (cl != null) {
-                url = cl.getResource(resourceName);
-            }
-        }
-
-        if (url == null) {
-            url = callingClass.getResource(resourceName);
-        }
-
-        if ((url == null) && (resourceName != null) && (resourceName.charAt(0) != '/')) {
-            return getResource('/' + resourceName, callingClass);
-        }
-
-        return url;
-    }
-
-    /**
-     * Load a given resources. <p/> This method will try to load the resources
-     * using the following methods (in order):
-     * <ul>
-     * <li>From Thread.currentThread().getContextClassLoader()
-     * <li>From ClassLoaderUtil.class.getClassLoader()
-     * <li>callingClass.getClassLoader()
-     * </ul>
-     *
-     * @param resourceName The name of the resource to load
-     * @param callingClass The Class object of the calling object
-     */
-    static List<URL> getResources(String resourceName, Class<?> callingClass) {
-        List<URL> ret = new ArrayList<URL>();
-        Enumeration<URL> urls = new Enumeration<URL>() {
-            public boolean hasMoreElements() {
-                return false;
-            }
-            public URL nextElement() {
-                return null;
-            }
-
-        };
-        try {
-            urls = Thread.currentThread().getContextClassLoader().getResources(resourceName);
-        } catch (IOException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
-            //ignore
-        }
-        if (!urls.hasMoreElements() && resourceName.startsWith("/")) {
-            //certain classloaders need it without the leading /
-            try {
-                urls =
-                    Thread.currentThread().getContextClassLoader().getResources(
-                        resourceName.substring(1)
-                    );
-            } catch (IOException e) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                }
-                // ignore
-            }
-        }
-
-        ClassLoader cluClassloader = ClassLoaderUtils.class.getClassLoader();
-        if (cluClassloader == null) {
-            cluClassloader = ClassLoader.getSystemClassLoader();
-        }
-        if (!urls.hasMoreElements()) {
-            try {
-                urls = cluClassloader.getResources(resourceName);
-            } catch (IOException e) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                }
-                // ignore
-            }
-        }
-        if (!urls.hasMoreElements() && resourceName.startsWith("/")) {
-            //certain classloaders need it without the leading /
-            try {
-                urls = cluClassloader.getResources(resourceName.substring(1));
-            } catch (IOException e) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                }
-                // ignore
-            }
-        }
-
-        if (!urls.hasMoreElements()) {
-            ClassLoader cl = callingClass.getClassLoader();
-
-            if (cl != null) {
-                try {
-                    urls = cl.getResources(resourceName);
-                } catch (IOException e) {
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                    }
-                    // ignore
-                }
-            }
-        }
-
-        if (!urls.hasMoreElements()) {
-            URL url = callingClass.getResource(resourceName);
-            if (url != null) {
-                ret.add(url);
-            }
-        }
-        while (urls.hasMoreElements()) {
-            ret.add(urls.nextElement());
-        }
-
-
-        if (ret.isEmpty() && (resourceName != null) && (resourceName.charAt(0) != '/')) {
-            return getResources('/' + resourceName, callingClass);
-        }
-        return ret;
-    }
-
-
-    /**
-     * This is a convenience method to load a resource as a stream. <p/> The
-     * algorithm used to find the resource is given in getResource()
-     *
-     * @param resourceName The name of the resource to load
-     * @param callingClass The Class object of the calling object
-     */
-    static InputStream getResourceAsStream(String resourceName, Class<?> callingClass) {
-        URL url = getResource(resourceName, callingClass);
-
-        try {
-            return (url != null) ? url.openStream() : null;
-        } catch (IOException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
-            return null;
-        }
-    }
-
-    /**
-     * Load a class with a given name. <p/> It will try to load the class in the
+     * Load a class with a given name. <p></p> It will try to load the class in the
      * following order:
      * <ul>
      * <li>From Thread.currentThread().getContextClassLoader()
@@ -249,9 +57,7 @@
                 return cl.loadClass(className);
             }
         } catch (ClassNotFoundException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
+            LOG.debug(e.getMessage(), e);
             //ignore
         }
         return loadClass2(className, callingClass);
@@ -271,9 +77,7 @@
                     return callingClass.getClassLoader().loadClass(className);
                 }
             }
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-            }
+            LOG.debug(ex.getMessage(), ex);
             throw ex;
         }
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/InvalidTransformException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/InvalidTransformException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -26,7 +26,6 @@
 
 /**
  *
- * @author Christian Geuer-Pollmann
  */
 public class InvalidTransformException extends XMLSecurityException {
 
@@ -68,8 +67,13 @@
      * @param msgId
      * @param originalException
      */
-    public InvalidTransformException(String msgId, Exception originalException) {
-        super(msgId, originalException);
+    public InvalidTransformException(Exception originalException, String msgId) {
+        super(originalException, msgId);
+    }
+
+    @Deprecated
+    public InvalidTransformException(String msgID, Exception originalException) {
+        this(originalException, msgID);
     }
 
     /**
@@ -79,7 +83,12 @@
      * @param exArgs
      * @param originalException
      */
-    public InvalidTransformException(String msgId, Object exArgs[], Exception originalException) {
-        super(msgId, exArgs, originalException);
+    public InvalidTransformException(Exception originalException, String msgId, Object exArgs[]) {
+        super(originalException, msgId, exArgs);
+    }
+
+    @Deprecated
+    public InvalidTransformException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java	Sat Oct 24 01:11:51 2020 +0100
@@ -55,36 +55,35 @@
 import org.xml.sax.SAXException;
 
 /**
- * Implements the behaviour of the <code>ds:Transform</code> element.
+ * Implements the behaviour of the {@code ds:Transform} element.
  *
- * This <code>Transform</code>(Factory) class acts as the Factory and Proxy of
+ * This {@code Transform}(Factory) class acts as the Factory and Proxy of
  * the implementing class that supports the functionality of <a
  * href=http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg>a Transform
  * algorithm</a>.
  * Implements the Factory and Proxy pattern for ds:Transform algorithms.
  *
- * @author Christian Geuer-Pollmann
  * @see Transforms
  * @see TransformSpi
  */
 public final class Transform extends SignatureElementProxy {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(Transform.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(Transform.class);
 
     /** All available Transform classes are registered here */
     private static Map<String, Class<? extends TransformSpi>> transformSpiHash =
         new ConcurrentHashMap<String, Class<? extends TransformSpi>>();
 
     private final TransformSpi transformSpi;
+    private boolean secureValidation;
 
     /**
      * Generates a Transform object that implements the specified
-     * <code>Transform algorithm</code> URI.
+     * {@code Transform algorithm} URI.
      *
      * @param doc the proxy {@link Document}
-     * @param algorithmURI <code>Transform algorithm</code> URI representation,
+     * @param algorithmURI {@code Transform algorithm} URI representation,
      * such as specified in
      * <a href=http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg>Transform algorithm </a>
      * @throws InvalidTransformException
@@ -95,12 +94,12 @@
 
     /**
      * Generates a Transform object that implements the specified
-     * <code>Transform algorithm</code> URI.
+     * {@code Transform algorithm} URI.
      *
-     * @param algorithmURI <code>Transform algorithm</code> URI representation,
+     * @param algorithmURI {@code Transform algorithm} URI representation,
      * such as specified in
      * <a href=http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg>Transform algorithm </a>
-     * @param contextChild the child element of <code>Transform</code> element
+     * @param contextChild the child element of {@code Transform} element
      * @param doc the proxy {@link Document}
      * @throws InvalidTransformException
      */
@@ -123,10 +122,10 @@
     /**
      * Constructs {@link Transform}
      *
-     * @param doc the {@link Document} in which <code>Transform</code> will be
+     * @param doc the {@link Document} in which {@code Transform} will be
      * placed
-     * @param algorithmURI URI representation of <code>Transform algorithm</code>
-     * @param contextNodes the child node list of <code>Transform</code> element
+     * @param algorithmURI URI representation of {@code Transform algorithm}
+     * @param contextNodes the child node list of {@code Transform} element
      * @throws InvalidTransformException
      */
     public Transform(Document doc, String algorithmURI, NodeList contextNodes)
@@ -136,15 +135,15 @@
     }
 
     /**
-     * @param element <code>ds:Transform</code> element
-     * @param BaseURI the URI of the resource where the XML instance was stored
+     * @param element {@code ds:Transform} element
+     * @param baseURI the URI of the resource where the XML instance was stored
      * @throws InvalidTransformException
      * @throws TransformationException
      * @throws XMLSecurityException
      */
-    public Transform(Element element, String BaseURI)
+    public Transform(Element element, String baseURI)
         throws InvalidTransformException, TransformationException, XMLSecurityException {
-        super(element, BaseURI);
+        super(element, baseURI);
 
         // retrieve Algorithm Attribute from ds:Transform
         String algorithmURI = element.getAttributeNS(null, Constants._ATT_ALGORITHM);
@@ -164,12 +163,12 @@
         } catch (InstantiationException ex) {
             Object exArgs[] = { algorithmURI };
             throw new InvalidTransformException(
-                "signature.Transform.UnknownTransform", exArgs, ex
+                ex, "signature.Transform.UnknownTransform", exArgs
             );
         } catch (IllegalAccessException ex) {
             Object exArgs[] = { algorithmURI };
             throw new InvalidTransformException(
-                "signature.Transform.UnknownTransform", exArgs, ex
+                ex, "signature.Transform.UnknownTransform", exArgs
             );
         }
     }
@@ -177,8 +176,8 @@
     /**
      * Registers implementing class of the Transform algorithm with algorithmURI
      *
-     * @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code>
-     * @param implementingClass <code>implementingClass</code> the implementing
+     * @param algorithmURI algorithmURI URI representation of {@code Transform algorithm}
+     * @param implementingClass {@code implementingClass} the implementing
      * class of {@link TransformSpi}
      * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI
      * is already registered
@@ -205,8 +204,8 @@
     /**
      * Registers implementing class of the Transform algorithm with algorithmURI
      *
-     * @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code>
-     * @param implementingClass <code>implementingClass</code> the implementing
+     * @param algorithmURI algorithmURI URI representation of {@code Transform algorithm}
+     * @param implementingClass {@code implementingClass} the implementing
      * class of {@link TransformSpi}
      * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI
      * is already registered
@@ -270,7 +269,7 @@
      * @return the URI representation of Transformation algorithm
      */
     public String getURI() {
-        return this.constructionElement.getAttributeNS(null, Constants._ATT_ALGORITHM);
+        return getLocalAttribute(Constants._ATT_ALGORITHM);
     }
 
     /**
@@ -311,21 +310,22 @@
         XMLSignatureInput result = null;
 
         try {
+            transformSpi.secureValidation = secureValidation;
             result = transformSpi.enginePerformTransform(input, os, this);
         } catch (ParserConfigurationException ex) {
             Object exArgs[] = { this.getURI(), "ParserConfigurationException" };
             throw new CanonicalizationException(
-                "signature.Transform.ErrorDuringTransform", exArgs, ex);
+                ex, "signature.Transform.ErrorDuringTransform", exArgs);
         } catch (SAXException ex) {
             Object exArgs[] = { this.getURI(), "SAXException" };
             throw new CanonicalizationException(
-                "signature.Transform.ErrorDuringTransform", exArgs, ex);
+                ex, "signature.Transform.ErrorDuringTransform", exArgs);
         }
 
         return result;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_TRANSFORM;
     }
@@ -336,7 +336,7 @@
     private TransformSpi initializeTransform(String algorithmURI, NodeList contextNodes)
         throws InvalidTransformException {
 
-        this.constructionElement.setAttributeNS(null, Constants._ATT_ALGORITHM, algorithmURI);
+        setLocalAttribute(Constants._ATT_ALGORITHM, algorithmURI);
 
         Class<? extends TransformSpi> transformSpiClass = transformSpiHash.get(algorithmURI);
         if (transformSpiClass == null) {
@@ -349,28 +349,34 @@
         } catch (InstantiationException ex) {
             Object exArgs[] = { algorithmURI };
             throw new InvalidTransformException(
-                "signature.Transform.UnknownTransform", exArgs, ex
+                ex, "signature.Transform.UnknownTransform", exArgs
             );
         } catch (IllegalAccessException ex) {
             Object exArgs[] = { algorithmURI };
             throw new InvalidTransformException(
-                "signature.Transform.UnknownTransform", exArgs, ex
+                ex, "signature.Transform.UnknownTransform", exArgs
             );
         }
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Create URI \"" + algorithmURI + "\" class \""
-                      + newTransformSpi.getClass() + "\"");
-            log.log(java.util.logging.Level.FINE, "The NodeList is " + contextNodes);
-        }
+        LOG.debug("Create URI \"{}\" class \"{}\"", algorithmURI, newTransformSpi.getClass());
+        LOG.debug("The NodeList is {}", contextNodes);
 
         // give it to the current document
         if (contextNodes != null) {
-            for (int i = 0; i < contextNodes.getLength(); i++) {
-                this.constructionElement.appendChild(contextNodes.item(i).cloneNode(true));
+            int length = contextNodes.getLength();
+            for (int i = 0; i < length; i++) {
+                appendSelf(contextNodes.item(i).cloneNode(true));
             }
         }
         return newTransformSpi;
     }
 
+    public boolean isSecureValidation() {
+        return secureValidation;
+    }
+
+    public void setSecureValidation(boolean secureValidation) {
+        this.secureValidation = secureValidation;
+    }
+
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/TransformSpi.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/TransformSpi.java	Sat Oct 24 01:11:51 2020 +0100
@@ -36,10 +36,11 @@
  * have to be overridden are the
  * {@link #enginePerformTransform(XMLSignatureInput, Transform)} method.
  *
- * @author Christian Geuer-Pollmann
  */
 public abstract class TransformSpi {
 
+    protected boolean secureValidation;
+
     /**
      * The mega method which MUST be implemented by the Transformation Algorithm.
      *
@@ -104,9 +105,9 @@
     }
 
     /**
-     * Returns the URI representation of <code>Transformation algorithm</code>
+     * Returns the URI representation of {@code Transformation algorithm}
      *
-     * @return the URI representation of <code>Transformation algorithm</code>
+     * @return the URI representation of {@code Transformation algorithm}
      */
     protected abstract String engineGetURI();
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/TransformationException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/TransformationException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -26,7 +26,6 @@
 
 /**
  *
- * @author Christian Geuer-Pollmann
  */
 public class TransformationException extends XMLSecurityException {
     /**
@@ -42,6 +41,10 @@
         super();
     }
 
+    public TransformationException(Exception ex) {
+        super(ex);
+    }
+
     /**
      * Constructor TransformationException
      *
@@ -64,21 +67,31 @@
     /**
      * Constructor TransformationException
      *
+     * @param originalException
      * @param msgID
-     * @param originalException
      */
+    public TransformationException(Exception originalException, String msgID) {
+        super(originalException, msgID);
+    }
+
+    @Deprecated
     public TransformationException(String msgID, Exception originalException) {
-        super(msgID, originalException);
+        this(originalException, msgID);
     }
 
     /**
      * Constructor TransformationException
      *
+     * @param originalException
      * @param msgID
      * @param exArgs
-     * @param originalException
      */
-    public TransformationException(String msgID, Object exArgs[], Exception originalException) {
-        super(msgID, exArgs, originalException);
+    public TransformationException(Exception originalException, String msgID, Object exArgs[]) {
+        super(originalException, msgID, exArgs);
+    }
+
+    @Deprecated
+    public TransformationException(String msgID, Object[] exArgs, Exception originalException) {
+        this(originalException, msgID, exArgs);
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transforms.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transforms.java	Sat Oct 24 01:11:51 2020 +0100
@@ -43,11 +43,10 @@
  * Holder of the {@link com.sun.org.apache.xml.internal.security.transforms.Transform} steps to
  * be performed on the data.
  * The input to the first Transform is the result of dereferencing the
- * <code>URI</code> attribute of the <code>Reference</code> element.
+ * {@code URI} attribute of the {@code Reference} element.
  * The output from the last Transform is the input for the
- * <code>DigestMethod algorithm</code>
+ * {@code DigestMethod algorithm}
  *
- * @author Christian Geuer-Pollmann
  * @see Transform
  * @see com.sun.org.apache.xml.internal.security.signature.Reference
  */
@@ -101,43 +100,42 @@
     public static final String TRANSFORM_XPATH2FILTER
         = "http://www.w3.org/2002/06/xmldsig-filter2";
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(Transforms.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(Transforms.class);
 
     private Element[] transforms;
 
-    protected Transforms() { };
+    protected Transforms() { }
 
     private boolean secureValidation;
 
     /**
      * Constructs {@link Transforms}.
      *
-     * @param doc the {@link Document} in which <code>XMLSignature</code> will
+     * @param doc the {@link Document} in which {@code XMLSignature} will
      * be placed
      */
     public Transforms(Document doc) {
         super(doc);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
     }
 
     /**
      * Constructs {@link Transforms} from {@link Element} which is
-     * <code>Transforms</code> Element
+     * {@code Transforms} Element
      *
-     * @param element  is <code>Transforms</code> element
-     * @param BaseURI the URI where the XML instance was stored
+     * @param element  is {@code Transforms} element
+     * @param baseURI the URI where the XML instance was stored
      * @throws DOMException
      * @throws InvalidTransformException
      * @throws TransformationException
      * @throws XMLSecurityException
      * @throws XMLSignatureException
      */
-    public Transforms(Element element, String BaseURI)
+    public Transforms(Element element, String baseURI)
         throws DOMException, XMLSignatureException, InvalidTransformException,
             TransformationException, XMLSecurityException {
-        super(element, BaseURI);
+        super(element, baseURI);
 
         int numberOfTransformElems = this.getLength();
 
@@ -157,7 +155,7 @@
     }
 
     /**
-     * Adds the <code>Transform</code> with the specified <code>Transform
+     * Adds the {@code Transform} with the specified <code>Transform
      * algorithm URI</code>
      *
      * @param transformURI the URI form of transform that indicates which
@@ -166,20 +164,18 @@
      */
     public void addTransform(String transformURI) throws TransformationException {
         try {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Transforms.addTransform(" + transformURI + ")");
-            }
+            LOG.debug("Transforms.addTransform({})", transformURI);
 
-            Transform transform = new Transform(this.doc, transformURI);
+            Transform transform = new Transform(getDocument(), transformURI);
 
             this.addTransform(transform);
         } catch (InvalidTransformException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         }
     }
 
     /**
-     * Adds the <code>Transform</code> with the specified <code>Transform
+     * Adds the {@code Transform} with the specified <code>Transform
      * algorithm URI</code>
      *
      * @param transformURI the URI form of transform that indicates which
@@ -190,20 +186,18 @@
     public void addTransform(String transformURI, Element contextElement)
        throws TransformationException {
         try {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Transforms.addTransform(" + transformURI + ")");
-            }
+            LOG.debug("Transforms.addTransform({})", transformURI);
 
-            Transform transform = new Transform(this.doc, transformURI, contextElement);
+            Transform transform = new Transform(getDocument(), transformURI, contextElement);
 
             this.addTransform(transform);
         } catch (InvalidTransformException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         }
     }
 
     /**
-     * Adds the <code>Transform</code> with the specified <code>Transform
+     * Adds the {@code Transform} with the specified <code>Transform
      * algorithm URI</code>.
      *
      * @param transformURI the URI form of transform that indicates which
@@ -215,10 +209,10 @@
        throws TransformationException {
 
         try {
-            Transform transform = new Transform(this.doc, transformURI, contextNodes);
+            Transform transform = new Transform(getDocument(), transformURI, contextNodes);
             this.addTransform(transform);
         } catch (InvalidTransformException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         }
     }
 
@@ -228,22 +222,20 @@
      * @param transform {@link Transform} object
      */
     private void addTransform(Transform transform) {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Transforms.addTransform(" + transform.getURI() + ")");
-        }
+        LOG.debug("Transforms.addTransform({})", transform.getURI());
 
         Element transformElement = transform.getElement();
 
-        this.constructionElement.appendChild(transformElement);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendSelf(transformElement);
+        addReturnToSelf();
     }
 
     /**
-     * Applies all included <code>Transform</code>s to xmlSignatureInput and
+     * Applies all included {@code Transform}s to xmlSignatureInput and
      * returns the result of these transformations.
      *
-     * @param xmlSignatureInput the input for the <code>Transform</code>s
-     * @return the result of the <code>Transforms</code>
+     * @param xmlSignatureInput the input for the {@code Transform}s
+     * @return the result of the {@code Transforms}
      * @throws TransformationException
      */
     public XMLSignatureInput performTransforms(
@@ -253,12 +245,12 @@
     }
 
     /**
-     * Applies all included <code>Transform</code>s to xmlSignatureInput and
+     * Applies all included {@code Transform}s to xmlSignatureInput and
      * returns the result of these transformations.
      *
-     * @param xmlSignatureInput the input for the <code>Transform</code>s
+     * @param xmlSignatureInput the input for the {@code Transform}s
      * @param os where to output the last transformation.
-     * @return the result of the <code>Transforms</code>
+     * @return the result of the {@code Transforms}
      * @throws TransformationException
      */
     public XMLSignatureInput performTransforms(
@@ -268,26 +260,24 @@
             int last = this.getLength() - 1;
             for (int i = 0; i < last; i++) {
                 Transform t = this.item(i);
-                String uri = t.getURI();
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Perform the (" + i + ")th " + uri + " transform");
-                }
+                LOG.debug("Perform the ({})th {} transform", i, t.getURI());
                 checkSecureValidation(t);
                 xmlSignatureInput = t.performTransform(xmlSignatureInput);
             }
             if (last >= 0) {
                 Transform t = this.item(last);
+                LOG.debug("Perform the ({})th {} transform", last, t.getURI());
                 checkSecureValidation(t);
                 xmlSignatureInput = t.performTransform(xmlSignatureInput, os);
             }
 
             return xmlSignatureInput;
         } catch (IOException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         } catch (CanonicalizationException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         } catch (InvalidCanonicalizerException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         }
     }
 
@@ -300,6 +290,7 @@
                 "signature.Transform.ForbiddenTransform", exArgs
             );
         }
+        transform.setSecureValidation(secureValidation);
     }
 
     /**
@@ -308,34 +299,34 @@
      * @return the number of transformations
      */
     public int getLength() {
-        if (transforms == null) {
-            transforms =
-                XMLUtils.selectDsNodes(this.constructionElement.getFirstChild(), "Transform");
-        }
+        initTransforms();
         return transforms.length;
     }
 
     /**
-     * Return the <it>i</it><sup>th</sup> <code>{@link Transform}</code>.
-     * Valid <code>i</code> values are 0 to <code>{@link #getLength}-1</code>.
+     * Return the <i>i</i><sup>th</sup> {@code {@link Transform}}.
+     * Valid {@code i} values are 0 to {@code {@link #getLength}-1}.
      *
      * @param i index of {@link Transform} to return
-     * @return the <it>i</it><sup>th</sup> Transform
+     * @return the <i>i</i><sup>th</sup> Transform
      * @throws TransformationException
      */
     public Transform item(int i) throws TransformationException {
         try {
-            if (transforms == null) {
-                transforms =
-                    XMLUtils.selectDsNodes(this.constructionElement.getFirstChild(), "Transform");
-            }
+            initTransforms();
             return new Transform(transforms[i], this.baseURI);
         } catch (XMLSecurityException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         }
     }
 
-    /** @inheritDoc */
+    private void initTransforms() {
+        if (transforms == null) {
+            transforms = XMLUtils.selectDsNodes(getFirstChild(), "Transform");
+        }
+    }
+
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_TRANSFORMS;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/FuncHere.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/FuncHere.java	Sat Oct 24 01:11:51 2020 +0100
@@ -71,9 +71,7 @@
      * @return the xobject
      * @throws javax.xml.transform.TransformerException
      */
-    @Override
-    public XObject execute(XPathContext xctxt)
-        throws javax.xml.transform.TransformerException {
+    public XObject execute(XPathContext xctxt) throws TransformerException {
 
         Node xpathOwnerNode = (Node) xctxt.getOwnerObject();
 
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformBase64Decode.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformBase64Decode.java	Sat Oct 24 01:11:51 2020 +0100
@@ -22,30 +22,29 @@
  */
 package com.sun.org.apache.xml.internal.security.transforms.implementations;
 
-import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Base64;
 
-import javax.xml.XMLConstants;
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
-import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
 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.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.Base64;
+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;
 import org.xml.sax.SAXException;
 
+import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
+
 /**
- * Implements the <CODE>http://www.w3.org/2000/09/xmldsig#base64</CODE> decoding
+ * Implements the {@code http://www.w3.org/2000/09/xmldsig#base64} decoding
  * transform.
  *
  * <p>The normative specification for base64 decoding transforms is
@@ -58,7 +57,7 @@
  * <p>This transform requires an octet stream for input.
  * If an XPath node-set (or sufficiently functional alternative) is
  * given as input, then it is converted to an octet stream by
- * performing operations logically equivalent to 1) applying an XPath
+ * performing operations LOGically equivalent to 1) applying an XPath
  * transform with expression self::text(), then 2) taking the string-value
  * of the node-set. Thus, if an XML element is identified by a barename
  * XPointer in the Reference URI, and its content consists solely of base64
@@ -67,8 +66,6 @@
  * elements as well as any descendant comments and processing instructions.
  * The output of this transform is an octet stream.</p>
  *
- * @author Christian Geuer-Pollmann
- * @see com.sun.org.apache.xml.internal.security.utils.Base64
  */
 public class TransformBase64Decode extends TransformSpi {
 
@@ -79,7 +76,7 @@
     /**
      * Method engineGetURI
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected String engineGetURI() {
         return TransformBase64Decode.implementedTransformURI;
@@ -90,7 +87,7 @@
      *
      * @param input
      * @return {@link XMLSignatureInput} as the result of transformation
-     * @inheritDoc
+     * {@inheritDoc}
      * @throws CanonicalizationException
      * @throws IOException
      * @throws TransformationException
@@ -104,64 +101,70 @@
     protected XMLSignatureInput enginePerformTransform(
         XMLSignatureInput input, OutputStream os, Transform transformObject
     ) throws IOException, CanonicalizationException, TransformationException {
-        try {
-            if (input.isElement()) {
-                Node el = input.getSubNode();
-                if (input.getSubNode().getNodeType() == Node.TEXT_NODE) {
-                    el = el.getParentNode();
-                }
-                StringBuilder sb = new StringBuilder();
-                traverseElement((Element)el, sb);
-                if (os == null) {
-                    byte[] decodedBytes = Base64.decode(sb.toString());
-                    return new XMLSignatureInput(decodedBytes);
-                }
-                Base64.decode(sb.toString(), os);
-                XMLSignatureInput output = new XMLSignatureInput((byte[])null);
-                output.setOutputStream(os);
+        if (input.isElement()) {
+            Node el = input.getSubNode();
+            if (input.getSubNode().getNodeType() == Node.TEXT_NODE) {
+                el = el.getParentNode();
+            }
+            StringBuilder sb = new StringBuilder();
+            traverseElement((Element)el, sb);
+            if (os == null) {
+                byte[] decodedBytes = Base64.getMimeDecoder().decode(sb.toString());
+                XMLSignatureInput output = new XMLSignatureInput(decodedBytes);
+                output.setSecureValidation(secureValidation);
+                return output;
+            }
+            byte[] bytes = Base64.getMimeDecoder().decode(sb.toString());
+            os.write(bytes);
+            XMLSignatureInput output = new XMLSignatureInput((byte[])null);
+            output.setSecureValidation(secureValidation);
+            output.setOutputStream(os);
+            return output;
+        }
+
+        if (input.isOctetStream() || input.isNodeSet()) {
+            if (os == null) {
+                byte[] base64Bytes = input.getBytes();
+                byte[] decodedBytes = Base64.getMimeDecoder().decode(base64Bytes);
+                XMLSignatureInput output = new XMLSignatureInput(decodedBytes);
+                output.setSecureValidation(secureValidation);
                 return output;
             }
-
-            if (input.isOctetStream() || input.isNodeSet()) {
-                if (os == null) {
-                    byte[] base64Bytes = input.getBytes();
-                    byte[] decodedBytes = Base64.decode(base64Bytes);
-                    return new XMLSignatureInput(decodedBytes);
-                }
-                if (input.isByteArray() || input.isNodeSet()) {
-                    Base64.decode(input.getBytes(), os);
-                } else {
-                    Base64.decode(new BufferedInputStream(input.getOctetStreamReal()), os);
-                }
-                XMLSignatureInput output = new XMLSignatureInput((byte[])null);
-                output.setOutputStream(os);
-                return output;
+            if (input.isByteArray() || input.isNodeSet()) {
+                byte[] bytes = Base64.getMimeDecoder().decode(input.getBytes());
+                os.write(bytes);
+            } else {
+                byte[] inputBytes = JavaUtils.getBytesFromStream(input.getOctetStreamReal());
+                byte[] bytes = Base64.getMimeDecoder().decode(inputBytes);
+                os.write(bytes);
             }
+            XMLSignatureInput output = new XMLSignatureInput((byte[])null);
+            output.setSecureValidation(secureValidation);
+            output.setOutputStream(os);
+            return output;
+        }
 
-            try {
-                //Exceptional case there is current not text case testing this(Before it was a
-                //a common case).
-                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-                dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
-                Document doc =
-                    dbf.newDocumentBuilder().parse(input.getOctetStream());
+        try {
+            //Exceptional case there is current not text case testing this(Before it was a
+            //a common case).
+            Document doc =
+                XMLUtils.createDocumentBuilder(false, secureValidation).parse(input.getOctetStream());
 
-                Element rootNode = doc.getDocumentElement();
-                StringBuilder sb = new StringBuilder();
-                traverseElement(rootNode, sb);
-                byte[] decodedBytes = Base64.decode(sb.toString());
-                return new XMLSignatureInput(decodedBytes);
-            } catch (ParserConfigurationException e) {
-                throw new TransformationException("c14n.Canonicalizer.Exception",e);
-            } catch (SAXException e) {
-                throw new TransformationException("SAX exception", e);
-            }
-        } catch (Base64DecodingException e) {
-            throw new TransformationException("Base64Decoding", e);
+            Element rootNode = doc.getDocumentElement();
+            StringBuilder sb = new StringBuilder();
+            traverseElement(rootNode, sb);
+            byte[] decodedBytes = Base64.getMimeDecoder().decode(sb.toString());
+            XMLSignatureInput output = new XMLSignatureInput(decodedBytes);
+            output.setSecureValidation(secureValidation);
+            return output;
+        } catch (ParserConfigurationException e) {
+            throw new TransformationException(e, "c14n.Canonicalizer.Exception");
+        } catch (SAXException e) {
+            throw new TransformationException(e, "SAX exception");
         }
     }
 
-    void traverseElement(org.w3c.dom.Element node, StringBuilder sb) {
+    void traverseElement(Element node, StringBuilder sb) {
         Node sibling = node.getFirstChild();
         while (sibling != null) {
             switch (sibling.getNodeType()) {
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N.java	Sat Oct 24 01:11:51 2020 +0100
@@ -32,10 +32,9 @@
 import com.sun.org.apache.xml.internal.security.transforms.Transforms;
 
 /**
- * Implements the <CODE>http://www.w3.org/TR/2001/REC-xml-c14n-20010315</CODE>
+ * Implements the {@code http://www.w3.org/TR/2001/REC-xml-c14n-20010315}
  * transform.
  *
- * @author Christian Geuer-Pollmann
  */
 public class TransformC14N extends TransformSpi {
 
@@ -44,7 +43,7 @@
         Transforms.TRANSFORM_C14N_OMIT_COMMENTS;
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected String engineGetURI() {
         return TransformC14N.implementedTransformURI;
@@ -54,12 +53,14 @@
         XMLSignatureInput input, OutputStream os, Transform transformObject
     ) throws CanonicalizationException {
         Canonicalizer20010315OmitComments c14n = new Canonicalizer20010315OmitComments();
+        c14n.setSecureValidation(secureValidation);
         if (os != null) {
             c14n.setWriter(os);
         }
         byte[] result = null;
         result = c14n.engineCanonicalize(input);
         XMLSignatureInput output = new XMLSignatureInput(result);
+        output.setSecureValidation(secureValidation);
         if (os != null) {
             output.setOutputStream(os);
         }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N11.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N11.java	Sat Oct 24 01:11:51 2020 +0100
@@ -32,10 +32,9 @@
 import com.sun.org.apache.xml.internal.security.transforms.Transforms;
 
 /**
- * Implements the <CODE>http://www.w3.org/2006/12/xml-c14n11</CODE>
+ * Implements the {@code http://www.w3.org/2006/12/xml-c14n11}
  * (C14N 1.1) transform.
  *
- * @author Sean Mullan
  */
 public class TransformC14N11 extends TransformSpi {
 
@@ -47,12 +46,14 @@
         XMLSignatureInput input, OutputStream os, Transform transform
     ) throws CanonicalizationException {
         Canonicalizer11_OmitComments c14n = new Canonicalizer11_OmitComments();
+        c14n.setSecureValidation(secureValidation);
         if (os != null) {
             c14n.setWriter(os);
         }
         byte[] result = null;
         result = c14n.engineCanonicalize(input);
         XMLSignatureInput output = new XMLSignatureInput(result);
+        output.setSecureValidation(secureValidation);
         if (os != null) {
             output.setOutputStream(os);
         }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N11_WithComments.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N11_WithComments.java	Sat Oct 24 01:11:51 2020 +0100
@@ -32,10 +32,9 @@
 import com.sun.org.apache.xml.internal.security.transforms.Transforms;
 
 /**
- * Implements the <CODE>http://www.w3.org/2006/12/xml-c14n-11#WithComments</CODE>
+ * Implements the {@code http://www.w3.org/2006/12/xml-c14n-11#WithComments}
  * (C14N 1.1 With Comments) transform.
  *
- * @author Sean Mullan
  */
 public class TransformC14N11_WithComments extends TransformSpi {
 
@@ -48,6 +47,7 @@
     ) throws CanonicalizationException {
 
         Canonicalizer11_WithComments c14n = new Canonicalizer11_WithComments();
+        c14n.setSecureValidation(secureValidation);
         if (os != null) {
             c14n.setWriter(os);
         }
@@ -55,6 +55,7 @@
         byte[] result = null;
         result = c14n.engineCanonicalize(input);
         XMLSignatureInput output = new XMLSignatureInput(result);
+        output.setSecureValidation(secureValidation);
         if (os != null) {
             output.setOutputStream(os);
         }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NExclusive.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NExclusive.java	Sat Oct 24 01:11:51 2020 +0100
@@ -48,7 +48,7 @@
     /**
      * Method engineGetURI
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected String engineGetURI() {
         return implementedTransformURI;
@@ -79,18 +79,20 @@
 
             Canonicalizer20010315ExclOmitComments c14n =
                 new Canonicalizer20010315ExclOmitComments();
+            c14n.setSecureValidation(secureValidation);
             if (os != null) {
                 c14n.setWriter(os);
             }
             byte[] result = c14n.engineCanonicalize(input, inclusiveNamespaces);
 
             XMLSignatureInput output = new XMLSignatureInput(result);
+            output.setSecureValidation(secureValidation);
             if (os != null) {
                 output.setOutputStream(os);
             }
             return output;
         } catch (XMLSecurityException ex) {
-            throw new CanonicalizationException("empty", ex);
+            throw new CanonicalizationException(ex);
         }
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NExclusiveWithComments.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NExclusiveWithComments.java	Sat Oct 24 01:11:51 2020 +0100
@@ -36,10 +36,9 @@
 import org.w3c.dom.Element;
 
 /**
- * Implements the <CODE>http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments</CODE>
+ * Implements the {@code http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments}
  * transform.
  *
- * @author Christian Geuer-Pollmann
  */
 public class TransformC14NExclusiveWithComments extends TransformSpi {
 
@@ -49,7 +48,7 @@
 
     /**
      * Method engineGetURI
-     *@inheritDoc
+     *{@inheritDoc}
      *
      */
     protected String engineGetURI() {
@@ -82,15 +81,17 @@
 
             Canonicalizer20010315ExclWithComments c14n =
                 new Canonicalizer20010315ExclWithComments();
+            c14n.setSecureValidation(secureValidation);
             if (os != null) {
                 c14n.setWriter(os);
             }
             byte[] result = c14n.engineCanonicalize(input, inclusiveNamespaces);
             XMLSignatureInput output = new XMLSignatureInput(result);
+            output.setSecureValidation(secureValidation);
 
             return output;
         } catch (XMLSecurityException ex) {
-            throw new CanonicalizationException("empty", ex);
+            throw new CanonicalizationException(ex);
         }
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NWithComments.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NWithComments.java	Sat Oct 24 01:11:51 2020 +0100
@@ -32,10 +32,9 @@
 import com.sun.org.apache.xml.internal.security.transforms.Transforms;
 
 /**
- * Implements the <CODE>http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments</CODE>
+ * Implements the {@code http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments}
  * transform.
  *
- * @author Christian Geuer-Pollmann
  */
 public class TransformC14NWithComments extends TransformSpi {
 
@@ -43,17 +42,18 @@
     public static final String implementedTransformURI =
         Transforms.TRANSFORM_C14N_WITH_COMMENTS;
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected String engineGetURI() {
         return implementedTransformURI;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected XMLSignatureInput enginePerformTransform(
         XMLSignatureInput input, OutputStream os, Transform transformObject
     ) throws CanonicalizationException {
 
         Canonicalizer20010315WithComments c14n = new Canonicalizer20010315WithComments();
+        c14n.setSecureValidation(secureValidation);
         if (os != null) {
             c14n.setWriter(os);
         }
@@ -61,6 +61,7 @@
         byte[] result = null;
         result = c14n.engineCanonicalize(input);
         XMLSignatureInput output = new XMLSignatureInput(result);
+        output.setSecureValidation(secureValidation);
         if (os != null) {
             output.setOutputStream(os);
         }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformEnvelopedSignature.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformEnvelopedSignature.java	Sat Oct 24 01:11:51 2020 +0100
@@ -36,10 +36,9 @@
 import org.w3c.dom.Node;
 
 /**
- * Implements the <CODE>http://www.w3.org/2000/09/xmldsig#enveloped-signature</CODE>
+ * Implements the {@code http://www.w3.org/2000/09/xmldsig#enveloped-signature}
  * transform.
  *
- * @author Christian Geuer-Pollmann
  */
 public class TransformEnvelopedSignature extends TransformSpi {
 
@@ -50,14 +49,14 @@
     /**
      * Method engineGetURI
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected String engineGetURI() {
         return implementedTransformURI;
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected XMLSignatureInput enginePerformTransform(
         XMLSignatureInput input, OutputStream os, Transform transformObject
@@ -136,7 +135,7 @@
                 return -1;
             }
             return 1;
-            //return !XMLUtils.isDescendantOrSelf(exclude,n);
+            //return !XMLUtils.isDescendantOrSelf(exclude, n);
         }
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java	Sat Oct 24 01:11:51 2020 +0100
@@ -44,10 +44,9 @@
 /**
  * Class TransformXPath
  *
- * Implements the <CODE>http://www.w3.org/TR/1999/REC-xpath-19991116</CODE>
+ * Implements the {@code http://www.w3.org/TR/1999/REC-xpath-19991116}
  * transform.
  *
- * @author Christian Geuer-Pollmann
  * @see <a href="http://www.w3.org/TR/1999/REC-xpath-19991116">XPath</a>
  *
  */
@@ -59,7 +58,7 @@
     /**
      * Method engineGetURI
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected String engineGetURI() {
         return implementedTransformURI;
@@ -67,7 +66,7 @@
 
     /**
      * Method enginePerformTransform
-     * @inheritDoc
+     * {@inheritDoc}
      * @param input
      *
      * @throws TransformationException
@@ -96,14 +95,14 @@
 
                 throw new TransformationException("xml.WrongContent", exArgs);
             }
-            Node xpathnode = xpathElement.getChildNodes().item(0);
-            String str = XMLUtils.getStrFromNode(xpathnode);
-            input.setNeedsToBeExpanded(needsCircumvent(str));
+            Node xpathnode = xpathElement.getFirstChild();
             if (xpathnode == null) {
                 throw new DOMException(
                     DOMException.HIERARCHY_REQUEST_ERR, "Text must be in ds:Xpath"
                 );
             }
+            String str = XMLUtils.getStrFromNode(xpathnode);
+            input.setNeedsToBeExpanded(needsCircumvent(str));
 
             XPathFactory xpathFactory = XPathFactory.newInstance();
             XPathAPI xpathAPIInstance = xpathFactory.newXPathAPI();
@@ -111,7 +110,7 @@
             input.setNodeSet(true);
             return input;
         } catch (DOMException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         }
     }
 
@@ -120,7 +119,7 @@
      * @return true if needs to be circumvent for bug.
      */
     private boolean needsCircumvent(String str) {
-        return (str.indexOf("namespace") != -1) || (str.indexOf("name()") != -1);
+        return str.indexOf("namespace") != -1 || str.indexOf("name()") != -1;
     }
 
     static class XPathNodeFilter implements NodeFilter {
@@ -151,7 +150,7 @@
                 Object[] eArgs = {currentNode};
                 throw new XMLSecurityRuntimeException("signature.Transform.node", eArgs, e);
             } catch (Exception e) {
-                Object[] eArgs = {currentNode, Short.valueOf(currentNode.getNodeType())};
+                Object[] eArgs = {currentNode, currentNode.getNodeType()};
                 throw new XMLSecurityRuntimeException("signature.Transform.nodeAndType",eArgs, e);
             }
         }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java	Sat Oct 24 01:11:51 2020 +0100
@@ -66,7 +66,7 @@
     /**
      * Method engineGetURI
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected String engineGetURI() {
         return implementedTransformURI;
@@ -74,7 +74,7 @@
 
     /**
      * Method enginePerformTransform
-     * @inheritDoc
+     * {@inheritDoc}
      * @param input
      *
      * @throws TransformationException
@@ -83,9 +83,9 @@
         XMLSignatureInput input, OutputStream os, Transform transformObject
     ) throws TransformationException {
         try {
-            List<NodeList> unionNodes = new ArrayList<NodeList>();
-            List<NodeList> subtractNodes = new ArrayList<NodeList>();
-            List<NodeList> intersectNodes = new ArrayList<NodeList>();
+            List<NodeList> unionNodes = new ArrayList<>();
+            List<NodeList> subtractNodes = new ArrayList<>();
+            List<NodeList> intersectNodes = new ArrayList<>();
 
             Element[] xpathElements =
                 XMLUtils.selectNodes(
@@ -139,21 +139,21 @@
             input.setNodeSet(true);
             return input;
         } catch (TransformerException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         } catch (DOMException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         } catch (CanonicalizationException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         } catch (InvalidCanonicalizerException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         } catch (XMLSecurityException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         } catch (SAXException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         } catch (IOException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         } catch (ParserConfigurationException ex) {
-            throw new TransformationException("empty", ex);
+            throw new TransformationException(ex);
         }
     }
 }
@@ -208,7 +208,7 @@
     public int isNodeIncludeDO(Node n, int level) {
         int result = 1;
         if (hasSubtractFilter) {
-            if ((inSubtract == -1) || (level <= inSubtract)) {
+            if (inSubtract == -1 || level <= inSubtract) {
                 if (inList(n, subtractNodes)) {
                     inSubtract = level;
                 } else {
@@ -220,7 +220,7 @@
             }
         }
         if (result != -1 && hasIntersectFilter
-            && ((inIntersect == -1) || (level <= inIntersect))) {
+            && (inIntersect == -1 || level <= inIntersect)) {
             if (!inList(n, intersectNodes)) {
                 inIntersect = -1;
                 result = 0;
@@ -236,13 +236,13 @@
             return 1;
         }
         if (hasUnionFilter) {
-            if ((inUnion == -1) && inList(n, unionNodes)) {
+            if (inUnion == -1 && inList(n, unionNodes)) {
                 inUnion = level;
             }
             if (inUnion != -1) {
                 return 1;
             }
-            result=0;
+            result = 0;
         }
 
         return result;
@@ -282,7 +282,7 @@
     }
 
     private static Set<Node> convertNodeListToSet(List<NodeList> l) {
-        Set<Node> result = new HashSet<Node>();
+        Set<Node> result = new HashSet<>();
         for (NodeList rootNodes : l) {
             int length = rootNodes.getLength();
 
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPointer.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPointer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -33,7 +33,6 @@
 /**
  * Class TransformXPointer
  *
- * @author Christian Geuer-Pollmann
  */
 public class TransformXPointer extends TransformSpi {
 
@@ -42,7 +41,7 @@
         Transforms.TRANSFORM_XPOINTER;
 
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     protected String engineGetURI() {
         return implementedTransformURI;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXSLT.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXSLT.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,6 +25,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 
 import javax.xml.XMLConstants;
@@ -49,10 +50,9 @@
 /**
  * Class TransformXSLT
  *
- * Implements the <CODE>http://www.w3.org/TR/1999/REC-xslt-19991116</CODE>
+ * Implements the {@code http://www.w3.org/TR/1999/REC-xslt-19991116}
  * transform.
  *
- * @author Christian Geuer-Pollmann
  */
 public class TransformXSLT extends TransformSpi {
 
@@ -60,17 +60,17 @@
     public static final String implementedTransformURI =
         Transforms.TRANSFORM_XSLT;
 
-    static final String XSLTSpecNS              = "http://www.w3.org/1999/XSL/Transform";
+    static final String XSLTSpecNS = "http://www.w3.org/1999/XSL/Transform";
     static final String defaultXSLTSpecNSprefix = "xslt";
-    static final String XSLTSTYLESHEET          = "stylesheet";
+    static final String XSLTSTYLESHEET = "stylesheet";
 
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(TransformXSLT.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(TransformXSLT.class);
 
     /**
      * Method engineGetURI
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     protected String engineGetURI() {
         return implementedTransformURI;
@@ -101,8 +101,6 @@
              * attempt to convert it to octets (apply Canonical XML]) as described
              * in the Reference Processing Model (section 4.3.3.2).
              */
-            Source xmlSource =
-                new StreamSource(new ByteArrayInputStream(input.getBytes()));
             Source stylesheet;
 
             /*
@@ -114,15 +112,16 @@
              * so we convert the stylesheet to byte[] and use this as input stream
              */
             {
-                ByteArrayOutputStream os = new ByteArrayOutputStream();
-                Transformer transformer = tFactory.newTransformer();
-                DOMSource source = new DOMSource(xsltElement);
-                StreamResult result = new StreamResult(os);
+                try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+                    Transformer transformer = tFactory.newTransformer();
+                    DOMSource source = new DOMSource(xsltElement);
+                    StreamResult result = new StreamResult(os);
 
-                transformer.transform(source, result);
+                    transformer.transform(source, result);
 
-                stylesheet =
-                    new StreamSource(new ByteArrayInputStream(os.toByteArray()));
+                    stylesheet =
+                        new StreamSource(new ByteArrayInputStream(os.toByteArray()));
+                }
             }
 
             Transformer transformer = tFactory.newTransformer(stylesheet);
@@ -135,33 +134,34 @@
             try {
                 transformer.setOutputProperty("{http://xml.apache.org/xalan}line-separator", "\n");
             } catch (Exception e) {
-                log.log(java.util.logging.Level.WARNING, "Unable to set Xalan line-separator property: " + e.getMessage());
+                LOG.warn("Unable to set Xalan line-separator property: " + e.getMessage());
             }
 
-            if (baos == null) {
-                ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
-                StreamResult outputTarget = new StreamResult(baos1);
+            try (InputStream is = new ByteArrayInputStream(input.getBytes())) {
+                Source xmlSource = new StreamSource(is);
+                if (baos == null) {
+                    try (ByteArrayOutputStream baos1 = new ByteArrayOutputStream()) {
+                        StreamResult outputTarget = new StreamResult(baos1);
+                        transformer.transform(xmlSource, outputTarget);
+                        XMLSignatureInput output = new XMLSignatureInput(baos1.toByteArray());
+                        output.setSecureValidation(secureValidation);
+                        return output;
+                    }
+                }
+                StreamResult outputTarget = new StreamResult(baos);
+
                 transformer.transform(xmlSource, outputTarget);
-                return new XMLSignatureInput(baos1.toByteArray());
             }
-            StreamResult outputTarget = new StreamResult(baos);
-
-            transformer.transform(xmlSource, outputTarget);
             XMLSignatureInput output = new XMLSignatureInput((byte[])null);
+            output.setSecureValidation(secureValidation);
             output.setOutputStream(baos);
             return output;
         } catch (XMLSecurityException ex) {
-            Object exArgs[] = { ex.getMessage() };
-
-            throw new TransformationException("generic.EmptyMessage", exArgs, ex);
+            throw new TransformationException(ex);
         } catch (TransformerConfigurationException ex) {
-            Object exArgs[] = { ex.getMessage() };
-
-            throw new TransformationException("generic.EmptyMessage", exArgs, ex);
+            throw new TransformationException(ex);
         } catch (TransformerException ex) {
-            Object exArgs[] = { ex.getMessage() };
-
-            throw new TransformationException("generic.EmptyMessage", exArgs, ex);
+            throw new TransformationException(ex);
         }
     }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-implementations of XML Signature transforms.
-</P></BODY></HTML>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-the framework for XML Signature transforms.
-</P></BODY></HTML>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/InclusiveNamespaces.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/InclusiveNamespaces.java	Sat Oct 24 01:11:51 2020 +0100
@@ -35,11 +35,10 @@
 /**
  * This Object serves as Content for the ds:Transforms for exclusive
  * Canonicalization.
- * <BR />
+ * <p></p>
  * It implements the {@link Element} interface
  * and can be used directly in a DOM tree.
  *
- * @author Christian Geuer-Pollmann
  */
 public class InclusiveNamespaces extends ElementProxy implements TransformParam {
 
@@ -82,27 +81,27 @@
 
         StringBuilder sb = new StringBuilder();
         for (String prefix : prefixList) {
-            if (prefix.equals("xmlns")) {
+            if ("xmlns".equals(prefix)) {
                 sb.append("#default ");
             } else {
-                sb.append(prefix + " ");
+                sb.append(prefix);
+                sb.append(" ");
             }
         }
 
-        this.constructionElement.setAttributeNS(
-            null, InclusiveNamespaces._ATT_EC_PREFIXLIST, sb.toString().trim());
+        setLocalAttribute(InclusiveNamespaces._ATT_EC_PREFIXLIST, sb.toString().trim());
     }
 
     /**
      * Constructor InclusiveNamespaces
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public InclusiveNamespaces(Element element, String BaseURI)
+    public InclusiveNamespaces(Element element, String baseURI)
         throws XMLSecurityException {
-        super(element, BaseURI);
+        super(element, baseURI);
     }
 
     /**
@@ -111,21 +110,21 @@
      * @return The Inclusive Namespace string
      */
     public String getInclusiveNamespaces() {
-        return this.constructionElement.getAttributeNS(null, InclusiveNamespaces._ATT_EC_PREFIXLIST);
+        return getLocalAttribute(InclusiveNamespaces._ATT_EC_PREFIXLIST);
     }
 
     /**
-     * Decodes the <code>inclusiveNamespaces</code> String and returns all
-     * selected namespace prefixes as a Set. The <code>#default</code>
+     * Decodes the {@code inclusiveNamespaces} String and returns all
+     * selected namespace prefixes as a Set. The {@code #default}
      * namespace token is represented as an empty namespace prefix
-     * (<code>"xmlns"</code>).
-     * <BR/>
-     * The String <code>inclusiveNamespaces=" xenc    ds #default"</code>
+     * ({@code "xmlns"}).
+     * <BR>
+     * The String {@code inclusiveNamespaces=" xenc    ds #default"}
      * is returned as a Set containing the following Strings:
      * <UL>
-     * <LI><code>xmlns</code></LI>
-     * <LI><code>xenc</code></LI>
-     * <LI><code>ds</code></LI>
+     * <LI>{@code xmlns}</LI>
+     * <LI>{@code xenc}</LI>
+     * <LI>{@code ds}</LI>
      * </UL>
      *
      * @param inclusiveNamespaces
@@ -134,7 +133,7 @@
     public static SortedSet<String> prefixStr2Set(String inclusiveNamespaces) {
         SortedSet<String> prefixes = new TreeSet<String>();
 
-        if ((inclusiveNamespaces == null) || (inclusiveNamespaces.length() == 0)) {
+        if (inclusiveNamespaces == null || inclusiveNamespaces.length() == 0) {
             return prefixes;
         }
 
@@ -153,7 +152,7 @@
     /**
      * Method getBaseNamespace
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     public String getBaseNamespace() {
         return InclusiveNamespaces.ExclusiveCanonicalizationNamespace;
@@ -162,7 +161,7 @@
     /**
      * Method getBaseLocalName
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     public String getBaseLocalName() {
         return InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES;
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/XPath2FilterContainer.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/XPath2FilterContainer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -36,7 +36,6 @@
  * Implements the parameters for the <A
  * HREF="http://www.w3.org/TR/xmldsig-filter2/">XPath Filter v2.0</A>.
  *
- * @author $Author: coheigea $
  * @see <A HREF="http://www.w3.org/TR/xmldsig-filter2/">XPath Filter v2.0 (TR)</A>
  */
 public class XPath2FilterContainer extends ElementProxy implements TransformParam {
@@ -90,24 +89,22 @@
     private XPath2FilterContainer(Document doc, String xpath2filter, String filterType) {
         super(doc);
 
-        this.constructionElement.setAttributeNS(
-            null, XPath2FilterContainer._ATT_FILTER, filterType);
-        this.constructionElement.appendChild(doc.createTextNode(xpath2filter));
+        setLocalAttribute(XPath2FilterContainer._ATT_FILTER, filterType);
+        appendSelf(createText(xpath2filter));
     }
 
     /**
      * Constructor XPath2FilterContainer
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    private XPath2FilterContainer(Element element, String BaseURI) throws XMLSecurityException {
+    private XPath2FilterContainer(Element element, String baseURI) throws XMLSecurityException {
 
-        super(element, BaseURI);
+        super(element, baseURI);
 
-        String filterStr =
-            this.constructionElement.getAttributeNS(null, XPath2FilterContainer._ATT_FILTER);
+        String filterStr = getLocalAttribute(XPath2FilterContainer._ATT_FILTER);
 
         if (!filterStr.equals(XPath2FilterContainer._ATT_FILTER_VALUE_INTERSECT)
             && !filterStr.equals(XPath2FilterContainer._ATT_FILTER_VALUE_SUBTRACT)
@@ -179,7 +176,7 @@
 
             if (!(type.equals(XPath2FilterContainer._ATT_FILTER_VALUE_INTERSECT)
                 || type.equals(XPath2FilterContainer._ATT_FILTER_VALUE_SUBTRACT)
-                || type.equals(XPath2FilterContainer._ATT_FILTER_VALUE_UNION))){
+                || type.equals(XPath2FilterContainer._ATT_FILTER_VALUE_UNION))) {
                 throw new IllegalArgumentException("The type(" + i + ")=\"" + type
                                                    + "\" is illegal");
             }
@@ -197,47 +194,44 @@
      * Creates a XPath2FilterContainer from an existing Element; needed for verification.
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @return the filter
      *
      * @throws XMLSecurityException
      */
     public static XPath2FilterContainer newInstance(
-        Element element, String BaseURI
+        Element element, String baseURI
     ) throws XMLSecurityException {
-        return new XPath2FilterContainer(element, BaseURI);
+        return new XPath2FilterContainer(element, baseURI);
     }
 
     /**
-     * Returns <code>true</code> if the <code>Filter</code> attribute has value "intersect".
+     * Returns {@code true} if the {@code Filter} attribute has value "intersect".
      *
-     * @return <code>true</code> if the <code>Filter</code> attribute has value "intersect".
+     * @return {@code true} if the {@code Filter} attribute has value "intersect".
      */
     public boolean isIntersect() {
-        return this.constructionElement.getAttributeNS(
-            null, XPath2FilterContainer._ATT_FILTER
+        return getLocalAttribute(XPath2FilterContainer._ATT_FILTER
         ).equals(XPath2FilterContainer._ATT_FILTER_VALUE_INTERSECT);
     }
 
     /**
-     * Returns <code>true</code> if the <code>Filter</code> attribute has value "subtract".
+     * Returns {@code true} if the {@code Filter} attribute has value "subtract".
      *
-     * @return <code>true</code> if the <code>Filter</code> attribute has value "subtract".
+     * @return {@code true} if the {@code Filter} attribute has value "subtract".
      */
     public boolean isSubtract() {
-        return this.constructionElement.getAttributeNS(
-            null, XPath2FilterContainer._ATT_FILTER
+        return getLocalAttribute(XPath2FilterContainer._ATT_FILTER
         ).equals(XPath2FilterContainer._ATT_FILTER_VALUE_SUBTRACT);
     }
 
     /**
-     * Returns <code>true</code> if the <code>Filter</code> attribute has value "union".
+     * Returns {@code true} if the {@code Filter} attribute has value "union".
      *
-     * @return <code>true</code> if the <code>Filter</code> attribute has value "union".
+     * @return {@code true} if the {@code Filter} attribute has value "union".
      */
     public boolean isUnion() {
-        return this.constructionElement.getAttributeNS(
-            null, XPath2FilterContainer._ATT_FILTER
+        return getLocalAttribute(XPath2FilterContainer._ATT_FILTER
         ).equals(XPath2FilterContainer._ATT_FILTER_VALUE_UNION);
     }
 
@@ -255,18 +249,15 @@
      * Filter String. We must use this stupid hook to enable the here() function
      * to work.
      *
-     * $todo$ I dunno whether this crashes: <XPath> here()<!-- comment -->/ds:Signature[1]</XPath>
      * @return the first Text node which contains information from the XPath 2 Filter String
      */
     public Node getXPathFilterTextNode() {
-
-        NodeList children = this.constructionElement.getChildNodes();
-        int length = children.getLength();
-
-        for (int i = 0; i < length; i++) {
-            if (children.item(i).getNodeType() == Node.TEXT_NODE) {
-                return children.item(i);
+        Node childNode = getElement().getFirstChild();
+        while (childNode != null) {
+            if (childNode.getNodeType() == Node.TEXT_NODE) {
+                return childNode;
             }
+            childNode = childNode.getNextSibling();
         }
 
         return null;
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/XPath2FilterContainer04.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/XPath2FilterContainer04.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,17 +25,14 @@
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import com.sun.org.apache.xml.internal.security.transforms.TransformParam;
 import com.sun.org.apache.xml.internal.security.utils.ElementProxy;
-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.NodeList;
 
 /**
  * Implements the parameters for the <A
  * HREF="http://www.w3.org/TR/xmldsig-filter2/">XPath Filter v2.0</A>.
  *
- * @author $Author: coheigea $
  * @see <A HREF="http://www.w3.org/TR/xmldsig-filter2/">XPath Filter v2.0 (TR)</A>
  */
 public class XPath2FilterContainer04 extends ElementProxy implements TransformParam {
@@ -78,16 +75,15 @@
     private XPath2FilterContainer04(Document doc, String xpath2filter, String filterType) {
         super(doc);
 
-        this.constructionElement.setAttributeNS(
-            null, XPath2FilterContainer04._ATT_FILTER, filterType);
+        setLocalAttribute(XPath2FilterContainer04._ATT_FILTER, filterType);
 
-        if ((xpath2filter.length() > 2)
-            && (!Character.isWhitespace(xpath2filter.charAt(0)))) {
-            XMLUtils.addReturnToElement(this.constructionElement);
-            this.constructionElement.appendChild(doc.createTextNode(xpath2filter));
-            XMLUtils.addReturnToElement(this.constructionElement);
+        if (xpath2filter.length() > 2
+            && !Character.isWhitespace(xpath2filter.charAt(0))) {
+            addReturnToSelf();
+            appendSelf(createText(xpath2filter));
+            addReturnToSelf();
         } else {
-            this.constructionElement.appendChild(doc.createTextNode(xpath2filter));
+            appendSelf(createText(xpath2filter));
         }
     }
 
@@ -95,16 +91,15 @@
      * Constructor XPath2FilterContainer04
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    private XPath2FilterContainer04(Element element, String BaseURI)
+    private XPath2FilterContainer04(Element element, String baseURI)
         throws XMLSecurityException {
 
-        super(element, BaseURI);
+        super(element, baseURI);
 
-        String filterStr =
-            this.constructionElement.getAttributeNS(null, XPath2FilterContainer04._ATT_FILTER);
+        String filterStr = getLocalAttribute(XPath2FilterContainer04._ATT_FILTER);
 
         if (!filterStr.equals(XPath2FilterContainer04._ATT_FILTER_VALUE_INTERSECT)
             && !filterStr.equals(XPath2FilterContainer04._ATT_FILTER_VALUE_SUBTRACT)
@@ -166,47 +161,44 @@
      * Creates a XPath2FilterContainer04 from an existing Element; needed for verification.
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @return the instance
      *
      * @throws XMLSecurityException
      */
     public static XPath2FilterContainer04 newInstance(
-        Element element, String BaseURI
+        Element element, String baseURI
     ) throws XMLSecurityException {
-        return new XPath2FilterContainer04(element, BaseURI);
+        return new XPath2FilterContainer04(element, baseURI);
     }
 
     /**
-     * Returns <code>true</code> if the <code>Filter</code> attribute has value "intersect".
+     * Returns {@code true} if the {@code Filter} attribute has value "intersect".
      *
-     * @return <code>true</code> if the <code>Filter</code> attribute has value "intersect".
+     * @return {@code true} if the {@code Filter} attribute has value "intersect".
      */
     public boolean isIntersect() {
-        return this.constructionElement.getAttributeNS(
-            null, XPath2FilterContainer04._ATT_FILTER
+        return getLocalAttribute(XPath2FilterContainer04._ATT_FILTER
         ).equals(XPath2FilterContainer04._ATT_FILTER_VALUE_INTERSECT);
     }
 
     /**
-     * Returns <code>true</code> if the <code>Filter</code> attribute has value "subtract".
+     * Returns {@code true} if the {@code Filter} attribute has value "subtract".
      *
-     * @return <code>true</code> if the <code>Filter</code> attribute has value "subtract".
+     * @return {@code true} if the {@code Filter} attribute has value "subtract".
      */
     public boolean isSubtract() {
-        return this.constructionElement.getAttributeNS(
-            null, XPath2FilterContainer04._ATT_FILTER
+        return getLocalAttribute(XPath2FilterContainer04._ATT_FILTER
         ).equals(XPath2FilterContainer04._ATT_FILTER_VALUE_SUBTRACT);
     }
 
     /**
-     * Returns <code>true</code> if the <code>Filter</code> attribute has value "union".
+     * Returns {@code true} if the {@code Filter} attribute has value "union".
      *
-     * @return <code>true</code> if the <code>Filter</code> attribute has value "union".
+     * @return {@code true} if the {@code Filter} attribute has value "union".
      */
     public boolean isUnion() {
-        return this.constructionElement.getAttributeNS(
-            null, XPath2FilterContainer04._ATT_FILTER
+        return getLocalAttribute(XPath2FilterContainer04._ATT_FILTER
         ).equals(XPath2FilterContainer04._ATT_FILTER_VALUE_UNION);
     }
 
@@ -224,28 +216,26 @@
      * Filter String. We must use this stupid hook to enable the here() function
      * to work.
      *
-     * $todo$ I dunno whether this crashes: <XPath> here()<!-- comment -->/ds:Signature[1]</XPath>
      * @return the first Text node which contains information from the XPath 2 Filter String
      */
     public Node getXPathFilterTextNode() {
-        NodeList children = this.constructionElement.getChildNodes();
-        int length = children.getLength();
-
-        for (int i = 0; i < length; i++) {
-            if (children.item(i).getNodeType() == Node.TEXT_NODE) {
-                return children.item(i);
+        Node childNode = getElement().getFirstChild();
+        while (childNode != null) {
+            if (childNode.getNodeType() == Node.TEXT_NODE) {
+                return childNode;
             }
+            childNode = childNode.getNextSibling();
         }
 
         return null;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public final String getBaseLocalName() {
         return XPath2FilterContainer04._TAG_XPATH2;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public final String getBaseNamespace() {
         return XPath2FilterContainer04.XPathFilter2NS;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/XPathContainer.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/XPathContainer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -27,15 +27,14 @@
 import com.sun.org.apache.xml.internal.security.utils.Constants;
 import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy;
 import org.w3c.dom.Document;
-import org.w3c.dom.NodeList;
+import org.w3c.dom.Node;
 import org.w3c.dom.Text;
 
 /**
  * This Object serves both as namespace prefix resolver and as container for
- * the <CODE>ds:XPath</CODE> Element. It implements the {@link org.w3c.dom.Element} interface
+ * the {@code ds:XPath} Element. It implements the {@link org.w3c.dom.Element} interface
  * and can be used directly in a DOM tree.
  *
- * @author Christian Geuer-Pollmann
  */
 public class XPathContainer extends SignatureElementProxy implements TransformParam {
 
@@ -49,33 +48,32 @@
     }
 
     /**
-     * Sets the TEXT value of the <CODE>ds:XPath</CODE> Element.
+     * Sets the TEXT value of the {@code ds:XPath} Element.
      *
      * @param xpath
      */
     public void setXPath(String xpath) {
-        if (this.constructionElement.getChildNodes() != null) {
-            NodeList nl = this.constructionElement.getChildNodes();
-
-            for (int i = 0; i < nl.getLength(); i++) {
-                this.constructionElement.removeChild(nl.item(i));
-            }
+        Node childNode = getElement().getFirstChild();
+        while (childNode != null) {
+            Node nodeToBeRemoved = childNode;
+            childNode = childNode.getNextSibling();
+            getElement().removeChild(nodeToBeRemoved);
         }
 
-        Text xpathText = this.doc.createTextNode(xpath);
-        this.constructionElement.appendChild(xpathText);
+        Text xpathText = createText(xpath);
+        appendSelf(xpathText);
     }
 
     /**
-     * Returns the TEXT value of the <CODE>ds:XPath</CODE> Element.
+     * Returns the TEXT value of the {@code ds:XPath} Element.
      *
-     * @return the TEXT value of the <CODE>ds:XPath</CODE> Element.
+     * @return the TEXT value of the {@code ds:XPath} Element.
      */
     public String getXPath() {
         return this.getTextFromTextChild();
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseLocalName() {
         return Constants._TAG_XPATH;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/XPathFilterCHGPContainer.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/XPathFilterCHGPContainer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -35,7 +35,6 @@
  * Implements the parameters for a custom Transform which has a better performance
  * than the xfilter2.
  *
- * @author $Author: coheigea $
  */
 public class XPathFilterCHGPContainer extends ElementProxy implements TransformParam {
 
@@ -87,52 +86,48 @@
         super(doc);
 
         if (includeSlashPolicy) {
-            this.constructionElement.setAttributeNS(
-                null, XPathFilterCHGPContainer._ATT_INCLUDESLASH, "true"
-            );
+            setLocalAttribute(XPathFilterCHGPContainer._ATT_INCLUDESLASH, "true");
         } else {
-            this.constructionElement.setAttributeNS(
-                null, XPathFilterCHGPContainer._ATT_INCLUDESLASH, "false"
-            );
+            setLocalAttribute(XPathFilterCHGPContainer._ATT_INCLUDESLASH, "false");
         }
 
-        if ((includeButSearch != null) && (includeButSearch.trim().length() > 0)) {
+        if (includeButSearch != null && includeButSearch.trim().length() > 0) {
             Element includeButSearchElem =
                 ElementProxy.createElementForFamily(
                     doc, this.getBaseNamespace(), XPathFilterCHGPContainer._TAG_INCLUDE_BUT_SEARCH
                 );
 
             includeButSearchElem.appendChild(
-                this.doc.createTextNode(indentXPathText(includeButSearch))
+                createText(indentXPathText(includeButSearch))
             );
-            XMLUtils.addReturnToElement(this.constructionElement);
-            this.constructionElement.appendChild(includeButSearchElem);
+            addReturnToSelf();
+            appendSelf(includeButSearchElem);
         }
 
-        if ((excludeButSearch != null) && (excludeButSearch.trim().length() > 0)) {
+        if (excludeButSearch != null && excludeButSearch.trim().length() > 0) {
             Element excludeButSearchElem =
                 ElementProxy.createElementForFamily(
                     doc, this.getBaseNamespace(), XPathFilterCHGPContainer._TAG_EXCLUDE_BUT_SEARCH
                 );
 
             excludeButSearchElem.appendChild(
-                this.doc.createTextNode(indentXPathText(excludeButSearch)));
+                createText(indentXPathText(excludeButSearch)));
 
-            XMLUtils.addReturnToElement(this.constructionElement);
-            this.constructionElement.appendChild(excludeButSearchElem);
+            addReturnToSelf();
+            appendSelf(excludeButSearchElem);
         }
 
-        if ((exclude != null) && (exclude.trim().length() > 0)) {
+        if (exclude != null && exclude.trim().length() > 0) {
             Element excludeElem =
                 ElementProxy.createElementForFamily(
                    doc, this.getBaseNamespace(), XPathFilterCHGPContainer._TAG_EXCLUDE);
 
-            excludeElem.appendChild(this.doc.createTextNode(indentXPathText(exclude)));
-            XMLUtils.addReturnToElement(this.constructionElement);
-            this.constructionElement.appendChild(excludeElem);
+            excludeElem.appendChild(createText(indentXPathText(exclude)));
+            addReturnToSelf();
+            appendSelf(excludeElem);
         }
 
-        XMLUtils.addReturnToElement(this.constructionElement);
+        addReturnToSelf();
     }
 
     /**
@@ -142,7 +137,7 @@
      * @return the string with enters
      */
     static String indentXPathText(String xp) {
-        if ((xp.length() > 2) && (!Character.isWhitespace(xp.charAt(0)))) {
+        if (xp.length() > 2 && !Character.isWhitespace(xp.charAt(0))) {
             return "\n" + xp + "\n";
         }
         return xp;
@@ -152,12 +147,12 @@
      * Constructor XPathFilterCHGPContainer
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    private XPathFilterCHGPContainer(Element element, String BaseURI)
+    private XPathFilterCHGPContainer(Element element, String baseURI)
         throws XMLSecurityException {
-        super(element, BaseURI);
+        super(element, baseURI);
     }
 
     /**
@@ -182,15 +177,15 @@
      * Creates a XPathFilterCHGPContainer from an existing Element; needed for verification.
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      *
      * @throws XMLSecurityException
      * @return the created object.
      */
     public static XPathFilterCHGPContainer getInstance(
-        Element element, String BaseURI
+        Element element, String baseURI
     ) throws XMLSecurityException {
-        return new XPathFilterCHGPContainer(element, BaseURI);
+        return new XPathFilterCHGPContainer(element, baseURI);
     }
 
     /**
@@ -206,7 +201,7 @@
 
         Element xElem =
             XMLUtils.selectNode(
-                this.constructionElement.getFirstChild(), this.getBaseNamespace(), type, 0
+                getElement().getFirstChild(), this.getBaseNamespace(), type, 0
             );
 
         return XMLUtils.getFullTextChildrenFromElement(xElem);
@@ -245,8 +240,7 @@
      * @return the string
      */
     public boolean getIncludeSlashPolicy() {
-        return this.constructionElement.getAttributeNS(
-            null, XPathFilterCHGPContainer._ATT_INCLUDESLASH).equals("true");
+        return getLocalAttribute(XPathFilterCHGPContainer._ATT_INCLUDESLASH).equals("true");
     }
 
     /**
@@ -265,7 +259,7 @@
         }
 
         return XMLUtils.selectNodeText(
-            this.constructionElement.getFirstChild(), this.getBaseNamespace(), type, 0
+            getFirstChild(), this.getBaseNamespace(), type, 0
         );
     }
 
@@ -299,7 +293,7 @@
     /**
      * Method getBaseLocalName
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     public final String getBaseLocalName() {
         return XPathFilterCHGPContainer._TAG_XPATHCHGP;
@@ -308,7 +302,7 @@
     /**
      * Method getBaseNamespace
      *
-     * @inheritDoc
+     * {@inheritDoc}
      */
     public final String getBaseNamespace() {
         return TRANSFORM_XPATHFILTERCHGP;
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java	Sat Oct 24 01:11:51 2020 +0100
@@ -39,12 +39,10 @@
  * Optimized code. (raw version taken from oreilly.jonathan.util,
  * and currently org.apache.xerces.ds.util.Base64)
  *
- * @author Raul Benito(Of the xerces copy, and little adaptations).
- * @author Anli Shundi
- * @author Christian Geuer-Pollmann
  * @see <A HREF="ftp://ftp.isi.edu/in-notes/rfc2045.txt">RFC 2045</A>
  * @see com.sun.org.apache.xml.internal.security.transforms.implementations.TransformBase64Decode
  */
+@Deprecated
 public class Base64 {
 
     /** Field BASE64DEFAULTLENGTH */
@@ -105,9 +103,9 @@
      * <b>N.B.:</B> <code>{@link BigInteger}<code>'s toByteArray
      * returns eventually longer arrays because of the leading sign-bit.
      *
-     * @param big <code>BigInteger<code> to be converted
-     * @param bitlen <code>int<code> the desired length in bits of the representation
-     * @return a byte array with <code>bitlen</code> bits of <code>big</code>
+     * @param big {@code BigInteger} to be converted
+     * @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) {
 
@@ -120,8 +118,8 @@
 
         byte[] bigBytes = big.toByteArray();
 
-        if (((big.bitLength() % 8) != 0)
-            && (((big.bitLength() / 8) + 1) == (bitlen / 8))) {
+        if (big.bitLength() % 8 != 0
+            && big.bitLength() / 8 + 1 == bitlen / 8) {
             return bigBytes;
         }
 
@@ -129,7 +127,7 @@
         int startSrc = 0;    // no need to skip anything
         int bigLen = bigBytes.length;    //valid length of the string
 
-        if ((big.bitLength() % 8) == 0) {    // correct values
+        if (big.bitLength() % 8 == 0) {    // correct values
             startSrc = 1;    // skip sign bit
 
             bigLen--;    // valid length of the string
@@ -144,27 +142,28 @@
     }
 
     /**
-     * Encode in Base64 the given <code>{@link BigInteger}<code>.
+     * Encode in Base64 the given {@code {@link BigInteger}}.
      *
      * @param big
      * @return String with Base64 encoding
      */
     public static final String encode(BigInteger big) {
-        return encode(getBytes(big, big.bitLength()));
+        byte[] bytes = XMLUtils.getBytes(big, big.bitLength());
+        return XMLUtils.encodeToString(bytes);
     }
 
     /**
-     * Returns a byte-array representation of a <code>{@link BigInteger}<code>.
+     * Returns a byte-array representation of a {@code {@link BigInteger}}.
      * No sign-bit is output.
      *
-     * <b>N.B.:</B> <code>{@link BigInteger}<code>'s toByteArray
+     * <b>N.B.:</B> {@code {@link BigInteger}}'s toByteArray
      * returns eventually longer arrays because of the leading sign-bit.
      *
-     * @param big <code>BigInteger<code> to be converted
-     * @param bitlen <code>int<code> the desired length in bits of the representation
-     * @return a byte array with <code>bitlen</code> bits of <code>big</code>
+     * @param big {@code BigInteger} to be converted
+     * @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 final byte[] encode(BigInteger big, int bitlen) {
 
         //round bitlen
         bitlen = ((bitlen + 7) >> 3) << 3;
@@ -175,8 +174,8 @@
 
         byte[] bigBytes = big.toByteArray();
 
-        if (((big.bitLength() % 8) != 0)
-            && (((big.bitLength() / 8) + 1) == (bitlen / 8))) {
+        if (big.bitLength() % 8 != 0
+            && big.bitLength() / 8 + 1 == bitlen / 8) {
             return bigBytes;
         }
 
@@ -184,7 +183,7 @@
         int startSrc = 0;    // no need to skip anything
         int bigLen = bigBytes.length;    //valid length of the string
 
-        if ((big.bitLength() % 8) == 0) {    // correct values
+        if (big.bitLength() % 8 == 0) {    // correct values
             startSrc = 1;    // skip sign bit
 
             bigLen--;    // valid length of the string
@@ -211,10 +210,9 @@
     }
 
     /**
-     * Method decodeBigIntegerFromText
-     *
-     * @param text
-     * @return the biginter obtained from the text node
+     * Decode a base 64 string into a {@link BigInteger}
+     * @param base64str Base 64 encoded string.
+     * @return a decoded BigInteger
      * @throws Base64DecodingException
      */
     public static final BigInteger decodeBigIntegerFromText(Text text)
@@ -246,8 +244,8 @@
     /**
      * Method decode
      *
-     * Takes the <CODE>Text</CODE> children of the Element and interprets
-     * them as input for the <CODE>Base64.decode()</CODE> function.
+     * Takes the {@code Text} children of the Element and interprets
+     * them as input for the {@code Base64.decode()} function.
      *
      * @param element
      * @return the byte obtained of the decoding the element
@@ -305,8 +303,8 @@
      * Encode a byte array and fold lines at the standard 76th character unless
      * ignore line breaks property is set.
      *
-     * @param binaryData <code>byte[]<code> to be base64 encoded
-     * @return the <code>String<code> with encoded data
+     * @param binaryData {@code byte[]} to be base64 encoded
+     * @return the {@code String} with encoded data
      */
     public static final String encode(byte[] binaryData) {
         return XMLUtils.ignoreLineBreaks()
@@ -328,11 +326,9 @@
         throws IOException, Base64DecodingException {
 
         byte[] retBytes = null;
-        UnsyncByteArrayOutputStream baos = null;
+        UnsyncByteArrayOutputStream baos = new UnsyncByteArrayOutputStream();
         try {
-            baos = new UnsyncByteArrayOutputStream();
             String line;
-
             while (null != (line = reader.readLine())) {
                 byte[] bytes = decode(line);
                 baos.write(bytes);
@@ -345,12 +341,12 @@
         return retBytes;
     }
 
-    protected static final boolean isWhiteSpace(byte octect) {
-        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
+    protected static final boolean isWhiteSpace(byte octet) {
+        return octet == 0x20 || octet == 0xd || octet == 0xa || octet == 0x9;
     }
 
-    protected static final boolean isPad(byte octect) {
-        return (octect == PAD);
+    protected static final boolean isPad(byte octet) {
+        return octet == PAD;
     }
 
     /**
@@ -363,11 +359,11 @@
      * Encode a byte array in Base64 format and return an optionally
      * wrapped line.
      *
-     * @param binaryData <code>byte[]</code> data to be encoded
-     * @param length <code>int<code> length of wrapped lines; No wrapping if less than 4.
-     * @return a <code>String</code> with encoded data
+     * @param binaryData {@code byte[]} data to be encoded
+     * @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 final String  encode(byte[] binaryData, int length) {
         if (length < 4) {
             length = Integer.MAX_VALUE;
         }
@@ -381,14 +377,14 @@
             return "";
         }
 
-        long fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+        long fewerThan24bits = lengthDataBits % ((long) TWENTYFOURBITGROUP);
         int numberTriplets = (int) (lengthDataBits / TWENTYFOURBITGROUP);
         int numberQuartet = fewerThan24bits != 0L ? numberTriplets + 1 : numberTriplets;
         int quartesPerLine = length / 4;
         int numberLines = (numberQuartet - 1) / quartesPerLine;
         char encodedData[] = null;
 
-        encodedData = new char[numberQuartet * 4 + numberLines];
+        encodedData = new char[numberQuartet * 4 + numberLines * 2];
 
         byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
         int encodedIndex = 0;
@@ -401,8 +397,8 @@
                 b2 = binaryData[dataIndex++];
                 b3 = binaryData[dataIndex++];
 
-                l  = (byte)(b2 & 0x0f);
-                k  = (byte)(b1 & 0x03);
+                l = (byte)(b2 & 0x0f);
+                k = (byte)(b1 & 0x03);
 
                 byte val1 = ((b1 & SIGN) == 0) ? (byte)(b1 >> 2): (byte)((b1) >> 2 ^ 0xc0);
 
@@ -417,6 +413,7 @@
 
                 i++;
             }
+            encodedData[encodedIndex++] = 0xd;
             encodedData[encodedIndex++] = 0xa;
         }
 
@@ -425,8 +422,8 @@
             b2 = binaryData[dataIndex++];
             b3 = binaryData[dataIndex++];
 
-            l  = (byte)(b2 & 0x0f);
-            k  = (byte)(b1 & 0x03);
+            l = (byte)(b2 & 0x0f);
+            k = (byte)(b1 & 0x03);
 
             byte val1 = ((b1 & SIGN) == 0) ? (byte)(b1 >> 2) : (byte)((b1) >> 2 ^ 0xc0);
 
@@ -510,7 +507,7 @@
             //should be divisible by four
         }
 
-        int numberQuadruple = (len / FOURBYTE);
+        int numberQuadruple = len / FOURBYTE;
 
         if (numberQuadruple == 0) {
             return new byte[0];
@@ -529,7 +526,7 @@
         //first last bits.
         b1 = base64Alphabet[base64Data[dataIndex++]];
         b2 = base64Alphabet[base64Data[dataIndex++]];
-        if ((b1==-1) || (b2==-1)) {
+        if (b1 == -1 || b2 == -1) {
              //if found "no data" just return null
             throw new Base64DecodingException("decoding.general");
         }
@@ -538,7 +535,7 @@
         byte d3, d4;
         b3 = base64Alphabet[d3 = base64Data[dataIndex++]];
         b4 = base64Alphabet[d4 = base64Data[dataIndex++]];
-        if ((b3 == -1) || (b4 == -1) ) {
+        if (b3 == -1 || b4 == -1) {
             //Check if they are PAD characters
             if (isPad(d3) && isPad(d4)) {               //Two PAD e.g. 3c[Pad][Pad]
                 if ((b2 & 0xf) != 0) { //last 4 bits should be zero
@@ -573,10 +570,7 @@
             b3 = base64Alphabet[base64Data[dataIndex++]];
             b4 = base64Alphabet[base64Data[dataIndex++]];
 
-            if ((b1 == -1) ||
-                (b2 == -1) ||
-                (b3 == -1) ||
-                (b4 == -1)) {
+            if (b1 == -1 || b2 == -1 || b3 == -1 || b4 == -1) {
                 //if found "no data" just return null
                 throw new Base64DecodingException("decoding.general");
             }
@@ -600,7 +594,7 @@
         throws Base64DecodingException, IOException {
         byte[] bytes = new byte[base64Data.length()];
         int len = getBytesInternal(base64Data, bytes);
-        decode(bytes,os,len);
+        decode(bytes, os, len);
     }
 
     /**
@@ -613,7 +607,7 @@
      */
     public static final void decode(byte[] base64Data, OutputStream os)
         throws Base64DecodingException, IOException {
-        decode(base64Data,os,-1);
+        decode(base64Data, os, -1);
     }
 
     protected static final void decode(byte[] base64Data, OutputStream os, int len)
@@ -628,7 +622,7 @@
             //should be divisible by four
         }
 
-        int numberQuadruple = (len / FOURBYTE);
+        int numberQuadruple = len / FOURBYTE;
 
         if (numberQuadruple == 0) {
             return;
@@ -641,28 +635,25 @@
         int dataIndex = 0;
 
         //the begin
-        for (i=numberQuadruple - 1; i > 0; i--) {
+        for (i = numberQuadruple - 1; i > 0; i--) {
             b1 = base64Alphabet[base64Data[dataIndex++]];
             b2 = base64Alphabet[base64Data[dataIndex++]];
             b3 = base64Alphabet[base64Data[dataIndex++]];
             b4 = base64Alphabet[base64Data[dataIndex++]];
-            if ((b1 == -1) ||
-                (b2 == -1) ||
-                (b3 == -1) ||
-                (b4 == -1) ) {
+            if (b1 == -1 || b2 == -1 || b3 == -1 || b4 == -1) {
                 //if found "no data" just return null
                 throw new Base64DecodingException("decoding.general");
             }
 
             os.write((byte)(b1 << 2 | b2 >> 4));
             os.write((byte)(((b2 & 0xf) << 4 ) | ((b3 >> 2) & 0xf)));
-            os.write( (byte)(b3 << 6 | b4));
+            os.write((byte)(b3 << 6 | b4));
         }
         b1 = base64Alphabet[base64Data[dataIndex++]];
         b2 = base64Alphabet[base64Data[dataIndex++]];
 
         //  first last bits.
-        if ((b1 == -1) || (b2 == -1) ) {
+        if (b1 == -1 || b2 == -1) {
             //if found "no data" just return null
             throw new Base64DecodingException("decoding.general");
         }
@@ -670,7 +661,7 @@
         byte d3, d4;
         b3 = base64Alphabet[d3 = base64Data[dataIndex++]];
         b4 = base64Alphabet[d4 = base64Data[dataIndex++]];
-        if ((b3 == -1 ) || (b4 == -1) ) { //Check if they are PAD characters
+        if (b3 == -1 || b4 == -1) { //Check if they are PAD characters
             if (isPad(d3) && isPad(d4)) {               //Two PAD e.g. 3c[Pad][Pad]
                 if ((b2 & 0xf) != 0) { //last 4 bits should be zero
                     throw new Base64DecodingException("decoding.general");
@@ -707,7 +698,7 @@
         //byte decodedData[] = null;
         byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
 
-        int index=0;
+        int index = 0;
         byte[] data = new byte[4];
         int read;
         //the begin
@@ -748,7 +739,7 @@
         b2 = base64Alphabet[d2];
         b3 = base64Alphabet[d3];
         b4 = base64Alphabet[d4];
-        if ((b3 == -1) || (b4 == -1)) { //Check if they are PAD characters
+        if (b3 == -1 || b4 == -1) { //Check if they are PAD characters
             if (isPad(d3) && isPad(d4)) {               //Two PAD e.g. 3c[Pad][Pad]
                 if ((b2 & 0xf) != 0) { //last 4 bits should be zero
                     throw new Base64DecodingException("decoding.general");
@@ -777,7 +768,7 @@
      * remove WhiteSpace from MIME containing encoded Base64 data.
      *
      * @param data  the byte array of base64 data (with WS)
-     * @return      the new length
+     * @return the new length
      */
     protected static final int removeWhiteSpace(byte[] data) {
         if (data == null) {
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ClassLoaderUtils.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ClassLoaderUtils.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,208 +23,22 @@
 
 package com.sun.org.apache.xml.internal.security.utils;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-
 /**
- * This class is extremely useful for loading resources and classes in a fault
+ * This class is extremely useful for loading classes in a fault
  * tolerant manner that works across different applications servers. Do not
  * touch this unless you're a grizzled classloading guru veteran who is going to
  * verify any change on 6 different application servers.
  */
 final class ClassLoaderUtils {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static final java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(ClassLoaderUtils.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ClassLoaderUtils.class);
 
     private ClassLoaderUtils() {
     }
 
     /**
-     * Load a given resource. <p/> This method will try to load the resource
-     * using the following methods (in order):
-     * <ul>
-     * <li>From Thread.currentThread().getContextClassLoader()
-     * <li>From ClassLoaderUtil.class.getClassLoader()
-     * <li>callingClass.getClassLoader()
-     * </ul>
-     *
-     * @param resourceName The name of the resource to load
-     * @param callingClass The Class object of the calling object
-     */
-    static URL getResource(String resourceName, Class<?> callingClass) {
-        URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
-        if (url == null && resourceName.startsWith("/")) {
-            //certain classloaders need it without the leading /
-            url =
-                Thread.currentThread().getContextClassLoader().getResource(
-                    resourceName.substring(1)
-                );
-        }
-
-        ClassLoader cluClassloader = ClassLoaderUtils.class.getClassLoader();
-        if (cluClassloader == null) {
-            cluClassloader = ClassLoader.getSystemClassLoader();
-        }
-        if (url == null) {
-            url = cluClassloader.getResource(resourceName);
-        }
-        if (url == null && resourceName.startsWith("/")) {
-            //certain classloaders need it without the leading /
-            url = cluClassloader.getResource(resourceName.substring(1));
-        }
-
-        if (url == null) {
-            ClassLoader cl = callingClass.getClassLoader();
-
-            if (cl != null) {
-                url = cl.getResource(resourceName);
-            }
-        }
-
-        if (url == null) {
-            url = callingClass.getResource(resourceName);
-        }
-
-        if ((url == null) && (resourceName != null) && (resourceName.charAt(0) != '/')) {
-            return getResource('/' + resourceName, callingClass);
-        }
-
-        return url;
-    }
-
-    /**
-     * Load a given resources. <p/> This method will try to load the resources
-     * using the following methods (in order):
-     * <ul>
-     * <li>From Thread.currentThread().getContextClassLoader()
-     * <li>From ClassLoaderUtil.class.getClassLoader()
-     * <li>callingClass.getClassLoader()
-     * </ul>
-     *
-     * @param resourceName The name of the resource to load
-     * @param callingClass The Class object of the calling object
-     */
-    static List<URL> getResources(String resourceName, Class<?> callingClass) {
-        List<URL> ret = new ArrayList<URL>();
-        Enumeration<URL> urls = new Enumeration<URL>() {
-            public boolean hasMoreElements() {
-                return false;
-            }
-            public URL nextElement() {
-                return null;
-            }
-
-        };
-        try {
-            urls = Thread.currentThread().getContextClassLoader().getResources(resourceName);
-        } catch (IOException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
-            //ignore
-        }
-        if (!urls.hasMoreElements() && resourceName.startsWith("/")) {
-            //certain classloaders need it without the leading /
-            try {
-                urls =
-                    Thread.currentThread().getContextClassLoader().getResources(
-                        resourceName.substring(1)
-                    );
-            } catch (IOException e) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                }
-                // ignore
-            }
-        }
-
-        ClassLoader cluClassloader = ClassLoaderUtils.class.getClassLoader();
-        if (cluClassloader == null) {
-            cluClassloader = ClassLoader.getSystemClassLoader();
-        }
-        if (!urls.hasMoreElements()) {
-            try {
-                urls = cluClassloader.getResources(resourceName);
-            } catch (IOException e) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                }
-                // ignore
-            }
-        }
-        if (!urls.hasMoreElements() && resourceName.startsWith("/")) {
-            //certain classloaders need it without the leading /
-            try {
-                urls = cluClassloader.getResources(resourceName.substring(1));
-            } catch (IOException e) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                }
-                // ignore
-            }
-        }
-
-        if (!urls.hasMoreElements()) {
-            ClassLoader cl = callingClass.getClassLoader();
-
-            if (cl != null) {
-                try {
-                    urls = cl.getResources(resourceName);
-                } catch (IOException e) {
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                    }
-                    // ignore
-                }
-            }
-        }
-
-        if (!urls.hasMoreElements()) {
-            URL url = callingClass.getResource(resourceName);
-            if (url != null) {
-                ret.add(url);
-            }
-        }
-        while (urls.hasMoreElements()) {
-            ret.add(urls.nextElement());
-        }
-
-
-        if (ret.isEmpty() && (resourceName != null) && (resourceName.charAt(0) != '/')) {
-            return getResources('/' + resourceName, callingClass);
-        }
-        return ret;
-    }
-
-
-    /**
-     * This is a convenience method to load a resource as a stream. <p/> The
-     * algorithm used to find the resource is given in getResource()
-     *
-     * @param resourceName The name of the resource to load
-     * @param callingClass The Class object of the calling object
-     */
-    static InputStream getResourceAsStream(String resourceName, Class<?> callingClass) {
-        URL url = getResource(resourceName, callingClass);
-
-        try {
-            return (url != null) ? url.openStream() : null;
-        } catch (IOException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
-            return null;
-        }
-    }
-
-    /**
-     * Load a class with a given name. <p/> It will try to load the class in the
+     * Load a class with a given name. <p></p> It will try to load the class in the
      * following order:
      * <ul>
      * <li>From Thread.currentThread().getContextClassLoader()
@@ -246,9 +60,7 @@
                 return cl.loadClass(className);
             }
         } catch (ClassNotFoundException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
+            LOG.debug(e.getMessage(), e);
             //ignore
         }
         return loadClass2(className, callingClass);
@@ -268,9 +80,7 @@
                     return callingClass.getClassLoader().loadClass(className);
                 }
             }
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-            }
+            LOG.debug(ex.getMessage(), ex);
             throw ex;
         }
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Constants.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Constants.java	Sat Oct 24 01:11:51 2020 +0100
@@ -29,9 +29,8 @@
  * <A HREF="http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg">XML
  * Signature specification</A>.
  *
- * @author $Author: coheigea $
  */
-public class Constants {
+public final class Constants {
 
     /** Field configurationFile */
     public static final String configurationFile = "data/websig.conf";
@@ -41,9 +40,9 @@
 
     /** Field exceptionMessagesResourceBundleDir */
     public static final String exceptionMessagesResourceBundleDir =
-        "com/sun/org/apache/xml/internal/security/resource";
+        "com.sun.org.apache.xml.internal.security/resource";
 
-    /** Field exceptionMessagesResourceBundleBase is the location of the <CODE>ResourceBundle</CODE> */
+    /** Field exceptionMessagesResourceBundleBase is the location of the {@code ResourceBundle} */
     public static final String exceptionMessagesResourceBundleBase =
         exceptionMessagesResourceBundleDir + "/" + "xmlsecurity";
 
@@ -69,6 +68,9 @@
     /** The URL for more algorithms **/
     public static final String MoreAlgorithmsSpecNS = "http://www.w3.org/2001/04/xmldsig-more#";
 
+    /** The (newer) URL for more algorithms **/
+    public static final String XML_DSIG_NS_MORE_07_05 = "http://www.w3.org/2007/05/xmldsig-more#";
+
     /** The URI for XML spec*/
     public static final String XML_LANG_SPACE_SpecNS = "http://www.w3.org/XML/1998/namespace";
 
@@ -197,7 +199,7 @@
     public static final String _TAG_P = "P";
 
     /** Tag of Element Q **/
-    public static final String _TAG_Q   = "Q";
+    public static final String _TAG_Q = "Q";
 
     /** Tag of Element G **/
     public static final String _TAG_G = "G";
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,6 +25,7 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import javax.xml.namespace.NamespaceContext;
 
@@ -37,7 +38,7 @@
  */
 public class DOMNamespaceContext implements NamespaceContext {
 
-    private Map<String, String> namespaceMap = new HashMap<String, String>();
+    private Map<String, String> namespaceMap = new HashMap<>();
 
     public DOMNamespaceContext(Node contextNode) {
         addNamespaces(contextNode);
@@ -48,10 +49,9 @@
     }
 
     public String getPrefix(String arg0) {
-        for (String key : namespaceMap.keySet()) {
-            String value = namespaceMap.get(key);
-            if (value.equals(arg0)) {
-                return key;
+        for (Entry<String, String> entry : namespaceMap.entrySet()) {
+            if (entry.getValue().equals(arg0)) {
+                return entry.getKey();
             }
         }
         return null;
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/DigesterOutputStream.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/DigesterOutputStream.java	Sat Oct 24 01:11:51 2020 +0100
@@ -27,12 +27,11 @@
 import com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm;
 
 /**
- * @author raul
  *
  */
 public class DigesterOutputStream extends ByteArrayOutputStream {
-    private static final java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(DigesterOutputStream.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(DigesterOutputStream.class);
 
     final MessageDigestAlgorithm mda;
 
@@ -43,25 +42,25 @@
         this.mda = mda;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public void write(byte[] arg0) {
         write(arg0, 0, arg0.length);
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public void write(int arg0) {
         mda.update((byte)arg0);
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public void write(byte[] arg0, int arg1, int arg2) {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Pre-digested input:");
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Pre-digested input:");
             StringBuilder sb = new StringBuilder(arg2);
             for (int i = arg1; i < (arg1 + arg2); i++) {
                 sb.append((char)arg0[i]);
             }
-            log.log(java.util.logging.Level.FINE, sb.toString());
+            LOG.debug(sb.toString());
         }
         mda.update(arg0, arg1, arg2);
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementChecker.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * 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.utils;
-
-import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**@deprecated*/
-@Deprecated
-public interface ElementChecker {
-    /**
-     * Check that the element is the one expect
-     *
-     * @throws XMLSecurityException
-     */
-    void guaranteeThatElementInCorrectSpace(ElementProxy expected, Element actual)
-        throws XMLSecurityException;
-
-    boolean isNamespaceElement(Node el, String type, String ns);
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementCheckerImpl.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * 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.utils;
-
-import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**@deprecated*/
-@Deprecated
-public abstract class ElementCheckerImpl implements ElementChecker {
-
-    public boolean isNamespaceElement(Node el, String type, String ns) {
-        if ((el == null) ||
-            ns != el.getNamespaceURI() || !el.getLocalName().equals(type)){
-            return false;
-        }
-
-        return true;
-    }
-
-    /** A checker for DOM that interns NS */
-    public static class InternedNsChecker extends ElementCheckerImpl {
-        public void guaranteeThatElementInCorrectSpace(
-            ElementProxy expected, Element actual
-        ) throws XMLSecurityException {
-
-            String expectedLocalname = expected.getBaseLocalName();
-            String expectedNamespace = expected.getBaseNamespace();
-
-            String localnameIS = actual.getLocalName();
-            String namespaceIS = actual.getNamespaceURI();
-            if ((expectedNamespace != namespaceIS) ||
-                !expectedLocalname.equals(localnameIS)) {
-                Object exArgs[] = { namespaceIS + ":" + localnameIS,
-                                    expectedNamespace + ":" + expectedLocalname};
-                throw new XMLSecurityException("xml.WrongElement", exArgs);
-            }
-        }
-    }
-
-    /** A checker for DOM that interns NS */
-    public static class FullChecker extends ElementCheckerImpl {
-
-        public void guaranteeThatElementInCorrectSpace(
-            ElementProxy expected, Element actual
-        ) throws XMLSecurityException {
-            String expectedLocalname = expected.getBaseLocalName();
-            String expectedNamespace = expected.getBaseNamespace();
-
-            String localnameIS = actual.getLocalName();
-            String namespaceIS = actual.getNamespaceURI();
-            if ((!expectedNamespace.equals(namespaceIS)) ||
-                !expectedLocalname.equals(localnameIS) ) {
-                Object exArgs[] = { namespaceIS + ":" + localnameIS,
-                                    expectedNamespace + ":" + expectedLocalname};
-                throw new XMLSecurityException("xml.WrongElement", exArgs);
-            }
-        }
-    }
-
-    /** An empty checker if schema checking is used */
-    public static class EmptyChecker extends ElementCheckerImpl {
-        public void guaranteeThatElementInCorrectSpace(
-            ElementProxy expected, Element actual
-        ) throws XMLSecurityException {
-            // empty
-        }
-    }
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java	Sat Oct 24 01:11:51 2020 +0100
@@ -24,9 +24,9 @@
 
 import java.math.BigInteger;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.Base64;
 import java.util.Map;
 
-import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
@@ -41,17 +41,19 @@
  */
 public abstract class ElementProxy {
 
-    protected static final java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(ElementProxy.class.getName());
+    protected static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ElementProxy.class);
 
-    /** Field constructionElement */
-    protected Element constructionElement = null;
+    /**
+     * What XML element does this ElementProxy instance wrap?
+     */
+    private Element wrappedElement;
 
     /** Field baseURI */
-    protected String baseURI = null;
+    protected String baseURI;
 
     /** Field doc */
-    protected Document doc = null;
+    private Document wrappedDoc;
 
     /** Field prefixMappings */
     private static Map<String, String> prefixMappings = new ConcurrentHashMap<String, String>();
@@ -73,30 +75,26 @@
             throw new RuntimeException("Document is null");
         }
 
-        this.doc = doc;
-        this.constructionElement =
-            createElementForFamilyLocal(this.doc, this.getBaseNamespace(), this.getBaseLocalName());
+        this.wrappedDoc = doc;
+        this.wrappedElement = createElementForFamilyLocal(this.getBaseNamespace(), this.getBaseLocalName());
     }
 
     /**
      * Constructor ElementProxy
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public ElementProxy(Element element, String BaseURI) throws XMLSecurityException {
+    public ElementProxy(Element element, String baseURI) throws XMLSecurityException {
         if (element == null) {
             throw new XMLSecurityException("ElementProxy.nullElement");
         }
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "setElement(\"" + element.getTagName() + "\", \"" + BaseURI + "\")");
-        }
+        LOG.debug("setElement(\"{}\", \"{}\")", element.getTagName(), baseURI);
 
-        this.doc = element.getOwnerDocument();
-        this.constructionElement = element;
-        this.baseURI = BaseURI;
+        setElement(element);
+        this.baseURI = baseURI;
 
         this.guaranteeThatElementInCorrectSpace();
     }
@@ -117,15 +115,16 @@
 
 
     protected Element createElementForFamilyLocal(
-        Document doc, String namespace, String localName
+        String namespace, String localName
     ) {
+        Document doc = getDocument();
         Element result = null;
         if (namespace == null) {
             result = doc.createElementNS(null, localName);
         } else {
             String baseName = this.getBaseNamespace();
             String prefix = ElementProxy.getDefaultPrefix(baseName);
-            if ((prefix == null) || (prefix.length() == 0)) {
+            if (prefix == null || prefix.length() == 0) {
                 result = doc.createElementNS(namespace, localName);
                 result.setAttributeNS(Constants.NamespaceSpecNS, "xmlns", namespace);
             } else {
@@ -141,7 +140,7 @@
      * This method creates an Element in a given namespace with a given localname.
      * It uses the {@link ElementProxy#getDefaultPrefix} method to decide whether
      * a particular prefix is bound to that namespace.
-     * <BR />
+     * <p></p>
      * This method was refactored out of the constructor.
      *
      * @param doc
@@ -156,7 +155,7 @@
         if (namespace == null) {
             result = doc.createElementNS(null, localName);
         } else {
-            if ((prefix == null) || (prefix.length() == 0)) {
+            if (prefix == null || prefix.length() == 0) {
                 result = doc.createElementNS(namespace, localName);
                 result.setAttributeNS(Constants.NamespaceSpecNS, "xmlns", namespace);
             } else {
@@ -172,31 +171,27 @@
      * Method setElement
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public void setElement(Element element, String BaseURI) throws XMLSecurityException {
+    public void setElement(Element element, String baseURI) throws XMLSecurityException {
         if (element == null) {
             throw new XMLSecurityException("ElementProxy.nullElement");
         }
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "setElement(" + element.getTagName() + ", \"" + BaseURI + "\"");
-        }
+        LOG.debug("setElement({}, \"{}\")", element.getTagName(), baseURI);
 
-        this.doc = element.getOwnerDocument();
-        this.constructionElement = element;
-        this.baseURI = BaseURI;
+        setElement(element);
+        this.baseURI = baseURI;
     }
 
-
     /**
      * Returns the Element which was constructed by the Object.
      *
      * @return the Element which was constructed by the Object.
      */
     public final Element getElement() {
-        return this.constructionElement;
+        return this.wrappedElement;
     }
 
     /**
@@ -208,20 +203,27 @@
 
         HelperNodeList nl = new HelperNodeList();
 
-        nl.appendChild(this.doc.createTextNode("\n"));
-        nl.appendChild(this.getElement());
-        nl.appendChild(this.doc.createTextNode("\n"));
+        nl.appendChild(createText("\n"));
+        nl.appendChild(getElement());
+        nl.appendChild(createText("\n"));
 
         return nl;
     }
 
+    protected Text createText(String text) {
+        return this.wrappedDoc.createTextNode(text);
+    }
+
     /**
      * Method getDocument
      *
      * @return the Document where this element is contained.
      */
     public Document getDocument() {
-        return this.doc;
+        if (wrappedDoc == null) {
+            wrappedDoc = XMLUtils.getOwnerDocument(wrappedElement);
+        }
+        return wrappedDoc;
     }
 
     /**
@@ -243,8 +245,8 @@
         String expectedLocalName = this.getBaseLocalName();
         String expectedNamespaceUri = this.getBaseNamespace();
 
-        String actualLocalName = this.constructionElement.getLocalName();
-        String actualNamespaceUri = this.constructionElement.getNamespaceURI();
+        String actualLocalName = getElement().getLocalName();
+        String actualNamespaceUri = getElement().getNamespaceURI();
 
         if(!expectedNamespaceUri.equals(actualNamespaceUri)
             && !expectedLocalName.equals(actualLocalName)) {
@@ -262,14 +264,25 @@
      */
     public void addBigIntegerElement(BigInteger bi, String localname) {
         if (bi != null) {
-            Element e = XMLUtils.createElementInSignatureSpace(this.doc, localname);
+            Element e = XMLUtils.createElementInSignatureSpace(getDocument(), localname);
+
+            byte[] bytes = XMLUtils.getBytes(bi, bi.bitLength());
+            String encodedInt = Base64.getMimeEncoder().encodeToString(bytes);
+
+            Document doc = e.getOwnerDocument();
+            Text text = doc.createTextNode(encodedInt);
 
-            Base64.fillElementWithBigInteger(e, bi);
-            this.constructionElement.appendChild(e);
-            XMLUtils.addReturnToElement(this.constructionElement);
+            e.appendChild(text);
+
+            appendSelf(e);
+            addReturnToSelf();
         }
     }
 
+    protected void addReturnToSelf() {
+        XMLUtils.addReturnToElement(getElement());
+    }
+
     /**
      * Method addBase64Element
      *
@@ -278,11 +291,14 @@
      */
     public void addBase64Element(byte[] bytes, String localname) {
         if (bytes != null) {
-            Element e = Base64.encodeToElement(this.doc, localname, bytes);
+            Element el = XMLUtils.createElementInSignatureSpace(getDocument(), localname);
+            Text text = getDocument().createTextNode(Base64.getMimeEncoder().encodeToString(bytes));
 
-            this.constructionElement.appendChild(e);
+            el.appendChild(text);
+
+            appendSelf(el);
             if (!XMLUtils.ignoreLineBreaks()) {
-                this.constructionElement.appendChild(this.doc.createTextNode("\n"));
+                appendSelf(createText("\n"));
             }
         }
     }
@@ -294,12 +310,12 @@
      * @param localname
      */
     public void addTextElement(String text, String localname) {
-        Element e = XMLUtils.createElementInSignatureSpace(this.doc, localname);
-        Text t = this.doc.createTextNode(text);
+        Element e = XMLUtils.createElementInSignatureSpace(getDocument(), localname);
+        Text t = createText(text);
 
-        e.appendChild(t);
-        this.constructionElement.appendChild(e);
-        XMLUtils.addReturnToElement(this.constructionElement);
+        appendOther(e, t);
+        appendSelf(e);
+        addReturnToSelf();
     }
 
     /**
@@ -310,12 +326,24 @@
     public void addBase64Text(byte[] bytes) {
         if (bytes != null) {
             Text t = XMLUtils.ignoreLineBreaks()
-                ? this.doc.createTextNode(Base64.encode(bytes))
-                : this.doc.createTextNode("\n" + Base64.encode(bytes) + "\n");
-            this.constructionElement.appendChild(t);
+                ? createText(Base64.getMimeEncoder().encodeToString(bytes))
+                : createText("\n" + Base64.getMimeEncoder().encodeToString(bytes) + "\n");
+            appendSelf(t);
         }
     }
 
+    protected void appendSelf(ElementProxy toAppend) {
+        getElement().appendChild(toAppend.getElement());
+    }
+
+    protected void appendSelf(Node toAppend) {
+        getElement().appendChild(toAppend);
+    }
+
+    protected void appendOther(Element parent, Node toAppend) {
+        parent.appendChild(toAppend);
+    }
+
     /**
      * Method addText
      *
@@ -323,9 +351,9 @@
      */
     public void addText(String text) {
         if (text != null) {
-            Text t = this.doc.createTextNode(text);
+            Text t = createText(text);
 
-            this.constructionElement.appendChild(t);
+            appendSelf(t);
         }
     }
 
@@ -335,35 +363,15 @@
      * @param localname
      * @param namespace
      * @return The biginteger contained in the given element
-     * @throws Base64DecodingException
      */
     public BigInteger getBigIntegerFromChildElement(
         String localname, String namespace
-    ) throws Base64DecodingException {
-        return Base64.decodeBigIntegerFromText(
+    ) {
+        return new BigInteger(1, Base64.getMimeDecoder().decode(
             XMLUtils.selectNodeText(
-                this.constructionElement.getFirstChild(), namespace, localname, 0
-            )
-        );
-    }
-
-    /**
-     * Method getBytesFromChildElement
-     * @deprecated
-     * @param localname
-     * @param namespace
-     * @return the bytes
-     * @throws XMLSecurityException
-     */
-    @Deprecated
-    public byte[] getBytesFromChildElement(String localname, String namespace)
-        throws XMLSecurityException {
-        Element e =
-            XMLUtils.selectNode(
-                this.constructionElement.getFirstChild(), namespace, localname, 0
-            );
-
-        return Base64.decode(e);
+                getFirstChild(), namespace, localname, 0
+            ).getNodeValue()
+        ));
     }
 
     /**
@@ -375,7 +383,7 @@
      */
     public String getTextFromChildElement(String localname, String namespace) {
         return XMLUtils.selectNode(
-                this.constructionElement.getFirstChild(),
+                getFirstChild(),
                 namespace,
                 localname,
                 0).getTextContent();
@@ -388,7 +396,7 @@
      * @throws XMLSecurityException
      */
     public byte[] getBytesFromTextChild() throws XMLSecurityException {
-        return Base64.decode(XMLUtils.getFullTextChildrenFromElement(this.constructionElement));
+        return Base64.getMimeDecoder().decode(getTextFromTextChild());
     }
 
     /**
@@ -398,7 +406,7 @@
      *    element
      */
     public String getTextFromTextChild() {
-        return XMLUtils.getFullTextChildrenFromElement(this.constructionElement);
+        return XMLUtils.getFullTextChildrenFromElement(getElement());
     }
 
     /**
@@ -410,7 +418,7 @@
      */
     public int length(String namespace, String localname) {
         int number = 0;
-        Node sibling = this.constructionElement.getFirstChild();
+        Node sibling = getFirstChild();
         while (sibling != null) {
             if (localname.equals(sibling.getLocalName())
                 && namespace.equals(sibling.getNamespaceURI())) {
@@ -438,9 +446,9 @@
         throws XMLSecurityException {
         String ns;
 
-        if ((prefix == null) || (prefix.length() == 0)) {
+        if (prefix == null || prefix.length() == 0) {
             throw new XMLSecurityException("defaultNamespaceCannotBeSetHere");
-        } else if (prefix.equals("xmlns")) {
+        } else if ("xmlns".equals(prefix)) {
             throw new XMLSecurityException("defaultNamespaceCannotBeSetHere");
         } else if (prefix.startsWith("xmlns:")) {
             ns = prefix;//"xmlns:" + prefix.substring("xmlns:".length());
@@ -448,18 +456,18 @@
             ns = "xmlns:" + prefix;
         }
 
-        Attr a = this.constructionElement.getAttributeNodeNS(Constants.NamespaceSpecNS, ns);
+        Attr a = getElement().getAttributeNodeNS(Constants.NamespaceSpecNS, ns);
 
         if (a != null) {
             if (!a.getNodeValue().equals(uri)) {
-                Object exArgs[] = { ns, this.constructionElement.getAttributeNS(null, ns) };
+                Object exArgs[] = { ns, getElement().getAttributeNS(null, ns) };
 
                 throw new XMLSecurityException("namespacePrefixAlreadyUsedByOtherURI", exArgs);
             }
             return;
         }
 
-        this.constructionElement.setAttributeNS(Constants.NamespaceSpecNS, ns, uri);
+        getElement().setAttributeNS(Constants.NamespaceSpecNS, ns, uri);
     }
 
     /**
@@ -474,6 +482,11 @@
     public static void setDefaultPrefix(String namespace, String prefix)
         throws XMLSecurityException {
         JavaUtils.checkRegisterPermission();
+        setNamespacePrefix(namespace, prefix);
+    }
+
+    private static void setNamespacePrefix(String namespace, String prefix)
+        throws XMLSecurityException {
         if (prefixMappings.containsValue(prefix)) {
             String storedPrefix = prefixMappings.get(namespace);
             if (!storedPrefix.equals(prefix)) {
@@ -496,14 +509,14 @@
      * This method registers the default prefixes.
      */
     public static void registerDefaultPrefixes() throws XMLSecurityException {
-        setDefaultPrefix("http://www.w3.org/2000/09/xmldsig#", "ds");
-        setDefaultPrefix("http://www.w3.org/2001/04/xmlenc#", "xenc");
-        setDefaultPrefix("http://www.w3.org/2009/xmlenc11#", "xenc11");
-        setDefaultPrefix("http://www.xmlsecurity.org/experimental#", "experimental");
-        setDefaultPrefix("http://www.w3.org/2002/04/xmldsig-filter2", "dsig-xpath-old");
-        setDefaultPrefix("http://www.w3.org/2002/06/xmldsig-filter2", "dsig-xpath");
-        setDefaultPrefix("http://www.w3.org/2001/10/xml-exc-c14n#", "ec");
-        setDefaultPrefix(
+        setNamespacePrefix("http://www.w3.org/2000/09/xmldsig#", "ds");
+        setNamespacePrefix("http://www.w3.org/2001/04/xmlenc#", "xenc");
+        setNamespacePrefix("http://www.w3.org/2009/xmlenc11#", "xenc11");
+        setNamespacePrefix("http://www.xmlsecurity.org/experimental#", "experimental");
+        setNamespacePrefix("http://www.w3.org/2002/04/xmldsig-filter2", "dsig-xpath-old");
+        setNamespacePrefix("http://www.w3.org/2002/06/xmldsig-filter2", "dsig-xpath");
+        setNamespacePrefix("http://www.w3.org/2001/10/xml-exc-c14n#", "ec");
+        setNamespacePrefix(
             "http://www.nue.et-inf.uni-siegen.de/~geuer-pollmann/#xpathFilter", "xx"
         );
     }
@@ -518,4 +531,51 @@
         return prefixMappings.get(namespace);
     }
 
+    /**
+     * New value for the wrapped XML element that this object is a proxy for.
+     *
+     * @param elem  New element
+     *
+     * @see #getElement()
+     */
+    protected void setElement(Element elem) {
+        wrappedElement = elem;
+    }
+
+    /**
+     * Set a new value for the wrapped document that this object is a proxy for.
+     *
+     * @param doc New document object being wrapped.
+     *
+     * @see #getDocument()
+     */
+    protected void setDocument(Document doc) {
+        wrappedDoc = doc;
+    }
+
+    protected String getLocalAttribute(String attrName) {
+        return getElement().getAttributeNS(null, attrName);
+    }
+
+    protected void setLocalAttribute(String attrName, String value) {
+        getElement().setAttributeNS(null, attrName, value);
+    }
+
+    protected void setLocalIdAttribute(String attrName, String value) {
+
+        if (value != null) {
+            Attr attr = getDocument().createAttributeNS(null, attrName);
+            attr.setValue(value);
+            getElement().setAttributeNodeNS(attr);
+            getElement().setIdAttributeNode(attr, true);
+        }
+        else {
+            getElement().removeAttributeNS(null, attrName);
+        }
+    }
+
+    protected Node getFirstChild() {
+        return getElement().getFirstChild();
+    }
+
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/EncryptionConstants.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/EncryptionConstants.java	Sat Oct 24 01:11:51 2020 +0100
@@ -22,96 +22,7 @@
  */
 package com.sun.org.apache.xml.internal.security.utils;
 
-public class EncryptionConstants {
-    // Attributes that exist in XML Signature in the same way
-    /** Tag of Attr Algorithm **/
-    public static final String _ATT_ALGORITHM              = Constants._ATT_ALGORITHM;
-
-    /** Tag of Attr Id**/
-    public static final String _ATT_ID                     = Constants._ATT_ID;
-
-    /** Tag of Attr Target **/
-    public static final String _ATT_TARGET                 = Constants._ATT_TARGET;
-
-    /** Tag of Attr Type **/
-    public static final String _ATT_TYPE                   = Constants._ATT_TYPE;
-
-    /** Tag of Attr URI **/
-    public static final String _ATT_URI                    = Constants._ATT_URI;
-
-    // Attributes new in XML Encryption
-    /** Tag of Attr encoding **/
-    public static final String _ATT_ENCODING               = "Encoding";
-
-    /** Tag of Attr recipient **/
-    public static final String _ATT_RECIPIENT              = "Recipient";
-
-    /** Tag of Attr mimetype **/
-    public static final String _ATT_MIMETYPE               = "MimeType";
-
-    /** Tag of Element CarriedKeyName **/
-    public static final String _TAG_CARRIEDKEYNAME         = "CarriedKeyName";
-
-    /** Tag of Element CipherData **/
-    public static final String _TAG_CIPHERDATA             = "CipherData";
-
-    /** Tag of Element CipherReference **/
-    public static final String _TAG_CIPHERREFERENCE        = "CipherReference";
-
-    /** Tag of Element CipherValue **/
-    public static final String _TAG_CIPHERVALUE            = "CipherValue";
-
-    /** Tag of Element DataReference **/
-    public static final String _TAG_DATAREFERENCE          = "DataReference";
-
-    /** Tag of Element EncryptedData **/
-    public static final String _TAG_ENCRYPTEDDATA          = "EncryptedData";
-
-    /** Tag of Element EncryptedKey **/
-    public static final String _TAG_ENCRYPTEDKEY           = "EncryptedKey";
-
-    /** Tag of Element EncryptionMethod **/
-    public static final String _TAG_ENCRYPTIONMETHOD       = "EncryptionMethod";
-
-    /** Tag of Element EncryptionProperties **/
-    public static final String _TAG_ENCRYPTIONPROPERTIES   = "EncryptionProperties";
-
-    /** Tag of Element EncryptionProperty **/
-    public static final String _TAG_ENCRYPTIONPROPERTY     = "EncryptionProperty";
-
-    /** Tag of Element KeyReference **/
-    public static final String _TAG_KEYREFERENCE           = "KeyReference";
-
-    /** Tag of Element KeySize **/
-    public static final String _TAG_KEYSIZE                = "KeySize";
-
-    /** Tag of Element OAEPparams **/
-    public static final String _TAG_OAEPPARAMS             = "OAEPparams";
-
-    /** Tag of Element MGF **/
-    public static final String _TAG_MGF                    = "MGF";
-
-    /** Tag of Element ReferenceList **/
-    public static final String _TAG_REFERENCELIST          = "ReferenceList";
-
-    /** Tag of Element Transforms **/
-    public static final String _TAG_TRANSFORMS             = "Transforms";
-
-    /** Tag of Element AgreementMethod **/
-    public static final String _TAG_AGREEMENTMETHOD        = "AgreementMethod";
-
-    /** Tag of Element KA-Nonce **/
-    public static final String _TAG_KA_NONCE               = "KA-Nonce";
-
-    /** Tag of Element OriginatorKeyInfo **/
-    public static final String _TAG_ORIGINATORKEYINFO      = "OriginatorKeyInfo";
-
-    /** Tag of Element RecipientKeyInfo **/
-    public static final String _TAG_RECIPIENTKEYINFO       = "RecipientKeyInfo";
-
-    /** Field ENCRYPTIONSPECIFICATION_URL */
-    public static final String ENCRYPTIONSPECIFICATION_URL =
-        "http://www.w3.org/TR/2001/WD-xmlenc-core-20010626/";
+public final class EncryptionConstants {
 
     /** The namespace of the
      * <A HREF="http://www.w3.org/TR/2001/WD-xmlenc-core-20010626/">
@@ -119,119 +30,6 @@
     public static final String EncryptionSpecNS =
         "http://www.w3.org/2001/04/xmlenc#";
 
-    /**
-     * The namespace of the XML Encryption 1.1 specification
-     */
-    public static final String EncryptionSpec11NS =
-        "http://www.w3.org/2009/xmlenc11#";
-
-    /** URI for content*/
-    public static final String TYPE_CONTENT                = EncryptionSpecNS + "Content";
-
-    /** URI for element*/
-    public static final String TYPE_ELEMENT                = EncryptionSpecNS + "Element";
-
-    /** URI for mediatype*/
-    public static final String TYPE_MEDIATYPE              =
-        "http://www.isi.edu/in-notes/iana/assignments/media-types/";
-
-    /** Block Encryption - REQUIRED TRIPLEDES */
-    public static final String ALGO_ID_BLOCKCIPHER_TRIPLEDES =
-        EncryptionConstants.EncryptionSpecNS + "tripledes-cbc";
-
-    /** Block Encryption - REQUIRED AES-128 */
-    public static final String ALGO_ID_BLOCKCIPHER_AES128 =
-        EncryptionConstants.EncryptionSpecNS + "aes128-cbc";
-
-    /** Block Encryption - REQUIRED AES-256 */
-    public static final String ALGO_ID_BLOCKCIPHER_AES256 =
-        EncryptionConstants.EncryptionSpecNS + "aes256-cbc";
-
-    /** Block Encryption - OPTIONAL AES-192 */
-    public static final String ALGO_ID_BLOCKCIPHER_AES192 =
-        EncryptionConstants.EncryptionSpecNS + "aes192-cbc";
-
-    /** Block Encryption - OPTIONAL AES-128-GCM */
-    public static final String ALGO_ID_BLOCKCIPHER_AES128_GCM =
-        "http://www.w3.org/2009/xmlenc11#aes128-gcm";
-
-    /** Block Encryption - OPTIONAL AES-192-GCM */
-    public static final String ALGO_ID_BLOCKCIPHER_AES192_GCM =
-        "http://www.w3.org/2009/xmlenc11#aes192-gcm";
-
-    /** Block Encryption - OPTIONAL AES-256-GCM */
-    public static final String ALGO_ID_BLOCKCIPHER_AES256_GCM =
-        "http://www.w3.org/2009/xmlenc11#aes256-gcm";
-
-    /** Key Transport - REQUIRED RSA-v1.5*/
-    public static final String ALGO_ID_KEYTRANSPORT_RSA15 =
-        EncryptionConstants.EncryptionSpecNS + "rsa-1_5";
-
-    /** Key Transport - REQUIRED RSA-OAEP */
-    public static final String ALGO_ID_KEYTRANSPORT_RSAOAEP =
-        EncryptionConstants.EncryptionSpecNS + "rsa-oaep-mgf1p";
-
-    /** Key Transport - OPTIONAL RSA-OAEP_11 */
-    public static final String ALGO_ID_KEYTRANSPORT_RSAOAEP_11 =
-        EncryptionConstants.EncryptionSpec11NS + "rsa-oaep";
-
-    /** Key Agreement - OPTIONAL Diffie-Hellman */
-    public static final String ALGO_ID_KEYAGREEMENT_DH =
-        EncryptionConstants.EncryptionSpecNS + "dh";
-
-    /** Symmetric Key Wrap - REQUIRED TRIPLEDES KeyWrap */
-    public static final String ALGO_ID_KEYWRAP_TRIPLEDES =
-        EncryptionConstants.EncryptionSpecNS + "kw-tripledes";
-
-    /** Symmetric Key Wrap - REQUIRED AES-128 KeyWrap */
-    public static final String ALGO_ID_KEYWRAP_AES128 =
-        EncryptionConstants.EncryptionSpecNS + "kw-aes128";
-
-    /** Symmetric Key Wrap - REQUIRED AES-256 KeyWrap */
-    public static final String ALGO_ID_KEYWRAP_AES256 =
-        EncryptionConstants.EncryptionSpecNS + "kw-aes256";
-
-    /** Symmetric Key Wrap - OPTIONAL AES-192 KeyWrap */
-    public static final String ALGO_ID_KEYWRAP_AES192 =
-        EncryptionConstants.EncryptionSpecNS + "kw-aes192";
-
-    /** Message Authentication - RECOMMENDED XML Digital Signature */
-    public static final String ALGO_ID_AUTHENTICATION_XMLSIGNATURE =
-        "http://www.w3.org/TR/2001/CR-xmldsig-core-20010419/";
-
-    /** Canonicalization - OPTIONAL Canonical XML with Comments */
-    public static final String ALGO_ID_C14N_WITHCOMMENTS =
-        "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments";
-
-    /** Canonicalization - OPTIONAL Canonical XML (omits comments) */
-    public static final String ALGO_ID_C14N_OMITCOMMENTS =
-        "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
-
-    /** Encoding - REQUIRED base64 */
-    public static final String ALGO_ID_ENCODING_BASE64 =
-        "http://www.w3.org/2000/09/xmldsig#base64";
-
-    /** MGF1 with SHA-1 */
-    public static final String MGF1_SHA1 =
-        EncryptionConstants.EncryptionSpec11NS + "mgf1sha1";
-
-    /** MGF1 with SHA-224 */
-    public static final String MGF1_SHA224 =
-        EncryptionConstants.EncryptionSpec11NS + "mgf1sha224";
-
-    /** MGF1 with SHA-256 */
-    public static final String MGF1_SHA256 =
-        EncryptionConstants.EncryptionSpec11NS + "mgf1sha256";
-
-    /** MGF1 with SHA-384 */
-    public static final String MGF1_SHA384 =
-        EncryptionConstants.EncryptionSpec11NS + "mgf1sha384";
-
-    /** MGF1 with SHA-512 */
-    public static final String MGF1_SHA512 =
-        EncryptionConstants.EncryptionSpec11NS + "mgf1sha512";
-
-
     private EncryptionConstants() {
         // we don't allow instantiation
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/EncryptionElementProxy.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * 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.utils;
-
-
-import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * This is the base object for all objects which map directly to an Element from
- * the xenc spec.
- *
- * @author $Author: coheigea $
- */
-public abstract class EncryptionElementProxy extends ElementProxy {
-
-    /**
-     * Constructor EncryptionElementProxy
-     *
-     * @param doc
-     */
-    public EncryptionElementProxy(Document doc) {
-        super(doc);
-    }
-
-    /**
-     * Constructor EncryptionElementProxy
-     *
-     * @param element
-     * @param BaseURI
-     * @throws XMLSecurityException
-     */
-    public EncryptionElementProxy(Element element, String BaseURI)
-        throws XMLSecurityException {
-        super(element, BaseURI);
-    }
-
-    /** @inheritDoc */
-    public final String getBaseNamespace() {
-        return EncryptionConstants.EncryptionSpecNS;
-    }
-}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/HelperNodeList.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/HelperNodeList.java	Sat Oct 24 01:11:51 2020 +0100
@@ -30,12 +30,11 @@
 import org.w3c.dom.NodeList;
 
 /**
- * @author Christian Geuer-Pollmann
  */
 public class HelperNodeList implements NodeList {
 
     /** Field nodes */
-    List<Node> nodes = new ArrayList<Node>();
+    List<Node> nodes = new ArrayList<>();
     boolean allNodesMustHaveSameParent = false;
 
     /**
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/I18n.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/I18n.java	Sat Oct 24 01:11:51 2020 +0100
@@ -29,7 +29,6 @@
 /**
  * The Internationalization (I18N) pack.
  *
- * @author Christian Geuer-Pollmann
  */
 public class I18n {
 
@@ -57,13 +56,13 @@
      * Method translate
      *
      * translates a message ID into an internationalized String, see alse
-     * <CODE>XMLSecurityException.getExceptionMEssage()</CODE>. The strings are
-     * stored in the <CODE>ResourceBundle</CODE>, which is identified in
-     * <CODE>exceptionMessagesResourceBundleBase</CODE>
+     * {@code XMLSecurityException.getExceptionMEssage()}. The strings are
+     * stored in the {@code ResourceBundle}, which is identified in
+     * {@code exceptionMessagesResourceBundleBase}
      *
      * @param message
-     * @param args is an <CODE>Object[]</CODE> array of strings which are inserted into
-     * the String which is retrieved from the <CODE>ResouceBundle</CODE>
+     * @param args is an {@code Object[]} array of strings which are inserted into
+     * the String which is retrieved from the {@code ResouceBundle}
      * @return message translated
      */
     public static String translate(String message, Object[] args) {
@@ -74,7 +73,7 @@
      * Method translate
      *
      * translates a message ID into an internationalized String, see also
-     * <CODE>XMLSecurityException.getExceptionMessage()</CODE>
+     * {@code XMLSecurityException.getExceptionMessage()}
      *
      * @param message
      * @return message translated
@@ -153,7 +152,7 @@
      * @param languageCode
      * @param countryCode
      */
-    public synchronized static void init(String languageCode, String countryCode) {
+    public static synchronized void init(String languageCode, String countryCode) {
         if (alreadyInitialized) {
             return;
         }
@@ -165,4 +164,17 @@
             );
         alreadyInitialized = true;
     }
+
+    /**
+     * Method init
+     * @param resourceBundle
+     */
+    public static synchronized void init(ResourceBundle resourceBundle) {
+        if (alreadyInitialized) {
+            return;
+        }
+
+        I18n.resourceBundle = resourceBundle;
+        alreadyInitialized = true;
+    }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IgnoreAllErrorHandler.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IgnoreAllErrorHandler.java	Sat Oct 24 01:11:51 2020 +0100
@@ -27,41 +27,33 @@
 import org.xml.sax.SAXParseException;
 
 /**
- * This {@link org.xml.sax.ErrorHandler} does absolutely nothing but log
+ * This {@link org.xml.sax.ErrorHandler} does absolutely nothing but LOG
  * the events.
  *
- * @author Christian Geuer-Pollmann
  */
 public class IgnoreAllErrorHandler implements ErrorHandler {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static final java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(IgnoreAllErrorHandler.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(IgnoreAllErrorHandler.class);
 
     /** Field throwExceptions */
-    private static final boolean warnOnExceptions = getProperty(
-            "com.sun.org.apache.xml.internal.security.test.warn.on.exceptions");
+    private static final boolean warnOnExceptions =
+        getProperty("com.sun.org.apache.xml.internal.security.test.warn.on.exceptions");
 
     /** Field throwExceptions           */
-    private static final boolean throwExceptions = getProperty(
-            "com.sun.org.apache.xml.internal.security.test.throw.exceptions");
+    private static final boolean throwExceptions =
+        getProperty("com.sun.org.apache.xml.internal.security.test.throw.exceptions");
 
-    private static boolean getProperty(String name) {
+    private static boolean getProperty(final String name) {
         return java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction<Boolean>() {
-
-                    @Override
-                    public Boolean run() {
-                        return Boolean.getBoolean(name);
-                    }
-                });
+            (java.security.PrivilegedAction<Boolean>) () -> Boolean.getBoolean(name));
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     @Override
     public void warning(SAXParseException ex) throws SAXException {
         if (IgnoreAllErrorHandler.warnOnExceptions) {
-            log.log(java.util.logging.Level.WARNING, "", ex);
+            LOG.warn("", ex);
         }
         if (IgnoreAllErrorHandler.throwExceptions) {
             throw ex;
@@ -69,11 +61,11 @@
     }
 
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     @Override
     public void error(SAXParseException ex) throws SAXException {
         if (IgnoreAllErrorHandler.warnOnExceptions) {
-            log.log(java.util.logging.Level.SEVERE, "", ex);
+            LOG.error("", ex);
         }
         if (IgnoreAllErrorHandler.throwExceptions) {
             throw ex;
@@ -81,11 +73,11 @@
     }
 
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     @Override
     public void fatalError(SAXParseException ex) throws SAXException {
         if (IgnoreAllErrorHandler.warnOnExceptions) {
-            log.log(java.util.logging.Level.WARNING, "", ex);
+            LOG.warn("", ex);
         }
         if (IgnoreAllErrorHandler.throwExceptions) {
             throw ex;
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JDKXPathAPI.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JDKXPathAPI.java	Sat Oct 24 01:11:51 2020 +0100
@@ -66,7 +66,7 @@
                 try {
                     xpf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
                 } catch (XPathFactoryConfigurationException ex) {
-                    throw new TransformerException("empty", ex);
+                    throw new TransformerException(ex);
                 }
             }
             XPath xpath = xpf.newXPath();
@@ -75,13 +75,13 @@
             try {
                 xpathExpression = xpath.compile(xpathStr);
             } catch (XPathExpressionException ex) {
-                throw new TransformerException("empty", ex);
+                throw new TransformerException(ex);
             }
         }
         try {
             return (NodeList)xpathExpression.evaluate(contextNode, XPathConstants.NODESET);
         } catch (XPathExpressionException ex) {
-            throw new TransformerException("empty", ex);
+            throw new TransformerException(ex);
         }
     }
 
@@ -100,7 +100,7 @@
                 try {
                     xpf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
                 } catch (XPathFactoryConfigurationException ex) {
-                    throw new TransformerException("empty", ex);
+                    throw new TransformerException(ex);
                 }
             }
             XPath xpath = xpf.newXPath();
@@ -109,14 +109,13 @@
             try {
                 xpathExpression = xpath.compile(xpathStr);
             } catch (XPathExpressionException ex) {
-                throw new TransformerException("empty", ex);
+                throw new TransformerException(ex);
             }
         }
         try {
-            Boolean result = (Boolean)xpathExpression.evaluate(contextNode, XPathConstants.BOOLEAN);
-            return result.booleanValue();
+            return (Boolean)xpathExpression.evaluate(contextNode, XPathConstants.BOOLEAN);
         } catch (XPathExpressionException ex) {
-            throw new TransformerException("empty", ex);
+            throw new TransformerException(ex);
         }
     }
 
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java	Sat Oct 24 01:11:51 2020 +0100
@@ -22,27 +22,24 @@
  */
 package com.sun.org.apache.xml.internal.security.utils;
 
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.SecurityPermission;
 
 /**
  * A collection of different, general-purpose methods for JAVA-specific things
- * @author Christian Geuer-Pollmann
  */
-public class JavaUtils {
+public final class JavaUtils {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(JavaUtils.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(JavaUtils.class);
 
     private static final SecurityPermission REGISTER_PERMISSION =
-        new SecurityPermission(
-            "com.sun.org.apache.xml.internal.security.register");
+        new SecurityPermission("com.sun.org.apache.xml.internal.security.register");
 
     private JavaUtils() {
         // we don't allow instantiation
@@ -62,26 +59,16 @@
 
         byte refBytes[] = null;
 
-        FileInputStream fisRef = null;
-        UnsyncByteArrayOutputStream baos = null;
-        try {
-            fisRef = new FileInputStream(fileName);
-            baos = new UnsyncByteArrayOutputStream();
+        try (InputStream inputStream = Files.newInputStream(Paths.get(fileName));
+            UnsyncByteArrayOutputStream baos = new UnsyncByteArrayOutputStream()) {
             byte buf[] = new byte[1024];
             int len;
 
-            while ((len = fisRef.read(buf)) > 0) {
+            while ((len = inputStream.read(buf)) > 0) {
                 baos.write(buf, 0, len);
             }
 
             refBytes = baos.toByteArray();
-        } finally {
-            if (baos != null) {
-                baos.close();
-            }
-            if (fisRef != null) {
-                fisRef.close();
-            }
         }
 
         return refBytes;
@@ -94,30 +81,14 @@
      * @param bytes
      */
     public static void writeBytesToFilename(String filename, byte[] bytes) {
-        FileOutputStream fos = null;
-        try {
-            if (filename != null && bytes != null) {
-                File f = new File(filename);
-
-                fos = new FileOutputStream(f);
-
-                fos.write(bytes);
-                fos.close();
-            } else {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "writeBytesToFilename got null byte[] pointed");
-                }
+        if (filename != null && bytes != null) {
+            try (OutputStream outputStream = Files.newOutputStream(Paths.get(filename))) {
+                outputStream.write(bytes);
+            } catch (IOException ex) {
+                LOG.debug(ex.getMessage(), ex);
             }
-        } catch (IOException ex) {
-            if (fos != null) {
-                try {
-                    fos.close();
-                } catch (IOException ioe) {
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, ioe.getMessage(), ioe);
-                    }
-                }
-            }
+        } else {
+            LOG.debug("writeBytesToFilename got null byte[] pointed");
         }
     }
 
@@ -132,29 +103,20 @@
      * @throws IOException
      */
     public static byte[] getBytesFromStream(InputStream inputStream) throws IOException {
-        UnsyncByteArrayOutputStream baos = null;
-
-        byte[] retBytes = null;
-        try {
-            baos = new UnsyncByteArrayOutputStream();
+        try (UnsyncByteArrayOutputStream baos = new UnsyncByteArrayOutputStream()) {
             byte buf[] = new byte[4 * 1024];
             int len;
-
             while ((len = inputStream.read(buf)) > 0) {
                 baos.write(buf, 0, len);
             }
-            retBytes = baos.toByteArray();
-        } finally {
-            baos.close();
+            return baos.toByteArray();
         }
-
-        return retBytes;
     }
 
     /**
      * Converts an ASN.1 DSA value to a XML Signature DSA Value.
      *
-     * The JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value
+     * The JCE DSA Signature algorithm creates ASN.1 encoded (r, s) value
      * pairs (see section 2.2.2 of RFC 3279); the XML Signature requires the
      * core BigInteger values.
      *
@@ -174,12 +136,11 @@
 
         byte rLength = asn1Bytes[3];
         int i;
-        for (i = rLength; i > 0 && asn1Bytes[4 + rLength - i] == 0; i--);
+        for (i = rLength; i > 0 && asn1Bytes[4 + rLength - i] == 0; i--); //NOPMD
 
         byte sLength = asn1Bytes[5 + rLength];
         int j;
-        for (j = sLength;
-             j > 0 && asn1Bytes[6 + rLength + sLength - j] == 0; j--);
+        for (j = sLength; j > 0 && asn1Bytes[6 + rLength + sLength - j] == 0; j--); //NOPMD
 
         if (i > size || asn1Bytes[4 + rLength] != 2 || j > size) {
             throw new IOException("Invalid ASN.1 format of DSA signature");
@@ -196,7 +157,7 @@
     /**
      * Converts an XML Signature DSA Value to a ASN.1 DSA value.
      *
-     * The JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value
+     * The JCE DSA Signature algorithm creates ASN.1 encoded (r, s) value
      * pairs (see section 2.2.2 of RFC 3279); the XML Signature requires the
      * core BigInteger values.
      *
@@ -215,7 +176,7 @@
         }
 
         int i;
-        for (i = size; i > 0 && xmldsigBytes[size - i] == 0; i--);
+        for (i = size; i > 0 && xmldsigBytes[size - i] == 0; i--); //NOPMD
 
         int j = i;
         if (xmldsigBytes[size - i] < 0) {
@@ -223,7 +184,7 @@
         }
 
         int k;
-        for (k = size; k > 0 && xmldsigBytes[totalSize - k] == 0; k--);
+        for (k = size; k > 0 && xmldsigBytes[totalSize - k] == 0; k--); //NOPMD
 
         int l = k;
         if (xmldsigBytes[totalSize - k] < 0) {
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java	Sat Oct 24 01:11:51 2020 +0100
@@ -72,7 +72,7 @@
      */
     public static String normalize(String dn, boolean toXml) {
         //if empty string
-        if ((dn == null) || dn.equals("")) {
+        if (dn == null || dn.equals("")) {
             return "";
         }
 
@@ -87,8 +87,8 @@
             for (int j = 0; (k = DN.indexOf(',', j)) >= 0; j = k + 1) {
                 l += countQuotes(DN, j, k);
 
-                if ((k > 0) && (DN.charAt(k - 1) != '\\') && (l % 2) == 0) {
-                    sb.append(parseRDN(DN.substring(i, k).trim(), toXml) + ",");
+                if (k > 0 && DN.charAt(k - 1) != '\\' && (l % 2) == 0) {
+                    sb.append(parseRDN(DN.substring(i, k).trim(), toXml)).append(",");
 
                     i = k + 1;
                     l = 0;
@@ -120,8 +120,8 @@
         for (int j = 0; (k = str.indexOf('+', j)) >= 0; j = k + 1) {
             l += countQuotes(str, j, k);
 
-            if ((k > 0) && (str.charAt(k - 1) != '\\') && (l % 2) == 0) {
-                sb.append(parseATAV(trim(str.substring(i, k)), toXml) + "+");
+            if (k > 0 && str.charAt(k - 1) != '\\' && (l % 2) == 0) {
+                sb.append(parseATAV(trim(str.substring(i, k)), toXml)).append("+");
 
                 i = k + 1;
                 l = 0;
@@ -144,7 +144,7 @@
     static String parseATAV(String str, boolean toXml) throws IOException {
         int i = str.indexOf('=');
 
-        if ((i == -1) || ((i > 0) && (str.charAt(i - 1) == '\\'))) {
+        if (i == -1 || i > 0 && str.charAt(i - 1) == '\\') {
             return str;
         }
         String attrType = normalizeAT(str.substring(0, i));
@@ -198,8 +198,8 @@
                 c = (char) i;
 
                 //the following char is defined at 4.Relationship with RFC1779 and LDAPv2 inrfc2253
-                if ((c == ',') || (c == '=') || (c == '+') || (c == '<')
-                    || (c == '>') || (c == '#') || (c == ';')) {
+                if (c == ',' || c == '=' || c == '+' || c == '<'
+                    || c == '>' || c == '#' || c == ';') {
                     sb.append('\\');
                 }
 
@@ -277,10 +277,10 @@
                 char c2 = (char) sr.read();
 
                 //65 (A) 97 (a)
-                if ((((c1 >= 48) && (c1 <= 57)) || ((c1 >= 65) && (c1 <= 70)) || ((c1 >= 97) && (c1 <= 102)))
-                    && (((c2 >= 48) && (c2 <= 57))
-                        || ((c2 >= 65) && (c2 <= 70))
-                        || ((c2 >= 97) && (c2 <= 102)))) {
+                if ((c1 >= 48 && c1 <= 57 || c1 >= 65 && c1 <= 70 || c1 >= 97 && c1 <= 102)
+                    && (c2 >= 48 && c2 <= 57
+                        || c2 >= 65 && c2 <= 70
+                        || c2 >= 97 && c2 <= 102)) {
                     char ch = (char) Byte.parseByte("" + c1 + c2, 16);
 
                     sb.append(ch);
@@ -417,7 +417,7 @@
         for (int j = 0; (k = str.indexOf(symbol, j)) >= 0; j = k + 1) {
             l += countQuotes(str, j, k);
 
-            if ((k > 0) && (str.charAt(k - 1) != '\\') && (l % 2) == 0) {
+            if (k > 0 && str.charAt(k - 1) != '\\' && (l % 2) == 0) {
                 sb.append(trim(str.substring(i, k)) + replace);
 
                 i = k + 1;
@@ -463,8 +463,8 @@
         String trimed = str.trim();
         int i = str.indexOf(trimed) + trimed.length();
 
-        if ((str.length() > i) && trimed.endsWith("\\")
-            && !trimed.endsWith("\\\\") && (str.charAt(i) == ' ')) {
+        if (str.length() > i && trimed.endsWith("\\")
+            && !trimed.endsWith("\\\\") && str.charAt(i) == ' ') {
             trimed = trimed + " ";
         }
 
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Signature11ElementProxy.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/Signature11ElementProxy.java	Sat Oct 24 01:11:51 2020 +0100
@@ -29,12 +29,11 @@
 /**
  * Class SignatureElementProxy
  *
- * @author Brent Putman (putmanb@georgetown.edu)
  */
 public abstract class Signature11ElementProxy extends ElementProxy {
 
     protected Signature11ElementProxy() {
-    };
+    }
 
     /**
      * Constructor Signature11ElementProxy
@@ -46,24 +45,23 @@
             throw new RuntimeException("Document is null");
         }
 
-        this.doc = doc;
-        this.constructionElement =
-            XMLUtils.createElementInSignature11Space(this.doc, this.getBaseLocalName());
+        setDocument(doc);
+        setElement(XMLUtils.createElementInSignature11Space(doc, this.getBaseLocalName()));
     }
 
     /**
      * Constructor Signature11ElementProxy
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public Signature11ElementProxy(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public Signature11ElementProxy(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
 
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseNamespace() {
         return Constants.SignatureSpec11NS;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/SignatureElementProxy.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/SignatureElementProxy.java	Sat Oct 24 01:11:51 2020 +0100
@@ -29,12 +29,11 @@
 /**
  * Class SignatureElementProxy
  *
- * @author $Author: coheigea $
  */
 public abstract class SignatureElementProxy extends ElementProxy {
 
     protected SignatureElementProxy() {
-    };
+    }
 
     /**
      * Constructor SignatureElementProxy
@@ -46,24 +45,24 @@
             throw new RuntimeException("Document is null");
         }
 
-        this.doc = doc;
-        this.constructionElement =
-            XMLUtils.createElementInSignatureSpace(this.doc, this.getBaseLocalName());
+        setDocument(doc);
+        setElement(XMLUtils.createElementInSignatureSpace(doc,
+                this.getBaseLocalName()));
     }
 
     /**
      * Constructor SignatureElementProxy
      *
      * @param element
-     * @param BaseURI
+     * @param baseURI
      * @throws XMLSecurityException
      */
-    public SignatureElementProxy(Element element, String BaseURI) throws XMLSecurityException {
-        super(element, BaseURI);
+    public SignatureElementProxy(Element element, String baseURI) throws XMLSecurityException {
+        super(element, baseURI);
 
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String getBaseNamespace() {
         return Constants.SignatureSpecNS;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/SignerOutputStream.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/SignerOutputStream.java	Sat Oct 24 01:11:51 2020 +0100
@@ -28,12 +28,11 @@
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;
 
 /**
- * @author raul
  *
  */
 public class SignerOutputStream extends ByteArrayOutputStream {
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(SignerOutputStream.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(SignerOutputStream.class);
 
     final SignatureAlgorithm sa;
 
@@ -44,7 +43,7 @@
         this.sa = sa;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public void write(byte[] arg0)  {
         try {
             sa.update(arg0);
@@ -53,7 +52,7 @@
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public void write(int arg0) {
         try {
             sa.update((byte)arg0);
@@ -62,15 +61,15 @@
         }
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public void write(byte[] arg0, int arg1, int arg2) {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Canonicalized SignedInfo:");
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Canonicalized SignedInfo:");
             StringBuilder sb = new StringBuilder(arg2);
             for (int i = arg1; i < (arg1 + arg2); i++) {
                 sb.append((char)arg0[i]);
             }
-            log.log(java.util.logging.Level.FINE, sb.toString());
+            LOG.debug(sb.toString());
         }
         try {
             sa.update(arg0, arg1, arg2);
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncBufferedOutputStream.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncBufferedOutputStream.java	Sat Oct 24 01:11:51 2020 +0100
@@ -2,97 +2,84 @@
  * 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
+/*
+ *  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
+ *     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.
+ *  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.utils;
 
+import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 
-/**
- * A class that buffers without synchronizing its methods
- * @author raul
- */
-public class UnsyncBufferedOutputStream extends OutputStream {
-    static final int size = 8*1024;
-
-    private int pointer = 0;
-    private final OutputStream out;
-
-    private final byte[] buf;
+public class UnsyncBufferedOutputStream extends FilterOutputStream {
 
-    /**
-     * Creates a buffered output stream without synchronization
-     * @param out the outputstream to buffer
-     */
+    protected byte[] buffer;
+    protected int count;
+
     public UnsyncBufferedOutputStream(OutputStream out) {
-        buf = new byte[size];
-        this.out = out;
-    }
-
-    /** @inheritDoc */
-    public void write(byte[] arg0) throws IOException {
-        write(arg0, 0, arg0.length);
+        super(out);
+        buffer = new byte[8192];
     }
 
-    /** @inheritDoc */
-    public void write(byte[] arg0, int arg1, int len) throws IOException {
-        int newLen = pointer+len;
-        if (newLen > size) {
-            flushBuffer();
-            if (len > size) {
-                out.write(arg0, arg1,len);
-                return;
-            }
-            newLen = len;
+    public UnsyncBufferedOutputStream(OutputStream out, int size) {
+        super(out);
+        if (size <= 0) {
+            throw new IllegalArgumentException("size must be > 0");
         }
-        System.arraycopy(arg0, arg1, buf, pointer, len);
-        pointer = newLen;
+        buffer = new byte[size];
     }
 
-    private void flushBuffer() throws IOException {
-        if (pointer > 0) {
-            out.write(buf, 0, pointer);
-        }
-        pointer = 0;
-
-    }
-
-    /** @inheritDoc */
-    public void write(int arg0) throws IOException {
-        if (pointer >= size) {
-            flushBuffer();
-        }
-        buf[pointer++] = (byte)arg0;
-
-    }
-
-    /** @inheritDoc */
+    @Override
     public void flush() throws IOException {
-        flushBuffer();
+        flushInternal();
         out.flush();
     }
 
-    /** @inheritDoc */
-    public void close() throws IOException {
-        flush();
-        out.close();
+    @Override
+    public void write(byte[] bytes, int offset, int length) throws IOException {
+        if (length >= buffer.length) {
+            flushInternal();
+            out.write(bytes, offset, length);
+            return;
+        }
+
+        // flush the internal buffer first if we have not enough space left
+        if (length >= (buffer.length - count)) {
+            flushInternal();
+        }
+
+        // the length is always less than (internalBuffer.length - count) here so arraycopy is safe
+        System.arraycopy(bytes, offset, buffer, count, length);
+        count += length;
     }
 
+    @Override
+    public void write(int oneByte) throws IOException {
+        if (count == buffer.length) {
+            out.write(buffer, 0, count);
+            count = 0;
+        }
+        buffer[count++] = (byte) oneByte;
+    }
+
+    private void flushInternal() throws IOException {
+        if (count > 0) {
+            out.write(buffer, 0, count);
+            count = 0;
+        }
+    }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java	Sat Oct 24 01:11:51 2020 +0100
@@ -22,27 +22,30 @@
  */
 package com.sun.org.apache.xml.internal.security.utils;
 
+import java.io.IOException;
 import java.io.OutputStream;
 
 /**
  * A simple Unsynced ByteArrayOutputStream
- * @author raul
  *
  */
 public class UnsyncByteArrayOutputStream extends OutputStream  {
 
+    // Maximum array size. Using same value as ArrayList in OpenJDK.
+    // Integer.MAX_VALUE doesn't work on some VMs, as some header values are reserved
+    private static final int VM_ARRAY_INDEX_MAX_VALUE = Integer.MAX_VALUE - 8;
     private static final int INITIAL_SIZE = 8192;
 
     private byte[] buf;
     private int size = INITIAL_SIZE;
-    private int pos = 0;
+    private int pos;
 
     public UnsyncByteArrayOutputStream() {
         buf = new byte[INITIAL_SIZE];
     }
 
     public void write(byte[] arg0) {
-        if ((Integer.MAX_VALUE - pos) < arg0.length) {
+        if ((VM_ARRAY_INDEX_MAX_VALUE - pos) < arg0.length) {
             throw new OutOfMemoryError();
         }
         int newPos = pos + arg0.length;
@@ -54,7 +57,7 @@
     }
 
     public void write(byte[] arg0, int arg1, int arg2) {
-        if ((Integer.MAX_VALUE - pos) < arg2) {
+        if ((VM_ARRAY_INDEX_MAX_VALUE - pos) < arg2) {
             throw new OutOfMemoryError();
         }
         int newPos = pos + arg2;
@@ -66,7 +69,7 @@
     }
 
     public void write(int arg0) {
-        if ((Integer.MAX_VALUE - pos) == 0) {
+        if (VM_ARRAY_INDEX_MAX_VALUE - pos == 0) {
             throw new OutOfMemoryError();
         }
         int newPos = pos + 1;
@@ -86,13 +89,26 @@
         pos = 0;
     }
 
+    /**
+     * Takes the contents of this stream and writes it to the output stream
+     * {@code out}.
+     *
+     * @param out
+     *            an OutputStream on which to write the contents of this stream.
+     * @throws IOException
+     *             if an error occurs while writing to {@code out}.
+     */
+    public void writeTo(OutputStream out) throws IOException {
+        out.write(buf, 0, pos);
+    }
+
     private void expandSize(int newPos) {
         int newSize = size;
         while (newPos > newSize) {
             newSize = newSize << 1;
             // Deal with overflow
             if (newSize < 0) {
-                newSize = Integer.MAX_VALUE;
+                newSize = VM_ARRAY_INDEX_MAX_VALUE;
             }
         }
         byte newBuf[] = new byte[newSize];
@@ -100,4 +116,4 @@
         buf = newBuf;
         size = newSize;
     }
-}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/WeakObjectPool.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,118 @@
+/*
+ * 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.utils;
+
+import java.lang.ref.WeakReference;
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+
+/**
+ * Abstract base class for pooling objects.  The two public methods are
+ * {@link #getObject()} and ({@link #repool(Object)}.  Objects are held through
+ * weak references so even objects that are not repooled are subject to garbage collection.
+ *
+ * Subclasses must implement the abstract {@link #createObject()}.
+ * <p>
+ *
+ * Internally, the pool is stored in a java.util.concurrent.LinkedBlockingDeque
+ * instance.
+ */
+public abstract class WeakObjectPool<T, E extends Throwable> {
+
+    private static final Integer MARKER_VALUE = Integer.MAX_VALUE;//once here rather than auto-box it?
+
+    /** created, available objects to be checked out to clients */
+    private final BlockingQueue<WeakReference<T>> available;
+
+    /**
+     * Synchronized, identity map of loaned out objects (WeakHashMap);
+     * use to ensure we repool only object originating from here
+     * and do it once.
+     */
+    private final Map<T, Integer> onLoan;
+
+    /**
+     * The lone constructor.
+     */
+    protected WeakObjectPool() {
+        //alternative implementations: ArrayBlockingQueue has a fixed size
+        //  PriorityBlockingQueue: requires a dummy comparator; less memory but more overhead
+        available = new LinkedBlockingDeque<WeakReference<T>>();
+        this.onLoan = Collections.synchronizedMap(new WeakHashMap<T, Integer>());
+    }
+
+    /**
+     * Called whenever a new pool object is desired; subclasses must implement.
+     *
+     * @return object of the type desired by the subclass
+     * @throws E Throwable's subclass
+     */
+    protected abstract T createObject() throws E;
+
+
+    /**
+     * Subclasses can subclass to return a more specific type.
+     *
+     * @return an object from the pool; will block until an object is available
+     * @throws E
+     */
+    public T getObject() throws E {
+        WeakReference<T> ref;
+        T retValue = null;
+        do {
+            //remove any stale entries as well
+            ref = available.poll();
+        } while (ref != null && (retValue = ref.get()) == null);
+
+        if (retValue == null) {
+            //empty pool; create & add new one
+            retValue = createObject();
+        }
+        onLoan.put(retValue, MARKER_VALUE);
+        return retValue;
+    }
+
+
+    /**
+     * Adds the given object to the pool, provided that the object
+     * was created by this pool.
+     *
+     * @param obj the object to return to the pool
+     * @return whether the object was successfully added as available
+     */
+    public boolean repool(T obj) {
+        if (obj != null && onLoan.containsKey(obj)) {
+            //synchronize to protect against a caller returning the same object again...
+            synchronized (obj) {
+                //...and check to see that it was removed
+                if (onLoan.remove(obj) != null) {
+                    return available.offer(new WeakReference<T>(obj));
+                }
+            }
+        }
+        return false;
+    }
+}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java	Sat Oct 24 01:11:51 2020 +0100
@@ -24,14 +24,20 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.math.BigInteger;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
+import java.util.Base64;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
@@ -41,32 +47,25 @@
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
-import org.w3c.dom.ProcessingInstruction;
 import org.w3c.dom.Text;
 
 /**
  * DOM and XML accessibility and comfort functions.
  *
- * @author Christian Geuer-Pollmann
  */
-public class XMLUtils {
+public final class XMLUtils {
 
     private static boolean ignoreLineBreaks =
-        AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
-            public Boolean run() {
-                return Boolean.valueOf(Boolean.getBoolean
-                    ("com.sun.org.apache.xml.internal.security.ignoreLineBreaks"));
-            }
-        }).booleanValue();
+        AccessController.doPrivileged(
+            (PrivilegedAction<Boolean>) () -> Boolean.getBoolean("com.sun.org.apache.xml.internal.security.ignoreLineBreaks"));
 
     private static volatile String dsPrefix = "ds";
     private static volatile String ds11Prefix = "dsig11";
     private static volatile String xencPrefix = "xenc";
     private static volatile String xenc11Prefix = "xenc11";
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static final java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(XMLUtils.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(XMLUtils.class);
 
 
     /**
@@ -123,7 +122,7 @@
 
     public static Element getNextElement(Node el) {
         Node node = el;
-        while ((node != null) && (node.getNodeType() != Node.ELEMENT_NODE)) {
+        while (node != null && node.getNodeType() != Node.ELEMENT_NODE) {
             node = node.getNextSibling();
         }
         return (Element)node;
@@ -136,7 +135,7 @@
      * @param com whether comments or not
      */
     public static void getSet(Node rootNode, Set<Node> result, Node exclude, boolean com) {
-        if ((exclude != null) && isDescendantOrSelf(exclude, rootNode)) {
+        if (exclude != null && isDescendantOrSelf(exclude, rootNode)) {
             return;
         }
         getSetRec(rootNode, result, exclude, com);
@@ -154,7 +153,8 @@
             Element el = (Element)rootNode;
             if (el.hasAttributes()) {
                 NamedNodeMap nl = el.getAttributes();
-                for (int i = 0;i < nl.getLength(); i++) {
+                int length = nl.getLength();
+                for (int i = 0; i < length; i++) {
                     result.add(nl.item(i));
                 }
             }
@@ -163,7 +163,7 @@
             for (Node r = rootNode.getFirstChild(); r != null; r = r.getNextSibling()) {
                 if (r.getNodeType() == Node.TEXT_NODE) {
                     result.add(r);
-                    while ((r != null) && (r.getNodeType() == Node.TEXT_NODE)) {
+                    while (r != null && r.getNodeType() == Node.TEXT_NODE) {
                         r = r.getNextSibling();
                     }
                     if (r == null) {
@@ -208,37 +208,31 @@
     public static void outputDOM(Node contextNode, OutputStream os, boolean addPreamble) {
         try {
             if (addPreamble) {
-                os.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".getBytes("UTF-8"));
+                os.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".getBytes(java.nio.charset.StandardCharsets.UTF_8));
             }
 
             os.write(Canonicalizer.getInstance(
-                Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS).canonicalizeSubtree(contextNode)
+                Canonicalizer.ALGO_ID_C14N_PHYSICAL).canonicalizeSubtree(contextNode)
             );
         } catch (IOException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-            }
+            LOG.debug(ex.getMessage(), ex);
         }
         catch (InvalidCanonicalizerException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-            }
+            LOG.debug(ex.getMessage(), ex);
         } catch (CanonicalizationException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-            }
+            LOG.debug(ex.getMessage(), ex);
         }
     }
 
     /**
-     * Serializes the <CODE>contextNode</CODE> into the OutputStream, <I>but
+     * Serializes the {@code contextNode} into the OutputStream, <I>but
      * suppresses all Exceptions</I>.
-     * <BR />
+     * <p></p>
      * NOTE: <I>This should only be used for debugging purposes,
      * NOT in a production environment; this method ignores all exceptions,
      * so you won't notice if something goes wrong. If you're asking what is to
      * be used in a production environment, simply use the code inside the
-     * <code>try{}</code> statement, but handle the Exceptions appropriately.</I>
+     * {@code try{}} statement, but handle the Exceptions appropriately.</I>
      *
      * @param contextNode
      * @param os
@@ -249,19 +243,13 @@
                 Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS).canonicalizeSubtree(contextNode)
             );
         } catch (IOException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-            }
+            LOG.debug(ex.getMessage(), ex);
             // throw new RuntimeException(ex.getMessage());
         } catch (InvalidCanonicalizerException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-            }
+            LOG.debug(ex.getMessage(), ex);
             // throw new RuntimeException(ex.getMessage());
         } catch (CanonicalizationException ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-            }
+            LOG.debug(ex.getMessage(), ex);
             // throw new RuntimeException(ex.getMessage());
         }
     }
@@ -298,7 +286,7 @@
             throw new RuntimeException("Document is null");
         }
 
-        if ((dsPrefix == null) || (dsPrefix.length() == 0)) {
+        if (dsPrefix == null || dsPrefix.length() == 0) {
             return doc.createElementNS(Constants.SignatureSpecNS, elementName);
         }
         return doc.createElementNS(Constants.SignatureSpecNS, dsPrefix + ":" + elementName);
@@ -316,55 +304,13 @@
             throw new RuntimeException("Document is null");
         }
 
-        if ((ds11Prefix == null) || (ds11Prefix.length() == 0)) {
+        if (ds11Prefix == null || ds11Prefix.length() == 0) {
             return doc.createElementNS(Constants.SignatureSpec11NS, elementName);
         }
         return doc.createElementNS(Constants.SignatureSpec11NS, ds11Prefix + ":" + elementName);
     }
 
     /**
-     * Creates an Element in the XML Encryption specification namespace.
-     *
-     * @param doc the factory Document
-     * @param elementName the local name of the Element
-     * @return the Element
-     */
-    public static Element createElementInEncryptionSpace(Document doc, String elementName) {
-        if (doc == null) {
-            throw new RuntimeException("Document is null");
-        }
-
-        if ((xencPrefix == null) || (xencPrefix.length() == 0)) {
-            return doc.createElementNS(EncryptionConstants.EncryptionSpecNS, elementName);
-        }
-        return
-            doc.createElementNS(
-                EncryptionConstants.EncryptionSpecNS, xencPrefix + ":" + elementName
-            );
-    }
-
-    /**
-     * Creates an Element in the XML Encryption 1.1 specification namespace.
-     *
-     * @param doc the factory Document
-     * @param elementName the local name of the Element
-     * @return the Element
-     */
-    public static Element createElementInEncryption11Space(Document doc, String elementName) {
-        if (doc == null) {
-            throw new RuntimeException("Document is null");
-        }
-
-        if ((xenc11Prefix == null) || (xenc11Prefix.length() == 0)) {
-            return doc.createElementNS(EncryptionConstants.EncryptionSpec11NS, elementName);
-        }
-        return
-            doc.createElementNS(
-                EncryptionConstants.EncryptionSpec11NS, xenc11Prefix + ":" + elementName
-            );
-    }
-
-    /**
      * Returns true if the element is in XML Signature namespace and the local
      * name equals the supplied one.
      *
@@ -401,43 +347,9 @@
     }
 
     /**
-     * Returns true if the element is in XML Encryption namespace and the local
-     * name equals the supplied one.
-     *
-     * @param element
-     * @param localName
-     * @return true if the element is in XML Encryption namespace and the local name
-     * equals the supplied one
-     */
-    public static boolean elementIsInEncryptionSpace(Element element, String localName) {
-        if (element == null){
-            return false;
-        }
-        return EncryptionConstants.EncryptionSpecNS.equals(element.getNamespaceURI())
-            && element.getLocalName().equals(localName);
-    }
-
-    /**
-     * Returns true if the element is in XML Encryption 1.1 namespace and the local
-     * name equals the supplied one.
-     *
-     * @param element
-     * @param localName
-     * @return true if the element is in XML Encryption 1.1 namespace and the local name
-     * equals the supplied one
-     */
-    public static boolean elementIsInEncryption11Space(Element element, String localName) {
-        if (element == null){
-            return false;
-        }
-        return EncryptionConstants.EncryptionSpec11NS.equals(element.getNamespaceURI())
-            && element.getLocalName().equals(localName);
-    }
-
-    /**
      * This method returns the owner document of a particular node.
      * This method is necessary because it <I>always</I> returns a
-     * {@link Document}. {@link Node#getOwnerDocument} returns <CODE>null</CODE>
+     * {@link Document}. {@link Node#getOwnerDocument} returns {@code null}
      * if the {@link Node} is a {@link Document}.
      *
      * @param node
@@ -459,7 +371,7 @@
     /**
      * This method returns the first non-null owner document of the Nodes in this Set.
      * This method is necessary because it <I>always</I> returns a
-     * {@link Document}. {@link Node#getOwnerDocument} returns <CODE>null</CODE>
+     * {@link Document}. {@link Node#getOwnerDocument} returns {@code null}
      * if the {@link Node} is a {@link Document}.
      *
      * @param xpathNodeSet
@@ -496,7 +408,7 @@
      * @return the element.
      */
     public static Element createDSctx(Document doc, String prefix, String namespace) {
-        if ((prefix == null) || (prefix.trim().length() == 0)) {
+        if (prefix == null || prefix.trim().length() == 0) {
             throw new IllegalArgumentException("You must supply a prefix");
         }
 
@@ -532,6 +444,25 @@
         }
     }
 
+    public static String encodeToString(byte[] bytes) {
+        if (ignoreLineBreaks) {
+            return Base64.getEncoder().encodeToString(bytes);
+        }
+        return Base64.getMimeEncoder().encodeToString(bytes);
+    }
+
+    public static byte[] decode(String encodedString) {
+        return Base64.getMimeDecoder().decode(encodedString);
+    }
+
+    public static byte[] decode(byte[] encodedBytes) {
+        return Base64.getMimeDecoder().decode(encodedBytes);
+    }
+
+    public static boolean isIgnoreLineBreaks() {
+        return ignoreLineBreaks;
+    }
+
     /**
      * Method convertNodelistToSet
      *
@@ -540,11 +471,11 @@
      */
     public static Set<Node> convertNodelistToSet(NodeList xpathNodeSet) {
         if (xpathNodeSet == null) {
-            return new HashSet<Node>();
+            return new HashSet<>();
         }
 
         int length = xpathNodeSet.getLength();
-        Set<Node> set = new HashSet<Node>(length);
+        Set<Node> set = new HashSet<>(length);
 
         for (int i = 0; i < length; i++) {
             set.add(xpathNodeSet.item(i));
@@ -632,7 +563,7 @@
                 sibling = node.getFirstChild();
                 break;
             }
-            while ((sibling == null) && (parent != null)) {
+            while (sibling == null && parent != null) {
                 sibling = parent.getNextSibling();
                 parent = parent.getParentNode();
             }
@@ -691,29 +622,8 @@
      * @param number
      * @return nodes with the constrain
      */
-    public static Element selectXencNode(Node sibling, String nodeName, int number) {
-        while (sibling != null) {
-            if (EncryptionConstants.EncryptionSpecNS.equals(sibling.getNamespaceURI())
-                && sibling.getLocalName().equals(nodeName)) {
-                if (number == 0){
-                    return (Element)sibling;
-                }
-                number--;
-            }
-            sibling = sibling.getNextSibling();
-        }
-        return null;
-    }
-
-
-    /**
-     * @param sibling
-     * @param nodeName
-     * @param number
-     * @return nodes with the constrain
-     */
     public static Text selectDsNodeText(Node sibling, String nodeName, int number) {
-        Node n = selectDsNode(sibling,nodeName,number);
+        Node n = selectDsNode(sibling, nodeName, number);
         if (n == null) {
             return null;
         }
@@ -731,7 +641,7 @@
      * @return nodes with the constrain
      */
     public static Text selectDs11NodeText(Node sibling, String nodeName, int number) {
-        Node n = selectDs11Node(sibling,nodeName,number);
+        Node n = selectDs11Node(sibling, nodeName, number);
         if (n == null) {
             return null;
         }
@@ -750,7 +660,7 @@
      * @return nodes with the constrain
      */
     public static Text selectNodeText(Node sibling, String uri, String nodeName, int number) {
-        Node n = selectNode(sibling,uri,nodeName,number);
+        Node n = selectNode(sibling, uri, nodeName, number);
         if (n == null) {
             return null;
         }
@@ -807,7 +717,7 @@
      * @return nodes with the constraint
      */
     public static Element[] selectNodes(Node sibling, String uri, String nodeName) {
-        List<Element> list = new ArrayList<Element>();
+        List<Element> list = new ArrayList<>();
         while (sibling != null) {
             if (sibling.getNamespaceURI() != null && sibling.getNamespaceURI().equals(uri)
                 && sibling.getLocalName().equals(nodeName)) {
@@ -824,7 +734,7 @@
      * @return nodes with the constrain
      */
     public static Set<Node> excludeNodeFromSet(Node signatureElement, Set<Node> inputSet) {
-        Set<Node> resultSet = new HashSet<Node>();
+        Set<Node> resultSet = new HashSet<>();
         Iterator<Node> iterator = inputSet.iterator();
 
         while (iterator.hasNext()) {
@@ -859,9 +769,9 @@
 
             return sb.toString();
         } else if (xpathnode.getNodeType() == Node.ATTRIBUTE_NODE) {
-            return ((Attr) xpathnode).getNodeValue();
+            return xpathnode.getNodeValue();
         } else if (xpathnode.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
-            return ((ProcessingInstruction) xpathnode).getNodeValue();
+            return xpathnode.getNodeValue();
         }
 
         return null;
@@ -909,7 +819,7 @@
      * the empty string if the attribute value is empty.
      *
      * <p>This works around a limitation of the DOM
-     * <code>Element.getAttributeNode</code> method, which does not distinguish
+     * {@code Element.getAttributeNode} method, which does not distinguish
      * between an unspecified attribute and an attribute with a value of
      * "" (it returns "" for both cases).
      *
@@ -929,29 +839,33 @@
      * a matching Element has been found, just that no wrapping attack has been detected.
      */
     public static boolean protectAgainstWrappingAttack(Node startNode, String value) {
-        Node startParent = startNode.getParentNode();
-        Node processedNode = null;
-        Element foundElement = null;
-
         String id = value.trim();
         if (!id.isEmpty() && id.charAt(0) == '#') {
             id = id.substring(1);
         }
 
+        Node startParent = null;
+        Node processedNode = null;
+        Element foundElement = null;
+        if (startNode != null) {
+            startParent = startNode.getParentNode();
+        }
+
         while (startNode != null) {
             if (startNode.getNodeType() == Node.ELEMENT_NODE) {
                 Element se = (Element) startNode;
 
                 NamedNodeMap attributes = se.getAttributes();
                 if (attributes != null) {
-                    for (int i = 0; i < attributes.getLength(); i++) {
+                    int length = attributes.getLength();
+                    for (int i = 0; i < length; i++) {
                         Attr attr = (Attr)attributes.item(i);
                         if (attr.isId() && id.equals(attr.getValue())) {
                             if (foundElement == null) {
                                 // Continue searching to find duplicates
                                 foundElement = attr.getOwnerElement();
                             } else {
-                                log.log(java.util.logging.Level.FINE, "Multiple elements with the same 'Id' attribute value!");
+                                LOG.debug("Multiple elements with the same 'Id' attribute value!");
                                 return false;
                             }
                         }
@@ -990,24 +904,28 @@
     public static boolean protectAgainstWrappingAttack(
         Node startNode, Element knownElement, String value
     ) {
-        Node startParent = startNode.getParentNode();
-        Node processedNode = null;
-
         String id = value.trim();
         if (!id.isEmpty() && id.charAt(0) == '#') {
             id = id.substring(1);
         }
 
+        Node startParent = null;
+        Node processedNode = null;
+        if (startNode != null) {
+            startParent = startNode.getParentNode();
+        }
+
         while (startNode != null) {
             if (startNode.getNodeType() == Node.ELEMENT_NODE) {
                 Element se = (Element) startNode;
 
                 NamedNodeMap attributes = se.getAttributes();
                 if (attributes != null) {
-                    for (int i = 0; i < attributes.getLength(); i++) {
+                    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.log(java.util.logging.Level.FINE, "Multiple elements with the same 'Id' attribute value!");
+                            LOG.debug("Multiple elements with the same 'Id' attribute value!");
                             return false;
                         }
                     }
@@ -1037,4 +955,68 @@
         return true;
     }
 
+    public static DocumentBuilder createDocumentBuilder(boolean validating)
+            throws ParserConfigurationException {
+        return createDocumentBuilder(validating, true);
+    }
+
+    // The current implementation does not throw a ParserConfigurationException.
+    // Kept here in case we create the DocumentBuilder inline again.
+    public static DocumentBuilder createDocumentBuilder(
+        boolean validating, boolean disAllowDocTypeDeclarations
+    ) throws ParserConfigurationException {
+        DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+        dfactory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        if (disAllowDocTypeDeclarations) {
+            dfactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+        }
+        dfactory.setValidating(validating);
+        dfactory.setNamespaceAware(true);
+        return dfactory.newDocumentBuilder();
+    }
+
+    /**
+     * Returns a byte-array representation of a {@code {@link BigInteger}}.
+     * No sign-bit is output.
+     *
+     * <b>N.B.:</B> {@code {@link BigInteger}}'s toByteArray
+     * returns eventually longer arrays because of the leading sign-bit.
+     *
+     * @param big {@code BigInteger} to be converted
+     * @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 byte[] getBytes(BigInteger big, int bitlen) {
+
+        //round bitlen
+        bitlen = ((bitlen + 7) >> 3) << 3;
+
+        if (bitlen < big.bitLength()) {
+            throw new IllegalArgumentException(I18n.translate("utils.Base64.IllegalBitlength"));
+        }
+
+        byte[] bigBytes = big.toByteArray();
+
+        if (big.bitLength() % 8 != 0
+            && big.bitLength() / 8 + 1 == bitlen / 8) {
+            return bigBytes;
+        }
+
+        // some copying needed
+        int startSrc = 0;    // no need to skip anything
+        int bigLen = bigBytes.length;    //valid length of the string
+
+        if (big.bitLength() % 8 == 0) {    // correct values
+            startSrc = 1;    // skip sign bit
+
+            bigLen--;    // valid length of the string
+        }
+
+        int startDst = bitlen / 8 - bigLen;    //pad with leading nulls
+        byte[] resizedBytes = new byte[bitlen / 8];
+
+        System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, bigLen);
+
+        return resizedBytes;
+    }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XPathFactory.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XPathFactory.java	Sat Oct 24 01:11:51 2020 +0100
@@ -38,12 +38,12 @@
             if (funcTableClass != null) {
                 xalanInstalled = true;
             }
-        } catch (Exception e) {
+        } catch (Exception e) { //NOPMD
             //ignore
         }
     }
 
-    protected synchronized static boolean isXalanInstalled() {
+    protected static synchronized boolean isXalanInstalled() {
         return xalanInstalled;
     }
 
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XalanXPathAPI.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XalanXPathAPI.java	Sat Oct 24 01:11:51 2020 +0100
@@ -48,14 +48,14 @@
  */
 public class XalanXPathAPI implements XPathAPI {
 
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(XalanXPathAPI.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(XalanXPathAPI.class);
 
-    private String xpathStr = null;
+    private String xpathStr;
 
-    private XPath xpath = null;
+    private XPath xpath;
 
-    private static FunctionTable funcTable = null;
+    private static FunctionTable funcTable;
 
     private static boolean installed;
 
@@ -111,7 +111,7 @@
         context = null;
     }
 
-    public synchronized static boolean isInstalled() {
+    public static synchronized boolean isInstalled() {
         return installed;
     }
 
@@ -150,14 +150,12 @@
         Class<?>[] classes = new Class<?>[]{String.class, SourceLocator.class, PrefixResolver.class, int.class,
                                       ErrorListener.class, FunctionTable.class};
         Object[] objects =
-            new Object[]{str, null, prefixResolver, Integer.valueOf(XPath.SELECT), null, funcTable};
+            new Object[]{str, null, prefixResolver, XPath.SELECT, null, funcTable};
         try {
             Constructor<?> constructor = XPath.class.getConstructor(classes);
             xpath = (XPath) constructor.newInstance(objects);
         } catch (Exception ex) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, ex.getMessage(), ex);
-            }
+            LOG.debug(ex.getMessage(), ex);
         }
         if (xpath == null) {
             xpath = new XPath(str, null, prefixResolver, XPath.SELECT, null);
@@ -165,11 +163,9 @@
         return xpath;
     }
 
-    private synchronized static void fixupFunctionTable() {
+    private static synchronized void fixupFunctionTable() {
         installed = false;
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Registering Here function");
-        }
+        LOG.debug("Registering Here function");
         /**
          * Try to register our here() implementation as internal function.
          */
@@ -182,7 +178,7 @@
                 installed = true;
             }
         } catch (Exception ex) {
-            log.log(java.util.logging.Level.FINE, "Error installing function using the static installFunction method", ex);
+            LOG.debug("Error installing function using the static installFunction method", ex);
         }
         if (!installed) {
             try {
@@ -193,17 +189,13 @@
                 installFunction.invoke(funcTable, params);
                 installed = true;
             } catch (Exception ex) {
-                log.log(java.util.logging.Level.FINE, "Error installing function using the static installFunction method", ex);
+                LOG.debug("Error installing function using the static installFunction method", ex);
             }
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            if (installed) {
-                log.log(java.util.logging.Level.FINE, "Registered class " + FuncHere.class.getName()
-                          + " for XPath function 'here()' function in internal table");
-            } else {
-                log.log(java.util.logging.Level.FINE, "Unable to register class " + FuncHere.class.getName()
-                          + " for XPath function 'here()' function in internal table");
-            }
+        if (installed) {
+            LOG.debug("Registered class {} for XPath function 'here()' function in internal table", FuncHere.class.getName());
+        } else {
+            LOG.debug("Unable to register class {} for XPath function 'here()' function in internal table", FuncHere.class.getName());
         }
     }
 
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<HTML><HEAD></HEAD><BODY><P>
-general utility classes.
-</P></BODY></HTML>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ClassLoaderUtils.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,84 @@
+/*
+ * 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.utils.resolver;
+
+// NOTE! This is a duplicate of utils.ClassLoaderUtils with public
+// modifiers changed to package-private. Make sure to integrate any future
+// changes to utils.ClassLoaderUtils to this file.
+final class ClassLoaderUtils {
+
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ClassLoaderUtils.class);
+
+    private ClassLoaderUtils() {
+    }
+
+    /**
+     * Load a class with a given name. <p></p> It will try to load the class in the
+     * following order:
+     * <ul>
+     * <li>From Thread.currentThread().getContextClassLoader()
+     * <li>Using the basic Class.forName()
+     * <li>From ClassLoaderUtil.class.getClassLoader()
+     * <li>From the callingClass.getClassLoader()
+     * </ul>
+     *
+     * @param className The name of the class to load
+     * @param callingClass The Class object of the calling object
+     * @throws ClassNotFoundException If the class cannot be found anywhere.
+     */
+    static Class<?> loadClass(String className, Class<?> callingClass)
+        throws ClassNotFoundException {
+        try {
+            ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
+            if (cl != null) {
+                return cl.loadClass(className);
+            }
+        } catch (ClassNotFoundException e) {
+            LOG.debug(e.getMessage(), e);
+            //ignore
+        }
+        return loadClass2(className, callingClass);
+    }
+
+    private static Class<?> loadClass2(String className, Class<?> callingClass)
+        throws ClassNotFoundException {
+        try {
+            return Class.forName(className);
+        } catch (ClassNotFoundException ex) {
+            try {
+                if (ClassLoaderUtils.class.getClassLoader() != null) {
+                    return ClassLoaderUtils.class.getClassLoader().loadClass(className);
+                }
+            } catch (ClassNotFoundException exc) {
+                if (callingClass != null && callingClass.getClassLoader() != null) {
+                    return callingClass.getClassLoader().loadClass(className);
+                }
+            }
+            LOG.debug(ex.getMessage(), ex);
+            throw ex;
+        }
+    }
+}
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -42,12 +42,11 @@
  */
 public class ResourceResolver {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(ResourceResolver.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ResourceResolver.class);
 
     /** these are the system-wide resolvers */
-    private static List<ResourceResolver> resolverList = new ArrayList<ResourceResolver>();
+    private static final List<ResourceResolver> resolverList = new ArrayList<>();
 
     /** Field resolverSpi */
     private final ResourceResolverSpi resolverSpi;
@@ -64,21 +63,7 @@
     /**
      * Method getInstance
      *
-     * @param uri
-     * @param baseURI
-     * @return the instance
-     *
-     * @throws ResourceResolverException
-     */
-    public static final ResourceResolver getInstance(Attr uri, String baseURI)
-        throws ResourceResolverException {
-        return getInstance(uri, baseURI, false);
-    }
-
-    /**
-     * Method getInstance
-     *
-     * @param uri
+     * @param uriAttr
      * @param baseURI
      * @param secureValidation
      * @return the instance
@@ -99,29 +84,26 @@
                 ResourceResolver resolverTmp = resolver;
                 if (!resolver.resolverSpi.engineIsThreadSafe()) {
                     try {
-                        resolverTmp =
+                        ResourceResolver tmp =
                             new ResourceResolver(resolver.resolverSpi.getClass().newInstance());
+                        resolverTmp = tmp;
                     } catch (InstantiationException e) {
-                        throw new ResourceResolverException("", e, context.attr, context.baseUri);
+                        throw new ResourceResolverException(e, context.uriToResolve, context.baseUri, "");
                     } catch (IllegalAccessException e) {
-                        throw new ResourceResolverException("", e, context.attr, context.baseUri);
+                        throw new ResourceResolverException(e, context.uriToResolve, context.baseUri, "");
                     }
                 }
 
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE,
-                        "check resolvability by class " + resolverTmp.getClass().getName()
-                    );
-                }
+                LOG.debug("check resolvability by class {}", resolverTmp.getClass().getName());
 
-                if ((resolverTmp != null) && resolverTmp.canResolve(context)) {
+                if (resolverTmp != null && resolverTmp.canResolve(context)) {
                     // Check to see whether the Resolver is allowed
                     if (context.secureValidation
                         && (resolverTmp.resolverSpi instanceof ResolverLocalFilesystem
                             || resolverTmp.resolverSpi instanceof ResolverDirectHTTP)) {
                         Object exArgs[] = { resolverTmp.resolverSpi.getClass().getName() };
                         throw new ResourceResolverException(
-                            "signature.Reference.ForbiddenResolver", exArgs, context.attr, context.baseUri
+                            "signature.Reference.ForbiddenResolver", exArgs, context.uriToResolve, context.baseUri
                         );
                     }
                     return resolverTmp;
@@ -129,10 +111,10 @@
             }
         }
 
-        Object exArgs[] = { ((context.uriToResolve != null)
-                ? context.uriToResolve : "null"), context.baseUri };
+        Object exArgs[] = { context.uriToResolve != null
+                ? context.uriToResolve : "null", context.baseUri };
 
-        throw new ResourceResolverException("utils.resolver.noClass", exArgs, context.attr, context.baseUri);
+        throw new ResourceResolverException("utils.resolver.noClass", exArgs, context.uriToResolve, context.baseUri);
     }
 
     /**
@@ -148,7 +130,7 @@
     public static ResourceResolver getInstance(
         Attr uri, String baseURI, List<ResourceResolver> individualResolvers
     ) throws ResourceResolverException {
-        return getInstance(uri, baseURI, individualResolvers, false);
+        return getInstance(uri, baseURI, individualResolvers, true);
     }
 
     /**
@@ -165,12 +147,10 @@
     public static ResourceResolver getInstance(
         Attr uri, String baseURI, List<ResourceResolver> individualResolvers, boolean secureValidation
     ) throws ResourceResolverException {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE,
-                "I was asked to create a ResourceResolver and got "
-                + (individualResolvers == null ? 0 : individualResolvers.size())
-            );
-        }
+        LOG.debug(
+            "I was asked to create a ResourceResolver and got {}",
+            (individualResolvers == null ? 0 : individualResolvers.size())
+        );
 
         ResourceResolverContext context = new ResourceResolverContext(uri, baseURI, secureValidation);
 
@@ -180,10 +160,8 @@
                 ResourceResolver resolver = individualResolvers.get(i);
 
                 if (resolver != null) {
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        String currentClass = resolver.resolverSpi.getClass().getName();
-                        log.log(java.util.logging.Level.FINE, "check resolvability by class " + currentClass);
-                    }
+                    String currentClass = resolver.resolverSpi.getClass().getName();
+                    LOG.debug("check resolvability by class {}", currentClass);
 
                     if (resolver.canResolve(context)) {
                         return resolver;
@@ -196,7 +174,7 @@
     }
 
     /**
-     * Registers a ResourceResolverSpi class. This method logs a warning if
+     * Registers a ResourceResolverSpi class. This method LOGs a warning if
      * the class cannot be registered.
      *
      * @param className the name of the ResourceResolverSpi class to be registered
@@ -208,16 +186,17 @@
         JavaUtils.checkRegisterPermission();
         try {
             Class<ResourceResolverSpi> resourceResolverClass =
-                (Class<ResourceResolverSpi>) Class.forName(className);
+                (Class<ResourceResolverSpi>)
+                ClassLoaderUtils.loadClass(className, ResourceResolver.class);
             register(resourceResolverClass, false);
         } catch (ClassNotFoundException e) {
-            log.log(java.util.logging.Level.WARNING, "Error loading resolver " + className + " disabling it");
+            LOG.warn("Error loading resolver " + className + " disabling it");
         }
     }
 
     /**
      * Registers a ResourceResolverSpi class at the beginning of the provider
-     * list. This method logs a warning if the class cannot be registered.
+     * list. This method LOGs a warning if the class cannot be registered.
      *
      * @param className the name of the ResourceResolverSpi class to be registered
      * @throws SecurityException if a security manager is installed and the
@@ -228,15 +207,16 @@
         JavaUtils.checkRegisterPermission();
         try {
             Class<ResourceResolverSpi> resourceResolverClass =
-                (Class<ResourceResolverSpi>) Class.forName(className);
+                (Class<ResourceResolverSpi>)
+                ClassLoaderUtils.loadClass(className, ResourceResolver.class);
             register(resourceResolverClass, true);
         } catch (ClassNotFoundException e) {
-            log.log(java.util.logging.Level.WARNING, "Error loading resolver " + className + " disabling it");
+            LOG.warn("Error loading resolver " + className + " disabling it");
         }
     }
 
     /**
-     * Registers a ResourceResolverSpi class. This method logs a warning if the class
+     * Registers a ResourceResolverSpi class. This method LOGs a warning if the class
      * cannot be registered.
      * @param className
      * @param start
@@ -249,14 +229,14 @@
             ResourceResolverSpi resourceResolverSpi = className.newInstance();
             register(resourceResolverSpi, start);
         } catch (IllegalAccessException e) {
-            log.log(java.util.logging.Level.WARNING, "Error loading resolver " + className + " disabling it");
+            LOG.warn("Error loading resolver " + className + " disabling it");
         } catch (InstantiationException e) {
-            log.log(java.util.logging.Level.WARNING, "Error loading resolver " + className + " disabling it");
+            LOG.warn("Error loading resolver " + className + " disabling it");
         }
     }
 
     /**
-     * Registers a ResourceResolverSpi instance. This method logs a warning if the class
+     * Registers a ResourceResolverSpi instance. This method LOGs a warning if the class
      * cannot be registered.
      * @param resourceResolverSpi
      * @param start
@@ -272,9 +252,7 @@
                 resolverList.add(new ResourceResolver(resourceResolverSpi));
             }
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Registered resolver: " + resourceResolverSpi.toString());
-        }
+        LOG.debug("Registered resolver: {}", resourceResolverSpi.toString());
     }
 
     /**
@@ -290,15 +268,6 @@
     }
 
     /**
-     * @deprecated New clients should use {@link #resolve(Attr, String, boolean)}
-     */
-    @Deprecated
-    public XMLSignatureInput resolve(Attr uri, String baseURI)
-        throws ResourceResolverException {
-        return resolve(uri, baseURI, true);
-    }
-
-    /**
      * Method resolve
      *
      * @param uri
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolverException.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolverException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,21 +23,19 @@
 package com.sun.org.apache.xml.internal.security.utils.resolver;
 
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
-import org.w3c.dom.Attr;
 
 /**
  * This Exception is thrown if something related to the
  * {@link com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver} goes wrong.
  *
- * @author $Author: coheigea $
  */
 public class ResourceResolverException extends XMLSecurityException {
 
     private static final long serialVersionUID = 1L;
 
-    private Attr uri = null;
+    private String uri;
 
-    private String baseURI = null;
+    private String baseURI;
 
     /**
      * Constructor ResourceResolverException
@@ -46,7 +44,7 @@
      * @param uri
      * @param baseURI
      */
-    public ResourceResolverException(String msgID, Attr uri, String baseURI) {
+    public ResourceResolverException(String msgID, String uri, String baseURI) {
         super(msgID);
 
         this.uri = uri;
@@ -61,7 +59,7 @@
      * @param uri
      * @param baseURI
      */
-    public ResourceResolverException(String msgID, Object exArgs[], Attr uri,
+    public ResourceResolverException(String msgID, Object exArgs[], String uri,
                                      String baseURI) {
         super(msgID, exArgs);
 
@@ -72,42 +70,54 @@
     /**
      * Constructor ResourceResolverException
      *
-     * @param msgID
      * @param originalException
      * @param uri
      * @param baseURI
+     * @param msgID
      */
-    public ResourceResolverException(String msgID, Exception originalException,
-                                     Attr uri, String baseURI) {
-        super(msgID, originalException);
+    public ResourceResolverException(Exception originalException,
+                                     String uri, String baseURI, String msgID) {
+        super(originalException, msgID);
 
         this.uri = uri;
         this.baseURI = baseURI;
     }
 
+    @Deprecated
+    public ResourceResolverException(String msgID, Exception originalException,
+                                     String uri, String baseURI) {
+        this(originalException, uri, baseURI, msgID);
+    }
+
     /**
      * Constructor ResourceResolverException
      *
-     * @param msgID
-     * @param exArgs
      * @param originalException
      * @param uri
      * @param baseURI
+     * @param msgID
+     * @param exArgs
      */
-    public ResourceResolverException(String msgID, Object exArgs[],
-                                     Exception originalException, Attr uri,
-                                     String baseURI) {
-        super(msgID, exArgs, originalException);
+    public ResourceResolverException(Exception originalException, String uri,
+                                     String baseURI, String msgID, Object exArgs[]) {
+        super(originalException, msgID, exArgs);
 
         this.uri = uri;
         this.baseURI = baseURI;
     }
 
+    @Deprecated
+    public ResourceResolverException(String msgID, Object exArgs[],
+                                     Exception originalException, String uri,
+                                     String baseURI) {
+        this(originalException, uri, baseURI, msgID, exArgs);
+    }
+
     /**
      *
      * @param uri
      */
-    public void setURI(Attr uri) {
+    public void setURI(String uri) {
         this.uri = uri;
     }
 
@@ -115,7 +125,7 @@
      *
      * @return the uri
      */
-    public Attr getURI() {
+    public String getURI() {
         return this.uri;
     }
 
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolverSpi.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolverSpi.java	Sat Oct 24 01:11:51 2020 +0100
@@ -26,47 +26,18 @@
 import java.util.Map;
 
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
-import org.w3c.dom.Attr;
 
 /**
  * During reference validation, we have to retrieve resources from somewhere.
  *
- * @author $Author: coheigea $
  */
 public abstract class ResourceResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(ResourceResolverSpi.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ResourceResolverSpi.class);
 
     /** Field properties */
-    protected java.util.Map<String, String> properties = null;
-
-    /**
-     * Deprecated - used to carry state about whether resolution was being done in a secure fashion,
-     * but was not thread safe, so the resolution information is now passed as parameters to methods.
-     *
-     * @deprecated Secure validation flag is now passed to methods.
-     */
-    @Deprecated
-    protected final boolean secureValidation = true;
-
-    /**
-     * This is the workhorse method used to resolve resources.
-     *
-     * @param uri
-     * @param BaseURI
-     * @return the resource wrapped around a XMLSignatureInput
-     *
-     * @throws ResourceResolverException
-     *
-     * @deprecated New clients should override {@link #engineResolveURI(ResourceResolverContext)}
-     */
-    @Deprecated
-    public XMLSignatureInput engineResolve(Attr uri, String BaseURI)
-        throws ResourceResolverException {
-        throw new UnsupportedOperationException();
-    }
+    protected Map<String, String> properties;
 
     /**
      * This is the workhorse method used to resolve resources.
@@ -76,12 +47,8 @@
      *
      * @throws ResourceResolverException
      */
-    public XMLSignatureInput engineResolveURI(ResourceResolverContext context)
-        throws ResourceResolverException {
-        // The default implementation, to preserve backwards compatibility in the
-        // test cases, calls the old resolver API.
-        return engineResolve(context.attr, context.baseUri);
-    }
+    public abstract XMLSignatureInput engineResolveURI(ResourceResolverContext context)
+        throws ResourceResolverException;
 
     /**
      * Method engineSetProperty
@@ -91,7 +58,7 @@
      */
     public void engineSetProperty(String key, String value) {
         if (properties == null) {
-            properties = new HashMap<String, String>();
+            properties = new HashMap<>();
         }
         properties.put(key, value);
     }
@@ -116,7 +83,7 @@
     public void engineAddProperies(Map<String, String> newProperties) {
         if (newProperties != null && !newProperties.isEmpty()) {
             if (properties == null) {
-                properties = new HashMap<String, String>();
+                properties = new HashMap<>();
             }
             properties.putAll(newProperties);
         }
@@ -125,7 +92,7 @@
     /**
      * Tells if the implementation does can be reused by several threads safely.
      * It normally means that the implementation does not have any member, or there is
-     * member change between engineCanResolve & engineResolve invocations. Or it maintains all
+     * member change between engineCanResolve and engineResolve invocations. Or it maintains all
      * member info in ThreadLocal methods.
      */
     public boolean engineIsThreadSafe() {
@@ -136,32 +103,10 @@
      * This method helps the {@link ResourceResolver} to decide whether a
      * {@link ResourceResolverSpi} is able to perform the requested action.
      *
-     * @param uri
-     * @param BaseURI
-     * @return true if the engine can resolve the uri
-     *
-     * @deprecated See {@link #engineCanResolveURI(ResourceResolverContext)}
-     */
-    @Deprecated
-    public boolean engineCanResolve(Attr uri, String BaseURI) {
-        // This method used to be abstract, so any calls to "super" are bogus.
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * This method helps the {@link ResourceResolver} to decide whether a
-     * {@link ResourceResolverSpi} is able to perform the requested action.
-     *
-     * <p>New clients should override this method, and not override {@link #engineCanResolve(Attr, String)}
-     * </p>
      * @param context Context in which to do resolution.
      * @return true if the engine can resolve the uri
      */
-    public boolean engineCanResolveURI(ResourceResolverContext context) {
-        // To preserve backward compatibility with existing resolvers that might override the old method,
-        // call the old deprecated API.
-        return engineCanResolve( context.attr, context.baseUri );
-    }
+    public abstract boolean engineCanResolveURI(ResourceResolverContext context);
 
     /**
      * Method engineGetPropertyKeys
@@ -182,8 +127,8 @@
         String[] understood = this.engineGetPropertyKeys();
 
         if (understood != null) {
-            for (int i = 0; i < understood.length; i++) {
-                if (understood[i].equals(propertyToTest)) {
+            for (String str : understood) {
+                if (str.equals(propertyToTest)) {
                     return true;
                 }
             }
@@ -212,12 +157,12 @@
             char ch1 = str.charAt(1);
             char ch2 = str.charAt(2);
             char ch3 = str.charAt(3);
-            boolean isDosFilename = ((('A' <= ch0) && (ch0 <= 'Z'))
-                && (ch1 == ':') && (ch2 == '/')
-                && (ch3 != '/'));
+            boolean isDosFilename = 'A' <= ch0 && ch0 <= 'Z'
+                && ch1 == ':' && ch2 == '/'
+                && ch3 != '/';
 
-            if (isDosFilename && log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Found DOS filename: " + str);
+            if (isDosFilename) {
+                LOG.debug("Found DOS filename: {}", str);
             }
         }
 
@@ -228,7 +173,7 @@
             if (ch1 == ':') {
                 char ch0 = Character.toUpperCase(str.charAt(0));
 
-                if (('A' <= ch0) && (ch0 <= 'Z')) {
+                if ('A' <= ch0 && ch0 <= 'Z') {
                     str = "/" + str;
                 }
             }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverAnonymous.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverAnonymous.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,21 +23,21 @@
 
 package com.sun.org.apache.xml.internal.security.utils.resolver.implementations;
 
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverContext;
 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverSpi;
 
 /**
- * @author $Author: coheigea $
  */
 public class ResolverAnonymous extends ResourceResolverSpi {
 
-    private InputStream inStream = null;
+    private InputStream inStream;
 
     @Override
     public boolean engineIsThreadSafe() {
@@ -50,7 +50,7 @@
      * @throws IOException
      */
     public ResolverAnonymous(String filename) throws FileNotFoundException, IOException {
-        inStream = new FileInputStream(filename);
+        inStream = Files.newInputStream(Paths.get(filename));
     }
 
     /**
@@ -60,14 +60,16 @@
         inStream = is;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     @Override
     public XMLSignatureInput engineResolveURI(ResourceResolverContext context) {
-        return new XMLSignatureInput(inStream);
+        XMLSignatureInput input = new XMLSignatureInput(inStream);
+        input.setSecureValidation(context.secureValidation);
+        return input;
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     @Override
     public boolean engineCanResolveURI(ResourceResolverContext context) {
@@ -77,7 +79,7 @@
         return false;
     }
 
-    /** @inheritDoc */
+    /** {@inheritDoc} */
     public String[] engineGetPropertyKeys() {
         return new String[0];
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java	Sat Oct 24 01:11:51 2020 +0100
@@ -32,9 +32,10 @@
 import java.net.URI;
 import java.net.URL;
 import java.net.URLConnection;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
 
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
-import com.sun.org.apache.xml.internal.security.utils.Base64;
 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverContext;
 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException;
 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverSpi;
@@ -61,9 +62,8 @@
  */
 public class ResolverDirectHTTP extends ResourceResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(ResolverDirectHTTP.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ResolverDirectHTTP.class);
 
     /** Field properties[] */
     private static final String properties[] = {
@@ -96,26 +96,17 @@
     }
 
     /**
-     * Method resolve
-     *
-     * @param uri
-     * @param baseURI
-     *
-     * @throws ResourceResolverException
-     * @return
-     * $todo$ calculate the correct URI from the attribute and the baseURI
+     * {@inheritDoc}
      */
     @Override
     public XMLSignatureInput engineResolveURI(ResourceResolverContext context)
         throws ResourceResolverException {
-        InputStream inputStream = null;
+
         try {
-
             // calculate new URI
             URI uriNew = getNewURI(context.uriToResolve, context.baseUri);
             URL url = uriNew.toURL();
-            URLConnection urlConnection;
-            urlConnection = openConnection(url);
+            URLConnection urlConnection = openConnection(url);
 
             // check if Basic authentication is required
             String auth = urlConnection.getHeaderField("WWW-Authenticate");
@@ -127,11 +118,11 @@
                 String pass =
                     engineGetProperty(ResolverDirectHTTP.properties[ResolverDirectHTTP.HttpBasicPass]);
 
-                if ((user != null) && (pass != null)) {
+                if (user != null && pass != null) {
                     urlConnection = openConnection(url);
 
                     String password = user + ":" + pass;
-                    String encodedPassword = Base64.encode(password.getBytes("ISO-8859-1"));
+                    String encodedPassword = Base64.getMimeEncoder().encodeToString(password.getBytes(StandardCharsets.ISO_8859_1));
 
                     // set authentication property in the http header
                     urlConnection.setRequestProperty("Authorization",
@@ -140,45 +131,36 @@
             }
 
             String mimeType = urlConnection.getHeaderField("Content-Type");
-            inputStream = urlConnection.getInputStream();
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            byte buf[] = new byte[4096];
-            int read = 0;
-            int summarized = 0;
+            try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                InputStream inputStream = urlConnection.getInputStream()) {
+                byte[] buf = new byte[4096];
+                int read = 0;
+                int summarized = 0;
 
-            while ((read = inputStream.read(buf)) >= 0) {
-                baos.write(buf, 0, read);
-                summarized += read;
-            }
+                while ((read = inputStream.read(buf)) >= 0) {
+                    baos.write(buf, 0, read);
+                    summarized += read;
+                }
+
+                LOG.debug("Fetched {} bytes from URI {}", summarized, uriNew.toString());
 
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Fetched " + summarized + " bytes from URI " + uriNew.toString());
+                XMLSignatureInput result = new XMLSignatureInput(baos.toByteArray());
+                result.setSecureValidation(context.secureValidation);
+
+                result.setSourceURI(uriNew.toString());
+                result.setMIMEType(mimeType);
+
+                return result;
             }
 
-            XMLSignatureInput result = new XMLSignatureInput(baos.toByteArray());
-
-            result.setSourceURI(uriNew.toString());
-            result.setMIMEType(mimeType);
-
-            return result;
         } catch (URISyntaxException ex) {
-            throw new ResourceResolverException("generic.EmptyMessage", ex, context.attr, context.baseUri);
+            throw new ResourceResolverException(ex, context.uriToResolve, context.baseUri, "generic.EmptyMessage");
         } catch (MalformedURLException ex) {
-            throw new ResourceResolverException("generic.EmptyMessage", ex, context.attr, context.baseUri);
+            throw new ResourceResolverException(ex, context.uriToResolve, context.baseUri, "generic.EmptyMessage");
         } catch (IOException ex) {
-            throw new ResourceResolverException("generic.EmptyMessage", ex, context.attr, context.baseUri);
+            throw new ResourceResolverException(ex, context.uriToResolve, context.baseUri, "generic.EmptyMessage");
         } catch (IllegalArgumentException e) {
-            throw new ResourceResolverException("generic.EmptyMessage", e, context.attr, context.baseUri);
-        } finally {
-            if (inputStream != null) {
-                try {
-                    inputStream.close();
-                } catch (IOException e) {
-                    if (log.isLoggable(java.util.logging.Level.FINE)) {
-                        log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-                    }
-                }
-            }
+            throw new ResourceResolverException(e, context.uriToResolve, context.baseUri, "generic.EmptyMessage");
         }
     }
 
@@ -194,7 +176,7 @@
                 engineGetProperty(ResolverDirectHTTP.properties[ResolverDirectHTTP.HttpProxyPass]);
 
         Proxy proxy = null;
-        if ((proxyHostProp != null) && (proxyPortProp != null)) {
+        if (proxyHostProp != null && proxyPortProp != null) {
             int port = Integer.parseInt(proxyPortProp);
             proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHostProp, port));
         }
@@ -203,9 +185,9 @@
         if (proxy != null) {
             urlConnection = url.openConnection(proxy);
 
-            if ((proxyUser != null) && (proxyPass != null)) {
+            if (proxyUser != null && proxyPass != null) {
                 String password = proxyUser + ":" + proxyPass;
-                String authString = "Basic " + Base64.encode(password.getBytes("ISO-8859-1"));
+                String authString = "Basic " + Base64.getMimeEncoder().encodeToString(password.getBytes(StandardCharsets.ISO_8859_1));
 
                 urlConnection.setRequestProperty("Proxy-Authorization", authString);
             }
@@ -219,46 +201,35 @@
     /**
      * We resolve http URIs <I>without</I> fragment...
      *
-     * @param uri
-     * @param baseURI
+     * @param context
      * @return true if can be resolved
      */
     public boolean engineCanResolveURI(ResourceResolverContext context) {
         if (context.uriToResolve == null) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "quick fail, uri == null");
-            }
+            LOG.debug("quick fail, uri == null");
             return false;
         }
 
-        if (context.uriToResolve.equals("") || (context.uriToResolve.charAt(0)=='#')) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "quick fail for empty URIs and local ones");
-            }
+        if (context.uriToResolve.equals("") || context.uriToResolve.charAt(0) == '#') {
+            LOG.debug("quick fail for empty URIs and local ones");
             return false;
         }
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "I was asked whether I can resolve " + context.uriToResolve);
-        }
+        LOG.debug("I was asked whether I can resolve {}", context.uriToResolve);
 
         if (context.uriToResolve.startsWith("http:") ||
-            (context.baseUri != null && context.baseUri.startsWith("http:") )) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I state that I can resolve " + context.uriToResolve);
-            }
+            context.baseUri != null && context.baseUri.startsWith("http:")) {
+            LOG.debug("I state that I can resolve {}", context.uriToResolve);
             return true;
         }
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "I state that I can't resolve " + context.uriToResolve);
-        }
+        LOG.debug("I state that I can't resolve {}", context.uriToResolve);
 
         return false;
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     public String[] engineGetPropertyKeys() {
         return ResolverDirectHTTP.properties.clone();
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverFragment.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverFragment.java	Sat Oct 24 01:11:51 2020 +0100
@@ -34,16 +34,14 @@
 /**
  * This resolver is used for resolving same-document URIs like URI="" of URI="#id".
  *
- * @author $Author: coheigea $
  * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#sec-ReferenceProcessingModel">The Reference processing model in the XML Signature spec</A>
  * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#sec-Same-Document">Same-Document URI-References in the XML Signature spec</A>
  * @see <A HREF="http://www.ietf.org/rfc/rfc2396.txt">Section 4.2 of RFC 2396</A>
  */
 public class ResolverFragment extends ResourceResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(ResolverFragment.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ResolverFragment.class);
 
     @Override
     public boolean engineIsThreadSafe() {
@@ -51,12 +49,9 @@
     }
 
     /**
-     * Method engineResolve
-     *
-     * @inheritDoc
-     * @param uri
-     * @param baseURI
+     * {@inheritDoc}
      */
+    @Override
     public XMLSignatureInput engineResolveURI(ResourceResolverContext context)
         throws ResourceResolverException {
 
@@ -68,9 +63,7 @@
              * Identifies the node-set (minus any comment nodes) of the XML
              * resource containing the signature
              */
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "ResolverFragment with empty URI (means complete document)");
-            }
+            LOG.debug("ResolverFragment with empty URI (means complete document)");
             selectedElem = doc;
         } else {
             /*
@@ -87,7 +80,7 @@
             if (selectedElem == null) {
                 Object exArgs[] = { id };
                 throw new ResourceResolverException(
-                    "signature.Verification.MissingID", exArgs, context.attr, context.baseUri
+                    "signature.Verification.MissingID", exArgs, context.uriToResolve, context.baseUri
                 );
             }
             if (context.secureValidation) {
@@ -95,18 +88,17 @@
                 if (!XMLUtils.protectAgainstWrappingAttack(start, id)) {
                     Object exArgs[] = { id };
                     throw new ResourceResolverException(
-                        "signature.Verification.MultipleIDs", exArgs, context.attr, context.baseUri
+                        "signature.Verification.MultipleIDs", exArgs, context.uriToResolve, context.baseUri
                     );
                 }
             }
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE,
-                    "Try to catch an Element with ID " + id + " and Element was " + selectedElem
-                );
-            }
+            LOG.debug(
+                "Try to catch an Element with ID {} and Element was {}", id, selectedElem
+            );
         }
 
         XMLSignatureInput result = new XMLSignatureInput(selectedElem);
+        result.setSecureValidation(context.secureValidation);
         result.setExcludeComments(true);
 
         result.setMIMEType("text/xml");
@@ -120,29 +112,22 @@
 
     /**
      * Method engineCanResolve
-     * @inheritDoc
-     * @param uri
-     * @param baseURI
+     * {@inheritDoc}
+     * @param context
      */
     public boolean engineCanResolveURI(ResourceResolverContext context) {
         if (context.uriToResolve == null) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Quick fail for null uri");
-            }
+            LOG.debug("Quick fail for null uri");
             return false;
         }
 
         if (context.uriToResolve.equals("") ||
-            ((context.uriToResolve.charAt(0) == '#') && !context.uriToResolve.startsWith("#xpointer("))
+            context.uriToResolve.charAt(0) == '#' && !context.uriToResolve.startsWith("#xpointer(")
         ) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "State I can resolve reference: \"" + context.uriToResolve + "\"");
-            }
+            LOG.debug("State I can resolve reference: \"{}\"", context.uriToResolve);
             return true;
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Do not seem to be able to resolve reference: \"" + context.uriToResolve + "\"");
-        }
+        LOG.debug("Do not seem to be able to resolve reference: \"{}\"", context.uriToResolve);
         return false;
     }
 
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java	Sat Oct 24 01:11:51 2020 +0100
@@ -22,9 +22,11 @@
  */
 package com.sun.org.apache.xml.internal.security.utils.resolver.implementations;
 
-import java.io.FileInputStream;
+import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverContext;
@@ -38,9 +40,8 @@
 
     private static final int FILE_URI_LENGTH = "file:/".length();
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(ResolverLocalFilesystem.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ResolverLocalFilesystem.class);
 
     @Override
     public boolean engineIsThreadSafe() {
@@ -48,7 +49,7 @@
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     @Override
     public XMLSignatureInput engineResolveURI(ResourceResolverContext context)
@@ -59,14 +60,15 @@
 
             String fileName =
                 ResolverLocalFilesystem.translateUriToFilename(uriNew.toString());
-            FileInputStream inputStream = new FileInputStream(fileName);
+            InputStream inputStream = Files.newInputStream(Paths.get(fileName));
             XMLSignatureInput result = new XMLSignatureInput(inputStream);
+            result.setSecureValidation(context.secureValidation);
 
             result.setSourceURI(uriNew.toString());
 
             return result;
         } catch (Exception e) {
-            throw new ResourceResolverException("generic.EmptyMessage", e, context.attr, context.baseUri);
+            throw new ResourceResolverException(e, context.uriToResolve, context.baseUri, "generic.EmptyMessage");
         }
     }
 
@@ -106,38 +108,30 @@
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     public boolean engineCanResolveURI(ResourceResolverContext context) {
         if (context.uriToResolve == null) {
             return false;
         }
 
-        if (context.uriToResolve.equals("") || (context.uriToResolve.charAt(0)=='#') ||
+        if (context.uriToResolve.equals("") || context.uriToResolve.charAt(0) == '#' ||
             context.uriToResolve.startsWith("http:")) {
             return false;
         }
 
         try {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "I was asked whether I can resolve " + context.uriToResolve);
-            }
+            LOG.debug("I was asked whether I can resolve {}", context.uriToResolve);
 
             if (context.uriToResolve.startsWith("file:") || context.baseUri.startsWith("file:")) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "I state that I can resolve " + context.uriToResolve);
-                }
+                LOG.debug("I state that I can resolve {}", context.uriToResolve);
                 return true;
             }
         } catch (Exception e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
+            LOG.debug(e.getMessage(), e);
         }
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "But I can't");
-        }
+        LOG.debug("But I can't");
 
         return false;
     }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverXPointer.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverXPointer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -33,10 +33,10 @@
 
 /**
  * Handles barename XPointer Reference URIs.
- * <BR />
+ * <p></p>
  * To retain comments while selecting an element by an identifier ID,
  * use the following full XPointer: URI='#xpointer(id('ID'))'.
- * <BR />
+ * <p></p>
  * To retain comments while selecting the entire document,
  * use the following full XPointer: URI='#xpointer(/)'.
  * This XPointer contains a simple XPath expression that includes
@@ -44,13 +44,11 @@
  * nodes of the parse tree (all descendants, plus all attributes,
  * plus all namespaces nodes).
  *
- * @author $Author: coheigea $
  */
 public class ResolverXPointer extends ResourceResolverSpi {
 
-    /** {@link org.apache.commons.logging} logging facility */
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger(ResolverXPointer.class.getName());
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ResolverXPointer.class);
 
     private static final String XP = "#xpointer(id(";
     private static final int XP_LENGTH = XP.length();
@@ -61,7 +59,7 @@
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     @Override
     public XMLSignatureInput engineResolveURI(ResourceResolverContext context)
@@ -81,7 +79,7 @@
                 if (!XMLUtils.protectAgainstWrappingAttack(start, id)) {
                     Object exArgs[] = { id };
                     throw new ResourceResolverException(
-                        "signature.Verification.MultipleIDs", exArgs, context.attr, context.baseUri
+                        "signature.Verification.MultipleIDs", exArgs, context.uriToResolve, context.baseUri
                     );
                 }
             }
@@ -90,12 +88,13 @@
                 Object exArgs[] = { id };
 
                 throw new ResourceResolverException(
-                    "signature.Verification.MissingID", exArgs, context.attr, context.baseUri
+                    "signature.Verification.MissingID", exArgs, context.uriToResolve, context.baseUri
                 );
             }
         }
 
         XMLSignatureInput result = new XMLSignatureInput(resultNode);
+        result.setSecureValidation(context.secureValidation);
 
         result.setMIMEType("text/xml");
         if (context.baseUri != null && context.baseUri.length() > 0) {
@@ -108,7 +107,7 @@
     }
 
     /**
-     * @inheritDoc
+     * {@inheritDoc}
      */
     public boolean engineCanResolveURI(ResourceResolverContext context) {
         if (context.uriToResolve == null) {
@@ -146,11 +145,9 @@
             String idPlusDelim = uri.substring(XP_LENGTH, uri.length() - 2);
 
             int idLen = idPlusDelim.length() -1;
-            if (((idPlusDelim.charAt(0) == '"') && (idPlusDelim.charAt(idLen) == '"'))
-                || ((idPlusDelim.charAt(0) == '\'') && (idPlusDelim.charAt(idLen) == '\''))) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Id = " + idPlusDelim.substring(1, idLen));
-                }
+            if (idPlusDelim.charAt(0) == '"' && idPlusDelim.charAt(idLen) == '"'
+                || idPlusDelim.charAt(0) == '\'' && idPlusDelim.charAt(idLen) == '\'') {
+                LOG.debug("Id = {}", idPlusDelim.substring(1, idLen));
                 return true;
             }
         }
@@ -166,11 +163,11 @@
      */
     private static String getXPointerId(String uri) {
         if (uri.startsWith(XP) && uri.endsWith("))")) {
-            String idPlusDelim = uri.substring(XP_LENGTH,uri.length() - 2);
+            String idPlusDelim = uri.substring(XP_LENGTH, uri.length() - 2);
 
             int idLen = idPlusDelim.length() -1;
-            if (((idPlusDelim.charAt(0) == '"') && (idPlusDelim.charAt(idLen) == '"'))
-                || ((idPlusDelim.charAt(0) == '\'') && (idPlusDelim.charAt(idLen) == '\''))) {
+            if (idPlusDelim.charAt(0) == '"' && idPlusDelim.charAt(idLen) == '"'
+                || idPlusDelim.charAt(0) == '\'' && idPlusDelim.charAt(idLen) == '\'') {
                 return idPlusDelim.substring(1, idLen);
             }
         }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<HTML> 
-<HEAD> </HEAD> 
-<BODY> 
-<P>
-implememtations of different ResourceResolver classes used to resolve ds:Reference URIs.
-</P>
-</BODY> 
-</HTML>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/package.html	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<HTML> 
-<HEAD> </HEAD> 
-<BODY> 
-<P>
-the ResourceResolver classes used to resolve ds:Reference URIs.
-</P>
-</BODY> 
-</HTML>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/org/slf4j/internal/Logger.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,79 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 com.sun.org.slf4j.internal;
+
+// Bridge to java.util.logging.
+public class Logger {
+
+    private final java.util.logging.Logger impl;
+
+    public Logger(String name) {
+        impl = java.util.logging.Logger.getLogger(name);
+    }
+
+    public boolean isDebugEnabled() {
+        return impl.isLoggable(java.util.logging.Level.FINE);
+    }
+
+    public boolean isTraceEnabled() {
+        return impl.isLoggable(java.util.logging.Level.FINE);
+    }
+
+    public void debug(String s) {
+        impl.log(java.util.logging.Level.FINE, s);
+    }
+
+    public void debug(String s, Throwable e) {
+        impl.log(java.util.logging.Level.FINE, s, e);
+    }
+
+    public void debug(String s, Object... o) {
+        impl.log(java.util.logging.Level.FINE, s, o);
+    }
+
+    public void trace(String s) {
+        impl.log(java.util.logging.Level.FINE, s);
+    }
+
+    public void error(String s) {
+        impl.log(java.util.logging.Level.SEVERE, s);
+    }
+
+    public void error(String s, Throwable e) {
+        impl.log(java.util.logging.Level.SEVERE, s, e);
+    }
+
+    public void error(String s, Object... o) {
+        impl.log(java.util.logging.Level.SEVERE, s, o);
+    }
+
+    public void warn(String s) {
+        impl.log(java.util.logging.Level.WARNING, s);
+    }
+
+    public void warn(String s, Throwable e) {
+        impl.log(java.util.logging.Level.WARNING, s, e);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/org/slf4j/internal/LoggerFactory.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 com.sun.org.slf4j.internal;
+
+// Bridge to java.util.logging.
+public class LoggerFactory {
+
+    public static Logger getLogger(Class<?> clazz) {
+        return new Logger(clazz.getName());
+    }
+}
--- a/src/share/classes/com/sun/security/ntlm/NTLM.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/security/ntlm/NTLM.java	Sat Oct 24 01:11:51 2020 +0100
@@ -167,7 +167,7 @@
 
         byte[] readSecurityBuffer(int offset) throws NTLMException {
             int pos = readInt(offset+4);
-            if (pos == 0) return null;
+            if (pos == 0) return new byte[0];
             try {
                 return Arrays.copyOfRange(
                         internal, pos, pos + readShort(offset));
--- a/src/share/classes/com/sun/tools/example/debug/tty/TTY.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/com/sun/tools/example/debug/tty/TTY.java	Sat Oct 24 01:11:51 2020 +0100
@@ -40,6 +40,7 @@
 import com.sun.jdi.connect.*;
 
 import java.util.*;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.io.*;
 
 public class TTY implements EventNotifier {
@@ -48,7 +49,7 @@
     /**
      * List of Strings to execute at each stop.
      */
-    private List<String> monitorCommands = new ArrayList<String>();
+    private List<String> monitorCommands = new CopyOnWriteArrayList<>();
     private int monitorCount = 0;
 
     /**
--- a/src/share/classes/java/util/concurrent/ForkJoinPool.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/java/util/concurrent/ForkJoinPool.java	Sat Oct 24 01:11:51 2020 +0100
@@ -728,7 +728,7 @@
     static final class DefaultForkJoinWorkerThreadFactory
         implements ForkJoinWorkerThreadFactory {
         public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
-            return new ForkJoinWorkerThread(pool);
+            return new ForkJoinWorkerThread(pool, true);
         }
     }
 
--- a/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Sat Oct 24 01:11:51 2020 +0100
@@ -87,7 +87,19 @@
     protected ForkJoinWorkerThread(ForkJoinPool pool) {
         // Use a placeholder until a useful name can be set in registerWorker
         super("aForkJoinWorkerThread");
-        U.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, INNOCUOUS_ACC);
+        this.pool = pool;
+        this.workQueue = pool.registerWorker(this);
+    }
+
+    /**
+     * Version for use by the default pool.  This is a separate constructor to
+     * avoid affecting the protected constructor.
+     */
+    ForkJoinWorkerThread(ForkJoinPool pool, boolean innocuous) {
+        super("aForkJoinWorkerThread");
+        if (innocuous) {
+            U.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, INNOCUOUS_ACC);
+        }
         this.pool = pool;
         this.workQueue = pool.registerWorker(this);
     }
--- a/src/share/classes/javax/sound/midi/Sequence.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/javax/sound/midi/Sequence.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -266,11 +266,7 @@
      * @see #getTracks
      */
     public boolean deleteTrack(Track track) {
-
-        synchronized(tracks) {
-
-            return tracks.removeElement(track);
-        }
+        return tracks.removeElement(track);
     }
 
 
@@ -283,8 +279,8 @@
      * @see #deleteTrack
      */
     public Track[] getTracks() {
-
-        return (Track[]) tracks.toArray(new Track[tracks.size()]);
+        // Creation of the non-empty array will be synchronized inside toArray()
+        return tracks.toArray(new Track[0]);
     }
 
 
--- a/src/share/classes/javax/xml/crypto/dsig/DigestMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/javax/xml/crypto/dsig/DigestMethod.java	Sat Oct 24 01:11:51 2020 +0100
@@ -60,29 +60,31 @@
  */
 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.
      */
-    static final String SHA1 = "http://www.w3.org/2000/09/xmldsig#sha1";
+    String SHA1 = "http://www.w3.org/2000/09/xmldsig#sha1";
 
     /**
      * The <a href="http://www.w3.org/2001/04/xmlenc#sha256">
      * SHA256</a> digest method algorithm URI.
      */
-    static final String SHA256 = "http://www.w3.org/2001/04/xmlenc#sha256";
+    String SHA256 = "http://www.w3.org/2001/04/xmlenc#sha256";
 
     /**
      * The <a href="http://www.w3.org/2001/04/xmlenc#sha512">
      * SHA512</a> digest method algorithm URI.
      */
-    static final String SHA512 = "http://www.w3.org/2001/04/xmlenc#sha512";
+    String SHA512 = "http://www.w3.org/2001/04/xmlenc#sha512";
 
     /**
      * The <a href="http://www.w3.org/2001/04/xmlenc#ripemd160">
      * RIPEMD-160</a> digest method algorithm URI.
      */
-    static final String RIPEMD160 = "http://www.w3.org/2001/04/xmlenc#ripemd160";
+    String RIPEMD160 = "http://www.w3.org/2001/04/xmlenc#ripemd160";
 
     /**
      * Returns the algorithm-specific input parameters associated with this
--- a/src/share/classes/javax/xml/crypto/dsig/SignatureMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/javax/xml/crypto/dsig/SignatureMethod.java	Sat Oct 24 01:11:51 2020 +0100
@@ -61,25 +61,27 @@
  */
 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">DSAwithSHA1</a>
+     * The <a href="http://www.w3.org/2000/09/xmldsig#dsa-sha1">DSA-SHA1</a>
      * (DSS) signature method algorithm URI.
      */
-    static final String DSA_SHA1 =
+    String DSA_SHA1 =
         "http://www.w3.org/2000/09/xmldsig#dsa-sha1";
 
     /**
-     * The <a href="http://www.w3.org/2000/09/xmldsig#rsa-sha1">RSAwithSHA1</a>
+     * The <a href="http://www.w3.org/2000/09/xmldsig#rsa-sha1">RSA-SHA1</a>
      * (PKCS #1) signature method algorithm URI.
      */
-    static final String RSA_SHA1 =
+    String RSA_SHA1 =
         "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
 
     /**
      * The <a href="http://www.w3.org/2000/09/xmldsig#hmac-sha1">HMAC-SHA1</a>
      * MAC signature method algorithm URI
      */
-    static final String HMAC_SHA1 =
+    String HMAC_SHA1 =
         "http://www.w3.org/2000/09/xmldsig#hmac-sha1";
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/platform/Container.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,43 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 jdk.internal.platform;
+
+/*
+ * @author bobv
+ */
+public class Container {
+
+    private Container() { }
+
+    /**
+     * Returns the platform specific Container Metrics class or
+     * null if not supported on this platform.
+     *
+     * @return Metrics instance or null if not supported
+     */
+    public static Metrics metrics() {
+        return Metrics.systemMetrics();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/platform/Metrics.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,507 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 jdk.internal.platform;
+
+import java.lang.reflect.Method;
+
+/**
+ * Operating System Metrics class
+ *
+ * @implNote Some of the APIs within this class return metrics for an
+ * "Isolation Group" or "Container".  When the term "Isolation Group"
+ * is used in the API description, this refers to either:
+ *
+ *<ol>
+ *<li> All processes, including the current process within a container.
+ *
+ *<li> All processes, including the current process running together
+ *    isolated from other non-isolated processes.
+ *
+ *<li> All processes running on a host when that there is no isolation
+ *     in effect.
+ *</ol>
+ *
+ * @author bobv
+ */
+
+public interface Metrics {
+
+    /**
+     * Returns an instance of the Metrics class.
+     *
+     * @return Metrics object or null if not supported on this platform.
+     */
+    public static Metrics systemMetrics() {
+        try {
+            // We currently only support cgroupv1
+            Class<?> c = Class.forName("jdk.internal.platform.cgroupv1.Metrics");
+            @SuppressWarnings("unchecked")
+            Method m = c.getMethod("getInstance");
+            return (Metrics) m.invoke(null);
+        } catch (ClassNotFoundException e) {
+            return null;
+        } catch (ReflectiveOperationException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    /**
+     * Returns the interface responsible for providing the
+     * platform metrics.
+     *
+     * @implNote
+     * Metrics are currently only supported Linux.
+     * The provider for Linux is cgroupsv1.
+     *
+     * @return The name of the provider.
+     *
+     */
+    public String getProvider();
+
+
+    /*****************************************************************
+     * CPU Accounting Subsystem
+     ****************************************************************/
+
+    /**
+     * Returns the aggregate time, in nanoseconds, consumed by all
+     * tasks in the Isolation Group.
+     *
+     * @return Time in nanoseconds or 0L if metric is not available.
+     *
+     */
+    public long getCpuUsage();
+
+    /**
+     * Returns the aggregate time, in nanoseconds, consumed by all tasks in
+     * the Isolation Group, separated by CPU. If the current process
+     * is running within a container, the reported time will only be
+     * valid for processes running within the same container.  The values
+     * are returned in an array, one entry for each physical processor
+     * on the system.  Time values for processors unavailable to this
+     * Group are undefined.
+     *
+     * @return long array of time values.  The size of the array is equal
+     *         to the total number of physical processors in the system. If
+     *         this metric is not available, a zero length array will be
+     *         returned.
+     *
+     */
+    public long[] getPerCpuUsage();
+
+    /**
+     * Returns the aggregate user time, in nanoseconds, consumed by all
+     * tasks in the Isolation Group.
+     *
+     * @return User time in nanoseconds or 0L if metric is not available.
+     *
+     */
+    public long getCpuUserUsage();
+
+    /**
+     * Returns the aggregate system time, in nanoseconds, consumed by
+     * all tasks in the Isolation Group.
+     *
+     * @return System time in nanoseconds or 0L if metric is not available.
+     *
+     */
+    public long getCpuSystemUsage();
+
+    /*****************************************************************
+     * CPU Scheduling Metrics
+     ****************************************************************/
+
+    /**
+     * Returns the length of the scheduling period, in
+     * microseconds, for processes within the Isolation Group.
+     *
+     * @return time in microseconds or 0L if metric is not available.
+     *
+     */
+    public long getCpuPeriod();
+
+    /**
+     * Returns the total available run-time allowed, in microseconds,
+     * during each scheduling period for all tasks in the Isolation
+     * Group.
+     *
+     * @return time in microseconds or -1 if the quota is unlimited.
+     *
+     */
+    public long getCpuQuota();
+
+
+    /**
+     * Returns the relative weighting of processes with the Isolation
+     * Group used for prioritizing the scheduling of processes across
+     * all Isolation Groups running on a host.
+     *
+     * @implNote
+     * Popular container orchestration systems have standardized shares
+     * to be multiples of 1024, where 1024 is interpreted as 1 CPU share
+     * of execution.  Users can distribute CPU resources to multiple
+     * Isolation Groups by specifying the CPU share weighting needed by
+     * each process.  To request 2 CPUS worth of execution time, CPU shares
+     * would be set to 2048.
+     *
+     * @return shares value or -1 if no share set.
+     *
+     */
+    public long getCpuShares();
+
+    /**
+     * Returns the number of time-slice periods that have elapsed if
+     * a CPU quota has been setup for the Isolation Group; otherwise
+     * returns 0.
+     *
+     * @return count of elapsed periods or 0 if the quota is unlimited.
+     *
+     */
+    public long getCpuNumPeriods();
+
+    /**
+     * Returns the number of time-slice periods that the group has
+     * been throttled or limited due to the group exceeding its quota
+     * if a CPU quota has been setup for the Isolation Group.
+     *
+     * @return count of throttled periods or 0 if the quota is unlimited.
+     *
+     */
+    public long getCpuNumThrottled();
+
+    /**
+     * Returns the total time duration, in nanoseconds, that the
+     * group has been throttled or limited due to the group exceeding
+     * its quota if a CPU quota has been setup for the Isolation Group.
+     *
+     * @return Throttled time in nanoseconds or 0 if the quota is unlimited.
+     *
+     */
+    public long getCpuThrottledTime();
+
+
+    /**
+     * Returns the number of effective processors that this Isolation
+     * group has available to it.  This effective processor count is
+     * computed based on the number of dedicated CPUs, CPU shares and
+     * CPU quotas in effect for this isolation group.
+     *
+     * This method returns the same value as
+     * {@link java.lang.Runtime#availableProcessors()}.
+     *
+     * @return The number of effective CPUs.
+     *
+     */
+    public long getEffectiveCpuCount();
+
+    /*****************************************************************
+     * CPU Sets
+     ****************************************************************/
+
+    /**
+     * Returns the CPUS that are available for execution of processes
+     * in the current Isolation Group. The size of the array is equal
+     * to the total number of CPUs and the elements in the array are the
+     * physical CPU numbers that are available.  Some of the CPUs returned
+     * may be offline.  To get the current online CPUs, use
+     * {@link getEffectiveCpuSetCpus()}.
+     *
+     * @return An array of available CPUs or a zero length array
+     *         if the metric is not available.
+     *
+     */
+    public int[] getCpuSetCpus();
+
+    /**
+     * Returns the CPUS that are available and online for execution of
+     * processes within the current Isolation Group. The size of the
+     * array is equal to the total number of CPUs and the elements in
+     * the array are the physical CPU numbers.
+     *
+     * @return An array of available and online CPUs or a zero length
+     *         array if the metric is not available.
+     *
+     */
+    public int[] getEffectiveCpuSetCpus();
+
+    /**
+     * Returns the memory nodes that are available for use by processes
+     * in the current Isolation Group. The size of the array is equal
+     * to the total number of nodes and the elements in the array are the
+     * physical node numbers that are available.  Some of the nodes returned
+     * may be offline.  To get the current online memory nodes, use
+     * {@link getEffectiveCpuSetMems()}.
+     *
+     * @return An array of available memory nodes or a zero length array
+     *         if the metric is not available.
+     *
+     */
+    public int[] getCpuSetMems();
+
+    /**
+     * Returns the memory nodes that are available and online for use by
+     * processes within the current Isolation Group. The size of the
+     * array is equal to the total number of nodes and the elements in
+     * the array are the physical node numbers.
+     *
+     * @return An array of available and online nodes or a zero length
+     *         array if the metric is not available.
+     *
+     */
+    public int[] getEffectiveCpuSetMems();
+
+    /**
+     * Returns the (attempts per second * 1000), if enabled, that the
+     * operating system tries to satisfy a memory request for any
+     * process in the current Isolation Group when no free memory is
+     * readily available.  Use {@link #isCpuSetMemoryPressureEnabled()} to
+     * to determine if this support is enabled.
+     *
+     * @return Memory pressure or 0 if not enabled or metric is not
+     *         available.
+     *
+     */
+    public double getCpuSetMemoryPressure();
+
+    /**
+     * Returns the state of the memory pressure detection support.
+     *
+     * @return true if the support is available and enabled, otherwise false.
+     *
+     */
+    public boolean isCpuSetMemoryPressureEnabled();
+
+    /*****************************************************************
+     * Memory Subsystem
+     ****************************************************************/
+
+    /**
+     * Returns the number of times that user memory requests in the
+     * Isolation Group have exceeded the memory limit.
+     *
+     * @return The number of exceeded requests or 0 if none or metric
+     *         is not available.
+     *
+     */
+    public long getMemoryFailCount();
+
+    /**
+     * Returns the maximum amount of physical memory, in bytes, that
+     * can be allocated in the Isolation Group.
+     *
+     * @return The maximum amount of memory in bytes or -1 if either
+     *         there is no limit set or this metric is not available.
+     *
+     */
+    public long getMemoryLimit();
+
+    /**
+     * Returns the largest amount of physical memory, in bytes, that
+     * have been allocated in the Isolation Group.
+     *
+     * @return The largest amount of memory in bytes or or 0 if this
+     *         metric is not available.
+     *
+     */
+    public long getMemoryMaxUsage();
+
+    /**
+     * Returns the amount of physical memory, in bytes, that is currently
+     * allocated in the current Isolation Group.
+     *
+     * @return The amount of memory in bytes allocated or 0 if this
+     *         metric is not available.
+     *
+     */
+    public long getMemoryUsage();
+
+    /**
+     * Returns the number of times that kernel memory requests in the
+     * Isolation Group have exceeded the kernel memory limit.
+     *
+     * @return The number of exceeded requests or 0 if none or metric
+     *         is not available.
+     *
+     */
+    public long getKernelMemoryFailCount();
+
+    /**
+     * Returns the maximum amount of kernel physical memory, in bytes, that
+     * can be allocated in the Isolation Group.
+     *
+     * @return The maximum amount of memory in bytes or -1 if either
+     *         there is no limit set or this metric is not available.
+     *
+     */
+    public long getKernelMemoryLimit();
+
+    /**
+     * Returns the largest amount of kernel physical memory, in bytes, that
+     * have been allocated in the Isolation Group.
+     *
+     * @return The largest amount of memory in bytes or or 0 if this
+     *         metric is not available.
+     *
+     */
+    public long getKernelMemoryMaxUsage();
+
+    /**
+     * Returns the amount of kernel physical memory, in bytes, that
+     * is currently allocated in the current Isolation Group.
+     *
+     * @return The amount of memory in bytes allocated or 0 if this
+     *         metric is not available.
+     *
+     */
+    public long getKernelMemoryUsage();
+
+    /**
+     * Returns the number of times that networking memory requests in the
+     * Isolation Group have exceeded the kernel memory limit.
+     *
+     * @return The number of exceeded requests or 0 if none or metric
+     *         is not available.
+     *
+     */
+    public long getTcpMemoryFailCount();
+
+    /**
+     * Returns the maximum amount of networking physical memory, in bytes,
+     * that can be allocated in the Isolation Group.
+     *
+     * @return The maximum amount of memory in bytes or -1 if either
+     *         there is no limit set or this metric is not available.
+     *
+     */
+    public long getTcpMemoryLimit();
+
+    /**
+     * Returns the largest amount of networking physical memory, in bytes,
+     * that have been allocated in the Isolation Group.
+     *
+     * @return The largest amount of memory in bytes or or 0 if this
+     *         metric is not available.
+     *
+     */
+    public long getTcpMemoryMaxUsage();
+
+    /**
+     * Returns the amount of networking physical memory, in bytes, that
+     * is currently allocated in the current Isolation Group.
+     *
+     * @return The amount of memory in bytes allocated or 0 if this
+     *         metric is not available.
+     *
+     */
+    public long getTcpMemoryUsage();
+
+    /**
+     * Returns the number of times that user memory requests in the
+     * Isolation Group have exceeded the memory + swap limit.
+     *
+     * @return The number of exceeded requests or 0 if none or metric
+     *         is not available.
+     *
+     */
+    public long getMemoryAndSwapFailCount();
+
+    /**
+     * Returns the maximum amount of physical memory and swap space,
+     * in bytes, that can be allocated in the Isolation Group.
+     *
+     * @return The maximum amount of memory in bytes or -1 if either
+     *         there is no limit set or this metric is not available.
+     *
+     */
+    public long getMemoryAndSwapLimit();
+
+    /**
+     * Returns the largest amount of physical memory and swap space,
+     * in bytes, that have been allocated in the Isolation Group.
+     *
+     * @return The largest amount of memory in bytes or or 0 if this
+     *         metric is not available.
+     *
+     */
+    public long getMemoryAndSwapMaxUsage();
+
+    /**
+     * Returns the amount of physical memory and swap space, in bytes,
+     * that is currently allocated in the current Isolation Group.
+     *
+     * @return The amount of memory in bytes allocated or 0 if this
+     *         metric is not available.
+     *
+     */
+    public long getMemoryAndSwapUsage();
+
+    /**
+     * Returns the state of the Operating System Out of Memory termination
+     * policy.
+     *
+     * @return Returns true if operating system will terminate processes
+     *         in the Isolation Group that exceed the amount of available
+     *         memory, otherwise false.  Flase will be returned if this
+     *         capability is not available on the current operating system.
+     *
+     */
+    public boolean isMemoryOOMKillEnabled();
+
+    /**
+     * Returns the hint to the operating system that allows groups
+     * to specify the minimum amount of physical memory that they need to
+     * achieve reasonable performance in low memory systems.  This allows
+     * host systems to provide greater sharing of memory.
+     *
+     * @return The minimum amount of physical memory, in bytes, that the
+     *         operating system will try to maintain under low memory
+     *         conditions.  If this metric is not available, 0 will be
+     *         returned.
+     *
+     */
+    public long getMemorySoftLimit();
+
+    /*****************************************************************
+     * BlKIO Subsystem
+     ****************************************************************/
+
+    /**
+     * Returns the number of block I/O requests to the disk that have been
+     * issued by the Isolation Group.
+     *
+     * @return The count of requests or 0 if this metric is not available.
+     *
+     */
+    public long getBlkIOServiceCount();
+
+    /**
+     * Returns the number of block I/O bytes that have been transferred
+     * to/from the disk by the Isolation Group.
+     *
+     * @return The number of bytes transferred or 0 if this metric is not available.
+     *
+     */
+    public long getBlkIOServiced();
+}
--- a/src/share/classes/jdk/jfr/conf/default.jfc	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/jdk/jfr/conf/default.jfc	Sat Oct 24 01:11:51 2020 +0100
@@ -115,12 +115,12 @@
 
     <event name="jdk.ExecutionSample">
       <setting name="enabled" control="method-sampling-enabled">true</setting>
-      <setting name="period" control="method-sampling-interval">20 ms</setting>
+      <setting name="period" control="method-sampling-java-interval">20 ms</setting>
     </event>
 
     <event name="jdk.NativeMethodSample">
       <setting name="enabled" control="method-sampling-enabled">true</setting>
-      <setting name="period" control="method-sampling-interval">20 ms</setting>
+      <setting name="period" control="method-sampling-native-interval">20 ms</setting>
     </event>
 
     <event name="jdk.SafepointBegin">
@@ -743,13 +743,42 @@
       </condition>
 
       <selection name="method-sampling-interval" default="normal" label="Method Sampling">
-        <option label="Off" name="off">999 d</option>
-        <option label="Normal" name="normal">20 ms</option>
-        <option label="Maximum" name="maximum">10 ms</option>
+        <option label="Off" name="off">off</option>
+        <option label="Normal" name="normal">normal</option>
+        <option label="High" name="high">high</option>
+        <option label="Ludicrous (High Overhead)" name="ludicrous">ludicrous</option>
       </selection>
+      
+      <condition name="method-sampling-java-interval" true="999 d">
+        <test name="method-sampling-interval" operator="equal" value="off"/>
+      </condition>
+
+      <condition name="method-sampling-java-interval" true="20 ms">
+        <test name="method-sampling-interval" operator="equal" value="normal"/>
+      </condition>
+
+      <condition name="method-sampling-java-interval" true="10 ms">
+        <test name="method-sampling-interval" operator="equal" value="high"/>
+      </condition>
+
+      <condition name="method-sampling-java-interval" true="1 ms">
+        <test name="method-sampling-interval" operator="equal" value="ludicrous"/>
+      </condition>
+      
+      <condition name="method-sampling-native-interval" true="999 d">
+        <test name="method-sampling-interval" operator="equal" value="off"/>
+      </condition>
+
+      <condition name="method-sampling-native-interval" true="20 ms">
+        <or>
+          <test name="method-sampling-interval" operator="equal" value="normal"/>
+          <test name="method-sampling-interval" operator="equal" value="high"/>
+          <test name="method-sampling-interval" operator="equal" value="ludicrous"/>
+        </or>
+      </condition>  
 
       <condition name="method-sampling-enabled" true="false" false="true">
-        <test name="method-sampling-interval" operator="equal" value="999 d"/>
+        <test name="method-sampling-interval" operator="equal" value="off"/>
       </condition>
 
       <selection name="thread-dump-interval" default="normal" label="Thread Dump">
--- a/src/share/classes/jdk/jfr/conf/profile.jfc	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/jdk/jfr/conf/profile.jfc	Sat Oct 24 01:11:51 2020 +0100
@@ -115,12 +115,12 @@
 
     <event name="jdk.ExecutionSample">
       <setting name="enabled" control="method-sampling-enabled">true</setting>
-      <setting name="period" control="method-sampling-interval">10 ms</setting>
+      <setting name="period" control="method-sampling-java-interval">10 ms</setting>
     </event>
 
     <event name="jdk.NativeMethodSample">
       <setting name="enabled" control="method-sampling-enabled">true</setting>
-      <setting name="period" control="method-sampling-interval">10 ms</setting>
+      <setting name="period" control="method-sampling-native-interval">20 ms</setting>
     </event>
 
     <event name="jdk.SafepointBegin">
@@ -743,14 +743,43 @@
         <test name="compiler-level" operator="equal" value="all"/>
       </condition>
 
-      <selection name="method-sampling-interval" default="maximum" label="Method Sampling">
-        <option label="Off" name="off">999 d</option>
-        <option label="Normal" name="normal">20 ms</option>
-        <option label="Maximum" name="maximum">10 ms</option>
+      <selection name="method-sampling-interval" default="normal" label="Method Sampling">
+        <option label="Off" name="off">off</option>
+        <option label="Normal" name="normal">normal</option>
+        <option label="High" name="high">high</option>
+        <option label="Ludicrous (High Overhead)" name="ludicrous">ludicrous</option>
       </selection>
+      
+      <condition name="method-sampling-java-interval" true="999 d">
+        <test name="method-sampling-interval" operator="equal" value="off"/>
+      </condition>
 
+      <condition name="method-sampling-java-interval" true="20 ms">
+        <test name="method-sampling-interval" operator="equal" value="normal"/>
+      </condition>
+
+      <condition name="method-sampling-java-interval" true="10 ms">
+        <test name="method-sampling-interval" operator="equal" value="high"/>
+      </condition>
+
+      <condition name="method-sampling-java-interval" true="1 ms">
+        <test name="method-sampling-interval" operator="equal" value="ludicrous"/>
+      </condition>
+      
+      <condition name="method-sampling-native-interval" true="999 d">
+        <test name="method-sampling-interval" operator="equal" value="off"/>
+      </condition>
+
+      <condition name="method-sampling-native-interval" true="20 ms">
+        <or>
+          <test name="method-sampling-interval" operator="equal" value="normal"/>
+          <test name="method-sampling-interval" operator="equal" value="high"/>
+          <test name="method-sampling-interval" operator="equal" value="ludicrous"/>
+        </or>
+      </condition>    
+      
       <condition name="method-sampling-enabled" true="false" false="true">
-        <test name="method-sampling-interval" operator="equal" value="999 d"/>
+        <test name="method-sampling-interval" operator="equal" value="off"/>
       </condition>
 
       <selection name="thread-dump-interval" default="everyMinute" label="Thread Dump">
--- a/src/share/classes/jdk/jfr/internal/PlatformRecorder.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/jdk/jfr/internal/PlatformRecorder.java	Sat Oct 24 01:11:51 2020 +0100
@@ -316,7 +316,7 @@
     private void dumpMemoryToDestination(PlatformRecording recording)  {
         WriteableUserPath dest = recording.getDestination();
         if (dest != null) {
-            MetadataRepository.getInstance().setOutput(dest.getText());
+            MetadataRepository.getInstance().setOutput(dest.getRealPathText());
             recording.clearDestination();
         }
     }
@@ -407,7 +407,7 @@
                     event.id = r.getId();
                     event.name = r.getName();
                     WriteableUserPath p = r.getDestination();
-                    event.destination = p == null ? null : p.getText();
+                    event.destination = p == null ? null : p.getRealPathText();
                     Duration d = r.getDuration();
                     event.recordingDuration = d == null ? Long.MAX_VALUE : d.toMillis();
                     Duration age = r.getMaxAge();
--- a/src/share/classes/jdk/jfr/internal/PlatformRecording.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/jdk/jfr/internal/PlatformRecording.java	Sat Oct 24 01:11:51 2020 +0100
@@ -132,7 +132,7 @@
                     options.add("duration=" + Utils.formatTimespan(duration, ""));
                 }
                 if (destination != null) {
-                    options.add("filename=" + destination.getText());
+                    options.add("filename=" + destination.getRealPathText());
                 }
                 String optionText = options.toString();
                 if (optionText.length() != 0) {
@@ -165,7 +165,7 @@
         if (dest != null) {
             try {
                 dumpStopped(dest);
-                Logger.log(LogTag.JFR, LogLevel.INFO, "Wrote recording \"" + getName() + "\" (" + getId() + ") to " + dest.getText());
+                Logger.log(LogTag.JFR, LogLevel.INFO, "Wrote recording \"" + getName() + "\" (" + getId() + ") to " + dest.getRealPathText());
                 notifyIfStateChanged(newState, oldState);
                 close(); // remove if copied out
             } catch(IOException e) {
--- a/src/share/classes/jdk/jfr/internal/WriteableUserPath.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/jdk/jfr/internal/WriteableUserPath.java	Sat Oct 24 01:11:51 2020 +0100
@@ -50,7 +50,8 @@
     private final AccessControlContext controlContext;
     private final Path original;
     private final Path real;
-    private final String text;
+    private final String realPathText;
+    private final String originalText;
 
     // Not to ensure security, but to help
     // against programming errors
@@ -68,8 +69,9 @@
         BufferedWriter fw = Files.newBufferedWriter(path);
         fw.close();
         this.original = path;
+        this.originalText = path.toString();
         this.real = path.toRealPath();
-        this.text = real.toString();
+        this.realPathText = real.toString();
     }
 
     /**
@@ -85,15 +87,25 @@
     }
 
     /**
-     * Returns a string representation of the path.
+     * Returns a string representation of the real path.
      *
      * @return path as text
      */
-    public String getText() {
-        return text;
+    public String getRealPathText() {
+        return realPathText;
     }
 
     /**
+     * Returns a string representation of the original path.
+     *
+     * @return path as text
+     */
+    public String getOriginalText() {
+        return originalText;
+    }
+
+
+    /**
      * Returns a potentially malicious path where the user may have implemented
      * their own version of Path. This method should never be called in an
      * unsafe context and the Path value should never be passed along to other
--- a/src/share/classes/jdk/jfr/internal/management/ManagementSupport.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/jdk/jfr/internal/management/ManagementSupport.java	Sat Oct 24 01:11:51 2020 +0100
@@ -31,12 +31,16 @@
 import java.util.List;
 
 import jdk.jfr.EventType;
+import jdk.jfr.Recording;
 import jdk.jfr.internal.JVMSupport;
 import jdk.jfr.internal.LogLevel;
 import jdk.jfr.internal.LogTag;
 import jdk.jfr.internal.Logger;
 import jdk.jfr.internal.MetadataRepository;
+import jdk.jfr.internal.PlatformRecording;
+import jdk.jfr.internal.PrivateAccess;
 import jdk.jfr.internal.Utils;
+import jdk.jfr.internal.WriteableUserPath;
 import jdk.jfr.internal.instrument.JDKEvents;
 
 /**
@@ -86,4 +90,12 @@
     public static void logError(String message) {
         Logger.log(LogTag.JFR, LogLevel.ERROR, message);
     }
+
+    // Get the textual representation when the destination was set, which
+    // requires access to jdk.jfr.internal.PlatformRecording
+    public static String getDestinationOriginalText(Recording recording) {
+        PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording);
+        WriteableUserPath wup = pr.getDestination();
+        return wup == null ? null : wup.getOriginalText();
+    }
 }
--- a/src/share/classes/jdk/jfr/internal/tool/Command.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/jdk/jfr/internal/tool/Command.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -243,7 +243,7 @@
             }
             rad.read(); // try to read 1 byte
         } catch (FileNotFoundException e) {
-            throw new UserDataException("could not find file '" + path + "'");
+            throw new UserDataException("could not open file " + e.getMessage());
         } catch (IOException e) {
             throw new UserDataException("i/o error reading file '" + path + "', " + e.getMessage());
         }
--- a/src/share/classes/jdk/jfr/internal/tool/Print.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/jdk/jfr/internal/tool/Print.java	Sat Oct 24 01:11:51 2020 +0100
@@ -107,13 +107,23 @@
         int stackDepth = 5;
         EventPrintWriter eventWriter = null;
         int optionCount = options.size();
+        boolean foundEventFilter = false;
+        boolean foundCategoryFilter = false;
         while (optionCount > 0) {
             if (acceptFilterOption(options, "--events")) {
+                if (foundEventFilter) {
+                    throw new UserSyntaxException("use --events event1,event2,event3 to include multiple events");
+                }
+                foundEventFilter = true;
                 String filter = options.remove();
                 warnForWildcardExpansion("--events", filter);
                 eventFilter = addEventFilter(filter, eventFilter);
             }
             if (acceptFilterOption(options, "--categories")) {
+                if (foundCategoryFilter) {
+                    throw new UserSyntaxException("use --categories category1,category2 to include multiple categories");
+                }
+                foundCategoryFilter = true;
                 String filter = options.remove();
                 warnForWildcardExpansion("--categories", filter);
                 eventFilter = addCategoryFilter(filter, eventFilter);
@@ -137,6 +147,8 @@
             }
             if (optionCount == options.size()) {
                 // No progress made
+                checkCommonError(options, "--event", "--events");
+                checkCommonError(options, "--category", "--categories");
                 throw new UserSyntaxException("unknown option " + options.peek());
             }
             optionCount = options.size();
@@ -157,6 +169,12 @@
         pw.flush();
     }
 
+    private void checkCommonError(Deque<String> options, String typo, String correct) throws UserSyntaxException {
+       if (typo.equals(options.peek())) {
+           throw new UserSyntaxException("unknown option " + typo + ", did you mean " + correct + "?");
+       }
+    }
+
     private static boolean acceptFormatterOption(Deque<String> options, EventPrintWriter eventWriter, String expected) throws UserSyntaxException {
         if (expected.equals(options.peek())) {
             if (eventWriter != null) {
@@ -179,7 +197,7 @@
 
     private static Predicate<EventType> addCategoryFilter(String filterText, Predicate<EventType> eventFilter) throws UserSyntaxException {
         List<String> filters = explodeFilter(filterText);
-        return recurseIfPossible(eventType -> {
+        Predicate<EventType> newFilter = recurseIfPossible(eventType -> {
             for (String category : eventType.getCategoryNames()) {
                 for (String filter : filters) {
                     if (match(category, filter)) {
@@ -192,6 +210,7 @@
             }
             return false;
         });
+        return eventFilter == null ? newFilter : eventFilter.or(newFilter);
     }
 
     private static String acronomify(String multipleWords) {
@@ -210,7 +229,7 @@
 
     private static Predicate<EventType> addEventFilter(String filterText, final Predicate<EventType> eventFilter) throws UserSyntaxException {
         List<String> filters = explodeFilter(filterText);
-        return recurseIfPossible(eventType -> {
+        Predicate<EventType> newFilter = recurseIfPossible(eventType -> {
             for (String filter : filters) {
                 String fullEventName = eventType.getName();
                 if (match(fullEventName, filter)) {
@@ -223,6 +242,7 @@
             }
             return false;
         });
+        return eventFilter == null ? newFilter : eventFilter.or(newFilter);
     }
 
     private static boolean match(String text, String filter) {
--- a/src/share/classes/jdk/management/jfr/RecordingInfo.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/jdk/management/jfr/RecordingInfo.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,7 +25,6 @@
 
 package jdk.management.jfr;
 
-import java.nio.file.Path;
 import java.time.Duration;
 import java.time.Instant;
 import java.util.LinkedHashMap;
@@ -37,6 +36,7 @@
 
 import jdk.jfr.Recording;
 import jdk.jfr.RecordingState;
+import jdk.jfr.internal.management.ManagementSupport;
 
 /**
  * Management representation of a {@code Recording}.
@@ -80,8 +80,7 @@
         startTime = s == null ? 0L : s.toEpochMilli();
         Instant st = recording.getStopTime();
         stopTime = st == null ? 0L : st.toEpochMilli();
-        Path p = recording.getDestination();
-        destination = p == null ? null : p.toString();
+        destination = ManagementSupport.getDestinationOriginalText(recording);
         Duration duration = recording.getDuration();
         durationInSeconds = duration == null ? 0 : duration.getSeconds();
         settings = recording.getSettings();
--- a/src/share/classes/jdk/net/ExtendedSocketOptions.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/jdk/net/ExtendedSocketOptions.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -57,4 +57,66 @@
      */
     public static final SocketOption<SocketFlow> SO_FLOW_SLA = new
         ExtSocketOption<SocketFlow>("SO_FLOW_SLA", SocketFlow.class);
+
+    /**
+     * Keep-Alive idle time.
+     *
+     * <p>
+     * The value of this socket option is an {@code Integer} that is the number
+     * of seconds of idle time before keep-alive initiates a probe. The socket
+     * option is specific to stream-oriented sockets using the TCP/IP protocol.
+     * The exact semantics of this socket option are system dependent.
+     *
+     * <p>
+     * When the {@link java.net.StandardSocketOptions#SO_KEEPALIVE
+     * SO_KEEPALIVE} option is enabled, TCP probes a connection that has been
+     * idle for some amount of time. The default value for this idle period is
+     * system dependent, but is typically 2 hours. The {@code TCP_KEEPIDLE}
+     * option can be used to affect this value for a given socket.
+     */
+    public static final SocketOption<Integer> TCP_KEEPIDLE
+            = new ExtSocketOption<Integer>("TCP_KEEPIDLE", Integer.class);
+
+    /**
+     * Keep-Alive retransmission interval time.
+     *
+     * <p>
+     * The value of this socket option is an {@code Integer} that is the number
+     * of seconds to wait before retransmitting a keep-alive probe. The socket
+     * option is specific to stream-oriented sockets using the TCP/IP protocol.
+     * The exact semantics of this socket option are system dependent.
+     *
+     * <p>
+     * When the {@link java.net.StandardSocketOptions#SO_KEEPALIVE
+     * SO_KEEPALIVE} option is enabled, TCP probes a connection that has been
+     * idle for some amount of time. If the remote system does not respond to a
+     * keep-alive probe, TCP retransmits the probe after some amount of time.
+     * The default value for this retransmission interval is system dependent,
+     * but is typically 75 seconds. The {@code TCP_KEEPINTERVAL} option can be
+     * used to affect this value for a given socket.
+     */
+    public static final SocketOption<Integer> TCP_KEEPINTERVAL
+            = new ExtSocketOption<Integer>("TCP_KEEPINTERVAL", Integer.class);
+
+    /**
+     * Keep-Alive retransmission maximum limit.
+     *
+     * <p>
+     * The value of this socket option is an {@code Integer} that is the maximum
+     * number of keep-alive probes to be sent. The socket option is specific to
+     * stream-oriented sockets using the TCP/IP protocol. The exact semantics of
+     * this socket option are system dependent.
+     *
+     * <p>
+     * When the {@link java.net.StandardSocketOptions#SO_KEEPALIVE
+     * SO_KEEPALIVE} option is enabled, TCP probes a connection that has been
+     * idle for some amount of time. If the remote system does not respond to a
+     * keep-alive probe, TCP retransmits the probe a certain number of times
+     * before a connection is considered to be broken. The default value for
+     * this keep-alive probe retransmit limit is system dependent, but is
+     * typically 8. The {@code TCP_KEEPCOUNT} option can be used to affect this
+     * value for a given socket.
+     */
+    public static final SocketOption<Integer> TCP_KEEPCOUNT
+            = new ExtSocketOption<Integer>("TCP_KEEPCOUNT", Integer.class);
 }
--- a/src/share/classes/jdk/net/Sockets.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/jdk/net/Sockets.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -36,6 +36,7 @@
 import java.util.HashMap;
 import java.util.Collections;
 import sun.net.ExtendedOptionsImpl;
+import sun.net.ExtendedOptionsHelper;
 
 /**
  * Defines static methods to set and get socket options defined by the
@@ -363,6 +364,7 @@
         if (flowsupported) {
             set.add(ExtendedSocketOptions.SO_FLOW_SLA);
         }
+        set.addAll(ExtendedOptionsHelper.keepAliveOptions());
         set = Collections.unmodifiableSet(set);
         options.put(Socket.class, set);
 
@@ -372,6 +374,7 @@
         set.add(StandardSocketOptions.SO_RCVBUF);
         set.add(StandardSocketOptions.SO_REUSEADDR);
         set.add(StandardSocketOptions.IP_TOS);
+        set.addAll(ExtendedOptionsHelper.keepAliveOptions());
         set = Collections.unmodifiableSet(set);
         options.put(ServerSocket.class, set);
 
@@ -404,4 +407,5 @@
         set = Collections.unmodifiableSet(set);
         options.put(MulticastSocket.class, set);
     }
+
 }
--- a/src/share/classes/org/jcp/xml/dsig/internal/DigesterOutputStream.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/DigesterOutputStream.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DigesterOutputStream.java,v 1.5 2005/12/20 20:02:39 mullan Exp $
+ * $Id: DigesterOutputStream.java, v 1.5 2005/12/20 20:02:39 mullan Exp $
  */
 package org.jcp.xml.dsig.internal;
 
@@ -42,12 +42,10 @@
  * com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm objects.
  * It also optionally caches the input bytes.
  *
- * @author raul
- * @author Sean Mullan
  */
 public class DigesterOutputStream extends OutputStream {
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal");
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(DigesterOutputStream.class);
 
     private final boolean buffer;
     private UnsyncByteArrayOutputStream bos;
@@ -88,13 +86,13 @@
         if (buffer) {
             bos.write(input, offset, len);
         }
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Pre-digested input:");
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Pre-digested input:");
             StringBuilder sb = new StringBuilder(len);
             for (int i = offset; i < (offset + len); i++) {
                 sb.append((char)input[i]);
             }
-            log.log(java.util.logging.Level.FINE, sb.toString());
+            LOG.debug(sb.toString());
         }
         md.update(input, offset, len);
     }
--- a/src/share/classes/org/jcp/xml/dsig/internal/MacOutputStream.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/MacOutputStream.java	Sat Oct 24 01:11:51 2020 +0100
@@ -29,8 +29,6 @@
  * Derived from Apache sources and changed to use Mac objects instead of
  * com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm objects.
  *
- * @author raul
- * @author Sean Mullan
  *
  */
 public class MacOutputStream extends ByteArrayOutputStream {
--- a/src/share/classes/org/jcp/xml/dsig/internal/SignerOutputStream.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/SignerOutputStream.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: SignerOutputStream.java,v 1.2 2005/09/15 14:29:02 mullan Exp $
+ * $Id: SignerOutputStream.java, v 1.2 2005/09/15 14:29:02 mullan Exp $
  */
 package org.jcp.xml.dsig.internal;
 
@@ -37,8 +37,6 @@
  * objects as input instead of
  * com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm objects.
  *
- * @author raul
- * @author Sean Mullan
  */
 public class SignerOutputStream extends ByteArrayOutputStream {
     private final Signature sig;
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java	Sat Oct 24 01:11:51 2020 +0100
@@ -59,10 +59,10 @@
      * @param si the SignedInfo
      * @param sig the signature bytes to be verified
      * @param context the XMLValidateContext
-     * @return <code>true</code> if the signature verified successfully,
-     *    <code>false</code> if not
-     * @throws NullPointerException if <code>key</code>, <code>si</code> or
-     *    <code>sig</code> are <code>null</code>
+     * @return {@code true} if the signature verified successfully,
+     *    {@code false} if not
+     * @throws NullPointerException if {@code key}, {@code si} or
+     *    {@code sig} are {@code null}
      * @throws InvalidKeyException if the key is improperly encoded, of
      *    the wrong type, or parameters are missing, etc
      * @throws SignatureException if an unexpected error occurs, such
@@ -81,8 +81,8 @@
      * @param si the SignedInfo
      * @param context the XMLSignContext
      * @return the signature
-     * @throws NullPointerException if <code>key</code> or
-     *    <code>si</code> are <code>null</code>
+     * @throws NullPointerException if {@code key} or
+     *    {@code si} are {@code null}
      * @throws InvalidKeyException if the key is improperly encoded, of
      *    the wrong type, or parameters are missing, etc
      * @throws XMLSignatureException if an unexpected error occurs
@@ -105,6 +105,7 @@
      * This method invokes the {@link #marshalParams marshalParams}
      * method to marshal any algorithm-specific parameters.
      */
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
@@ -140,13 +141,13 @@
     }
 
     /**
-     * Unmarshals <code>SignatureMethodParameterSpec</code> from the specified
-     * <code>Element</code>. By default, this method throws an exception since
+     * Unmarshals {@code SignatureMethodParameterSpec} from the specified
+     * {@code Element}. By default, this method throws an exception since
      * most SignatureMethod algorithms do not have parameters. Subclasses should
      * override it if they have parameters.
      *
-     * @param paramsElem the <code>Element</code> holding the input params
-     * @return the algorithm-specific <code>SignatureMethodParameterSpec</code>
+     * @param paramsElem the {@code Element} holding the input params
+     * @return the algorithm-specific {@code SignatureMethodParameterSpec}
      * @throws MarshalException if the parameters cannot be unmarshalled
      */
     SignatureMethodParameterSpec unmarshalParams(Element paramsElem)
@@ -163,7 +164,7 @@
      * since most SignatureMethod algorithms do not have parameters. Subclasses
      * should override it if they have parameters.
      *
-     * @param params the algorithm-specific params (may be <code>null</code>)
+     * @param params the algorithm-specific params (may be {@code null})
      * @throws InvalidAlgorithmParameterException if the parameters are not
      *    appropriate for this signature method
      */
@@ -189,8 +190,8 @@
         }
         SignatureMethod osm = (SignatureMethod)o;
 
-        return (getAlgorithm().equals(osm.getAlgorithm()) &&
-            paramsEqual(osm.getParameterSpec()));
+        return getAlgorithm().equals(osm.getAlgorithm()) &&
+            paramsEqual(osm.getParameterSpec());
     }
 
     @Override
@@ -213,6 +214,6 @@
      */
     boolean paramsEqual(AlgorithmParameterSpec spec)
     {
-        return (getParameterSpec() == spec);
+        return getParameterSpec() == spec;
     }
 }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: ApacheCanonicalizer.java 1333869 2012-05-04 10:42:44Z coheigea $
+ * $Id: ApacheCanonicalizer.java 1785016 2017-03-01 18:23:48Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -34,6 +34,7 @@
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.InvalidAlgorithmParameterException;
 import java.util.Set;
+
 import javax.xml.crypto.*;
 import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.TransformException;
@@ -54,8 +55,8 @@
         com.sun.org.apache.xml.internal.security.Init.init();
     }
 
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom");
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ApacheCanonicalizer.class);
     protected Canonicalizer apacheCanonicalizer;
     private Transform apacheTransform;
     protected String inclusiveNamespaces;
@@ -116,9 +117,9 @@
         if (apacheCanonicalizer == null) {
             try {
                 apacheCanonicalizer = Canonicalizer.getInstance(getAlgorithm());
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Created canonicalizer for algorithm: " + getAlgorithm());
-                }
+                boolean secVal = Utils.secureValidation(xc);
+                apacheCanonicalizer.setSecureValidation(secVal);
+                LOG.debug("Created canonicalizer for algorithm: {}", getAlgorithm());
             } catch (InvalidCanonicalizerException ice) {
                 throw new TransformException
                     ("Couldn't find Canonicalizer for: " + getAlgorithm() +
@@ -171,9 +172,7 @@
                 @SuppressWarnings("unchecked")
                 Set<Node> ns = Utils.toNodeSet(nsd.iterator());
                 nodeSet = ns;
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Canonicalizing " + nodeSet.size() + " nodes");
-                }
+                LOG.debug("Canonicalizing {} nodes", nodeSet.size());
             } else {
                 return new OctetStreamData(new ByteArrayInputStream(
                     apacheCanonicalizer.canonicalize(
@@ -212,9 +211,9 @@
                 apacheTransform =
                     new Transform(ownerDoc, getAlgorithm(), transformElem.getChildNodes());
                 apacheTransform.setElement(transformElem, xc.getBaseURI());
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Created transform for algorithm: " + getAlgorithm());
-                }
+                boolean secVal = Utils.secureValidation(xc);
+                apacheTransform.setSecureValidation(secVal);
+                LOG.debug("Created transform for algorithm: {}", getAlgorithm());
             } catch (Exception ex) {
                 throw new TransformException
                     ("Couldn't find Transform for: " + getAlgorithm(), ex);
@@ -223,14 +222,10 @@
 
         XMLSignatureInput in;
         if (data instanceof ApacheData) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "ApacheData = true");
-            }
+            LOG.debug("ApacheData = true");
             in = ((ApacheData)data).getXMLSignatureInput();
         } else if (data instanceof NodeSetData) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "isNodeSet() = true");
-            }
+            LOG.debug("isNodeSet() = true");
             if (data instanceof DOMSubTreeData) {
                 DOMSubTreeData subTree = (DOMSubTreeData)data;
                 in = new XMLSignatureInput(subTree.getRoot());
@@ -242,9 +237,7 @@
                 in = new XMLSignatureInput(nodeSet);
             }
         } else {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "isNodeSet() = false");
-            }
+            LOG.debug("isNodeSet() = false");
             try {
                 in = new XMLSignatureInput
                     (((OctetStreamData)data).getOctetStream());
@@ -253,6 +246,9 @@
             }
         }
 
+        boolean secVal = Utils.secureValidation(xc);
+        in.setSecureValidation(secVal);
+
         try {
             in = apacheTransform.performTransform(in, os);
             if (!in.isNodeSet() && !in.isElement()) {
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheData.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheData.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: ApacheData.java 1333869 2012-05-04 10:42:44Z coheigea $
+ * $Id: ApacheData.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -34,7 +34,6 @@
 /**
  * XMLSignatureInput Data wrapper.
  *
- * @author Sean Mullan
  */
 public interface ApacheData extends Data {
 
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheNodeSetData.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheNodeSetData.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: ApacheNodeSetData.java 1203890 2011-11-18 22:47:56Z mullan $
+ * $Id: ApacheNodeSetData.java 1496478 2013-06-25 14:01:16Z mullan $
  */
 package org.jcp.xml.dsig.internal.dom;
 
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheOctetStreamData.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheOctetStreamData.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: ApacheOctetStreamData.java 1197150 2011-11-03 14:34:57Z coheigea $
+ * $Id: ApacheOctetStreamData.java 1667527 2015-03-18 12:54:20Z mullan $
  */
 package org.jcp.xml.dsig.internal.dom;
 
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: ApacheTransform.java 1333869 2012-05-04 10:42:44Z coheigea $
+ * $Id: ApacheTransform.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -32,10 +32,10 @@
 import java.security.InvalidAlgorithmParameterException;
 import java.security.spec.AlgorithmParameterSpec;
 import java.util.Set;
+
 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;
 
@@ -48,8 +48,6 @@
  * This is a wrapper/glue class which invokes the Apache XML-Security
  * Transform.
  *
- * @author Sean Mullan
- * @author Erwin van der Koogh
  */
 public abstract class ApacheTransform extends TransformService {
 
@@ -57,13 +55,14 @@
         com.sun.org.apache.xml.internal.security.Init.init();
     }
 
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom");
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ApacheTransform.class);
     private Transform apacheTransform;
     protected Document ownerDoc;
     protected Element transformElem;
     protected TransformParameterSpec params;
 
+    @Override
     public final AlgorithmParameterSpec getParameterSpec() {
         return params;
     }
@@ -110,7 +109,7 @@
         if (data == null) {
             throw new NullPointerException("data must not be null");
         }
-        return transformIt(data, xc, (OutputStream)null);
+        return transformIt(data, xc, null);
     }
 
     public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
@@ -137,10 +136,9 @@
                 apacheTransform =
                     new Transform(ownerDoc, getAlgorithm(), transformElem.getChildNodes());
                 apacheTransform.setElement(transformElem, xc.getBaseURI());
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Created transform for algorithm: " +
-                            getAlgorithm());
-                }
+                boolean secVal = Utils.secureValidation(xc);
+                apacheTransform.setSecureValidation(secVal);
+                LOG.debug("Created transform for algorithm: {}", getAlgorithm());
             } catch (Exception ex) {
                 throw new TransformException("Couldn't find Transform for: " +
                                              getAlgorithm(), ex);
@@ -158,18 +156,12 @@
 
         XMLSignatureInput in;
         if (data instanceof ApacheData) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "ApacheData = true");
-            }
+            LOG.debug("ApacheData = true");
             in = ((ApacheData)data).getXMLSignatureInput();
         } else if (data instanceof NodeSetData) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "isNodeSet() = true");
-            }
+            LOG.debug("isNodeSet() = true");
             if (data instanceof DOMSubTreeData) {
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "DOMSubTreeData = true");
-                }
+                LOG.debug("DOMSubTreeData = true");
                 DOMSubTreeData subTree = (DOMSubTreeData)data;
                 in = new XMLSignatureInput(subTree.getRoot());
                 in.setExcludeComments(subTree.excludeComments());
@@ -180,9 +172,7 @@
                 in = new XMLSignatureInput(nodeSet);
             }
         } else {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "isNodeSet() = false");
-            }
+            LOG.debug("isNodeSet() = false");
             try {
                 in = new XMLSignatureInput
                     (((OctetStreamData)data).getOctetStream());
@@ -190,6 +180,8 @@
                 throw new TransformException(ex);
             }
         }
+        boolean secVal = Utils.secureValidation(xc);
+        in.setSecureValidation(secVal);
 
         try {
             if (os != null) {
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMBase64Transform.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMBase64Transform.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMBase64Transform.java 1197150 2011-11-03 14:34:57Z coheigea $
+ * $Id: DOMBase64Transform.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -36,10 +36,10 @@
  * DOM-based implementation of Base64 Encoding Transform.
  * (Uses Apache XML-Sec Transform implementation)
  *
- * @author Sean Mullan
  */
 public final class DOMBase64Transform extends ApacheTransform {
 
+    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException {
         if (params != null) {
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14N11Method.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14N11Method.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,7 +21,7 @@
  * under the License.
  */
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * $Id$
@@ -41,7 +41,6 @@
  * DOM-based implementation of CanonicalizationMethod for Canonical XML 1.1
  * (with or without comments). Uses Apache XML-Sec Canonicalizer.
  *
- * @author Sean Mullan
  */
 public final class DOMCanonicalXMLC14N11Method extends ApacheCanonicalizer {
 
@@ -68,6 +67,8 @@
             if (subTree.excludeComments()) {
                 try {
                     apacheCanonicalizer = Canonicalizer.getInstance(C14N_11);
+                    boolean secVal = Utils.secureValidation(xc);
+                    apacheCanonicalizer.setSecureValidation(secVal);
                 } catch (InvalidCanonicalizerException ice) {
                     throw new TransformException
                         ("Couldn't find Canonicalizer for: " +
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14NMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14NMethod.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMCanonicalXMLC14NMethod.java 1197150 2011-11-03 14:34:57Z coheigea $
+ * $Id: DOMCanonicalXMLC14NMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -41,7 +41,6 @@
  * DOM-based implementation of CanonicalizationMethod for Canonical XML
  * (with or without comments). Uses Apache XML-Sec Canonicalizer.
  *
- * @author Sean Mullan
  */
 public final class DOMCanonicalXMLC14NMethod extends ApacheCanonicalizer {
 
@@ -65,6 +64,8 @@
                 try {
                     apacheCanonicalizer = Canonicalizer.getInstance
                         (CanonicalizationMethod.INCLUSIVE);
+                    boolean secVal = Utils.secureValidation(xc);
+                    apacheCanonicalizer.setSecureValidation(secVal);
                 } catch (InvalidCanonicalizerException ice) {
                     throw new TransformException
                         ("Couldn't find Canonicalizer for: " +
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalizationMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalizationMethod.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMCanonicalizationMethod.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMCanonicalizationMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -41,13 +41,12 @@
 /**
  * DOM-based abstract implementation of CanonicalizationMethod.
  *
- * @author Sean Mullan
  */
 public class DOMCanonicalizationMethod extends DOMTransform
     implements CanonicalizationMethod {
 
     /**
-     * Creates a <code>DOMCanonicalizationMethod</code>.
+     * Creates a {@code DOMCanonicalizationMethod}.
      *
      * @param spi TransformService
      */
@@ -55,17 +54,14 @@
         throws InvalidAlgorithmParameterException
     {
         super(spi);
-        if (!(spi instanceof ApacheCanonicalizer) &&
-                !isC14Nalg(spi.getAlgorithm())) {
-            throw new InvalidAlgorithmParameterException(
-                "Illegal CanonicalizationMethod");
+        if (!(spi instanceof ApacheCanonicalizer) && !isC14Nalg(spi.getAlgorithm())) {
+            throw new InvalidAlgorithmParameterException("Illegal CanonicalizationMethod");
         }
     }
 
     /**
-     * Creates a <code>DOMCanonicalizationMethod</code> from an element. This
-     * ctor invokes the abstract {@link #unmarshalParams unmarshalParams}
-     * method to unmarshal any algorithm-specific input parameters.
+     * Creates a {@code DOMCanonicalizationMethod} from an element. It unmarshals any
+     * algorithm-specific input parameters.
      *
      * @param cmElem a CanonicalizationMethod element
      */
@@ -74,8 +70,7 @@
         throws MarshalException
     {
         super(cmElem, context, provider);
-        if (!(spi instanceof ApacheCanonicalizer) &&
-                !isC14Nalg(spi.getAlgorithm())) {
+        if (!(spi instanceof ApacheCanonicalizer) && !isC14Nalg(spi.getAlgorithm())) {
             throw new MarshalException("Illegal CanonicalizationMethod");
         }
     }
@@ -86,10 +81,10 @@
      * the {@link #transform transform} method.
      *
      * @param data the data to be canonicalized
-     * @param xc the <code>XMLCryptoContext</code> containing
-     *     additional context (may be <code>null</code> if not applicable)
+     * @param xc the {@code XMLCryptoContext} containing
+     *     additional context (may be {@code null} if not applicable)
      * @return the canonicalized data
-     * @throws NullPointerException if <code>data</code> is <code>null</code>
+     * @throws NullPointerException if {@code data} is {@code null}
      * @throws TransformException if an unexpected error occurs while
      *    canonicalizing the data
      */
@@ -116,8 +111,8 @@
         }
         CanonicalizationMethod ocm = (CanonicalizationMethod)o;
 
-        return (getAlgorithm().equals(ocm.getAlgorithm()) &&
-            DOMUtils.paramsEqual(getParameterSpec(), ocm.getParameterSpec()));
+        return getAlgorithm().equals(ocm.getAlgorithm()) &&
+            DOMUtils.paramsEqual(getParameterSpec(), ocm.getParameterSpec());
     }
 
     @Override
@@ -133,11 +128,21 @@
     }
 
     private static boolean isC14Nalg(String alg) {
-        return (alg.equals(CanonicalizationMethod.INCLUSIVE) ||
-                alg.equals(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS) ||
-                alg.equals(CanonicalizationMethod.EXCLUSIVE) ||
-                alg.equals(CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS) ||
-                alg.equals(DOMCanonicalXMLC14N11Method.C14N_11) ||
-                alg.equals(DOMCanonicalXMLC14N11Method.C14N_11_WITH_COMMENTS));
+        return isInclusiveC14Nalg(alg) || isExclusiveC14Nalg(alg) || isC14N11alg(alg);
+    }
+
+    private static boolean isInclusiveC14Nalg(String alg) {
+        return alg.equals(CanonicalizationMethod.INCLUSIVE)
+            || alg.equals(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS);
+    }
+
+    private static boolean isExclusiveC14Nalg(String alg) {
+        return alg.equals(CanonicalizationMethod.EXCLUSIVE)
+            || alg.equals(CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS);
+    }
+
+    private static boolean isC14N11alg(String alg) {
+        return alg.equals(DOMCanonicalXMLC14N11Method.C14N_11)
+            || alg.equals(DOMCanonicalXMLC14N11Method.C14N_11_WITH_COMMENTS);
     }
 }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,7 +1,3 @@
-/*
- * 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
@@ -21,32 +17,32 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
  */
 /*
- * $Id: DOMCryptoBinary.java 1197150 2011-11-03 14:34:57Z coheigea $
+ * $Id$
  */
 package org.jcp.xml.dsig.internal.dom;
 
 import java.math.BigInteger;
 import javax.xml.crypto.*;
 import javax.xml.crypto.dom.DOMCryptoContext;
+
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Node;
 import org.w3c.dom.Text;
 
-import com.sun.org.apache.xml.internal.security.utils.Base64;
-
 /**
  * A DOM-based representation of the XML <code>CryptoBinary</code> simple type
  * as defined in the W3C specification for XML-Signature Syntax and Processing.
  * The XML Schema Definition is defined as:
  *
- * <pre>{@code
+ * <xmp>
  * <simpleType name="CryptoBinary">
  *   <restriction base = "base64Binary">
  *   </restriction>
  * </simpleType>
- * }</pre>
+ * </xmp>
  *
  * @author Sean Mullan
  */
@@ -68,7 +64,8 @@
         }
         this.bigNum = bigNum;
         // convert to bitstring
-        value = Base64.encode(bigNum);
+        byte[] bytes = XMLUtils.getBytes(bigNum, bigNum.bitLength());
+        value = XMLUtils.encodeToString(bytes);
     }
 
     /**
@@ -80,7 +77,7 @@
     public DOMCryptoBinary(Node cbNode) throws MarshalException {
         value = cbNode.getNodeValue();
         try {
-            bigNum = Base64.decodeBigIntegerFromText((Text) cbNode);
+            bigNum = new BigInteger(1, XMLUtils.decode(((Text) cbNode).getData()));
         } catch (Exception ex) {
             throw new MarshalException(ex);
         }
@@ -95,6 +92,7 @@
         return bigNum;
     }
 
+    @Override
     public void marshal(Node parent, String prefix, DOMCryptoContext context)
         throws MarshalException {
         parent.appendChild
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMDigestMethod.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMDigestMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -42,19 +42,21 @@
 /**
  * DOM-based abstract implementation of DigestMethod.
  *
- * @author Sean Mullan
  */
 public abstract class DOMDigestMethod extends DOMStructure
     implements DigestMethod {
 
+    static final String SHA224 =
+        "http://www.w3.org/2001/04/xmldsig-more#sha224"; // see RFC 4051
     static final String SHA384 =
         "http://www.w3.org/2001/04/xmldsig-more#sha384"; // see RFC 4051
+
     private DigestMethodParameterSpec params;
 
     /**
-     * Creates a <code>DOMDigestMethod</code>.
+     * Creates a {@code DOMDigestMethod}.
      *
-     * @param params the algorithm-specific params (may be <code>null</code>)
+     * @param params the algorithm-specific params (may be {@code null})
      * @throws InvalidAlgorithmParameterException if the parameters are not
      *    appropriate for this digest method
      */
@@ -70,7 +72,7 @@
     }
 
     /**
-     * Creates a <code>DOMDigestMethod</code> from an element. This constructor
+     * Creates a {@code DOMDigestMethod} from an element. This constructor
      * invokes the abstract {@link #unmarshalParams unmarshalParams} method to
      * unmarshal any algorithm-specific input parameters.
      *
@@ -92,12 +94,16 @@
         String alg = DOMUtils.getAttributeValue(dmElem, "Algorithm");
         if (alg.equals(DigestMethod.SHA1)) {
             return new SHA1(dmElem);
+        } else if (alg.equals(SHA224)) {
+            return new SHA224(dmElem);
         } else if (alg.equals(DigestMethod.SHA256)) {
             return new SHA256(dmElem);
         } else if (alg.equals(SHA384)) {
             return new SHA384(dmElem);
         } else if (alg.equals(DigestMethod.SHA512)) {
             return new SHA512(dmElem);
+        } else if (alg.equals(DigestMethod.RIPEMD160)) {
+            return new RIPEMD160(dmElem);
         } else {
             throw new MarshalException("unsupported DigestMethod algorithm: " +
                                        alg);
@@ -110,7 +116,7 @@
      * since most DigestMethod algorithms do not have parameters. Subclasses
      * should override it if they have parameters.
      *
-     * @param params the algorithm-specific params (may be <code>null</code>)
+     * @param params the algorithm-specific params (may be {@code null})
      * @throws InvalidAlgorithmParameterException if the parameters are not
      *    appropriate for this digest method
      */
@@ -129,13 +135,13 @@
     }
 
     /**
-     * Unmarshals <code>DigestMethodParameterSpec</code> from the specified
-     * <code>Element</code>.  By default, this method throws an exception since
+     * Unmarshals {@code DigestMethodParameterSpec} from the specified
+     * {@code Element}.  By default, this method throws an exception since
      * most DigestMethod algorithms do not have parameters. Subclasses should
      * override it if they have parameters.
      *
-     * @param paramsElem the <code>Element</code> holding the input params
-     * @return the algorithm-specific <code>DigestMethodParameterSpec</code>
+     * @param paramsElem the {@code Element} holding the input params
+     * @return the algorithm-specific {@code DigestMethodParameterSpec}
      * @throws MarshalException if the parameters cannot be unmarshalled
      */
     DigestMethodParameterSpec unmarshalParams(Element paramsElem)
@@ -151,6 +157,7 @@
      * This method invokes the abstract {@link #marshalParams marshalParams}
      * method to marshal any algorithm-specific parameters.
      */
+    @Override
     public void marshal(Node parent, String prefix, DOMCryptoContext context)
         throws MarshalException
     {
@@ -178,10 +185,10 @@
         }
         DigestMethod odm = (DigestMethod)o;
 
-        boolean paramsEqual = (params == null ? odm.getParameterSpec() == null :
-            params.equals(odm.getParameterSpec()));
+        boolean paramsEqual = params == null ? odm.getParameterSpec() == null :
+            params.equals(odm.getParameterSpec());
 
-        return (getAlgorithm().equals(odm.getAlgorithm()) && paramsEqual);
+        return getAlgorithm().equals(odm.getAlgorithm()) && paramsEqual;
     }
 
     @Override
@@ -235,6 +242,24 @@
         }
     }
 
+    static final class SHA224 extends DOMDigestMethod {
+        SHA224(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA224(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return SHA224;
+        }
+        @Override
+        String getMessageDigestAlgorithm() {
+            return "SHA-224";
+        }
+    }
+
     static final class SHA256 extends DOMDigestMethod {
         SHA256(AlgorithmParameterSpec params)
             throws InvalidAlgorithmParameterException {
@@ -282,4 +307,22 @@
             return "SHA-512";
         }
     }
+
+    static final class RIPEMD160 extends DOMDigestMethod {
+        RIPEMD160(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        RIPEMD160(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return DigestMethod.RIPEMD160;
+        }
+        @Override
+        String getMessageDigestAlgorithm() {
+            return "RIPEMD160";
+        }
+    }
 }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMEnvelopedTransform.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMEnvelopedTransform.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMEnvelopedTransform.java 1197150 2011-11-03 14:34:57Z coheigea $
+ * $Id: DOMEnvelopedTransform.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -35,7 +35,6 @@
  * DOM-based implementation of Enveloped Signature Transform.
  * (Uses Apache XML-Sec Transform implementation)
  *
- * @author Sean Mullan
  */
 public final class DOMEnvelopedTransform extends ApacheTransform {
 
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMExcC14NMethod.java 1197150 2011-11-03 14:34:57Z coheigea $
+ * $Id: DOMExcC14NMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -37,8 +37,8 @@
 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;
 
@@ -47,7 +47,6 @@
  * Canonical XML algorithm (with or without comments).
  * Uses Apache XML-Sec Canonicalizer.
  *
- * @author Sean Mullan
  */
 public final class DOMExcC14NMethod extends ApacheCanonicalizer {
 
@@ -81,7 +80,7 @@
         this.inclusiveNamespaces = prefixListAttr;
         int begin = 0;
         int end = prefixListAttr.indexOf(' ');
-        List<String> prefixList = new ArrayList<String>();
+        List<String> prefixList = new ArrayList<>();
         while (end != -1) {
             prefixList.add(prefixListAttr.substring(begin, end));
             begin = end + 1;
@@ -93,6 +92,12 @@
         this.params = new ExcC14NParameterSpec(prefixList);
     }
 
+    @SuppressWarnings("unchecked")
+    public List<String> getParameterSpecPrefixList(ExcC14NParameterSpec paramSpec) {
+        return paramSpec.getPrefixList();
+    }
+
+    @Override
     public void marshalParams(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException
     {
@@ -120,7 +125,7 @@
         ExcC14NParameterSpec params = (ExcC14NParameterSpec)spec;
         StringBuffer prefixListAttr = new StringBuffer("");
         @SuppressWarnings("unchecked")
-        List<String> prefixList = params.getPrefixList();
+        List<String> prefixList = getParameterSpecPrefixList(params);
         for (int i = 0, size = prefixList.size(); i < size; i++) {
             prefixListAttr.append(prefixList.get(i));
             if (i < size - 1) {
@@ -148,6 +153,8 @@
                 try {
                     apacheCanonicalizer = Canonicalizer.getInstance
                         (CanonicalizationMethod.EXCLUSIVE);
+                    boolean secVal = Utils.secureValidation(xc);
+                    apacheCanonicalizer.setSecureValidation(secVal);
                 } catch (InvalidCanonicalizerException ice) {
                     throw new TransformException
                         ("Couldn't find Canonicalizer for: " +
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMHMACSignatureMethod.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMHMACSignatureMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -50,20 +50,23 @@
 /**
  * DOM-based implementation of HMAC SignatureMethod.
  *
- * @author Sean Mullan
  */
 public abstract class DOMHMACSignatureMethod extends AbstractDOMSignatureMethod {
 
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom");
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(DOMHMACSignatureMethod.class);
 
     // see RFC 4051 for these algorithm definitions
+    static final String HMAC_SHA224 =
+        "http://www.w3.org/2001/04/xmldsig-more#hmac-sha224";
     static final String HMAC_SHA256 =
         "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256";
     static final String HMAC_SHA384 =
         "http://www.w3.org/2001/04/xmldsig-more#hmac-sha384";
     static final String HMAC_SHA512 =
         "http://www.w3.org/2001/04/xmldsig-more#hmac-sha512";
+    static final String HMAC_RIPEMD160 =
+        "http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160";
 
     private Mac hmac;
     private int outputLength;
@@ -71,9 +74,9 @@
     private SignatureMethodParameterSpec params;
 
     /**
-     * Creates a <code>DOMHMACSignatureMethod</code> with the specified params
+     * Creates a {@code DOMHMACSignatureMethod} with the specified params
      *
-     * @param params algorithm-specific parameters (may be <code>null</code>)
+     * @param params algorithm-specific parameters (may be {@code null})
      * @throws InvalidAlgorithmParameterException if params are inappropriate
      */
     DOMHMACSignatureMethod(AlgorithmParameterSpec params)
@@ -84,7 +87,7 @@
     }
 
     /**
-     * Creates a <code>DOMHMACSignatureMethod</code> from an element.
+     * Creates a {@code DOMHMACSignatureMethod} from an element.
      *
      * @param smElem a SignatureMethod element
      */
@@ -100,6 +103,7 @@
         }
     }
 
+    @Override
     void checkParams(SignatureMethodParameterSpec params)
         throws InvalidAlgorithmParameterException
     {
@@ -110,9 +114,7 @@
             }
             outputLength = ((HMACParameterSpec)params).getOutputLength();
             outputLengthSet = true;
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Setting outputLength from HMACParameterSpec to: " + outputLength);
-            }
+            LOG.debug("Setting outputLength from HMACParameterSpec to: {}", outputLength);
         }
     }
 
@@ -123,11 +125,9 @@
     SignatureMethodParameterSpec unmarshalParams(Element paramsElem)
         throws MarshalException
     {
-        outputLength = Integer.valueOf(paramsElem.getFirstChild().getNodeValue()).intValue();
+        outputLength = Integer.parseInt(paramsElem.getFirstChild().getNodeValue());
         outputLengthSet = true;
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "unmarshalled outputLength: " + outputLength);
-        }
+        LOG.debug("unmarshalled outputLength: {}", outputLength);
         return new HMACParameterSpec(outputLength);
     }
 
@@ -164,7 +164,7 @@
             throw new XMLSignatureException
                 ("HMACOutputLength must not be less than " + getDigestLength());
         }
-        hmac.init((SecretKey)key);
+        hmac.init(key);
         ((DOMSignedInfo)si).canonicalize(context, new MacOutputStream(hmac));
         byte[] result = hmac.doFinal();
 
@@ -191,7 +191,7 @@
             throw new XMLSignatureException
                 ("HMACOutputLength must not be less than " + getDigestLength());
         }
-        hmac.init((SecretKey)key);
+        hmac.init(key);
         ((DOMSignedInfo)si).canonicalize(context, new MacOutputStream(hmac));
         return hmac.doFinal();
     }
@@ -205,7 +205,7 @@
         }
         HMACParameterSpec ospec = (HMACParameterSpec)spec;
 
-        return (outputLength == ospec.getOutputLength());
+        return outputLength == ospec.getOutputLength();
     }
 
     Type getAlgorithmType() {
@@ -236,6 +236,28 @@
         }
     }
 
+    static final class SHA224 extends DOMHMACSignatureMethod {
+        SHA224(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA224(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return HMAC_SHA224;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "HmacSHA224";
+        }
+        @Override
+        int getDigestLength() {
+            return 224;
+        }
+    }
+
     static final class SHA256 extends DOMHMACSignatureMethod {
         SHA256(AlgorithmParameterSpec params)
             throws InvalidAlgorithmParameterException {
@@ -292,4 +314,26 @@
             return 512;
         }
     }
+
+    static final class RIPEMD160 extends DOMHMACSignatureMethod {
+        RIPEMD160(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        RIPEMD160(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return HMAC_RIPEMD160;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "HMACRIPEMD160";
+        }
+        @Override
+        int getDigestLength() {
+            return 160;
+        }
+    }
 }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,31 +21,34 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMKeyInfo.java 1333869 2012-05-04 10:42:44Z coheigea $
+ * $Id: DOMKeyInfo.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dsig.*;
+import java.security.Provider;
+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.XMLSignature;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
 import javax.xml.crypto.dsig.keyinfo.KeyInfo;
-import javax.xml.crypto.dom.*;
-
-import java.security.Provider;
-import java.util.*;
 
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 
 /**
  * DOM-based implementation of KeyInfo.
  *
- * @author Sean Mullan
  */
 public final class DOMKeyInfo extends DOMStructure implements KeyInfo {
 
@@ -53,15 +56,25 @@
     private final List<XMLStructure> keyInfoTypes;
 
     /**
-     * Creates a <code>DOMKeyInfo</code>.
+     * A utility function to suppress casting warnings.
+     * @param ki
+     * @return the content of a KeyInfo Object
+     */
+    @SuppressWarnings("unchecked")
+    public static List<XMLStructure> getContent(KeyInfo ki) {
+        return ki.getContent();
+    }
+
+    /**
+     * Creates a {@code DOMKeyInfo}.
      *
      * @param content a list of one or more {@link XMLStructure}s representing
      *    key information types. The list is defensively copied to protect
      *    against subsequent modification.
      * @param id an ID attribute
-     * @throws NullPointerException if <code>content</code> is <code>null</code>
-     * @throws IllegalArgumentException if <code>content</code> is empty
-     * @throws ClassCastException if <code>content</code> contains any entries
+     * @throws NullPointerException if {@code content} is {@code null}
+     * @throws IllegalArgumentException if {@code content} is empty
+     * @throws ClassCastException if {@code content} contains any entries
      *    that are not of type {@link XMLStructure}
      */
     public DOMKeyInfo(List<? extends XMLStructure> content, String id) {
@@ -69,7 +82,7 @@
             throw new NullPointerException("content cannot be null");
         }
         this.keyInfoTypes =
-            Collections.unmodifiableList(new ArrayList<XMLStructure>(content));
+            Collections.unmodifiableList(new ArrayList<>(content));
         if (this.keyInfoTypes.isEmpty()) {
             throw new IllegalArgumentException("content cannot be empty");
         }
@@ -83,7 +96,7 @@
     }
 
     /**
-     * Creates a <code>DOMKeyInfo</code> from XML.
+     * Creates a {@code DOMKeyInfo} from XML.
      *
      * @param kiElem KeyInfo element
      */
@@ -101,35 +114,32 @@
         }
 
         // get all children nodes
-        NodeList nl = kiElem.getChildNodes();
-        int length = nl.getLength();
-        if (length < 1) {
-            throw new MarshalException
-                ("KeyInfo must contain at least one type");
+        List<XMLStructure> content = new ArrayList<>();
+        Node firstChild = kiElem.getFirstChild();
+        if (firstChild == null) {
+            throw new MarshalException("KeyInfo must contain at least one type");
         }
-        List<XMLStructure> content = new ArrayList<XMLStructure>(length);
-        for (int i = 0; i < length; i++) {
-            Node child = nl.item(i);
-            // ignore all non-Element nodes
-            if (child.getNodeType() != Node.ELEMENT_NODE) {
-                continue;
+        while (firstChild != null) {
+            if (firstChild.getNodeType() == Node.ELEMENT_NODE) {
+                Element childElem = (Element)firstChild;
+                String localName = childElem.getLocalName();
+                String namespace = childElem.getNamespaceURI();
+                if ("X509Data".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
+                    content.add(new DOMX509Data(childElem));
+                } else if ("KeyName".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
+                    content.add(new DOMKeyName(childElem));
+                } else if ("KeyValue".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
+                    content.add(DOMKeyValue.unmarshal(childElem));
+                } else if ("RetrievalMethod".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
+                    content.add(new DOMRetrievalMethod(childElem,
+                                                       context, provider));
+                } else if ("PGPData".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
+                    content.add(new DOMPGPData(childElem));
+                } else { //may be MgmtData, SPKIData or element from other namespace
+                    content.add(new javax.xml.crypto.dom.DOMStructure(childElem));
+                }
             }
-            Element childElem = (Element)child;
-            String localName = childElem.getLocalName();
-            if (localName.equals("X509Data")) {
-                content.add(new DOMX509Data(childElem));
-            } else if (localName.equals("KeyName")) {
-                content.add(new DOMKeyName(childElem));
-            } else if (localName.equals("KeyValue")) {
-                content.add(DOMKeyValue.unmarshal(childElem));
-            } else if (localName.equals("RetrievalMethod")) {
-                content.add(new DOMRetrievalMethod(childElem,
-                                                   context, provider));
-            } else if (localName.equals("PGPData")) {
-                content.add(new DOMPGPData(childElem));
-            } else { //may be MgmtData, SPKIData or element from other namespace
-                content.add(new javax.xml.crypto.dom.DOMStructure((childElem)));
-            }
+            firstChild = firstChild.getNextSibling();
         }
         keyInfoTypes = Collections.unmodifiableList(content);
     }
@@ -164,9 +174,15 @@
             kiElem.setAttributeNS("http://www.w3.org/2000/xmlns/",
                                   "xmlns:" + dsPrefix, XMLSignature.XMLNS);
         }
-        marshal(pNode, kiElem, null, dsPrefix, (DOMCryptoContext)context);
+
+        Node nextSibling = null;
+        if (context instanceof DOMSignContext) {
+            nextSibling = ((DOMSignContext)context).getNextSibling();
+        }
+        marshal(pNode, kiElem, nextSibling, dsPrefix, (DOMCryptoContext)context);
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix,
                         DOMCryptoContext context)
         throws MarshalException
@@ -215,10 +231,10 @@
         }
         KeyInfo oki = (KeyInfo)o;
 
-        boolean idsEqual = (id == null ? oki.getId() == null
-                                       : id.equals(oki.getId()));
+        boolean idsEqual = id == null ? oki.getId() == null
+                                       : id.equals(oki.getId());
 
-        return (keyInfoTypes.equals(oki.getContent()) && idsEqual);
+        return keyInfoTypes.equals(oki.getContent()) && idsEqual;
     }
 
     @Override
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,20 +21,35 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMKeyInfoFactory.java 1333869 2012-05-04 10:42:44Z coheigea $
+ * $Id: DOMKeyInfoFactory.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
 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.RSAPublicKey;
 import java.util.List;
-import javax.xml.crypto.*;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.XMLStructure;
 import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.keyinfo.*;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
+import javax.xml.crypto.dsig.keyinfo.KeyName;
+import javax.xml.crypto.dsig.keyinfo.KeyValue;
+import javax.xml.crypto.dsig.keyinfo.PGPData;
+import javax.xml.crypto.dsig.keyinfo.RetrievalMethod;
+import javax.xml.crypto.dsig.keyinfo.X509Data;
+import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -42,7 +57,6 @@
 /**
  * DOM-based implementation of KeyInfoFactory.
  *
- * @author Sean Mullan
  */
 public final class DOMKeyInfoFactory extends KeyInfoFactory {
 
@@ -64,12 +78,12 @@
 
     public KeyValue newKeyValue(PublicKey key)  throws KeyException {
         String algorithm = key.getAlgorithm();
-        if (algorithm.equals("DSA")) {
-            return new DOMKeyValue.DSA(key);
-        } else if (algorithm.equals("RSA")) {
-            return new DOMKeyValue.RSA(key);
-        } else if (algorithm.equals("EC")) {
-            return new DOMKeyValue.EC(key);
+        if ("DSA".equals(algorithm)) {
+            return new DOMKeyValue.DSA((DSAPublicKey) key);
+        } else if ("RSA".equals(algorithm)) {
+            return new DOMKeyValue.RSA((RSAPublicKey) key);
+        } else if ("EC".equals(algorithm)) {
+            return new DOMKeyValue.EC((ECPublicKey) key);
         } else {
             throw new KeyException("unsupported key algorithm: " + algorithm);
         }
@@ -79,12 +93,12 @@
         return newPGPData(keyId, null, null);
     }
 
-    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     public PGPData newPGPData(byte[] keyId, byte[] keyPacket, List other) {
         return new DOMPGPData(keyId, keyPacket, other);
     }
 
-    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     public PGPData newPGPData(byte[] keyPacket, List other) {
         return new DOMPGPData(keyPacket, other);
     }
@@ -93,7 +107,7 @@
         return newRetrievalMethod(uri, null, null);
     }
 
-    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     public RetrievalMethod newRetrievalMethod(String uri, String type,
         List transforms) {
         if (uri == null) {
@@ -102,11 +116,12 @@
         return new DOMRetrievalMethod(uri, type, transforms);
     }
 
-    @SuppressWarnings("rawtypes")
+    @SuppressWarnings({ "rawtypes" })
     public X509Data newX509Data(List content) {
         return new DOMX509Data(content);
     }
 
+    @Override
     public X509IssuerSerial newX509IssuerSerial(String issuerName,
         BigInteger serialNumber) {
         return new DOMX509IssuerSerial(issuerName, serialNumber);
@@ -124,6 +139,7 @@
         return DOMURIDereferencer.INSTANCE;
     }
 
+    @Override
     public KeyInfo unmarshalKeyInfo(XMLStructure xmlStructure)
         throws MarshalException {
         if (xmlStructure == null) {
@@ -148,11 +164,12 @@
 
         // check tag
         String tag = element.getLocalName();
-        if (tag == null) {
+        String namespace = element.getNamespaceURI();
+        if (tag == null || namespace == null) {
             throw new MarshalException("Document implementation must " +
                 "support DOM Level 2 and be namespace aware");
         }
-        if (tag.equals("KeyInfo")) {
+        if ("KeyInfo".equals(tag) && XMLSignature.XMLNS.equals(namespace)) {
             try {
                 return new DOMKeyInfo(element, new UnmarshalContext(), getProvider());
             } catch (MarshalException me) {
@@ -161,7 +178,7 @@
                 throw new MarshalException(e);
             }
         } else {
-            throw new MarshalException("Invalid KeyInfo tag: " + tag);
+            throw new MarshalException("Invalid KeyInfo tag: " + namespace + ":" + tag);
         }
     }
 
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyName.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyName.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,16 +21,16 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMKeyName.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMKeyName.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
+import javax.xml.crypto.MarshalException;
 import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
+import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.keyinfo.KeyName;
 
 import org.w3c.dom.Document;
@@ -40,17 +40,16 @@
 /**
  * DOM-based implementation of KeyName.
  *
- * @author Sean Mullan
  */
 public final class DOMKeyName extends DOMStructure implements KeyName {
 
     private final String name;
 
     /**
-     * Creates a <code>DOMKeyName</code>.
+     * Creates a {@code DOMKeyName}.
      *
      * @param name the name of the key identifier
-     * @throws NullPointerException if <code>name</code> is null
+     * @throws NullPointerException if {@code name} is null
      */
     public DOMKeyName(String name) {
         if (name == null) {
@@ -60,7 +59,7 @@
     }
 
     /**
-     * Creates a <code>DOMKeyName</code> from a KeyName element.
+     * Creates a {@code DOMKeyName} from a KeyName element.
      *
      * @param knElem a KeyName element
      */
@@ -72,6 +71,7 @@
         return name;
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMKeyValue.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMKeyValue.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -54,25 +54,23 @@
 import java.security.spec.KeySpec;
 import java.security.spec.RSAPublicKeySpec;
 import java.util.Arrays;
+
+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.exceptions.Base64DecodingException;
-import com.sun.org.apache.xml.internal.security.utils.Base64;
-
 /**
  * DOM-based implementation of KeyValue.
  *
- * @author Sean Mullan
  */
-public abstract class DOMKeyValue extends DOMStructure implements KeyValue {
+public abstract class DOMKeyValue<K extends PublicKey> extends DOMStructure implements KeyValue {
 
     private static final String XMLDSIG_11_XMLNS
         = "http://www.w3.org/2009/xmldsig11#";
-    private final PublicKey publicKey;
+    private final K publicKey;
 
-    public DOMKeyValue(PublicKey key) throws KeyException {
+    public DOMKeyValue(K key) throws KeyException {
         if (key == null) {
             throw new NullPointerException("key cannot be null");
         }
@@ -80,7 +78,7 @@
     }
 
     /**
-     * Creates a <code>DOMKeyValue</code> from an element.
+     * Creates a {@code DOMKeyValue} from an element.
      *
      * @param kvtElem a KeyValue child element
      */
@@ -90,11 +88,16 @@
 
     static KeyValue unmarshal(Element kvElem) throws MarshalException {
         Element kvtElem = DOMUtils.getFirstChildElement(kvElem);
-        if (kvtElem.getLocalName().equals("DSAKeyValue")) {
+        if (kvtElem == null) {
+            throw new MarshalException("KeyValue must contain at least one type");
+        }
+
+        String namespace = kvtElem.getNamespaceURI();
+        if (kvtElem.getLocalName().equals("DSAKeyValue") && XMLSignature.XMLNS.equals(namespace)) {
             return new DSA(kvtElem);
-        } else if (kvtElem.getLocalName().equals("RSAKeyValue")) {
+        } else if (kvtElem.getLocalName().equals("RSAKeyValue") && XMLSignature.XMLNS.equals(namespace)) {
             return new RSA(kvtElem);
-        } else if (kvtElem.getLocalName().equals("ECKeyValue")) {
+        } else if (kvtElem.getLocalName().equals("ECKeyValue") && XMLDSIG_11_XMLNS.equals(namespace)) {
             return new EC(kvtElem);
         } else {
             return new Unknown(kvtElem);
@@ -109,6 +112,7 @@
         }
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
@@ -125,14 +129,14 @@
     abstract void marshalPublicKey(Node parent, Document doc, String dsPrefix,
         DOMCryptoContext context) throws MarshalException;
 
-    abstract PublicKey unmarshalKeyValue(Element kvtElem)
+    abstract K unmarshalKeyValue(Element kvtElem)
         throws MarshalException;
 
     private static PublicKey generatePublicKey(KeyFactory kf, KeySpec keyspec) {
         try {
             return kf.generatePublic(keyspec);
         } catch (InvalidKeySpecException e) {
-            //@@@ should dump exception to log
+            //@@@ should dump exception to LOG
             return null;
         }
     }
@@ -162,6 +166,15 @@
         return true;
     }
 
+    public static BigInteger decode(Element elem) throws MarshalException {
+        try {
+            String base64str = elem.getFirstChild().getNodeValue();
+            return new BigInteger(1, XMLUtils.decode(base64str));
+        } catch (Exception ex) {
+            throw new MarshalException(ex);
+        }
+    }
+
     @Override
     public int hashCode() {
         int result = 17;
@@ -172,14 +185,14 @@
         return result;
     }
 
-    static final class RSA extends DOMKeyValue {
+    static final class RSA extends DOMKeyValue<RSAPublicKey> {
         // RSAKeyValue CryptoBinaries
         private DOMCryptoBinary modulus, exponent;
         private KeyFactory rsakf;
 
-        RSA(PublicKey key) throws KeyException {
+        RSA(RSAPublicKey key) throws KeyException {
             super(key);
-            RSAPublicKey rkey = (RSAPublicKey)key;
+            RSAPublicKey rkey = key;
             exponent = new DOMCryptoBinary(rkey.getPublicExponent());
             modulus = new DOMCryptoBinary(rkey.getModulus());
         }
@@ -206,7 +219,8 @@
             parent.appendChild(rsaElem);
         }
 
-        PublicKey unmarshalKeyValue(Element kvtElem)
+        @Override
+        RSAPublicKey unmarshalKeyValue(Element kvtElem)
             throws MarshalException
         {
             if (rsakf == null) {
@@ -218,25 +232,26 @@
                 }
             }
             Element modulusElem = DOMUtils.getFirstChildElement(kvtElem,
-                                                                "Modulus");
-            modulus = new DOMCryptoBinary(modulusElem.getFirstChild());
+                                                                "Modulus",
+                                                                XMLSignature.XMLNS);
+            BigInteger modulus = decode(modulusElem);
             Element exponentElem = DOMUtils.getNextSiblingElement(modulusElem,
-                                                                  "Exponent");
-            exponent = new DOMCryptoBinary(exponentElem.getFirstChild());
-            RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus.getBigNum(),
-                                                         exponent.getBigNum());
-            return generatePublicKey(rsakf, spec);
+                                                                  "Exponent",
+                                                                  XMLSignature.XMLNS);
+            BigInteger exponent = decode(exponentElem);
+            RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent);
+            return (RSAPublicKey) generatePublicKey(rsakf, spec);
         }
     }
 
-    static final class DSA extends DOMKeyValue {
+    static final class DSA extends DOMKeyValue<DSAPublicKey> {
         // DSAKeyValue CryptoBinaries
-        private DOMCryptoBinary p, q, g, y, j; //, seed, pgen;
+        private DOMCryptoBinary p, q, g, y; //, seed, pgen;
         private KeyFactory dsakf;
 
-        DSA(PublicKey key) throws KeyException {
+        DSA(DSAPublicKey key) throws KeyException {
             super(key);
-            DSAPublicKey dkey = (DSAPublicKey) key;
+            DSAPublicKey dkey = key;
             DSAParams params = dkey.getParams();
             p = new DOMCryptoBinary(params.getP());
             q = new DOMCryptoBinary(params.getQ());
@@ -248,6 +263,7 @@
             super(elem);
         }
 
+        @Override
         void marshalPublicKey(Node parent, Document doc, String dsPrefix,
                               DOMCryptoContext context)
             throws MarshalException
@@ -275,7 +291,8 @@
             parent.appendChild(dsaElem);
         }
 
-        PublicKey unmarshalKeyValue(Element kvtElem)
+        @Override
+        DSAPublicKey unmarshalKeyValue(Element kvtElem)
             throws MarshalException
         {
             if (dsakf == null) {
@@ -287,41 +304,41 @@
                 }
             }
             Element curElem = DOMUtils.getFirstChildElement(kvtElem);
+            if (curElem == null) {
+                throw new MarshalException("KeyValue must contain at least one type");
+            }
             // check for P and Q
-            if (curElem.getLocalName().equals("P")) {
-                p = new DOMCryptoBinary(curElem.getFirstChild());
-                curElem = DOMUtils.getNextSiblingElement(curElem, "Q");
-                q = new DOMCryptoBinary(curElem.getFirstChild());
+            BigInteger p = null;
+            BigInteger q = null;
+            if (curElem.getLocalName().equals("P") && XMLSignature.XMLNS.equals(curElem.getNamespaceURI())) {
+                p = decode(curElem);
+                curElem = DOMUtils.getNextSiblingElement(curElem, "Q", XMLSignature.XMLNS);
+                q = decode(curElem);
                 curElem = DOMUtils.getNextSiblingElement(curElem);
             }
-            if (curElem.getLocalName().equals("G")) {
-                g = new DOMCryptoBinary(curElem.getFirstChild());
-                curElem = DOMUtils.getNextSiblingElement(curElem, "Y");
+            BigInteger g = null;
+            if (curElem != null
+                && curElem.getLocalName().equals("G") && XMLSignature.XMLNS.equals(curElem.getNamespaceURI())) {
+                g = decode(curElem);
+                curElem = DOMUtils.getNextSiblingElement(curElem, "Y", XMLSignature.XMLNS);
             }
-            y = new DOMCryptoBinary(curElem.getFirstChild());
-            curElem = DOMUtils.getNextSiblingElement(curElem);
-            if (curElem != null && curElem.getLocalName().equals("J")) {
-                j = new DOMCryptoBinary(curElem.getFirstChild());
-                // curElem = DOMUtils.getNextSiblingElement(curElem);
-            }
-            /*
+            BigInteger y = null;
             if (curElem != null) {
-                seed = new DOMCryptoBinary(curElem.getFirstChild());
+                y = decode(curElem);
                 curElem = DOMUtils.getNextSiblingElement(curElem);
-                pgen = new DOMCryptoBinary(curElem.getFirstChild());
             }
-            */
+            //if (curElem != null && curElem.getLocalName().equals("J")) {
+                //j = new DOMCryptoBinary(curElem.getFirstChild());
+                // curElem = DOMUtils.getNextSiblingElement(curElem);
+            //}
             //@@@ do we care about j, pgenCounter or seed?
-            DSAPublicKeySpec spec = new DSAPublicKeySpec(y.getBigNum(),
-                                                         p.getBigNum(),
-                                                         q.getBigNum(),
-                                                         g.getBigNum());
-            return generatePublicKey(dsakf, spec);
+            DSAPublicKeySpec spec = new DSAPublicKeySpec(y, p, q, g);
+            return (DSAPublicKey) generatePublicKey(dsakf, spec);
         }
     }
 
-    static final class EC extends DOMKeyValue {
-        // ECKeyValue CryptoBinaries
+    static final class EC extends DOMKeyValue<ECPublicKey> {
+     // ECKeyValue CryptoBinaries
         private byte[] ecPublicKey;
         private KeyFactory eckf;
         private ECParameterSpec ecParams;
@@ -376,9 +393,8 @@
             return new Curve(name, oid, curve, g, bigInt(n), h);
         }
 
-        EC(PublicKey key) throws KeyException {
-            super(key);
-            ECPublicKey ecKey = (ECPublicKey)key;
+        EC(ECPublicKey ecKey) throws KeyException {
+            super(ecKey);
             ECPoint ecPoint = ecKey.getW();
             ecParams = ecKey.getParams();
             ecPublicKey = encodePoint(ecPoint, ecParams.getCurve());
@@ -390,14 +406,14 @@
 
         private static ECPoint decodePoint(byte[] data, EllipticCurve curve)
                 throws IOException {
-            if ((data.length == 0) || (data[0] != 4)) {
+            if (data.length == 0 || data[0] != 4) {
                 throw new IOException("Only uncompressed point format " +
                                       "supported");
             }
             // Per ANSI X9.62, an encoded point is a 1 byte type followed by
-            // ceiling(log base 2 field-size / 8) bytes of x and the same of y.
+            // ceiling(LOG base 2 field-size / 8) bytes of x and the same of y.
             int n = (data.length - 1) / 2;
-            if (n != ((curve.getField().getFieldSize() + 7) >> 3)) {
+            if (n != (curve.getField().getFieldSize() + 7) >> 3) {
                 throw new IOException("Point does not match field size");
             }
 
@@ -412,7 +428,7 @@
             int n = (curve.getField().getFieldSize() + 7) >> 3;
             byte[] xb = trimZeroes(point.getAffineX().toByteArray());
             byte[] yb = trimZeroes(point.getAffineY().toByteArray());
-            if ((xb.length > n) || (yb.length > n)) {
+            if (xb.length > n || yb.length > n) {
                 throw new RuntimeException("Point coordinates do not " +
                                            "match field size");
             }
@@ -425,7 +441,7 @@
 
         private static byte[] trimZeroes(byte[] b) {
             int i = 0;
-            while ((i < b.length - 1) && (b[i] == 0)) {
+            while (i < b.length - 1 && b[i] == 0) {
                 i++;
             }
             if (i == 0) {
@@ -464,18 +480,7 @@
             }
         }
 
-        private static ECParameterSpec getECParameterSpec(String oid) {
-            if (oid.equals(SECP256R1.getObjectId())) {
-                return SECP256R1;
-            } else if (oid.equals(SECP384R1.getObjectId())) {
-                return SECP384R1;
-            } else if (oid.equals(SECP521R1.getObjectId())) {
-                return SECP521R1;
-            } else {
-                return null;
-            }
-        }
-
+        @Override
         void marshalPublicKey(Node parent, Document doc, String dsPrefix,
                               DOMCryptoContext context)
             throws MarshalException
@@ -490,7 +495,6 @@
             Element publicKeyElem = DOMUtils.createElement(doc, "PublicKey",
                                                            XMLDSIG_11_XMLNS,
                                                            prefix);
-            Object[] args = new Object[] { ecParams };
             String oid = getCurveOid(ecParams);
             if (oid == null) {
                 throw new MarshalException("Invalid ECParameterSpec");
@@ -501,14 +505,15 @@
             namedCurveElem.setAttributeNS("http://www.w3.org/2000/xmlns/",
                                           qname, XMLDSIG_11_XMLNS);
             ecKeyValueElem.appendChild(namedCurveElem);
-            String encoded = Base64.encode(ecPublicKey);
+            String encoded = XMLUtils.encodeToString(ecPublicKey);
             publicKeyElem.appendChild
                 (DOMUtils.getOwnerDocument(publicKeyElem).createTextNode(encoded));
             ecKeyValueElem.appendChild(publicKeyElem);
             parent.appendChild(ecKeyValueElem);
         }
 
-        PublicKey unmarshalKeyValue(Element kvtElem)
+        @Override
+        ECPublicKey unmarshalKeyValue(Element kvtElem)
             throws MarshalException
         {
             if (eckf == null) {
@@ -521,14 +526,20 @@
             }
             ECParameterSpec ecParams = null;
             Element curElem = DOMUtils.getFirstChildElement(kvtElem);
-            if (curElem.getLocalName().equals("ECParameters")) {
+            if (curElem == null) {
+                throw new MarshalException("KeyValue must contain at least one type");
+            }
+
+            if (curElem.getLocalName().equals("ECParameters")
+                && XMLDSIG_11_XMLNS.equals(curElem.getNamespaceURI())) {
                 throw new UnsupportedOperationException
                     ("ECParameters not supported");
-            } else if (curElem.getLocalName().equals("NamedCurve")) {
+            } else if (curElem.getLocalName().equals("NamedCurve")
+                && XMLDSIG_11_XMLNS.equals(curElem.getNamespaceURI())) {
                 String uri = DOMUtils.getAttributeValue(curElem, "URI");
                 // strip off "urn:oid"
                 if (uri.startsWith("urn:oid:")) {
-                    String oid = uri.substring(8);
+                    String oid = uri.substring("urn:oid:".length());
                     ecParams = getECParameterSpec(oid);
                     if (ecParams == null) {
                         throw new MarshalException("Invalid curve OID");
@@ -539,20 +550,31 @@
             } else {
                 throw new MarshalException("Invalid ECKeyValue");
             }
-            curElem = DOMUtils.getNextSiblingElement(curElem, "PublicKey");
+            curElem = DOMUtils.getNextSiblingElement(curElem, "PublicKey", XMLDSIG_11_XMLNS);
             ECPoint ecPoint = null;
 
             try {
-                ecPoint = decodePoint(Base64.decode(curElem),
+                String content = XMLUtils.getFullTextChildrenFromElement(curElem);
+                ecPoint = decodePoint(XMLUtils.decode(content),
                                       ecParams.getCurve());
-            } catch (Base64DecodingException bde) {
-                throw new MarshalException("Invalid EC PublicKey", bde);
             } catch (IOException ioe) {
                 throw new MarshalException("Invalid EC Point", ioe);
             }
 
             ECPublicKeySpec spec = new ECPublicKeySpec(ecPoint, ecParams);
-            return generatePublicKey(eckf, spec);
+            return (ECPublicKey) generatePublicKey(eckf, spec);
+        }
+
+        private static ECParameterSpec getECParameterSpec(String oid) {
+            if (oid.equals(SECP256R1.getObjectId())) {
+                return SECP256R1;
+            } else if (oid.equals(SECP384R1.getObjectId())) {
+                return SECP384R1;
+            } else if (oid.equals(SECP521R1.getObjectId())) {
+                return SECP521R1;
+            } else {
+                return null;
+            }
         }
 
         static final class Curve extends ECParameterSpec {
@@ -580,15 +602,19 @@
         return new BigInteger(s, 16);
     }
 
-    static final class Unknown extends DOMKeyValue {
+    static final class Unknown extends DOMKeyValue<PublicKey> {
         private javax.xml.crypto.dom.DOMStructure externalPublicKey;
         Unknown(Element elem) throws MarshalException {
             super(elem);
         }
+
+        @Override
         PublicKey unmarshalKeyValue(Element kvElem) throws MarshalException {
             externalPublicKey = new javax.xml.crypto.dom.DOMStructure(kvElem);
             return null;
         }
+
+        @Override
         void marshalPublicKey(Node parent, Document doc, String dsPrefix,
                               DOMCryptoContext context)
             throws MarshalException
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMManifest.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMManifest.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -35,7 +35,6 @@
 import java.security.Provider;
 import java.util.*;
 
-import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -43,7 +42,6 @@
 /**
  * DOM-based implementation of Manifest.
  *
- * @author Sean Mullan
  */
 public final class DOMManifest extends DOMStructure implements Manifest {
 
@@ -51,16 +49,16 @@
     private final String id;
 
     /**
-     * Creates a <code>DOMManifest</code> containing the specified
+     * Creates a {@code DOMManifest} containing the specified
      * list of {@link Reference}s and optional id.
      *
-     * @param references a list of one or more <code>Reference</code>s. The list
+     * @param references a list of one or more {@code Reference}s. The list
      *    is defensively copied to protect against subsequent modification.
-     * @param id the id (may be <code>null</code>
-     * @throws NullPointerException if <code>references</code> is
-     *    <code>null</code>
-     * @throws IllegalArgumentException if <code>references</code> is empty
-     * @throws ClassCastException if <code>references</code> contains any
+     * @param id the id (may be {@code null}
+     * @throws NullPointerException if {@code references} is
+     *    {@code null}
+     * @throws IllegalArgumentException if {@code references} is empty
+     * @throws ClassCastException if {@code references} contains any
      *    entries that are not of type {@link Reference}
      */
     public DOMManifest(List<? extends Reference> references, String id) {
@@ -68,7 +66,7 @@
             throw new NullPointerException("references cannot be null");
         }
         this.references =
-            Collections.unmodifiableList(new ArrayList<Reference>(references));
+            Collections.unmodifiableList(new ArrayList<>(references));
         if (this.references.isEmpty()) {
             throw new IllegalArgumentException("list of references must " +
                 "contain at least one entry");
@@ -83,7 +81,7 @@
     }
 
     /**
-     * Creates a <code>DOMManifest</code> from an element.
+     * Creates a {@code DOMManifest} from an element.
      *
      * @param manElem a Manifest element
      */
@@ -91,30 +89,25 @@
                        Provider provider)
         throws MarshalException
     {
-        Attr attr = manElem.getAttributeNodeNS(null, "Id");
-        if (attr != null) {
-            this.id = attr.getValue();
-            manElem.setIdAttributeNode(attr, true);
-        } else {
-            this.id = null;
-        }
+        this.id = DOMUtils.getIdAttributeValue(manElem, "Id");
 
         boolean secVal = Utils.secureValidation(context);
 
-        Element refElem = DOMUtils.getFirstChildElement(manElem, "Reference");
-        List<Reference> refs = new ArrayList<Reference>();
+        Element refElem = DOMUtils.getFirstChildElement(manElem, "Reference", XMLSignature.XMLNS);
+        List<Reference> refs = new ArrayList<>();
         refs.add(new DOMReference(refElem, context, provider));
 
         refElem = DOMUtils.getNextSiblingElement(refElem);
         while (refElem != null) {
             String localName = refElem.getLocalName();
-            if (!localName.equals("Reference")) {
+            String namespace = refElem.getNamespaceURI();
+            if (!"Reference".equals(localName) || !XMLSignature.XMLNS.equals(namespace)) {
                 throw new MarshalException("Invalid element name: " +
-                                           localName + ", expected Reference");
+                                           namespace + ":" + localName + ", expected Reference");
             }
             refs.add(new DOMReference(refElem, context, provider));
             if (secVal && Policy.restrictNumReferences(refs.size())) {
-                String error = "A maximum of " + Policy.maxReferences()
+                String error = "A maxiumum of " + Policy.maxReferences()
                     + " references per Manifest are allowed when"
                     + " secure validation is enabled";
                 throw new MarshalException(error);
@@ -129,14 +122,16 @@
     }
 
     @SuppressWarnings("unchecked")
-    static List<Reference> getManifestReferences(Manifest mf) {
+    public static List<Reference> getManifestReferences(Manifest mf) {
         return mf.getReferences();
     }
 
+    @Override
     public List<Reference> getReferences() {
         return references;
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
@@ -164,10 +159,10 @@
         }
         Manifest oman = (Manifest)o;
 
-        boolean idsEqual = (id == null ? oman.getId() == null
-                                       : id.equals(oman.getId()));
+        boolean idsEqual = id == null ? oman.getId() == null
+                                       : id.equals(oman.getId());
 
-        return (idsEqual && references.equals(oman.getReferences()));
+        return idsEqual && references.equals(oman.getReferences());
     }
 
     @Override
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMPGPData.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMPGPData.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,30 +21,29 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMPGPData.java 1203846 2011-11-18 21:18:17Z mullan $
+ * $Id: DOMPGPData.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
 import java.util.*;
+
 import javax.xml.crypto.*;
 import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
+import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.keyinfo.PGPData;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 
-import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
-import com.sun.org.apache.xml.internal.security.utils.Base64;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 
 /**
  * DOM-based implementation of PGPData.
  *
- * @author Sean Mullan
  */
 public final class DOMPGPData extends DOMStructure implements PGPData {
 
@@ -53,7 +52,7 @@
     private final List<XMLStructure> externalElements;
 
     /**
-     * Creates a <code>DOMPGPData</code> containing the specified key packet.
+     * Creates a {@code DOMPGPData} containing the specified key packet.
      * and optional list of external elements.
      *
      * @param keyPacket a PGP Key Material Packet as defined in section 5.5 of
@@ -61,12 +60,12 @@
      *    array is cloned to prevent subsequent modification.
      * @param other a list of {@link XMLStructure}s representing elements from
      *    an external namespace. The list is defensively copied to prevent
-     *    subsequent modification. May be <code>null</code> or empty.
-     * @throws NullPointerException if <code>keyPacket</code> is
-     *    <code>null</code>
+     *    subsequent modification. May be {@code null} or empty.
+     * @throws NullPointerException if {@code keyPacket} is
+     *    {@code null}
      * @throws IllegalArgumentException if the key packet is not in the
      *    correct format
-     * @throws ClassCastException if <code>other</code> contains any
+     * @throws ClassCastException if {@code other} contains any
      *    entries that are not of type {@link XMLStructure}
      */
     public DOMPGPData(byte[] keyPacket, List<? extends XMLStructure> other) {
@@ -77,7 +76,7 @@
             this.externalElements = Collections.emptyList();
         } else {
             this.externalElements =
-                Collections.unmodifiableList(new ArrayList<XMLStructure>(other));
+                Collections.unmodifiableList(new ArrayList<>(other));
             for (int i = 0, size = this.externalElements.size(); i < size; i++) {
                 if (!(this.externalElements.get(i) instanceof XMLStructure)) {
                     throw new ClassCastException
@@ -91,7 +90,7 @@
     }
 
     /**
-     * Creates a <code>DOMPGPData</code> containing the specified key id and
+     * Creates a {@code DOMPGPData} containing the specified key id and
      * optional key packet and list of external elements.
      *
      * @param keyId a PGP public key id as defined in section 11.2 of
@@ -99,15 +98,15 @@
      *    array is cloned to prevent subsequent modification.
      * @param keyPacket a PGP Key Material Packet as defined in section 5.5 of
      *    <a href="http://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a> (may
-     *    be <code>null</code>). The array is cloned to prevent subsequent
+     *    be {@code null}). The array is cloned to prevent subsequent
      *    modification.
      * @param other a list of {@link XMLStructure}s representing elements from
      *    an external namespace. The list is defensively copied to prevent
-     *    subsequent modification. May be <code>null</code> or empty.
-     * @throws NullPointerException if <code>keyId</code> is <code>null</code>
+     *    subsequent modification. May be {@code null} or empty.
+     * @throws NullPointerException if {@code keyId} is {@code null}
      * @throws IllegalArgumentException if the key id or packet is not in the
      *    correct format
-     * @throws ClassCastException if <code>other</code> contains any
+     * @throws ClassCastException if {@code other} contains any
      *    entries that are not of type {@link XMLStructure}
      */
     public DOMPGPData(byte[] keyId, byte[] keyPacket,
@@ -124,7 +123,7 @@
             this.externalElements = Collections.emptyList();
         } else {
             this.externalElements =
-                Collections.unmodifiableList(new ArrayList<XMLStructure>(other));
+                Collections.unmodifiableList(new ArrayList<>(other));
             for (int i = 0, size = this.externalElements.size(); i < size; i++) {
                 if (!(this.externalElements.get(i) instanceof XMLStructure)) {
                     throw new ClassCastException
@@ -141,53 +140,53 @@
     }
 
     /**
-     * Creates a <code>DOMPGPData</code> from an element.
+     * Creates a {@code DOMPGPData} from an element.
      *
      * @param pdElem a PGPData element
      */
     public DOMPGPData(Element pdElem) throws MarshalException {
         // get all children nodes
-        byte[] keyId = null;
-        byte[] keyPacket = null;
-        NodeList nl = pdElem.getChildNodes();
-        int length = nl.getLength();
-        List<XMLStructure> other = new ArrayList<XMLStructure>(length);
-        for (int x = 0; x < length; x++) {
-            Node n = nl.item(x);
-            if (n.getNodeType() == Node.ELEMENT_NODE) {
-                Element childElem = (Element)n;
+        byte[] pgpKeyId = null;
+        byte[] pgpKeyPacket = null;
+
+        List<XMLStructure> other = new ArrayList<>();
+        Node firstChild = pdElem.getFirstChild();
+        while (firstChild != null) {
+            if (firstChild.getNodeType() == Node.ELEMENT_NODE) {
+                Element childElem = (Element)firstChild;
                 String localName = childElem.getLocalName();
-                try {
-                    if (localName.equals("PGPKeyID")) {
-                        keyId = Base64.decode(childElem);
-                    } else if (localName.equals("PGPKeyPacket")){
-                        keyPacket = Base64.decode(childElem);
-                    } else {
-                        other.add
-                            (new javax.xml.crypto.dom.DOMStructure(childElem));
-                    }
-                } catch (Base64DecodingException bde) {
-                    throw new MarshalException(bde);
+                String namespace = childElem.getNamespaceURI();
+                if ("PGPKeyID".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
+                    String content = XMLUtils.getFullTextChildrenFromElement(childElem);
+                    pgpKeyId = XMLUtils.decode(content);
+                } else if ("PGPKeyPacket".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
+                    String content = XMLUtils.getFullTextChildrenFromElement(childElem);
+                    pgpKeyPacket = XMLUtils.decode(content);
+                } else {
+                    other.add
+                    (new javax.xml.crypto.dom.DOMStructure(childElem));
                 }
             }
+            firstChild = firstChild.getNextSibling();
         }
-        this.keyId = keyId;
-        this.keyPacket = keyPacket;
+        this.keyId = pgpKeyId;
+        this.keyPacket = pgpKeyPacket;
         this.externalElements = Collections.unmodifiableList(other);
     }
 
     public byte[] getKeyId() {
-        return (keyId == null ? null : (byte[])keyId.clone());
+        return keyId == null ? null : keyId.clone();
     }
 
     public byte[] getKeyPacket() {
-        return (keyPacket == null ? null : (byte[])keyPacket.clone());
+        return keyPacket == null ? null : keyPacket.clone();
     }
 
     public List<XMLStructure> getExternalElements() {
         return externalElements;
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
@@ -201,7 +200,7 @@
                                                        XMLSignature.XMLNS,
                                                        dsPrefix);
             keyIdElem.appendChild
-                (ownerDoc.createTextNode(Base64.encode(keyId)));
+                (ownerDoc.createTextNode(XMLUtils.encodeToString(keyId)));
             pdElem.appendChild(keyIdElem);
         }
 
@@ -212,7 +211,7 @@
                                                         XMLSignature.XMLNS,
                                                         dsPrefix);
             keyPktElem.appendChild
-                (ownerDoc.createTextNode(Base64.encode(keyPacket)));
+                (ownerDoc.createTextNode(XMLUtils.encodeToString(keyPacket)));
             pdElem.appendChild(keyPktElem);
         }
 
@@ -253,8 +252,8 @@
         }
 
         // tag value must be 6, 14, 5 or 7
-        if (((tag & 6) != 6) && ((tag & 14) != 14) &&
-            ((tag & 5) != 5) && ((tag & 7) != 7)) {
+        if ((tag & 6) != 6 && (tag & 14) != 14 &&
+            (tag & 5) != 5 && (tag & 7) != 7) {
             throw new IllegalArgumentException("keypacket tag is invalid: " +
                                                "must be 6, 14, 5, or 7");
         }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,7 +21,7 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Portions copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * ===========================================================================
@@ -31,7 +31,7 @@
  * ===========================================================================
  */
 /*
- * $Id: DOMReference.java 1334007 2012-05-04 14:59:46Z coheigea $
+ * $Id: DOMReference.java 1803518 2017-07-31 11:02:52Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -45,27 +45,32 @@
 import java.net.URISyntaxException;
 import java.security.*;
 import java.util.*;
+
 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 org.jcp.xml.dsig.internal.DigesterOutputStream;
-import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
-import com.sun.org.apache.xml.internal.security.utils.Base64;
 import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 
 /**
  * DOM-based implementation of Reference.
  *
- * @author Sean Mullan
- * @author Joyce Leung
  */
 public final class DOMReference extends DOMStructure
     implements Reference, DOMURIReference {
 
    /**
+    * The maximum number of transforms per reference, if secure validation is enabled.
+    */
+   public static final int MAXIMUM_TRANSFORM_COUNT = 5;
+
+   /**
     * Look up useC14N11 system property. If true, an explicit C14N11 transform
     * will be added if necessary when generating the signature. See section
     * 3.1.1 of http://www.w3.org/2007/xmlsec/Drafts/xmldsig-core/ for more info.
@@ -73,15 +78,11 @@
     * If true, overrides the same property if set in the XMLSignContext.
     */
     private static boolean useC14N11 =
-        AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
-            public Boolean run() {
-                return Boolean.valueOf(Boolean.getBoolean
-                    ("com.sun.org.apache.xml.internal.security.useC14N11"));
-            }
-        });
+        AccessController.doPrivileged((PrivilegedAction<Boolean>)
+            () -> Boolean.getBoolean("com.sun.org.apache.xml.internal.security.useC14N11"));
 
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom");
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(DOMReference.class);
 
     private final DigestMethod digestMethod;
     private final String id;
@@ -103,18 +104,18 @@
     private Provider provider;
 
     /**
-     * Creates a <code>Reference</code> from the specified parameters.
+     * Creates a {@code Reference} from the specified parameters.
      *
      * @param uri the URI (may be null)
      * @param type the type (may be null)
      * @param dm the digest method
      * @param transforms a list of {@link Transform}s. The list
      *    is defensively copied to protect against subsequent modification.
-     *    May be <code>null</code> or empty.
-     * @param id the reference ID (may be <code>null</code>)
-     * @throws NullPointerException if <code>dm</code> is <code>null</code>
-     * @throws ClassCastException if any of the <code>transforms</code> are
-     *    not of type <code>Transform</code>
+     *    May be {@code null} or empty.
+     * @param id the reference ID (may be {@code null})
+     * @throws NullPointerException if {@code dm} is {@code null}
+     * @throws ClassCastException if any of the {@code transforms} are
+     *    not of type {@code Transform}
      */
     public DOMReference(String uri, String type, DigestMethod dm,
                         List<? extends Transform> transforms, String id,
@@ -141,9 +142,9 @@
             throw new NullPointerException("DigestMethod must be non-null");
         }
         if (appliedTransforms == null) {
-            this.allTransforms = new ArrayList<Transform>();
+            this.allTransforms = new ArrayList<>();
         } else {
-            this.allTransforms = new ArrayList<Transform>(appliedTransforms);
+            this.allTransforms = new ArrayList<>(appliedTransforms);
             for (int i = 0, size = this.allTransforms.size(); i < size; i++) {
                 if (!(this.allTransforms.get(i) instanceof Transform)) {
                     throw new ClassCastException
@@ -154,7 +155,7 @@
         if (transforms == null) {
             this.transforms = Collections.emptyList();
         } else {
-            this.transforms = new ArrayList<Transform>(transforms);
+            this.transforms = new ArrayList<>(transforms);
             for (int i = 0, size = this.transforms.size(); i < size; i++) {
                 if (!(this.transforms.get(i) instanceof Transform)) {
                     throw new ClassCastException
@@ -165,7 +166,7 @@
         }
         this.digestMethod = dm;
         this.uri = uri;
-        if ((uri != null) && (!uri.equals(""))) {
+        if (uri != null && !uri.equals("")) {
             try {
                 new URI(uri);
             } catch (URISyntaxException e) {
@@ -183,7 +184,7 @@
     }
 
     /**
-     * Creates a <code>DOMReference</code> from an element.
+     * Creates a {@code DOMReference} from an element.
      *
      * @param refElem a Reference element
      */
@@ -195,22 +196,25 @@
 
         // unmarshal Transforms, if specified
         Element nextSibling = DOMUtils.getFirstChildElement(refElem);
-        List<Transform> transforms = new ArrayList<Transform>(5);
-        if (nextSibling.getLocalName().equals("Transforms")) {
+        List<Transform> newTransforms = new ArrayList<>(MAXIMUM_TRANSFORM_COUNT);
+        if (nextSibling.getLocalName().equals("Transforms")
+            && XMLSignature.XMLNS.equals(nextSibling.getNamespaceURI())) {
             Element transformElem = DOMUtils.getFirstChildElement(nextSibling,
-                                                                  "Transform");
-            transforms.add(new DOMTransform(transformElem, context, provider));
+                                                                  "Transform",
+                                                                  XMLSignature.XMLNS);
+            newTransforms.add(new DOMTransform(transformElem, context, provider));
             transformElem = DOMUtils.getNextSiblingElement(transformElem);
             while (transformElem != null) {
                 String localName = transformElem.getLocalName();
-                if (!localName.equals("Transform")) {
+                String namespace = transformElem.getNamespaceURI();
+                if (!"Transform".equals(localName) || !XMLSignature.XMLNS.equals(namespace)) {
                     throw new MarshalException(
                         "Invalid element name: " + localName +
                         ", expected Transform");
                 }
-                transforms.add
+                newTransforms.add
                     (new DOMTransform(transformElem, context, provider));
-                if (secVal && Policy.restrictNumTransforms(transforms.size())) {
+                if (secVal && Policy.restrictNumTransforms(newTransforms.size())) {
                     String error = "A maximum of " + Policy.maxTransforms()
                         + " transforms per Reference are allowed when"
                         + " secure validation is enabled";
@@ -220,7 +224,8 @@
             }
             nextSibling = DOMUtils.getNextSiblingElement(nextSibling);
         }
-        if (!nextSibling.getLocalName().equals("DigestMethod")) {
+        if (!nextSibling.getLocalName().equals("DigestMethod")
+            && XMLSignature.XMLNS.equals(nextSibling.getNamespaceURI())) {
             throw new MarshalException("Invalid element name: " +
                                        nextSibling.getLocalName() +
                                        ", expected DigestMethod");
@@ -238,12 +243,9 @@
         }
 
         // unmarshal DigestValue
-        Element dvElem = DOMUtils.getNextSiblingElement(dmElem, "DigestValue");
-        try {
-            this.digestValue = Base64.decode(dvElem);
-        } catch (Base64DecodingException bde) {
-            throw new MarshalException(bde);
-        }
+        Element dvElem = DOMUtils.getNextSiblingElement(dmElem, "DigestValue", XMLSignature.XMLNS);
+        String content = XMLUtils.getFullTextChildrenFromElement(dvElem);
+        this.digestValue = XMLUtils.decode(content);
 
         // check for extra elements
         if (DOMUtils.getNextSiblingElement(dvElem) != null) {
@@ -265,7 +267,7 @@
         this.type = DOMUtils.getAttributeValue(refElem, "Type");
         this.here = refElem.getAttributeNodeNS(null, "URI");
         this.refElem = refElem;
-        this.transforms = transforms;
+        this.transforms = newTransforms;
         this.allTransforms = transforms;
         this.appliedTransformData = null;
         this.provider = provider;
@@ -292,25 +294,23 @@
     }
 
     public byte[] getDigestValue() {
-        return (digestValue == null ? null : (byte[])digestValue.clone());
+        return digestValue == null ? null : digestValue.clone();
     }
 
     public byte[] getCalculatedDigestValue() {
-        return (calcDigestValue == null ? null
-                                        : (byte[])calcDigestValue.clone());
+        return calcDigestValue == null ? null
+                                        : calcDigestValue.clone();
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Marshalling Reference");
-        }
+        LOG.debug("Marshalling Reference");
         Document ownerDoc = DOMUtils.getOwnerDocument(parent);
 
         refElem = DOMUtils.createElement(ownerDoc, "Reference",
                                          XMLSignature.XMLNS, dsPrefix);
-
         // set attributes
         DOMUtils.setAttributeID(refElem, "Id", id);
         DOMUtils.setAttribute(refElem, "URI", uri);
@@ -333,16 +333,15 @@
         ((DOMDigestMethod)digestMethod).marshal(refElem, dsPrefix, context);
 
         // create and append DigestValue element
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Adding digestValueElem");
-        }
+        LOG.debug("Adding digestValueElem");
         Element digestValueElem = DOMUtils.createElement(ownerDoc,
                                                          "DigestValue",
                                                          XMLSignature.XMLNS,
                                                          dsPrefix);
         if (digestValue != null) {
             digestValueElem.appendChild
-                (ownerDoc.createTextNode(Base64.encode(digestValue)));
+                (ownerDoc.createTextNode(XMLUtils.encodeToString(digestValue)));
+
         }
         refElem.appendChild(digestValueElem);
 
@@ -362,10 +361,8 @@
         digestValue = transform(data, signContext);
 
         // insert digestValue into DigestValue element
-        String encodedDV = Base64.encode(digestValue);
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Reference object uri = " + uri);
-        }
+        String encodedDV = XMLUtils.encodeToString(digestValue);
+        LOG.debug("Reference object uri = {}", uri);
         Element digestElem = DOMUtils.getLastChildElement(refElem);
         if (digestElem == null) {
             throw new XMLSignatureException("DigestValue element expected");
@@ -375,9 +372,7 @@
             (refElem.getOwnerDocument().createTextNode(encodedDV));
 
         digested = true;
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Reference digesting completed");
-        }
+        LOG.debug("Reference digesting completed");
     }
 
     public boolean validate(XMLValidateContext validateContext)
@@ -392,9 +387,9 @@
         Data data = dereference(validateContext);
         calcDigestValue = transform(data, validateContext);
 
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Expected digest: " + Base64.encode(digestValue));
-            log.log(java.util.logging.Level.FINE, "Actual digest: " + Base64.encode(calcDigestValue));
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Expected digest: " + XMLUtils.encodeToString(digestValue));
+            LOG.debug("Actual digest: " + XMLUtils.encodeToString(calcDigestValue));
         }
 
         validationStatus = Arrays.equals(digestValue, calcDigestValue);
@@ -422,10 +417,8 @@
         }
         try {
             data = deref.dereference(this, context);
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "URIDereferencer class name: " + deref.getClass().getName());
-                log.log(java.util.logging.Level.FINE, "Data class name: " + data.getClass().getName());
-            }
+            LOG.debug("URIDereferencer class name: {}", deref.getClass().getName());
+            LOG.debug("Data class name: {}", data.getClass().getName());
         } catch (URIReferenceException ure) {
             throw new XMLSignatureException(ure);
         }
@@ -449,16 +442,14 @@
         DigesterOutputStream dos;
         Boolean cache = (Boolean)
             context.getProperty("javax.xml.crypto.dsig.cacheReference");
-        if (cache != null && cache.booleanValue()) {
+        if (cache != null && cache) {
             this.derefData = copyDerefData(dereferencedData);
             dos = new DigesterOutputStream(md, true);
         } else {
             dos = new DigesterOutputStream(md);
         }
-        OutputStream os = null;
         Data data = dereferencedData;
-        try {
-            os = new UnsyncBufferedOutputStream(dos);
+        try (OutputStream os = new UnsyncBufferedOutputStream(dos)) {
             for (int i = 0, size = transforms.size(); i < size; i++) {
                 DOMTransform transform = (DOMTransform)transforms.get(i);
                 if (i < size - 1) {
@@ -478,7 +469,7 @@
                     if (!c14n11) {
                         Boolean prop = (Boolean)context.getProperty
                             ("com.sun.org.apache.xml.internal.security.useC14N11");
-                        c14n11 = (prop != null && prop.booleanValue());
+                        c14n11 = prop != null && prop;
                         if (c14n11) {
                             c14nalg = "http://www.w3.org/2006/12/xml-c14n11";
                         }
@@ -508,6 +499,9 @@
                 } else {
                     throw new XMLSignatureException("unrecognized Data type");
                 }
+
+                boolean secVal = Utils.secureValidation(context);
+                xi.setSecureValidation(secVal);
                 if (context instanceof XMLSignContext && c14n11
                     && !xi.isOctetStream() && !xi.isOutputStreamSet()) {
                     TransformService spi = null;
@@ -542,7 +536,7 @@
                 }
             }
             os.flush();
-            if (cache != null && cache.booleanValue()) {
+            if (cache != null && cache) {
                 this.dis = dos.getInputStream();
             }
             return dos.getDigestValue();
@@ -557,13 +551,6 @@
         } catch (com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException e) {
             throw new XMLSignatureException(e);
         } finally {
-            if (os != null) {
-                try {
-                    os.close();
-                } catch (IOException e) {
-                    throw new XMLSignatureException(e);
-                }
-            }
             if (dos != null) {
                 try {
                     dos.close();
@@ -589,12 +576,12 @@
         }
         Reference oref = (Reference)o;
 
-        boolean idsEqual = (id == null ? oref.getId() == null
-                                       : id.equals(oref.getId()));
-        boolean urisEqual = (uri == null ? oref.getURI() == null
-                                         : uri.equals(oref.getURI()));
-        boolean typesEqual = (type == null ? oref.getType() == null
-                                           : type.equals(oref.getType()));
+        boolean idsEqual = id == null ? oref.getId() == null
+                                       : id.equals(oref.getId());
+        boolean urisEqual = uri == null ? oref.getURI() == null
+                                         : uri.equals(oref.getURI());
+        boolean typesEqual = type == null ? oref.getType() == null
+                                           : type.equals(oref.getType());
         boolean digestValuesEqual =
             Arrays.equals(digestValue, oref.getDigestValue());
 
@@ -640,8 +627,8 @@
                         public Iterator<Node> iterator() { return s.iterator(); }
                     };
                 } catch (Exception e) {
-                    // log a warning
-                    log.log(java.util.logging.Level.WARNING, "cannot cache dereferenced data: " + e);
+                    // LOG a warning
+                    LOG.warn("cannot cache dereferenced data: " + e);
                     return null;
                 }
             } else if (xsi.isElement()) {
@@ -653,8 +640,8 @@
                         (xsi.getOctetStream(), xsi.getSourceURI(),
                          xsi.getMIMEType());
                 } catch (IOException ioe) {
-                    // log a warning
-                    log.log(java.util.logging.Level.WARNING, "cannot cache dereferenced data: " + ioe);
+                    // LOG a warning
+                    LOG.warn("cannot cache dereferenced data: " + ioe);
                     return null;
                 }
             }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,7 +21,7 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Portions copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * ===========================================================================
@@ -31,23 +31,35 @@
  * ===========================================================================
  */
 /*
- * $Id: DOMRetrievalMethod.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMRetrievalMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
 import java.io.ByteArrayInputStream;
+import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.security.Provider;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 
-import javax.xml.XMLConstants;
-import javax.xml.crypto.*;
-import javax.xml.crypto.dsig.*;
+import javax.xml.crypto.Data;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.NodeSetData;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.XMLStructure;
 import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dom.DOMURIReference;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.keyinfo.RetrievalMethod;
-import javax.xml.parsers.*;
+import javax.xml.parsers.DocumentBuilder;
+
+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;
@@ -56,8 +68,6 @@
 /**
  * DOM-based implementation of RetrievalMethod.
  *
- * @author Sean Mullan
- * @author Joyce Leung
  */
 public final class DOMRetrievalMethod extends DOMStructure
     implements RetrievalMethod, DOMURIReference {
@@ -68,20 +78,20 @@
     private Attr here;
 
     /**
-     * Creates a <code>DOMRetrievalMethod</code> containing the specified
+     * Creates a {@code DOMRetrievalMethod} containing the specified
      * URIReference and List of Transforms.
      *
      * @param uri the URI
      * @param type the type
      * @param transforms a list of {@link Transform}s. The list is defensively
-     *    copied to prevent subsequent modification. May be <code>null</code>
+     *    copied to prevent subsequent modification. May be {@code null}
      *    or empty.
-     * @throws IllegalArgumentException if the format of <code>uri</code> is
+     * @throws IllegalArgumentException if the format of {@code uri} is
      *    invalid, as specified by Reference's URI attribute in the W3C
      *    specification for XML-Signature Syntax and Processing
-     * @throws NullPointerException if <code>uriReference</code>
-     *    is <code>null</code>
-     * @throws ClassCastException if <code>transforms</code> contains any
+     * @throws NullPointerException if {@code uriReference}
+     *    is {@code null}
+     * @throws ClassCastException if {@code transforms} contains any
      *    entries that are not of type {@link Transform}
      */
     public DOMRetrievalMethod(String uri, String type,
@@ -94,7 +104,7 @@
             this.transforms = Collections.emptyList();
         } else {
             this.transforms = Collections.unmodifiableList(
-                new ArrayList<Transform>(transforms));
+                new ArrayList<>(transforms));
             for (int i = 0, size = this.transforms.size(); i < size; i++) {
                 if (!(this.transforms.get(i) instanceof Transform)) {
                     throw new ClassCastException
@@ -115,7 +125,7 @@
     }
 
     /**
-     * Creates a <code>DOMRetrievalMethod</code> from an element.
+     * Creates a {@code DOMRetrievalMethod} from an element.
      *
      * @param rmElem a RetrievalMethod element
      */
@@ -133,28 +143,28 @@
         boolean secVal = Utils.secureValidation(context);
 
         // get Transforms, if specified
-        List<Transform> transforms = new ArrayList<Transform>();
+        List<Transform> newTransforms = new ArrayList<>();
         Element transformsElem = DOMUtils.getFirstChildElement(rmElem);
 
         if (transformsElem != null) {
             String localName = transformsElem.getLocalName();
-            if (!localName.equals("Transforms")) {
+            String namespace = transformsElem.getNamespaceURI();
+            if (!"Transforms".equals(localName) || !XMLSignature.XMLNS.equals(namespace)) {
                 throw new MarshalException("Invalid element name: " +
-                                           localName + ", expected Transforms");
+                                           namespace + ":" + localName + ", expected Transforms");
             }
             Element transformElem =
-                DOMUtils.getFirstChildElement(transformsElem, "Transform");
-            transforms.add(new DOMTransform(transformElem, context, provider));
-            transformElem = DOMUtils.getNextSiblingElement(transformElem);
+                DOMUtils.getFirstChildElement(transformsElem, "Transform", XMLSignature.XMLNS);
             while (transformElem != null) {
                 String name = transformElem.getLocalName();
-                if (!name.equals("Transform")) {
+                namespace = transformElem.getNamespaceURI();
+                if (!"Transform".equals(name) || !XMLSignature.XMLNS.equals(namespace)) {
                     throw new MarshalException("Invalid element name: " +
                                                name + ", expected Transform");
                 }
-                transforms.add
+                newTransforms.add
                     (new DOMTransform(transformElem, context, provider));
-                if (secVal && Policy.restrictNumTransforms(transforms.size())) {
+                if (secVal && Policy.restrictNumTransforms(newTransforms.size())) {
                     String error = "A maximum of " + Policy.maxTransforms()
                         + " transforms per Reference are allowed when"
                         + " secure validation is enabled";
@@ -163,10 +173,10 @@
                 transformElem = DOMUtils.getNextSiblingElement(transformElem);
             }
         }
-        if (transforms.isEmpty()) {
+        if (newTransforms.isEmpty()) {
             this.transforms = Collections.emptyList();
         } else {
-            this.transforms = Collections.unmodifiableList(transforms);
+            this.transforms = Collections.unmodifiableList(newTransforms);
         }
     }
 
@@ -182,6 +192,7 @@
         return transforms;
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
@@ -244,8 +255,8 @@
         }
 
         // guard against RetrievalMethod loops
-        if ((data instanceof NodeSetData) && Utils.secureValidation(context)
-            && Policy.restrictRetrievalMethodLoops()) {
+        if (data instanceof NodeSetData && Utils.secureValidation(context)
+                && Policy.restrictRetrievalMethodLoops()) {
             NodeSetData nsd = (NodeSetData)data;
             Iterator<?> i = nsd.iterator();
             if (i.hasNext()) {
@@ -264,16 +275,15 @@
     public XMLStructure dereferenceAsXMLStructure(XMLCryptoContext context)
         throws URIReferenceException
     {
-        try {
-            ApacheData data = (ApacheData)dereference(context);
-            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-            dbf.setNamespaceAware(true);
-            dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
-            DocumentBuilder db = dbf.newDocumentBuilder();
-            Document doc = db.parse(new ByteArrayInputStream
-                (data.getXMLSignatureInput().getBytes()));
+        DocumentBuilder db = null;
+        boolean secVal = Utils.secureValidation(context);
+        ApacheData data = (ApacheData)dereference(context);
+        try (InputStream is = new ByteArrayInputStream(data.getXMLSignatureInput().getBytes())) {
+            db = XMLUtils.createDocumentBuilder(false, secVal);
+            Document doc = db.parse(is);
             Element kiElem = doc.getDocumentElement();
-            if (kiElem.getLocalName().equals("X509Data")) {
+            if (kiElem.getLocalName().equals("X509Data")
+                && XMLSignature.XMLNS.equals(kiElem.getNamespaceURI())) {
                 return new DOMX509Data(kiElem);
             } else {
                 return null; // unsupported
@@ -293,11 +303,11 @@
         }
         RetrievalMethod orm = (RetrievalMethod)obj;
 
-        boolean typesEqual = (type == null ? orm.getType() == null
-                                           : type.equals(orm.getType()));
+        boolean typesEqual = type == null ? orm.getType() == null
+                                           : type.equals(orm.getType());
 
-        return (uri.equals(orm.getURI()) &&
-            transforms.equals(orm.getTransforms()) && typesEqual);
+        return uri.equals(orm.getURI()) &&
+            transforms.equals(orm.getTransforms()) && typesEqual;
     }
 
     @Override
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMSignatureMethod.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMSignatureMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -36,6 +36,9 @@
 import java.security.*;
 import java.security.interfaces.DSAKey;
 import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+
 import org.w3c.dom.Element;
 
 import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA;
@@ -46,25 +49,30 @@
 /**
  * DOM-based abstract implementation of SignatureMethod.
  *
- * @author Sean Mullan
  */
 public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
 
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom");
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(DOMSignatureMethod.class);
 
     private SignatureMethodParameterSpec params;
     private Signature signature;
 
     // see RFC 4051 for these algorithm definitions
+    static final String RSA_SHA224 =
+        "http://www.w3.org/2001/04/xmldsig-more#rsa-sha224";
     static final String RSA_SHA256 =
         "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
     static final String RSA_SHA384 =
         "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384";
     static final String RSA_SHA512 =
         "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512";
+    static final String RSA_RIPEMD160 =
+        "http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160";
     static final String ECDSA_SHA1 =
         "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1";
+    static final String ECDSA_SHA224 =
+        "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224";
     static final String ECDSA_SHA256 =
         "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256";
     static final String ECDSA_SHA384 =
@@ -74,10 +82,26 @@
     static final String DSA_SHA256 =
         "http://www.w3.org/2009/xmldsig11#dsa-sha256";
 
+    // see RFC 6931 for these algorithm definitions
+    static final String ECDSA_RIPEMD160 =
+        "http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160";
+    static final String RSA_SHA1_MGF1 =
+        "http://www.w3.org/2007/05/xmldsig-more#sha1-rsa-MGF1";
+    static final String RSA_SHA224_MGF1 =
+        "http://www.w3.org/2007/05/xmldsig-more#sha224-rsa-MGF1";
+    static final String RSA_SHA256_MGF1 =
+        "http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1";
+    static final String RSA_SHA384_MGF1 =
+        "http://www.w3.org/2007/05/xmldsig-more#sha384-rsa-MGF1";
+    static final String RSA_SHA512_MGF1 =
+        "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";
+
     /**
-     * Creates a <code>DOMSignatureMethod</code>.
+     * Creates a {@code DOMSignatureMethod}.
      *
-     * @param params the algorithm-specific params (may be <code>null</code>)
+     * @param params the algorithm-specific params (may be {@code null})
      * @throws InvalidAlgorithmParameterException if the parameters are not
      *    appropriate for this signature method
      */
@@ -94,7 +118,7 @@
     }
 
     /**
-     * Creates a <code>DOMSignatureMethod</code> from an element. This ctor
+     * Creates a {@code DOMSignatureMethod} from an element. This ctor
      * invokes the {@link #unmarshalParams unmarshalParams} method to
      * unmarshal any algorithm-specific input parameters.
      *
@@ -116,32 +140,56 @@
         String alg = DOMUtils.getAttributeValue(smElem, "Algorithm");
         if (alg.equals(SignatureMethod.RSA_SHA1)) {
             return new SHA1withRSA(smElem);
+        } else if (alg.equals(RSA_SHA224)) {
+            return new SHA224withRSA(smElem);
         } else if (alg.equals(RSA_SHA256)) {
             return new SHA256withRSA(smElem);
         } else if (alg.equals(RSA_SHA384)) {
             return new SHA384withRSA(smElem);
         } else if (alg.equals(RSA_SHA512)) {
             return new SHA512withRSA(smElem);
+        } else if (alg.equals(RSA_RIPEMD160)) {
+            return new RIPEMD160withRSA(smElem);
+        } else if (alg.equals(RSA_SHA1_MGF1)) {
+            return new SHA1withRSAandMGF1(smElem);
+        } else if (alg.equals(RSA_SHA224_MGF1)) {
+            return new SHA224withRSAandMGF1(smElem);
+        } else if (alg.equals(RSA_SHA256_MGF1)) {
+            return new SHA256withRSAandMGF1(smElem);
+        } else if (alg.equals(RSA_SHA384_MGF1)) {
+            return new SHA384withRSAandMGF1(smElem);
+        } else if (alg.equals(RSA_SHA512_MGF1)) {
+            return new SHA512withRSAandMGF1(smElem);
+        } else if (alg.equals(RSA_RIPEMD160_MGF1)) {
+            return new RIPEMD160withRSAandMGF1(smElem);
         } else if (alg.equals(SignatureMethod.DSA_SHA1)) {
             return new SHA1withDSA(smElem);
         } else if (alg.equals(DSA_SHA256)) {
             return new SHA256withDSA(smElem);
         } else if (alg.equals(ECDSA_SHA1)) {
             return new SHA1withECDSA(smElem);
+        } else if (alg.equals(ECDSA_SHA224)) {
+            return new SHA224withECDSA(smElem);
         } else if (alg.equals(ECDSA_SHA256)) {
             return new SHA256withECDSA(smElem);
         } else if (alg.equals(ECDSA_SHA384)) {
             return new SHA384withECDSA(smElem);
         } else if (alg.equals(ECDSA_SHA512)) {
             return new SHA512withECDSA(smElem);
+        } else if (alg.equals(ECDSA_RIPEMD160)) {
+            return new RIPEMD160withECDSA(smElem);
         } else if (alg.equals(SignatureMethod.HMAC_SHA1)) {
             return new DOMHMACSignatureMethod.SHA1(smElem);
+        } else if (alg.equals(DOMHMACSignatureMethod.HMAC_SHA224)) {
+            return new DOMHMACSignatureMethod.SHA224(smElem);
         } else if (alg.equals(DOMHMACSignatureMethod.HMAC_SHA256)) {
             return new DOMHMACSignatureMethod.SHA256(smElem);
         } else if (alg.equals(DOMHMACSignatureMethod.HMAC_SHA384)) {
             return new DOMHMACSignatureMethod.SHA384(smElem);
         } else if (alg.equals(DOMHMACSignatureMethod.HMAC_SHA512)) {
             return new DOMHMACSignatureMethod.SHA512(smElem);
+        } else if (alg.equals(DOMHMACSignatureMethod.HMAC_RIPEMD160)) {
+            return new DOMHMACSignatureMethod.RIPEMD160(smElem);
         } else {
             throw new MarshalException
                 ("unsupported SignatureMethod algorithm: " + alg);
@@ -152,6 +200,23 @@
         return params;
     }
 
+    /**
+     * Returns an instance of Signature from the specified Provider.
+     * The algorithm is specified by the {@code getJCAAlgorithm()} method.
+     *
+     * @param p the Provider to use
+     * @return an instance of Signature implementing the algorithm
+     *    specified by {@code getJCAAlgorithm()}
+     * @throws NoSuchAlgorithmException if the Provider does not support the
+     *    signature algorithm
+     */
+    Signature getSignature(Provider p)
+            throws NoSuchAlgorithmException {
+        return (p == null)
+            ? Signature.getInstance(getJCAAlgorithm())
+            : Signature.getInstance(getJCAAlgorithm(), p);
+    }
+
     boolean verify(Key key, SignedInfo si, byte[] sig,
                    XMLValidateContext context)
         throws InvalidKeyException, SignatureException, XMLSignatureException
@@ -165,25 +230,22 @@
         }
         checkKeySize(context, key);
         if (signature == null) {
-            try {
-                Provider p = (Provider)context.getProperty
+            Provider p = (Provider) context.getProperty
                     ("org.jcp.xml.dsig.internal.dom.SignatureProvider");
-                signature = (p == null)
-                    ? Signature.getInstance(getJCAAlgorithm())
-                    : Signature.getInstance(getJCAAlgorithm(), p);
+            try {
+                signature = getSignature(p);
             } catch (NoSuchAlgorithmException nsae) {
                 throw new XMLSignatureException(nsae);
             }
         }
         signature.initVerify((PublicKey)key);
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Signature provider:" + signature.getProvider());
-            log.log(java.util.logging.Level.FINE, "verifying with key: " + key);
-        }
-        ((DOMSignedInfo)si).canonicalize(context,
-                                         new SignerOutputStream(signature));
+        LOG.debug("Signature provider: {}", signature.getProvider());
+        LOG.debug("Verifying with key: {}", key);
+        LOG.debug("JCA Algorithm: {}", getJCAAlgorithm());
+        LOG.debug("Signature Bytes length: {}", sig.length);
 
-        try {
+        try (SignerOutputStream outputStream = new SignerOutputStream(signature)) {
+            ((DOMSignedInfo)si).canonicalize(context, outputStream);
             Type type = getAlgorithmType();
             if (type == Type.DSA) {
                 int size = ((DSAKey)key).getParams().getQ().bitLength();
@@ -215,10 +277,8 @@
                 // key size cannot be determined, so we cannot check against
                 // restrictions. Note that a DSA key w/o params will be
                 // rejected later if the certificate chain is validated.
-                if (log.isLoggable(java.util.logging.Level.FINE)) {
-                    log.log(java.util.logging.Level.FINE, "Size for " +
+                LOG.debug("Size for " +
                             key.getAlgorithm() + " key cannot be determined");
-                }
                 return;
             }
             if (Policy.restrictKey(key.getAlgorithm(), size)) {
@@ -242,26 +302,21 @@
         }
         checkKeySize(context, key);
         if (signature == null) {
-            try {
-                Provider p = (Provider)context.getProperty
+            Provider p = (Provider)context.getProperty
                     ("org.jcp.xml.dsig.internal.dom.SignatureProvider");
-                signature = (p == null)
-                    ? Signature.getInstance(getJCAAlgorithm())
-                    : Signature.getInstance(getJCAAlgorithm(), p);
+            try {
+                signature = getSignature(p);
             } catch (NoSuchAlgorithmException nsae) {
                 throw new XMLSignatureException(nsae);
             }
         }
         signature.initSign((PrivateKey)key);
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Signature provider:" + signature.getProvider());
-            log.log(java.util.logging.Level.FINE, "Signing with key: " + key);
-        }
+        LOG.debug("Signature provider: {}", signature.getProvider());
+        LOG.debug("Signing with key: {}", key);
+        LOG.debug("JCA Algorithm: {}", getJCAAlgorithm());
 
-        ((DOMSignedInfo)si).canonicalize(context,
-                                         new SignerOutputStream(signature));
-
-        try {
+        try (SignerOutputStream outputStream = new SignerOutputStream(signature)) {
+            ((DOMSignedInfo)si).canonicalize(context, outputStream);
             Type type = getAlgorithmType();
             if (type == Type.DSA) {
                 int size = ((DSAKey)key).getParams().getQ().bitLength();
@@ -279,6 +334,40 @@
         }
     }
 
+    abstract static class AbstractRSAPSSSignatureMethod
+            extends DOMSignatureMethod {
+
+        AbstractRSAPSSSignatureMethod(AlgorithmParameterSpec params)
+                throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+
+        AbstractRSAPSSSignatureMethod(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+
+        abstract public PSSParameterSpec getPSSParameterSpec();
+
+        @Override
+        Signature getSignature(Provider p)
+                throws NoSuchAlgorithmException {
+            try {
+                Signature s = (p == null)
+                        ? Signature.getInstance("RSASSA-PSS")
+                        : Signature.getInstance("RSASSA-PSS", p);
+                try {
+                    s.setParameter(getPSSParameterSpec());
+                } catch (InvalidAlgorithmParameterException e) {
+                    throw new NoSuchAlgorithmException("Should not happen", e);
+                }
+                return s;
+            } catch (NoSuchAlgorithmException nsae) {
+                return (p == null)
+                        ? Signature.getInstance(getJCAAlgorithm())
+                        : Signature.getInstance(getJCAAlgorithm(), p);
+            }
+        }
+    }
     static final class SHA1withRSA extends DOMSignatureMethod {
         SHA1withRSA(AlgorithmParameterSpec params)
             throws InvalidAlgorithmParameterException {
@@ -287,12 +376,34 @@
         SHA1withRSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return SignatureMethod.RSA_SHA1;
         }
+        @Override
         String getJCAAlgorithm() {
             return "SHA1withRSA";
         }
+        @Override
+        Type getAlgorithmType() {
+            return Type.RSA;
+        }
+    }
+
+    static final class SHA224withRSA extends DOMSignatureMethod {
+        SHA224withRSA(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA224withRSA(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        public String getAlgorithm() {
+            return RSA_SHA224;
+        }
+        String getJCAAlgorithm() {
+            return "SHA224withRSA";
+        }
         Type getAlgorithmType() {
             return Type.RSA;
         }
@@ -355,6 +466,205 @@
         }
     }
 
+    static final class RIPEMD160withRSA extends DOMSignatureMethod {
+        RIPEMD160withRSA(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        RIPEMD160withRSA(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return RSA_RIPEMD160;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "RIPEMD160withRSA";
+        }
+        @Override
+        Type getAlgorithmType() {
+            return Type.RSA;
+        }
+    }
+
+    static final class SHA1withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
+
+        private static PSSParameterSpec spec
+                = new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1,
+                20, PSSParameterSpec.TRAILER_FIELD_BC);
+
+        SHA1withRSAandMGF1(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA1withRSAandMGF1(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return RSA_SHA1_MGF1;
+        }
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return spec;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "SHA1withRSAandMGF1";
+        }
+        @Override
+        Type getAlgorithmType() {
+            return Type.RSA;
+        }
+    }
+
+    static final class SHA224withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
+
+        private static PSSParameterSpec spec
+                = new PSSParameterSpec("SHA-224", "MGF1", MGF1ParameterSpec.SHA224,
+                28, PSSParameterSpec.TRAILER_FIELD_BC);
+
+        SHA224withRSAandMGF1(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA224withRSAandMGF1(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return RSA_SHA224_MGF1;
+        }
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return spec;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "SHA224withRSAandMGF1";
+        }
+        @Override
+        Type getAlgorithmType() {
+            return Type.RSA;
+        }
+    }
+
+    static final class SHA256withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
+
+        private static PSSParameterSpec spec
+                = new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256,
+                32, PSSParameterSpec.TRAILER_FIELD_BC);
+
+        SHA256withRSAandMGF1(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA256withRSAandMGF1(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return RSA_SHA256_MGF1;
+        }
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return spec;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "SHA256withRSAandMGF1";
+        }
+        @Override
+        Type getAlgorithmType() {
+            return Type.RSA;
+        }
+    }
+
+    static final class SHA384withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
+
+        private static PSSParameterSpec spec
+                = new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384,
+                48, PSSParameterSpec.TRAILER_FIELD_BC);
+
+        SHA384withRSAandMGF1(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA384withRSAandMGF1(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return RSA_SHA384_MGF1;
+        }
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return spec;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "SHA384withRSAandMGF1";
+        }
+        @Override
+        Type getAlgorithmType() {
+            return Type.RSA;
+        }
+    }
+
+    static final class SHA512withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
+
+        private static PSSParameterSpec spec
+                = new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512,
+                64, PSSParameterSpec.TRAILER_FIELD_BC);
+
+        SHA512withRSAandMGF1(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA512withRSAandMGF1(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return RSA_SHA512_MGF1;
+        }
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return spec;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "SHA512withRSAandMGF1";
+        }
+        @Override
+        Type getAlgorithmType() {
+            return Type.RSA;
+        }
+    }
+
+    static final class RIPEMD160withRSAandMGF1 extends DOMSignatureMethod {
+        RIPEMD160withRSAandMGF1(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        RIPEMD160withRSAandMGF1(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return RSA_RIPEMD160_MGF1;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "RIPEMD160withRSAandMGF1";
+        }
+        @Override
+        Type getAlgorithmType() {
+            return Type.RSA;
+        }
+    }
+
     static final class SHA1withDSA extends DOMSignatureMethod {
         SHA1withDSA(AlgorithmParameterSpec params)
             throws InvalidAlgorithmParameterException {
@@ -412,6 +722,28 @@
         }
     }
 
+    static final class SHA224withECDSA extends DOMSignatureMethod {
+        SHA224withECDSA(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA224withECDSA(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return ECDSA_SHA224;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "SHA224withECDSA";
+        }
+        @Override
+        Type getAlgorithmType() {
+            return Type.ECDSA;
+        }
+    }
+
     static final class SHA256withECDSA extends DOMSignatureMethod {
         SHA256withECDSA(AlgorithmParameterSpec params)
             throws InvalidAlgorithmParameterException {
@@ -468,4 +800,27 @@
             return Type.ECDSA;
         }
     }
+
+    static final class RIPEMD160withECDSA extends DOMSignatureMethod {
+        RIPEMD160withECDSA(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        RIPEMD160withECDSA(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return ECDSA_RIPEMD160;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "RIPEMD160withECDSA";
+        }
+        @Override
+        Type getAlgorithmType() {
+            return Type.ECDSA;
+        }
+    }
+
 }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperties.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperties.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMSignatureProperties.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMSignatureProperties.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -38,12 +38,10 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 
 /**
  * DOM-based implementation of SignatureProperties.
  *
- * @author Sean Mullan
  */
 public final class DOMSignatureProperties extends DOMStructure
     implements SignatureProperties {
@@ -52,16 +50,16 @@
     private final List<SignatureProperty> properties;
 
     /**
-     * Creates a <code>DOMSignatureProperties</code> from the specified
+     * Creates a {@code DOMSignatureProperties} from the specified
      * parameters.
      *
      * @param properties a list of one or more {@link SignatureProperty}s. The
      *    list is defensively copied to protect against subsequent modification.
-     * @param id the Id (may be <code>null</code>)
-     * @throws ClassCastException if <code>properties</code> contains any
+     * @param id the Id (may be {@code null})
+     * @throws ClassCastException if {@code properties} contains any
      *    entries that are not of type {@link SignatureProperty}
-     * @throws IllegalArgumentException if <code>properties</code> is empty
-     * @throws NullPointerException if <code>properties</code>
+     * @throws IllegalArgumentException if {@code properties} is empty
+     * @throws NullPointerException if {@code properties}
      */
     public DOMSignatureProperties(List<? extends SignatureProperty> properties,
                                   String id)
@@ -72,7 +70,7 @@
             throw new IllegalArgumentException("properties cannot be empty");
         } else {
             this.properties = Collections.unmodifiableList(
-                new ArrayList<SignatureProperty>(properties));
+                new ArrayList<>(properties));
             for (int i = 0, size = this.properties.size(); i < size; i++) {
                 if (!(this.properties.get(i) instanceof SignatureProperty)) {
                     throw new ClassCastException
@@ -84,12 +82,12 @@
     }
 
     /**
-     * Creates a <code>DOMSignatureProperties</code> from an element.
+     * Creates a {@code DOMSignatureProperties} from an element.
      *
      * @param propsElem a SignatureProperties element
      * @throws MarshalException if a marshalling error occurs
      */
-    public DOMSignatureProperties(Element propsElem, XMLCryptoContext context)
+    public DOMSignatureProperties(Element propsElem)
         throws MarshalException
     {
         // unmarshal attributes
@@ -101,26 +99,24 @@
             id = null;
         }
 
-        NodeList nodes = propsElem.getChildNodes();
-        int length = nodes.getLength();
-        List<SignatureProperty> properties =
-            new ArrayList<SignatureProperty>(length);
-        for (int i = 0; i < length; i++) {
-            Node child = nodes.item(i);
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                String name = child.getLocalName();
-                if (!name.equals("SignatureProperty")) {
-                    throw new MarshalException("Invalid element name: " + name +
+        List<SignatureProperty> newProperties = new ArrayList<>();
+        Node firstChild = propsElem.getFirstChild();
+        while (firstChild != null) {
+            if (firstChild.getNodeType() == Node.ELEMENT_NODE) {
+                String name = firstChild.getLocalName();
+                String namespace = firstChild.getNamespaceURI();
+                if (!"SignatureProperty".equals(name) || !XMLSignature.XMLNS.equals(namespace)) {
+                    throw new MarshalException("Invalid element name: " + namespace + ":" + name +
                                                ", expected SignatureProperty");
                 }
-                properties.add(new DOMSignatureProperty((Element)child,
-                                                        context));
+                newProperties.add(new DOMSignatureProperty((Element)firstChild));
             }
+            firstChild = firstChild.getNextSibling();
         }
-        if (properties.isEmpty()) {
+        if (newProperties.isEmpty()) {
             throw new MarshalException("properties cannot be empty");
         } else {
-            this.properties = Collections.unmodifiableList(properties);
+            this.properties = Collections.unmodifiableList(newProperties);
         }
     }
 
@@ -132,6 +128,7 @@
         return id;
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
@@ -164,10 +161,10 @@
         }
         SignatureProperties osp = (SignatureProperties)o;
 
-        boolean idsEqual = (id == null ? osp.getId() == null
-                                       : id.equals(osp.getId()));
+        boolean idsEqual = id == null ? osp.getId() == null
+                                       : id.equals(osp.getId());
 
-        return (properties.equals(osp.getProperties()) && idsEqual);
+        return properties.equals(osp.getProperties()) && idsEqual;
     }
 
     @Override
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperty.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperty.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMSignatureProperty.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMSignatureProperty.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -38,12 +38,10 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 
 /**
  * DOM-based implementation of SignatureProperty.
  *
- * @author Sean Mullan
  */
 public final class DOMSignatureProperty extends DOMStructure
     implements SignatureProperty {
@@ -53,17 +51,17 @@
     private final List<XMLStructure> content;
 
     /**
-     * Creates a <code>SignatureProperty</code> from the specified parameters.
+     * Creates a {@code SignatureProperty} from the specified parameters.
      *
      * @param content a list of one or more {@link XMLStructure}s. The list
      *    is defensively copied to protect against subsequent modification.
      * @param target the target URI
-     * @param id the Id (may be <code>null</code>)
-     * @throws ClassCastException if <code>content</code> contains any
+     * @param id the Id (may be {@code null})
+     * @throws ClassCastException if {@code content} contains any
      *    entries that are not of type {@link XMLStructure}
-     * @throws IllegalArgumentException if <code>content</code> is empty
-     * @throws NullPointerException if <code>content</code> or
-     *    <code>target</code> is <code>null</code>
+     * @throws IllegalArgumentException if {@code content} is empty
+     * @throws NullPointerException if {@code content} or
+     *    {@code target} is {@code null}
      */
     public DOMSignatureProperty(List<? extends XMLStructure> content,
                                 String target, String id)
@@ -76,7 +74,7 @@
             throw new IllegalArgumentException("content cannot be empty");
         } else {
             this.content = Collections.unmodifiableList(
-                new ArrayList<XMLStructure>(content));
+                new ArrayList<>(content));
             for (int i = 0, size = this.content.size(); i < size; i++) {
                 if (!(this.content.get(i) instanceof XMLStructure)) {
                     throw new ClassCastException
@@ -89,11 +87,11 @@
     }
 
     /**
-     * Creates a <code>DOMSignatureProperty</code> from an element.
+     * Creates a {@code DOMSignatureProperty} from an element.
      *
      * @param propElem a SignatureProperty element
      */
-    public DOMSignatureProperty(Element propElem, XMLCryptoContext context)
+    public DOMSignatureProperty(Element propElem)
         throws MarshalException
     {
         // unmarshal attributes
@@ -109,16 +107,16 @@
             id = null;
         }
 
-        NodeList nodes = propElem.getChildNodes();
-        int length = nodes.getLength();
-        List<XMLStructure> content = new ArrayList<XMLStructure>(length);
-        for (int i = 0; i < length; i++) {
-            content.add(new javax.xml.crypto.dom.DOMStructure(nodes.item(i)));
+        List<XMLStructure> newContent = new ArrayList<>();
+        Node firstChild = propElem.getFirstChild();
+        while (firstChild != null) {
+            newContent.add(new javax.xml.crypto.dom.DOMStructure(firstChild));
+            firstChild = firstChild.getNextSibling();
         }
-        if (content.isEmpty()) {
+        if (newContent.isEmpty()) {
             throw new MarshalException("content cannot be empty");
         } else {
-            this.content = Collections.unmodifiableList(content);
+            this.content = Collections.unmodifiableList(newContent);
         }
     }
 
@@ -134,6 +132,7 @@
         return target;
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
@@ -165,13 +164,13 @@
         }
         SignatureProperty osp = (SignatureProperty)o;
 
-        boolean idsEqual = (id == null ? osp.getId() == null
-                                       : id.equals(osp.getId()));
+        boolean idsEqual = id == null ? osp.getId() == null
+                                       : id.equals(osp.getId());
 
         @SuppressWarnings("unchecked")
         List<XMLStructure> ospContent = osp.getContent();
-        return (equalsContent(ospContent) &&
-                target.equals(osp.getTarget()) && idsEqual);
+        return equalsContent(ospContent) &&
+                target.equals(osp.getTarget()) && idsEqual;
     }
 
     @Override
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMSignedInfo.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMSignedInfo.java 1820179 2018-01-04 19:09:52Z mullan $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -43,19 +43,17 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-
-import com.sun.org.apache.xml.internal.security.utils.Base64;
 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.
  *
- * @author Sean Mullan
  */
 public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
 
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom");
+    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;
@@ -66,18 +64,18 @@
     private InputStream canonData;
 
     /**
-     * Creates a <code>DOMSignedInfo</code> from the specified parameters. Use
-     * this constructor when the <code>Id</code> is not specified.
+     * Creates a {@code DOMSignedInfo} from the specified parameters. Use
+     * this constructor when the {@code Id} is not specified.
      *
      * @param cm the canonicalization method
      * @param sm the signature method
      * @param references the list of references. The list is copied.
      * @throws NullPointerException if
-     *    <code>cm</code>, <code>sm</code>, or <code>references</code> is
-     *    <code>null</code>
-     * @throws IllegalArgumentException if <code>references</code> is empty
+     *    {@code cm}, {@code sm}, or {@code references} is
+     *    {@code null}
+     * @throws IllegalArgumentException if {@code references} is empty
      * @throws ClassCastException if any of the references are not of
-     *    type <code>Reference</code>
+     *    type {@code Reference}
      */
     public DOMSignedInfo(CanonicalizationMethod cm, SignatureMethod sm,
                          List<? extends Reference> references) {
@@ -87,7 +85,7 @@
         this.canonicalizationMethod = cm;
         this.signatureMethod = sm;
         this.references = Collections.unmodifiableList(
-            new ArrayList<Reference>(references));
+            new ArrayList<>(references));
         if (this.references.isEmpty()) {
             throw new IllegalArgumentException("list of references must " +
                 "contain at least one entry");
@@ -102,19 +100,19 @@
     }
 
     /**
-     * Creates a <code>DOMSignedInfo</code> from the specified parameters.
+     * Creates a {@code DOMSignedInfo} from the specified parameters.
      *
      * @param cm the canonicalization method
      * @param sm the signature method
      * @param references the list of references. The list is copied.
      * @param id an optional identifer that will allow this
-     *    <code>SignedInfo</code> to be referenced by other signatures and
+     *    {@code SignedInfo} to be referenced by other signatures and
      *    objects
-     * @throws NullPointerException if <code>cm</code>, <code>sm</code>,
-     *    or <code>references</code> is <code>null</code>
-     * @throws IllegalArgumentException if <code>references</code> is empty
+     * @throws NullPointerException if {@code cm}, {@code sm},
+     *    or {@code references} is {@code null}
+     * @throws IllegalArgumentException if {@code references} is empty
      * @throws ClassCastException if any of the references are not of
-     *    type <code>Reference</code>
+     *    type {@code Reference}
      */
     public DOMSignedInfo(CanonicalizationMethod cm, SignatureMethod sm,
                          List<? extends Reference> references, String id) {
@@ -123,7 +121,7 @@
     }
 
     /**
-     * Creates a <code>DOMSignedInfo</code> from an element.
+     * Creates a {@code DOMSignedInfo} from an element.
      *
      * @param siElem a SignedInfo element
      */
@@ -137,13 +135,15 @@
 
         // unmarshal CanonicalizationMethod
         Element cmElem = DOMUtils.getFirstChildElement(siElem,
-                                                       "CanonicalizationMethod");
+                                                       "CanonicalizationMethod",
+                                                       XMLSignature.XMLNS);
         canonicalizationMethod = new DOMCanonicalizationMethod(cmElem, context,
                                                                provider);
 
         // unmarshal SignatureMethod
         Element smElem = DOMUtils.getNextSiblingElement(cmElem,
-                                                        "SignatureMethod");
+                                                        "SignatureMethod",
+                                                        XMLSignature.XMLNS);
         signatureMethod = DOMSignatureMethod.unmarshal(smElem);
 
         boolean secVal = Utils.secureValidation(context);
@@ -157,21 +157,21 @@
         }
 
         // unmarshal References
-        ArrayList<Reference> refList = new ArrayList<Reference>(5);
-        Element refElem = DOMUtils.getNextSiblingElement(smElem, "Reference");
+        ArrayList<Reference> refList = new ArrayList<>(5);
+        Element refElem = DOMUtils.getNextSiblingElement(smElem, "Reference", XMLSignature.XMLNS);
         refList.add(new DOMReference(refElem, context, provider));
 
         refElem = DOMUtils.getNextSiblingElement(refElem);
         while (refElem != null) {
             String name = refElem.getLocalName();
-            if (!name.equals("Reference")) {
+            String namespace = refElem.getNamespaceURI();
+            if (!"Reference".equals(name) || !XMLSignature.XMLNS.equals(namespace)) {
                 throw new MarshalException("Invalid element name: " +
-                                           name + ", expected Reference");
+                                           namespace + ":" + name + ", expected Reference");
             }
             refList.add(new DOMReference(refElem, context, provider));
-
             if (secVal && Policy.restrictNumReferences(refList.size())) {
-                String error = "A maximum of " + Policy.maxReferences()
+                String error = "A maxiumum of " + Policy.maxReferences()
                     + " references per Manifest are allowed when"
                     + " secure validation is enabled";
                 throw new MarshalException(error);
@@ -207,50 +207,36 @@
             throw new NullPointerException("context cannot be null");
         }
 
-        OutputStream os = new UnsyncBufferedOutputStream(bos);
-
         DOMSubTreeData subTree = new DOMSubTreeData(localSiElem, true);
-        try {
+        try (OutputStream os = new UnsyncBufferedOutputStream(bos)) {
             ((DOMCanonicalizationMethod)
                 canonicalizationMethod).canonicalize(subTree, context, os);
+
+            os.flush();
+
+            byte[] signedInfoBytes = bos.toByteArray();
+
+            // this whole block should only be done if LOGging is enabled
+            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]);
+                }
+                LOG.debug(sb.toString());
+                LOG.debug("Data to be signed/verified:" + XMLUtils.encodeToString(signedInfoBytes));
+            }
+
+            this.canonData = new ByteArrayInputStream(signedInfoBytes);
         } catch (TransformException te) {
             throw new XMLSignatureException(te);
-        }
-
-        try {
-            os.flush();
         } catch (IOException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
-            // Impossible
-        }
-
-        byte[] signedInfoBytes = bos.toByteArray();
-
-        // this whole block should only be done if logging is enabled
-        if (log.isLoggable(java.util.logging.Level.FINE)) {
-            log.log(java.util.logging.Level.FINE, "Canonicalized SignedInfo:");
-            StringBuilder sb = new StringBuilder(signedInfoBytes.length);
-            for (int i = 0; i < signedInfoBytes.length; i++) {
-                sb.append((char)signedInfoBytes[i]);
-            }
-            log.log(java.util.logging.Level.FINE, sb.toString());
-            log.log(java.util.logging.Level.FINE, "Data to be signed/verified:" + Base64.encode(signedInfoBytes));
-        }
-
-        this.canonData = new ByteArrayInputStream(signedInfoBytes);
-
-        try {
-            os.close();
-        } catch (IOException e) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, e.getMessage(), e);
-            }
+            LOG.debug(e.getMessage(), e);
             // Impossible
         }
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
@@ -289,12 +275,17 @@
         }
         SignedInfo osi = (SignedInfo)o;
 
-        boolean idEqual = (id == null ? osi.getId() == null
-                                      : id.equals(osi.getId()));
+        boolean idEqual = id == null ? osi.getId() == null
+                                      : id.equals(osi.getId());
 
-        return (canonicalizationMethod.equals(osi.getCanonicalizationMethod())
+        return canonicalizationMethod.equals(osi.getCanonicalizationMethod())
                 && signatureMethod.equals(osi.getSignatureMethod()) &&
-                references.equals(osi.getReferences()) && idEqual);
+                references.equals(osi.getReferences()) && idEqual;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static List<Reference> getSignedInfoReferences(SignedInfo si) {
+        return si.getReferences();
     }
 
     @Override
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMStructure.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMStructure.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMStructure.java 1197150 2011-11-03 14:34:57Z coheigea $
+ * $Id: DOMStructure.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -36,7 +36,6 @@
 /**
  * DOM-based abstract implementation of XMLStructure.
  *
- * @author Sean Mullan
  */
 public abstract class DOMStructure implements XMLStructure {
 
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSubTreeData.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSubTreeData.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,7 +21,7 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * $Id$
@@ -54,6 +54,7 @@
         this.excludeComments = excludeComments;
     }
 
+    @Override
     public Iterator<Node> iterator() {
         return new DelayedNodeIterator(root, excludeComments);
     }
@@ -109,15 +110,15 @@
          * Dereferences a same-document URI fragment.
          *
          * @param node the node (document or element) referenced by the
-         *        URI fragment. If null, returns an empty set.
+         *     URI fragment. If null, returns an empty set.
          * @return a set of nodes (minus any comment nodes)
          */
         private List<Node> dereferenceSameDocumentURI(Node node) {
-            List<Node> nodeSet = new ArrayList<Node>();
+            List<Node> nodes = new ArrayList<>();
             if (node != null) {
-                nodeSetMinusCommentNodes(node, nodeSet, null);
+                nodeSetMinusCommentNodes(node, nodes, null);
             }
-            return nodeSet;
+            return nodes;
         }
 
         /**
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMTransform.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMTransform.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -34,19 +34,23 @@
 import java.security.Provider;
 import java.security.spec.AlgorithmParameterSpec;
 
+import javax.xml.crypto.Data;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.TransformException;
+import javax.xml.crypto.dsig.TransformService;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.dom.DOMSignContext;
-
 /**
  * DOM-based abstract implementation of Transform.
  *
- * @author Sean Mullan
  */
 public class DOMTransform extends DOMStructure implements Transform {
 
@@ -62,9 +66,8 @@
     }
 
     /**
-     * Creates a {@code DOMTransform} from an element. This constructor
-     * invokes the abstract {@link #unmarshalParams unmarshalParams} method to
-     * unmarshal any algorithm-specific input parameters.
+     * Creates a {@code DOMTransform} from an element. It unmarshals any
+     * algorithm-specific input parameters.
      *
      * @param transElem a Transform element
      */
@@ -107,9 +110,9 @@
     }
 
     /**
-     * This method invokes the abstract {@link #marshalParams marshalParams}
-     * method to marshal any algorithm-specific parameters.
+     * This method marshals any algorithm-specific parameters.
      */
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
@@ -139,11 +142,11 @@
      *
      * @param data the data to be transformed
      * @param xc the {@code XMLCryptoContext} containing
-     *     additional context (may be {@code null} if not applicable)
+     *    additional context (may be {@code null} if not applicable)
      * @return the transformed data
      * @throws NullPointerException if {@code data} is {@code null}
      * @throws XMLSignatureException if an unexpected error occurs while
-     *     executing the transform
+     *    executing the transform
      */
     public Data transform(Data data, XMLCryptoContext xc)
         throws TransformException
@@ -155,14 +158,14 @@
      * Transforms the specified data using the underlying transform algorithm.
      *
      * @param data the data to be transformed
-     * @param xc the {@code XMLCryptoContext} containing
-     *     additional context (may be {@code null} if not applicable)
+     * @param xc     the {@code XMLCryptoContext} containing
+     *    additional context (may be {@code null} if not applicable)
      * @param os the {@code OutputStream} that should be used to write
-     *     the transformed data to
+     *    the transformed data to
      * @return the transformed data
      * @throws NullPointerException if {@code data} is {@code null}
      * @throws XMLSignatureException if an unexpected error occurs while
-     *     executing the transform
+     *    executing the transform
      */
     public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
         throws TransformException
@@ -181,9 +184,9 @@
         }
         Transform otransform = (Transform)o;
 
-        return (getAlgorithm().equals(otransform.getAlgorithm()) &&
+        return getAlgorithm().equals(otransform.getAlgorithm()) &&
                 DOMUtils.paramsEqual(getParameterSpec(),
-                                     otransform.getParameterSpec()));
+                                     otransform.getParameterSpec());
     }
 
     @Override
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMURIDereferencer.java 1231033 2012-01-13 12:12:12Z coheigea $
+ * $Id: DOMURIDereferencer.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -43,9 +43,8 @@
 /**
  * DOM-based implementation of URIDereferencer.
  *
- * @author Sean Mullan
  */
-public class DOMURIDereferencer implements URIDereferencer {
+public final class DOMURIDereferencer implements URIDereferencer {
 
     static final URIDereferencer INSTANCE = new DOMURIDereferencer();
 
@@ -106,6 +105,7 @@
                 }
 
                 XMLSignatureInput result = new XMLSignatureInput(referencedElem);
+                result.setSecureValidation(secVal);
                 if (!uri.substring(1).startsWith("xpointer(id(")) {
                     result.setExcludeComments(true);
                 }
@@ -123,8 +123,7 @@
         try {
             ResourceResolver apacheResolver =
                 ResourceResolver.getInstance(uriAttr, baseURI, false);
-            XMLSignatureInput in = apacheResolver.resolve(uriAttr,
-                                                          baseURI, false);
+            XMLSignatureInput in = apacheResolver.resolve(uriAttr, baseURI, false);
             if (in.isOctetStream()) {
                 return new ApacheOctetStreamData(in);
             } else {
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMUtils.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMUtils.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMUtils.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMUtils.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -35,6 +35,8 @@
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+
+import javax.xml.XMLConstants;
 import javax.xml.crypto.*;
 import javax.xml.crypto.dsig.*;
 import javax.xml.crypto.dsig.spec.*;
@@ -42,9 +44,8 @@
 /**
  * Useful static DOM utility methods.
  *
- * @author Sean Mullan
  */
-public class DOMUtils {
+public final class DOMUtils {
 
     // class cannot be instantiated
     private DOMUtils() {}
@@ -64,6 +65,21 @@
     }
 
     /**
+     * Create a QName string from a prefix and local name.
+     *
+     * @param prefix    The prefix, if any. Can be either null or empty.
+     * @param localName The local name.
+     *
+     * @return The string for the qName, for example, "xsd:element".
+     */
+    public static String getQNameString(String prefix, String localName) {
+        String qName = prefix == null || prefix.length() == 0
+                ? localName : prefix + ":" + localName;
+
+        return qName;
+    }
+
+    /**
      * Creates an element in the specified namespace, with the specified tag
      * and namespace prefix.
      *
@@ -121,7 +137,7 @@
      * @param node the node
      * @return the first child element of the specified node, or null if there
      *    is no such element
-     * @throws NullPointerException if <code>node == null</code>
+     * @throws NullPointerException if {@code node == null}
      */
     public static Element getFirstChildElement(Node node) {
         Node child = node.getFirstChild();
@@ -141,12 +157,30 @@
      * @throws MarshalException if no such element or the local name is not
      *    equal to {@code localName}
      */
+    @Deprecated
     public static Element getFirstChildElement(Node node, String localName)
         throws MarshalException
     {
         return verifyElement(getFirstChildElement(node), localName);
     }
 
+    /**
+     * Returns the first child element of the specified node and checks that
+     * the local name is equal to {@code localName} and the namespace is equal to
+     * {@code namespaceURI}
+     *
+     * @param node the node
+     * @return the first child element of the specified node
+     * @throws NullPointerException if {@code node == null}
+     * @throws MarshalException if no such element or the local name is not
+     *    equal to {@code localName}
+     */
+    public static Element getFirstChildElement(Node node, String localName, String namespaceURI)
+        throws MarshalException
+    {
+        return verifyElement(getFirstChildElement(node), localName, namespaceURI);
+    }
+
     private static Element verifyElement(Element elem, String localName)
         throws MarshalException
     {
@@ -161,6 +195,22 @@
         return elem;
     }
 
+    private static Element verifyElement(Element elem, String localName, String namespaceURI)
+        throws MarshalException
+    {
+        if (elem == null) {
+            throw new MarshalException("Missing " + localName + " element");
+        }
+        String name = elem.getLocalName();
+        String namespace = elem.getNamespaceURI();
+        if (!name.equals(localName) || namespace == null && namespaceURI != null
+            || namespace != null && !namespace.equals(namespaceURI)) {
+            throw new MarshalException("Invalid element name: " +
+                namespace + ":" + name + ", expected " + namespaceURI + ":" + localName);
+        }
+        return elem;
+    }
+
     /**
      * Returns the last child element of the specified node, or null if there
      * is no such element.
@@ -168,7 +218,7 @@
      * @param node the node
      * @return the last child element of the specified node, or null if there
      *    is no such element
-     * @throws NullPointerException if <code>node == null</code>
+     * @throws NullPointerException if {@code node == null}
      */
     public static Element getLastChildElement(Node node) {
         Node child = node.getLastChild();
@@ -185,7 +235,7 @@
      * @param node the node
      * @return the next sibling element of the specified node, or null if there
      *    is no such element
-     * @throws NullPointerException if <code>node == null</code>
+     * @throws NullPointerException if {@code node == null}
      */
     public static Element getNextSiblingElement(Node node) {
         Node sibling = node.getNextSibling();
@@ -203,8 +253,9 @@
      * @return the next sibling element of the specified node
      * @throws NullPointerException if {@code node == null}
      * @throws MarshalException if no such element or the local name is not
-     *    equal to {@code localName}
+     * equal to {@code localName}
      */
+    @Deprecated
     public static Element getNextSiblingElement(Node node, String localName)
         throws MarshalException
     {
@@ -212,12 +263,29 @@
     }
 
     /**
+     * Returns the next sibling element of the specified node and checks that
+     * the local name is equal to {@code localName} and the namespace is equal to
+     * {@code namespaceURI}
+     *
+     * @param node the node
+     * @return the next sibling element of the specified node
+     * @throws NullPointerException if {@code node == null}
+     * @throws MarshalException if no such element or the local name is not
+     * equal to {@code localName}
+     */
+    public static Element getNextSiblingElement(Node node, String localName, String namespaceURI)
+        throws MarshalException
+    {
+        return verifyElement(getNextSiblingElement(node), localName, namespaceURI);
+    }
+
+    /**
      * Returns the attribute value for the attribute with the specified name.
      * Returns null if there is no such attribute, or
      * the empty string if the attribute value is empty.
      *
      * <p>This works around a limitation of the DOM
-     * <code>Element.getAttributeNode</code> method, which does not distinguish
+     * {@code Element.getAttributeNode} method, which does not distinguish
      * between an unspecified attribute and an attribute with a value of
      * "" (it returns "" for both cases).
      *
@@ -231,8 +299,30 @@
     }
 
     /**
-     * Returns a Set of <code>Node</code>s, backed by the specified
-     * <code>NodeList</code>.
+     * Returns the attribute value for the attribute with the specified name.
+     * Returns null if there is no such attribute, or
+     * the empty string if the attribute value is empty.
+     *
+     * <p>This works around a limitation of the DOM
+     * {@code Element.getAttributeNode} method, which does not distinguish
+     * between an unspecified attribute and an attribute with a value of
+     * "" (it returns "" for both cases).
+     *
+     * @param elem the element containing the attribute
+     * @param name the name of the attribute
+     * @return the attribute value (may be null if unspecified)
+     */
+    public static <N> String getIdAttributeValue(Element elem, String name) {
+        Attr attr = elem.getAttributeNodeNS(null, name);
+        if (attr != null && !attr.isId()) {
+            elem.setIdAttributeNode(attr, true);
+        }
+        return (attr == null) ? null : attr.getValue();
+    }
+
+    /**
+     * Returns a Set of {@code Node}s, backed by the specified
+     * {@code NodeList}.
      *
      * @param nl the NodeList
      * @return a Set of Nodes
@@ -250,7 +340,7 @@
         public int size() { return nl.getLength(); }
         public Iterator<Node> iterator() {
             return new Iterator<Node>() {
-                int index = 0;
+                private int index;
 
                 public void remove() {
                     throw new UnsupportedOperationException();
@@ -262,7 +352,7 @@
                     return nl.item(index++);
                 }
                 public boolean hasNext() {
-                    return index < nl.getLength() ? true : false;
+                    return index < nl.getLength();
                 }
             };
         }
@@ -302,9 +392,11 @@
      * @param node the parent node whose children are to be removed
      */
     public static void removeAllChildren(Node node) {
-        NodeList children = node.getChildNodes();
-        for (int i = 0, length = children.getLength(); i < length; i++) {
-            node.removeChild(children.item(i));
+        Node firstChild = node.getFirstChild();
+        while (firstChild != null) {
+            Node nodeToRemove = firstChild;
+            firstChild = firstChild.getNextSibling();
+            node.removeChild(nodeToRemove);
         }
     }
 
@@ -396,8 +488,8 @@
     private static boolean paramsEqual(XPathFilterParameterSpec spec1,
                                        XPathFilterParameterSpec spec2)
     {
-        return (spec1.getXPath().equals(spec2.getXPath()) &&
-                spec1.getNamespaceMap().equals(spec2.getNamespaceMap()));
+        return spec1.getXPath().equals(spec2.getXPath()) &&
+                spec1.getNamespaceMap().equals(spec2.getNamespaceMap());
     }
 
     private static boolean paramsEqual(XSLTTransformParameterSpec spec1,
@@ -415,4 +507,14 @@
             ((javax.xml.crypto.dom.DOMStructure) stylesheet).getNode();
         return nodesEqual(stylesheetElem, ostylesheetElem);
     }
+
+    public static boolean isNamespace(Node node)
+    {
+        final short nodeType = node.getNodeType();
+        if (nodeType == Node.ATTRIBUTE_NODE) {
+            final String namespaceURI = node.getNamespaceURI();
+            return XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI);
+        }
+        return false;
+    }
 }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509Data.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509Data.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,34 +21,34 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMX509Data.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMX509Data.java 1789702 2017-03-31 15:15:04Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.security.cert.*;
 import java.util.*;
+
 import javax.xml.crypto.*;
 import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.*;
+import javax.xml.crypto.dsig.keyinfo.X509Data;
 import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
-import javax.xml.crypto.dsig.keyinfo.X509Data;
 import javax.security.auth.x500.X500Principal;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 
-import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
-import com.sun.org.apache.xml.internal.security.utils.Base64;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 
 /**
  * DOM-based implementation of X509Data.
  *
- * @author Sean Mullan
  */
 //@@@ check for illegal combinations of data violating MUSTs in W3c spec
 public final class DOMX509Data extends DOMStructure implements X509Data {
@@ -60,21 +60,21 @@
      * Creates a DOMX509Data.
      *
      * @param content a list of one or more X.509 data types. Valid types are
-     *    {@link String} (subject names), <code>byte[]</code> (subject key ids),
+     *    {@link String} (subject names), {@code byte[]} (subject key ids),
      *    {@link java.security.cert.X509Certificate}, {@link X509CRL},
-     *    or {@link javax.xml.dsig.XMLStructure} ({@link X509IssuerSerial}
+     *    or {@link javax.xml.dsig.XMLStructure}
      *    objects or elements from an external namespace). The list is
      *    defensively copied to protect against subsequent modification.
-     * @throws NullPointerException if <code>content</code> is <code>null</code>
-     * @throws IllegalArgumentException if <code>content</code> is empty
-     * @throws ClassCastException if <code>content</code> contains any entries
+     * @throws NullPointerException if {@code content} is {@code null}
+     * @throws IllegalArgumentException if {@code content} is empty
+     * @throws ClassCastException if {@code content} contains any entries
      *    that are not of one of the valid types mentioned above
      */
     public DOMX509Data(List<?> content) {
         if (content == null) {
             throw new NullPointerException("content cannot be null");
         }
-        List<Object> contentCopy = new ArrayList<Object>(content);
+        List<Object> contentCopy = new ArrayList<>(content);
         if (contentCopy.isEmpty()) {
             throw new IllegalArgumentException("content cannot be empty");
         }
@@ -94,44 +94,38 @@
     }
 
     /**
-     * Creates a <code>DOMX509Data</code> from an element.
+     * Creates a {@code DOMX509Data} from an element.
      *
      * @param xdElem an X509Data element
      * @throws MarshalException if there is an error while unmarshalling
      */
     public DOMX509Data(Element xdElem) throws MarshalException {
         // get all children nodes
-        NodeList nl = xdElem.getChildNodes();
-        int length = nl.getLength();
-        List<Object> content = new ArrayList<Object>(length);
-        for (int i = 0; i < length; i++) {
-            Node child = nl.item(i);
-            // ignore all non-Element nodes
-            if (child.getNodeType() != Node.ELEMENT_NODE) {
-                continue;
+        List<Object> newContent = new ArrayList<>();
+        Node firstChild = xdElem.getFirstChild();
+        while (firstChild != null) {
+            if (firstChild.getNodeType() == Node.ELEMENT_NODE) {
+                Element childElem = (Element)firstChild;
+                String localName = childElem.getLocalName();
+                String namespace = childElem.getNamespaceURI();
+                if ("X509Certificate".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
+                    newContent.add(unmarshalX509Certificate(childElem));
+                } else if ("X509IssuerSerial".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
+                    newContent.add(new DOMX509IssuerSerial(childElem));
+                } else if ("X509SubjectName".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
+                    newContent.add(childElem.getFirstChild().getNodeValue());
+                } else if ("X509SKI".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
+                    String content = XMLUtils.getFullTextChildrenFromElement(childElem);
+                    newContent.add(XMLUtils.decode(content));
+                } else if ("X509CRL".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
+                    newContent.add(unmarshalX509CRL(childElem));
+                } else {
+                    newContent.add(new javax.xml.crypto.dom.DOMStructure(childElem));
+                }
             }
-
-            Element childElem = (Element)child;
-            String localName = childElem.getLocalName();
-            if (localName.equals("X509Certificate")) {
-                content.add(unmarshalX509Certificate(childElem));
-            } else if (localName.equals("X509IssuerSerial")) {
-                content.add(new DOMX509IssuerSerial(childElem));
-            } else if (localName.equals("X509SubjectName")) {
-                content.add(childElem.getFirstChild().getNodeValue());
-            } else if (localName.equals("X509SKI")) {
-                try {
-                    content.add(Base64.decode(childElem));
-                } catch (Base64DecodingException bde) {
-                    throw new MarshalException("cannot decode X509SKI", bde);
-                }
-            } else if (localName.equals("X509CRL")) {
-                content.add(unmarshalX509CRL(childElem));
-            } else {
-                content.add(new javax.xml.crypto.dom.DOMStructure(childElem));
-            }
+            firstChild = firstChild.getNextSibling();
         }
-        this.content = Collections.unmodifiableList(content);
+        this.content = Collections.unmodifiableList(newContent);
     }
 
     public List<Object> getContent() {
@@ -176,7 +170,7 @@
     {
         Element skidElem = DOMUtils.createElement(doc, "X509SKI",
                                                   XMLSignature.XMLNS, dsPrefix);
-        skidElem.appendChild(doc.createTextNode(Base64.encode(skid)));
+        skidElem.appendChild(doc.createTextNode(XMLUtils.encodeToString(skid)));
         parent.appendChild(skidElem);
     }
 
@@ -197,7 +191,7 @@
                                                   XMLSignature.XMLNS, dsPrefix);
         try {
             certElem.appendChild(doc.createTextNode
-                                 (Base64.encode(cert.getEncoded())));
+                                 (XMLUtils.encodeToString(cert.getEncoded())));
         } catch (CertificateEncodingException e) {
             throw new MarshalException("Error encoding X509Certificate", e);
         }
@@ -212,7 +206,7 @@
                                                  XMLSignature.XMLNS, dsPrefix);
         try {
             crlElem.appendChild(doc.createTextNode
-                                (Base64.encode(crl.getEncoded())));
+                                (XMLUtils.encodeToString(crl.getEncoded())));
         } catch (CRLException e) {
             throw new MarshalException("Error encoding X509CRL", e);
         }
@@ -222,20 +216,22 @@
     private X509Certificate unmarshalX509Certificate(Element elem)
         throws MarshalException
     {
-        try {
-            ByteArrayInputStream bs = unmarshalBase64Binary(elem);
+        try (ByteArrayInputStream bs = unmarshalBase64Binary(elem)) {
             return (X509Certificate)cf.generateCertificate(bs);
         } catch (CertificateException e) {
             throw new MarshalException("Cannot create X509Certificate", e);
+        } catch (IOException e) {
+            throw new MarshalException("Error closing stream", e);
         }
     }
 
     private X509CRL unmarshalX509CRL(Element elem) throws MarshalException {
-        try {
-            ByteArrayInputStream bs = unmarshalBase64Binary(elem);
+        try (ByteArrayInputStream bs = unmarshalBase64Binary(elem)) {
             return (X509CRL)cf.generateCRL(bs);
         } catch (CRLException e) {
             throw new MarshalException("Cannot create X509CRL", e);
+        } catch (IOException e) {
+            throw new MarshalException("Error closing stream", e);
         }
     }
 
@@ -245,11 +241,10 @@
             if (cf == null) {
                 cf = CertificateFactory.getInstance("X.509");
             }
-            return new ByteArrayInputStream(Base64.decode(elem));
+            String content = XMLUtils.getFullTextChildrenFromElement(elem);
+            return new ByteArrayInputStream(XMLUtils.decode(content));
         } catch (CertificateException e) {
             throw new MarshalException("Cannot create CertificateFactory", e);
-        } catch (Base64DecodingException bde) {
-            throw new MarshalException("Cannot decode Base64-encoded val", bde);
         }
     }
 
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509IssuerSerial.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509IssuerSerial.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,19 +21,20 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMX509IssuerSerial.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMX509IssuerSerial.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
+import javax.xml.crypto.MarshalException;
 import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
+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;
@@ -42,7 +43,6 @@
 /**
  * DOM-based implementation of X509IssuerSerial.
  *
- * @author Sean Mullan
  */
 public final class DOMX509IssuerSerial extends DOMStructure
     implements X509IssuerSerial {
@@ -51,16 +51,16 @@
     private final BigInteger serialNumber;
 
     /**
-     * Creates a <code>DOMX509IssuerSerial</code> containing the specified
+     * Creates a {@code DOMX509IssuerSerial} containing the specified
      * issuer distinguished name/serial number pair.
      *
      * @param issuerName the X.509 issuer distinguished name in RFC 2253
      *    String format
      * @param serialNumber the serial number
-     * @throws IllegalArgumentException if the format of <code>issuerName</code>
+     * @throws IllegalArgumentException if the format of {@code issuerName}
      *    is not RFC 2253 compliant
-     * @throws NullPointerException if <code>issuerName</code> or
-     *    <code>serialNumber</code> is <code>null</code>
+     * @throws NullPointerException if {@code issuerName} or
+     *    {@code serialNumber} is {@code null}
      */
     public DOMX509IssuerSerial(String issuerName, BigInteger serialNumber) {
         if (issuerName == null) {
@@ -76,15 +76,17 @@
     }
 
     /**
-     * Creates a <code>DOMX509IssuerSerial</code> from an element.
+     * Creates a {@code DOMX509IssuerSerial} from an element.
      *
      * @param isElem an X509IssuerSerial element
      */
     public DOMX509IssuerSerial(Element isElem) throws MarshalException {
         Element iNElem = DOMUtils.getFirstChildElement(isElem,
-                                                       "X509IssuerName");
+                                                       "X509IssuerName",
+                                                       XMLSignature.XMLNS);
         Element sNElem = DOMUtils.getNextSiblingElement(iNElem,
-                                                        "X509SerialNumber");
+                                                        "X509SerialNumber",
+                                                        XMLSignature.XMLNS);
         issuerName = iNElem.getFirstChild().getNodeValue();
         serialNumber = new BigInteger(sNElem.getFirstChild().getNodeValue());
     }
@@ -97,6 +99,7 @@
         return serialNumber;
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
@@ -124,8 +127,8 @@
             return false;
         }
         X509IssuerSerial ois = (X509IssuerSerial)obj;
-        return (issuerName.equals(ois.getIssuerName()) &&
-                serialNumber.equals(ois.getSerialNumber()));
+        return issuerName.equals(ois.getIssuerName()) &&
+                serialNumber.equals(ois.getSerialNumber());
     }
 
     @Override
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMXMLObject.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMXMLObject.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -38,13 +38,12 @@
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 
 /**
  * DOM-based implementation of XMLObject.
  *
- * @author Sean Mullan
  */
 public final class DOMXMLObject extends DOMStructure implements XMLObject {
 
@@ -55,15 +54,15 @@
     private Element objectElem;
 
     /**
-     * Creates an <code>XMLObject</code> from the specified parameters.
+     * Creates an {@code XMLObject} from the specified parameters.
      *
      * @param content a list of {@link XMLStructure}s. The list
      *    is defensively copied to protect against subsequent modification.
-     *    May be <code>null</code> or empty.
-     * @param id the Id (may be <code>null</code>)
-     * @param mimeType the mime type (may be <code>null</code>)
-     * @param encoding the encoding (may be <code>null</code>)
-     * @throws ClassCastException if <code>content</code> contains any
+     *    May be {@code null} or empty.
+     * @param id the Id (may be {@code null})
+     * @param mimeType the mime type (may be {@code null})
+     * @param encoding the encoding (may be {@code null})
+     * @throws ClassCastException if {@code content} contains any
      *    entries that are not of type {@link XMLStructure}
      */
     public DOMXMLObject(List<? extends XMLStructure> content, String id,
@@ -73,7 +72,7 @@
             this.content = Collections.emptyList();
         } else {
             this.content = Collections.unmodifiableList(
-                new ArrayList<XMLStructure>(content));
+                new ArrayList<>(content));
             for (int i = 0, size = this.content.size(); i < size; i++) {
                 if (!(this.content.get(i) instanceof XMLStructure)) {
                     throw new ClassCastException
@@ -87,7 +86,7 @@
     }
 
     /**
-     * Creates an <code>XMLObject</code> from an element.
+     * Creates an {@code XMLObject} from an element.
      *
      * @param objElem an Object element
      * @throws MarshalException if there is an error when unmarshalling
@@ -108,32 +107,43 @@
         }
         this.mimeType = DOMUtils.getAttributeValue(objElem, "MimeType");
 
-        NodeList nodes = objElem.getChildNodes();
-        int length = nodes.getLength();
-        List<XMLStructure> content = new ArrayList<XMLStructure>(length);
-        for (int i = 0; i < length; i++) {
-            Node child = nodes.item(i);
-            if (child.getNodeType() == Node.ELEMENT_NODE) {
-                Element childElem = (Element)child;
+        List<XMLStructure> newContent = new ArrayList<>();
+        Node firstChild = objElem.getFirstChild();
+        while (firstChild != null) {
+            if (firstChild.getNodeType() == Node.ELEMENT_NODE) {
+                Element childElem = (Element)firstChild;
                 String tag = childElem.getLocalName();
-                if (tag.equals("Manifest")) {
-                    content.add(new DOMManifest(childElem, context, provider));
-                    continue;
-                } else if (tag.equals("SignatureProperties")) {
-                    content.add(new DOMSignatureProperties(childElem, context));
-                    continue;
-                } else if (tag.equals("X509Data")) {
-                    content.add(new DOMX509Data(childElem));
-                    continue;
+                String namespace = childElem.getNamespaceURI();
+                if ("Manifest".equals(tag) && XMLSignature.XMLNS.equals(namespace)) {
+                    newContent.add(new DOMManifest(childElem, context, provider));
+                } else if ("SignatureProperties".equals(tag) && XMLSignature.XMLNS.equals(namespace)) {
+                    newContent.add(new DOMSignatureProperties(childElem));
+                } else if ("X509Data".equals(tag) && XMLSignature.XMLNS.equals(namespace)) {
+                    newContent.add(new DOMX509Data(childElem));
+                } else {
+                    //@@@FIXME: check for other dsig structures
+                    newContent.add(new javax.xml.crypto.dom.DOMStructure(firstChild));
                 }
-                //@@@FIXME: check for other dsig structures
+            } else {
+                newContent.add(new javax.xml.crypto.dom.DOMStructure(firstChild));
             }
-            content.add(new javax.xml.crypto.dom.DOMStructure(child));
+            firstChild = firstChild.getNextSibling();
         }
-        if (content.isEmpty()) {
+
+        // Here we capture namespace declarations, so that when they're marshalled back
+        // out, we can make copies of them. Note that attributes are NOT captured.
+        NamedNodeMap nnm = objElem.getAttributes();
+        for (int idx = 0 ; idx < nnm.getLength() ; idx++) {
+            Node nsDecl = nnm.item(idx);
+            if (DOMUtils.isNamespace(nsDecl)) {
+                newContent.add(new javax.xml.crypto.dom.DOMStructure(nsDecl));
+            }
+        }
+
+        if (newContent.isEmpty()) {
             this.content = Collections.emptyList();
         } else {
-            this.content = Collections.unmodifiableList(content);
+            this.content = Collections.unmodifiableList(newContent);
         }
         this.objectElem = objElem;
     }
@@ -154,6 +164,7 @@
         return encoding;
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException {
         Document ownerDoc = DOMUtils.getOwnerDocument(parent);
@@ -183,6 +194,7 @@
         parent.appendChild(objElem);
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public boolean equals(Object o) {
         if (this == o) {
@@ -194,19 +206,17 @@
         }
         XMLObject oxo = (XMLObject)o;
 
-        boolean idsEqual = (id == null ? oxo.getId() == null
-                                       : id.equals(oxo.getId()));
+        boolean idsEqual = id == null ? oxo.getId() == null
+                                       : id.equals(oxo.getId());
         boolean encodingsEqual =
-            (encoding == null ? oxo.getEncoding() == null
-                              : encoding.equals(oxo.getEncoding()));
+            encoding == null ? oxo.getEncoding() == null
+                              : encoding.equals(oxo.getEncoding());
         boolean mimeTypesEqual =
-            (mimeType == null ? oxo.getMimeType() == null
-                              : mimeType.equals(oxo.getMimeType()));
+            mimeType == null ? oxo.getMimeType() == null
+                              : mimeType.equals(oxo.getMimeType());
 
-        @SuppressWarnings("unchecked")
-        List<XMLStructure> oxoContent = oxo.getContent();
-        return (idsEqual && encodingsEqual && mimeTypesEqual &&
-                equalsContent(oxoContent));
+        return idsEqual && encodingsEqual && mimeTypesEqual &&
+                equalsContent(oxo.getContent());
     }
 
     @Override
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,7 +21,7 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Portions copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * ===========================================================================
@@ -31,7 +31,7 @@
  * ===========================================================================
  */
 /*
- * $Id: DOMXMLSignature.java 1333415 2012-05-03 12:03:51Z coheigea $
+ * $Id: DOMXMLSignature.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -49,26 +49,24 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 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.exceptions.Base64DecodingException;
-import com.sun.org.apache.xml.internal.security.utils.Base64;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 
 /**
  * DOM-based implementation of XMLSignature.
  *
- * @author Sean Mullan
- * @author Joyce Leung
  */
 public final class DOMXMLSignature extends DOMStructure
     implements XMLSignature {
 
-    private static java.util.logging.Logger log =
-        java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom");
+    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 KeyInfo ki;
@@ -80,24 +78,24 @@
     private boolean validationStatus;
     private boolean validated = false;
     private KeySelectorResult ksr;
-    private HashMap<String, XMLStructure> signatureIdMap;
+    private Map<String, XMLStructure> signatureIdMap;
 
     static {
         com.sun.org.apache.xml.internal.security.Init.init();
     }
 
     /**
-     * Creates a <code>DOMXMLSignature</code> from the specified components.
+     * Creates a {@code DOMXMLSignature} from the specified components.
      *
-     * @param si the <code>SignedInfo</code>
-     * @param ki the <code>KeyInfo</code>, or <code>null</code> if not specified
-     * @param objs a list of <code>XMLObject</code>s or <code>null</code>
+     * @param si the {@code SignedInfo}
+     * @param ki the {@code KeyInfo}, or {@code null} if not specified
+     * @param objs a list of {@code XMLObject}s or {@code null}
      *  if not specified. The list is copied to protect against subsequent
      *  modification.
-     * @param id an optional id (specify <code>null</code> to omit)
-     * @param signatureValueId an optional id (specify <code>null</code> to
+     * @param id an optional id (specify {@code null} to omit)
+     * @param signatureValueId an optional id (specify {@code null} to
      *  omit)
-     * @throws NullPointerException if <code>si</code> is <code>null</code>
+     * @throws NullPointerException if {@code si} is {@code null}
      */
     public DOMXMLSignature(SignedInfo si, KeyInfo ki,
                            List<? extends XMLObject> objs,
@@ -113,7 +111,7 @@
             this.objects = Collections.emptyList();
         } else {
             this.objects =
-                Collections.unmodifiableList(new ArrayList<XMLObject>(objs));
+                Collections.unmodifiableList(new ArrayList<>(objs));
             for (int i = 0, size = this.objects.size(); i < size; i++) {
                 if (!(this.objects.get(i) instanceof XMLObject)) {
                     throw new ClassCastException
@@ -125,7 +123,7 @@
     }
 
     /**
-     * Creates a <code>DOMXMLSignature</code> from XML.
+     * Creates a {@code DOMXMLSignature} from XML.
      *
      * @param sigElem Signature element
      * @throws MarshalException if XMLSignature cannot be unmarshalled
@@ -139,20 +137,22 @@
 
         // get Id attribute, if specified
         id = DOMUtils.getAttributeValue(localSigElem, "Id");
-
         // unmarshal SignedInfo
         Element siElem = DOMUtils.getFirstChildElement(localSigElem,
-                                                       "SignedInfo");
+                                                       "SignedInfo",
+                                                       XMLSignature.XMLNS);
         si = new DOMSignedInfo(siElem, context, provider);
 
         // unmarshal SignatureValue
         Element sigValElem = DOMUtils.getNextSiblingElement(siElem,
-                                                            "SignatureValue");
-        sv = new DOMSignatureValue(sigValElem, context);
+                                                            "SignatureValue",
+                                                            XMLSignature.XMLNS);
+        sv = new DOMSignatureValue(sigValElem);
 
         // unmarshal KeyInfo, if specified
         Element nextSibling = DOMUtils.getNextSiblingElement(sigValElem);
-        if (nextSibling != null && nextSibling.getLocalName().equals("KeyInfo")) {
+        if (nextSibling != null && nextSibling.getLocalName().equals("KeyInfo")
+            && XMLSignature.XMLNS.equals(nextSibling.getNamespaceURI())) {
             ki = new DOMKeyInfo(nextSibling, context, provider);
             nextSibling = DOMUtils.getNextSiblingElement(nextSibling);
         }
@@ -161,11 +161,12 @@
         if (nextSibling == null) {
             objects = Collections.emptyList();
         } else {
-            List<XMLObject> tempObjects = new ArrayList<XMLObject>();
+            List<XMLObject> tempObjects = new ArrayList<>();
             while (nextSibling != null) {
                 String name = nextSibling.getLocalName();
-                if (!name.equals("Object")) {
-                    throw new MarshalException("Invalid element name: " + name +
+                String namespace = nextSibling.getNamespaceURI();
+                if (!"Object".equals(name) || !XMLSignature.XMLNS.equals(namespace)) {
+                    throw new MarshalException("Invalid element name: " + namespace + ":" + name +
                                                ", expected KeyInfo or Object");
                 }
                 tempObjects.add(new DOMXMLObject(nextSibling,
@@ -200,6 +201,7 @@
         return ksr;
     }
 
+    @Override
     public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
         throws MarshalException
     {
@@ -245,6 +247,7 @@
         parent.insertBefore(sigElem, nextSibling);
     }
 
+    @Override
     public boolean validate(XMLValidateContext vc)
         throws XMLSignatureException
     {
@@ -276,15 +279,11 @@
         for (int i = 0, size = refs.size(); validateRefs && i < size; i++) {
             Reference ref = refs.get(i);
             boolean refValid = ref.validate(vc);
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Reference[" + ref.getURI() + "] is valid: " + refValid);
-            }
+            LOG.debug("Reference [{}] is valid: {}", ref.getURI(), refValid);
             validateRefs &= refValid;
         }
         if (!validateRefs) {
-            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                log.log(java.util.logging.Level.FINE, "Couldn't validate the References");
-            }
+            LOG.debug("Couldn't validate the References");
             validationStatus = false;
             validated = true;
             return validationStatus;
@@ -303,9 +302,7 @@
                 for (int j = 0; validateMans && j < csize; j++) {
                     XMLStructure xs = content.get(j);
                     if (xs instanceof Manifest) {
-                        if (log.isLoggable(java.util.logging.Level.FINE)) {
-                            log.log(java.util.logging.Level.FINE, "validating manifest");
-                        }
+                        LOG.debug("validating manifest");
                         Manifest man = (Manifest)xs;
                         @SuppressWarnings("unchecked")
                         List<Reference> manRefs = man.getReferences();
@@ -313,11 +310,9 @@
                         for (int k = 0; validateMans && k < rsize; k++) {
                             Reference ref = manRefs.get(k);
                             boolean refValid = ref.validate(vc);
-                            if (log.isLoggable(java.util.logging.Level.FINE)) {
-                                log.log(java.util.logging.Level.FINE,
-                                    "Manifest ref[" + ref.getURI() + "] is valid: " + refValid
-                                );
-                            }
+                            LOG.debug(
+                                "Manifest ref [{}] is valid: {}", ref.getURI(),  refValid
+                            );
                             validateMans &= refValid;
                         }
                     }
@@ -330,6 +325,7 @@
         return validationStatus;
     }
 
+    @Override
     public void sign(XMLSignContext signContext)
         throws MarshalException, XMLSignatureException
     {
@@ -341,11 +337,11 @@
                 DOMUtils.getSignaturePrefix(context), context);
 
         // generate references and signature value
-        List<Reference> allReferences = new ArrayList<Reference>();
+        List<Reference> allReferences = new ArrayList<>();
 
         // traverse the Signature and register all objects with IDs that
         // may contain References
-        signatureIdMap = new HashMap<String, XMLStructure>();
+        signatureIdMap = new HashMap<>();
         signatureIdMap.put(id, this);
         signatureIdMap.put(si.getId(), si);
         @SuppressWarnings("unchecked")
@@ -388,17 +384,17 @@
         }
 
         Key signingKey = null;
-        KeySelectorResult ksr = null;
         try {
-            ksr = signContext.getKeySelector().select(ki,
+            KeySelectorResult keySelectorResult = signContext.getKeySelector().select(ki,
                                                       KeySelector.Purpose.SIGN,
                                                       si.getSignatureMethod(),
                                                       signContext);
-            signingKey = ksr.getKey();
+            signingKey = keySelectorResult.getKey();
             if (signingKey == null) {
                 throw new XMLSignatureException("the keySelector did not " +
                                                 "find a signing key");
             }
+            ksr = keySelectorResult;
         } catch (KeySelectorException kse) {
             throw new XMLSignatureException("cannot find signing key", kse);
         }
@@ -413,7 +409,6 @@
         }
 
         this.localSigElem = sigElem;
-        this.ksr = ksr;
     }
 
     @Override
@@ -428,15 +423,15 @@
         XMLSignature osig = (XMLSignature)o;
 
         boolean idEqual =
-            (id == null ? osig.getId() == null : id.equals(osig.getId()));
+            id == null ? osig.getId() == null : id.equals(osig.getId());
         boolean keyInfoEqual =
-            (ki == null ? osig.getKeyInfo() == null
-                        : ki.equals(osig.getKeyInfo()));
+            ki == null ? osig.getKeyInfo() == null
+                        : ki.equals(osig.getKeyInfo());
 
-        return (idEqual && keyInfoEqual &&
+        return idEqual && keyInfoEqual &&
                 sv.equals(osig.getSignatureValue()) &&
                 si.equals(osig.getSignedInfo()) &&
-                objects.equals(osig.getObjects()));
+                objects.equals(osig.getObjects());
     }
 
     @Override
@@ -464,15 +459,14 @@
         // check dependencies
         String uri = ref.getURI();
         if (Utils.sameDocumentURI(uri)) {
-            String id = Utils.parseIdFromSameDocumentURI(uri);
-            if (id != null && signatureIdMap.containsKey(id)) {
-                XMLStructure xs = signatureIdMap.get(id);
+            String parsedId = Utils.parseIdFromSameDocumentURI(uri);
+            if (parsedId != null && signatureIdMap.containsKey(parsedId)) {
+                XMLStructure xs = signatureIdMap.get(parsedId);
                 if (xs instanceof DOMReference) {
                     digestReference((DOMReference)xs, signContext);
                 } else if (xs instanceof Manifest) {
                     Manifest man = (Manifest)xs;
-                    List<Reference> manRefs =
-                        DOMManifest.getManifestReferences(man);
+                    List<Reference> manRefs = DOMManifest.getManifestReferences(man);
                     for (int i = 0, size = manRefs.size(); i < size; i++) {
                         digestReference((DOMReference)manRefs.get(i),
                                         signContext);
@@ -511,15 +505,12 @@
             this.id = id;
         }
 
-        DOMSignatureValue(Element sigValueElem, XMLCryptoContext context)
+        DOMSignatureValue(Element sigValueElem)
             throws MarshalException
         {
-            try {
-                // base64 decode signatureValue
-                value = Base64.decode(sigValueElem);
-            } catch (Base64DecodingException bde) {
-                throw new MarshalException(bde);
-            }
+            // base64 decode signatureValue
+            String content = XMLUtils.getFullTextChildrenFromElement(sigValueElem);
+            value = XMLUtils.decode(content);
 
             Attr attr = sigValueElem.getAttributeNodeNS(null, "Id");
             if (attr != null) {
@@ -539,6 +530,11 @@
             return (value == null) ? null : (byte[])value.clone();
         }
 
+        public String getEncodedValue() {
+            return valueBase64;
+        }
+
+        @Override
         public boolean validate(XMLValidateContext validateContext)
             throws XMLSignatureException
         {
@@ -553,11 +549,16 @@
             // get validating key
             SignatureMethod sm = si.getSignatureMethod();
             Key validationKey = null;
-            KeySelectorResult ksResult;
+            KeySelectorResult ksResult = null;
             try {
-                ksResult = validateContext.getKeySelector().select
-                    (ki, KeySelector.Purpose.VERIFY, sm, validateContext);
-                validationKey = ksResult.getKey();
+                KeySelector keySelector = validateContext.getKeySelector();
+                if (keySelector != null) {
+                    ksResult = keySelector.select
+                        (ki, KeySelector.Purpose.VERIFY, sm, validateContext);
+                    if (ksResult != null) {
+                        validationKey = ksResult.getKey();
+                    }
+                }
                 if (validationKey == null) {
                     throw new XMLSignatureException("the keyselector did not " +
                                                     "find a validation key");
@@ -592,7 +593,7 @@
             SignatureValue osv = (SignatureValue)o;
 
             boolean idEqual =
-                (id == null ? osv.getId() == null : id.equals(osv.getId()));
+                id == null ? osv.getId() == null : id.equals(osv.getId());
 
             //XXX compare signature values?
             return idEqual;
@@ -612,7 +613,6 @@
                             DOMCryptoContext context)
             throws MarshalException
         {
-            // create SignatureValue element
             sigValueElem = DOMUtils.createElement(ownerDoc, "SignatureValue",
                                                   XMLSignature.XMLNS, dsPrefix);
             if (valueBase64 != null) {
@@ -626,7 +626,7 @@
 
         void setValue(byte[] value) {
             this.value = value;
-            valueBase64 = Base64.encode(value);
+            valueBase64 = XMLUtils.encodeToString(value);
             sigValueElem.appendChild(ownerDoc.createTextNode(valueBase64));
         }
     }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMXMLSignatureFactory.java 1333869 2012-05-04 10:42:44Z coheigea $
+ * $Id: DOMXMLSignatureFactory.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -38,6 +38,7 @@
 import java.security.InvalidAlgorithmParameterException;
 import java.security.NoSuchAlgorithmException;
 import java.util.List;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -45,7 +46,6 @@
 /**
  * DOM-based implementation of XMLSignatureFactory.
  *
- * @author Sean Mullan
  */
 public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
 
@@ -74,6 +74,7 @@
         return new DOMReference(uri, type, dm, transforms, id, getProvider());
     }
 
+    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public Reference newReference(String uri, DigestMethod dm,
         List appliedTransforms, Data result, List transforms, String type,
@@ -101,7 +102,7 @@
             (uri, type, dm, null, null, transforms, id, digestValue, getProvider());
     }
 
-    @SuppressWarnings("rawtypes")
+    @SuppressWarnings({ "rawtypes" })
     public SignedInfo newSignedInfo(CanonicalizationMethod cm,
         SignatureMethod sm, List references) {
         return newSignedInfo(cm, sm, references, null);
@@ -120,7 +121,7 @@
         return new DOMXMLObject(content, id, mimeType, encoding);
     }
 
-    @SuppressWarnings("rawtypes")
+    @SuppressWarnings({ "rawtypes" })
     public Manifest newManifest(List references) {
         return newManifest(references, null);
     }
@@ -185,11 +186,12 @@
 
         // check tag
         String tag = element.getLocalName();
-        if (tag == null) {
+        String namespace = element.getNamespaceURI();
+        if (tag == null || namespace == null) {
             throw new MarshalException("Document implementation must " +
                 "support DOM Level 2 and be namespace aware");
         }
-        if (tag.equals("Signature")) {
+        if ("Signature".equals(tag) && XMLSignature.XMLNS.equals(namespace)) {
             try {
                 return new DOMXMLSignature(element, context, getProvider());
             } catch (MarshalException me) {
@@ -198,7 +200,7 @@
                 throw new MarshalException(e);
             }
         } else {
-            throw new MarshalException("Invalid Signature tag: " + tag);
+            throw new MarshalException("Invalid Signature tag: " + namespace + ":" + tag);
         }
     }
 
@@ -218,12 +220,16 @@
         }
         if (algorithm.equals(DigestMethod.SHA1)) {
             return new DOMDigestMethod.SHA1(params);
+        } else if (algorithm.equals(DOMDigestMethod.SHA224)) {
+            return new DOMDigestMethod.SHA224(params);
         } else if (algorithm.equals(DigestMethod.SHA256)) {
             return new DOMDigestMethod.SHA256(params);
         } else if (algorithm.equals(DOMDigestMethod.SHA384)) {
             return new DOMDigestMethod.SHA384(params);
         } else if (algorithm.equals(DigestMethod.SHA512)) {
             return new DOMDigestMethod.SHA512(params);
+        } else if (algorithm.equals(DigestMethod.RIPEMD160)) {
+            return new DOMDigestMethod.RIPEMD160(params);
         } else {
             throw new NoSuchAlgorithmException("unsupported algorithm");
         }
@@ -237,33 +243,59 @@
         }
         if (algorithm.equals(SignatureMethod.RSA_SHA1)) {
             return new DOMSignatureMethod.SHA1withRSA(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA224)) {
+            return new DOMSignatureMethod.SHA224withRSA(params);
         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA256)) {
             return new DOMSignatureMethod.SHA256withRSA(params);
         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA384)) {
             return new DOMSignatureMethod.SHA384withRSA(params);
         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512)) {
             return new DOMSignatureMethod.SHA512withRSA(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512)) {
+            return new DOMSignatureMethod.SHA512withRSA(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_RIPEMD160)) {
+            return new DOMSignatureMethod.RIPEMD160withRSA(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA1_MGF1)) {
+            return new DOMSignatureMethod.SHA1withRSAandMGF1(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA224_MGF1)) {
+            return new DOMSignatureMethod.SHA224withRSAandMGF1(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA256_MGF1)) {
+            return new DOMSignatureMethod.SHA256withRSAandMGF1(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA384_MGF1)) {
+            return new DOMSignatureMethod.SHA384withRSAandMGF1(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512_MGF1)) {
+            return new DOMSignatureMethod.SHA512withRSAandMGF1(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_RIPEMD160_MGF1)) {
+            return new DOMSignatureMethod.RIPEMD160withRSAandMGF1(params);
         } else if (algorithm.equals(SignatureMethod.DSA_SHA1)) {
             return new DOMSignatureMethod.SHA1withDSA(params);
         } else if (algorithm.equals(DOMSignatureMethod.DSA_SHA256)) {
             return new DOMSignatureMethod.SHA256withDSA(params);
         } else if (algorithm.equals(SignatureMethod.HMAC_SHA1)) {
             return new DOMHMACSignatureMethod.SHA1(params);
+        } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA224)) {
+            return new DOMHMACSignatureMethod.SHA224(params);
         } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA256)) {
             return new DOMHMACSignatureMethod.SHA256(params);
         } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA384)) {
             return new DOMHMACSignatureMethod.SHA384(params);
         } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA512)) {
             return new DOMHMACSignatureMethod.SHA512(params);
+        } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_RIPEMD160)) {
+            return new DOMHMACSignatureMethod.RIPEMD160(params);
         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA1)) {
             return new DOMSignatureMethod.SHA1withECDSA(params);
+        } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA224)) {
+            return new DOMSignatureMethod.SHA224withECDSA(params);
         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA256)) {
             return new DOMSignatureMethod.SHA256withECDSA(params);
         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA384)) {
             return new DOMSignatureMethod.SHA384withECDSA(params);
         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA512)) {
             return new DOMSignatureMethod.SHA512withECDSA(params);
-        } else {
+        } else if (algorithm.equals(DOMSignatureMethod.ECDSA_RIPEMD160)) {
+            return new DOMSignatureMethod.RIPEMD160withECDSA(params);
+        }else {
             throw new NoSuchAlgorithmException("unsupported algorithm");
         }
     }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathFilter2Transform.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathFilter2Transform.java	Sat Oct 24 01:11:51 2020 +0100
@@ -28,10 +28,10 @@
  * ===========================================================================
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Portions copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMXPathFilter2Transform.java 1203789 2011-11-18 18:46:07Z mullan $
+ * $Id: DOMXPathFilter2Transform.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -54,7 +54,6 @@
  * DOM-based implementation of XPath Filter 2.0 Transform.
  * (Uses Apache XML-Sec Transform implementation)
  *
- * @author Joyce Leung
  */
 public final class DOMXPathFilter2Transform extends ApacheTransform {
 
@@ -83,34 +82,35 @@
 
     private void unmarshalParams(Element curXPathElem) throws MarshalException
     {
-        List<XPathType> list = new ArrayList<XPathType>();
-        while (curXPathElem != null) {
-            String xPath = curXPathElem.getFirstChild().getNodeValue();
-            String filterVal = DOMUtils.getAttributeValue(curXPathElem,
+        List<XPathType> list = new ArrayList<>();
+        Element currentElement = curXPathElem;
+        while (currentElement != null) {
+            String xPath = currentElement.getFirstChild().getNodeValue();
+            String filterVal = DOMUtils.getAttributeValue(currentElement,
                                                           "Filter");
             if (filterVal == null) {
                 throw new MarshalException("filter cannot be null");
             }
             XPathType.Filter filter = null;
-            if (filterVal.equals("intersect")) {
+            if ("intersect".equals(filterVal)) {
                 filter = XPathType.Filter.INTERSECT;
-            } else if (filterVal.equals("subtract")) {
+            } else if ("subtract".equals(filterVal)) {
                 filter = XPathType.Filter.SUBTRACT;
-            } else if (filterVal.equals("union")) {
+            } else if ("union".equals(filterVal)) {
                 filter = XPathType.Filter.UNION;
             } else {
                 throw new MarshalException("Unknown XPathType filter type" +
                                            filterVal);
             }
-            NamedNodeMap attributes = curXPathElem.getAttributes();
+            NamedNodeMap attributes = currentElement.getAttributes();
             if (attributes != null) {
                 int length = attributes.getLength();
                 Map<String, String> namespaceMap =
-                    new HashMap<String, String>(length);
+                    new HashMap<>(length);
                 for (int i = 0; i < length; i++) {
                     Attr attr = (Attr)attributes.item(i);
                     String prefix = attr.getPrefix();
-                    if (prefix != null && prefix.equals("xmlns")) {
+                    if (prefix != null && "xmlns".equals(prefix)) {
                         namespaceMap.put(attr.getLocalName(), attr.getValue());
                     }
                 }
@@ -119,7 +119,7 @@
                 list.add(new XPathType(xPath, filter));
             }
 
-            curXPathElem = DOMUtils.getNextSiblingElement(curXPathElem);
+            currentElement = DOMUtils.getNextSiblingElement(currentElement);
         }
         this.params = new XPathFilter2ParameterSpec(list);
     }
@@ -131,7 +131,7 @@
         XPathFilter2ParameterSpec xp =
             (XPathFilter2ParameterSpec)getParameterSpec();
         String prefix = DOMUtils.getNSPrefix(context, Transform.XPATH2);
-        String qname = (prefix == null || prefix.length() == 0)
+        String qname = prefix == null || prefix.length() == 0
                        ? "xmlns" : "xmlns:" + prefix;
         @SuppressWarnings("unchecked")
         List<XPathType> xpathList = xp.getXPathList();
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMXPathTransform.java 1203789 2011-11-18 18:46:07Z mullan $
+ * $Id: DOMXPathTransform.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -44,10 +44,10 @@
  * DOM-based implementation of XPath Filtering Transform.
  * (Uses Apache XML-Sec Transform implementation)
  *
- * @author Sean Mullan
  */
 public final class DOMXPathTransform extends ApacheTransform {
 
+    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException
     {
@@ -74,11 +74,11 @@
         if (attributes != null) {
             int length = attributes.getLength();
             Map<String, String> namespaceMap =
-                new HashMap<String, String>(length);
+                new HashMap<>(length);
             for (int i = 0; i < length; i++) {
                 Attr attr = (Attr)attributes.item(i);
                 String prefix = attr.getPrefix();
-                if (prefix != null && prefix.equals("xmlns")) {
+                if (prefix != null && "xmlns".equals(prefix)) {
                     namespaceMap.put(attr.getLocalName(), attr.getValue());
                 }
             }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXSLTTransform.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXSLTTransform.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: DOMXSLTTransform.java 1197150 2011-11-03 14:34:57Z coheigea $
+ * $Id: DOMXSLTTransform.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -40,10 +40,10 @@
  * DOM-based implementation of XSLT Transform.
  * (Uses Apache XML-Sec Transform implementation)
  *
- * @author Sean Mullan
  */
 public final class DOMXSLTTransform extends ApacheTransform {
 
+    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException {
         if (params == null) {
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,10 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: Utils.java 1197150 2011-11-03 14:34:57Z coheigea $
+ * $Id: Utils.java 1788465 2017-03-24 15:10:51Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -39,7 +39,6 @@
 /**
  * Miscellaneous static utility methods for use in JSR 105 RI.
  *
- * @author Sean Mullan
  */
 public final class Utils {
 
@@ -48,19 +47,20 @@
     public static byte[] readBytesFromStream(InputStream is)
         throws IOException
     {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        byte[] buf = new byte[1024];
-        while (true) {
-            int read = is.read(buf);
-            if (read == -1) { // EOF
-                break;
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+            byte[] buf = new byte[1024];
+            while (true) {
+                int read = is.read(buf);
+                if (read == -1) { // EOF
+                    break;
+                }
+                baos.write(buf, 0, read);
+                if (read < 1024) {
+                    break;
+                }
             }
-            baos.write(buf, 0, read);
-            if (read < 1024) {
-                break;
-            }
+            return baos.toByteArray();
         }
-        return baos.toByteArray();
     }
 
     /**
@@ -71,7 +71,7 @@
      * @return the Set of Nodes
      */
     static Set<Node> toNodeSet(Iterator<Node> i) {
-        Set<Node> nodeSet = new HashSet<Node>();
+        Set<Node> nodeSet = new HashSet<>();
         while (i.hasNext()) {
             Node n = i.next();
             nodeSet.add(n);
@@ -106,7 +106,7 @@
      * Returns true if uri is a same-document URI, false otherwise.
      */
     public static boolean sameDocumentURI(String uri) {
-        return (uri != null && (uri.length() == 0 || uri.charAt(0) == '#'));
+        return uri != null && (uri.length() == 0 || uri.charAt(0) == '#');
     }
 
     static boolean secureValidation(XMLCryptoContext xc) {
@@ -118,6 +118,6 @@
 
     private static boolean getBoolean(XMLCryptoContext xc, String name) {
         Boolean value = (Boolean)xc.getProperty(name);
-        return (value != null && value.booleanValue());
+        return value != null && value.booleanValue();
     }
 }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java	Sat Oct 24 01:11:51 2020 +0100
@@ -28,10 +28,10 @@
  * ===========================================================================
  */
 /*
- * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * Portions copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * $Id: XMLDSigRI.java 1400021 2012-10-19 10:16:04Z coheigea $
+ * $Id: XMLDSigRI.java 1804972 2017-08-14 09:59:23Z coheigea $
  */
 package org.jcp.xml.dsig.internal.dom;
 
@@ -43,7 +43,6 @@
 /**
  * The XMLDSig RI Provider.
  *
- * @author Joyce Leung
  */
 
 /**
--- a/src/share/classes/sun/font/Font2D.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/font/Font2D.java	Sat Oct 24 01:11:51 2020 +0100
@@ -30,8 +30,10 @@
 import java.awt.geom.AffineTransform;
 import java.lang.ref.Reference;
 import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.Locale;
+import java.util.Set;
 
 public abstract class Font2D {
 
@@ -105,7 +107,22 @@
      * This pre-supposes that a FontStrike is a shareable object, which
      * it should.
      */
-    protected Reference lastFontStrike = new SoftReference(null);
+    protected Reference<FontStrike> lastFontStrike = new WeakReference<>(null);
+
+    /*
+     * if useWeak is true, proactively clear the cache after this
+     * many strikes are present. 0 means leave it alone.
+     */
+    private int strikeCacheMax = 0;
+    /*
+     * Whether to use weak refs for this font, even if soft refs is the default.
+     */
+    private boolean useWeak;
+
+    void setUseWeakRefs(boolean weak, int maxStrikes) {
+        this.useWeak = weak;
+        this.strikeCacheMax = weak && maxStrikes > 0 ? maxStrikes : 0;
+    }
 
     /*
      * POSSIBLE OPTIMISATION:
@@ -304,6 +321,15 @@
         return getStrike(desc, false);
     }
 
+    void updateLastStrikeRef(FontStrike strike) {
+        lastFontStrike.clear();
+        if (useWeak) {
+            lastFontStrike = new WeakReference<>(strike);
+        } else {
+            lastFontStrike = new SoftReference<>(strike);
+        }
+    }
+
     FontStrike getStrike(FontStrikeDesc desc) {
         return getStrike(desc, true);
     }
@@ -324,15 +350,13 @@
          */
         FontStrike strike = (FontStrike)lastFontStrike.get();
         if (strike != null && desc.equals(strike.desc)) {
-            //strike.lastlookupTime = System.currentTimeMillis();
             return strike;
         } else {
             Reference strikeRef = strikeCache.get(desc);
             if (strikeRef != null) {
                 strike = (FontStrike)strikeRef.get();
                 if (strike != null) {
-                    //strike.lastlookupTime = System.currentTimeMillis();
-                    lastFontStrike = new SoftReference(strike);
+                    updateLastStrikeRef(strike);
                     StrikeCache.refStrike(strike);
                     return strike;
                 }
@@ -366,31 +390,21 @@
              * which is what we want for what is likely a transient strike.
              */
             int txType = desc.glyphTx.getType();
-            if (txType == AffineTransform.TYPE_GENERAL_TRANSFORM ||
+            if (useWeak ||
+                txType == AffineTransform.TYPE_GENERAL_TRANSFORM ||
                 (txType & AffineTransform.TYPE_GENERAL_ROTATION) != 0 &&
                 strikeCache.size() > 10) {
                 strikeRef = StrikeCache.getStrikeRef(strike, true);
             } else {
-                strikeRef = StrikeCache.getStrikeRef(strike);
+                strikeRef = StrikeCache.getStrikeRef(strike, useWeak);
             }
             strikeCache.put(desc, strikeRef);
-            //strike.lastlookupTime = System.currentTimeMillis();
-            lastFontStrike = new SoftReference(strike);
+            updateLastStrikeRef(strike);
             StrikeCache.refStrike(strike);
             return strike;
         }
     }
 
-    void removeFromCache(FontStrikeDesc desc) {
-        Reference ref = strikeCache.get(desc);
-        if (ref != null) {
-            Object o = ref.get();
-            if (o == null) {
-                strikeCache.remove(desc);
-            }
-        }
-    }
-
     /**
      * The length of the metrics array must be >= 8.  This method will
      * store the following elements in that array before returning:
--- a/src/share/classes/sun/font/FontStrikeDisposer.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/font/FontStrikeDisposer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,6 +25,8 @@
 
 package sun.font;
 
+import java.lang.ref.Reference;
+import java.util.concurrent.ConcurrentHashMap;
 import sun.java2d.Disposer;
 import sun.java2d.DisposerRecord;
 
@@ -53,7 +55,7 @@
 class FontStrikeDisposer
     implements DisposerRecord, Disposer.PollDisposable {
 
-    Font2D font2D;
+    ConcurrentHashMap<FontStrikeDesc, Reference> strikeCache;
     FontStrikeDesc desc;
     long[] longGlyphImages;
     int [] intGlyphImages;
@@ -65,7 +67,7 @@
 
     public FontStrikeDisposer(Font2D font2D, FontStrikeDesc desc,
                               long pContext, int[] images) {
-        this.font2D = font2D;
+        this.strikeCache = font2D.strikeCache;
         this.desc = desc;
         this.pScalerContext = pContext;
         this.intGlyphImages = images;
@@ -73,7 +75,7 @@
 
     public FontStrikeDisposer(Font2D font2D, FontStrikeDesc desc,
                               long pContext, long[] images) {
-        this.font2D = font2D;
+        this.strikeCache = font2D.strikeCache;
         this.desc = desc;
         this.pScalerContext = pContext;
         this.longGlyphImages = images;
@@ -81,20 +83,26 @@
 
     public FontStrikeDisposer(Font2D font2D, FontStrikeDesc desc,
                               long pContext) {
-        this.font2D = font2D;
+        this.strikeCache = font2D.strikeCache;
         this.desc = desc;
         this.pScalerContext = pContext;
     }
 
     public FontStrikeDisposer(Font2D font2D, FontStrikeDesc desc) {
-        this.font2D = font2D;
+        this.strikeCache = font2D.strikeCache;
         this.desc = desc;
         this.comp = true;
     }
 
     public synchronized void dispose() {
         if (!disposed) {
-            font2D.removeFromCache(desc);
+            Reference<FontStrike> ref = strikeCache.get(desc);
+            if (ref != null) {
+                Object o = ref.get();
+                if (o == null) {
+                    strikeCache.remove(desc);
+                }
+            }
             StrikeCache.disposeStrike(this);
             disposed = true;
         }
--- a/src/share/classes/sun/font/SunFontManager.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/font/SunFontManager.java	Sat Oct 24 01:11:51 2020 +0100
@@ -260,6 +260,13 @@
         return _usingPerAppContextComposites;
     }
 
+    /* After we reach MAXSOFTREFCNT, use weak refs for created fonts.
+     * This means that a small number of created fonts as used in a UI app
+     * will not be eagerly collected, but an app that create many will
+     * have them collected more frequently to reclaim storage.
+     */
+    private static int maxSoftRefCnt = 10;
+
     static {
 
         java.security.AccessController.doPrivileged(
@@ -284,6 +291,9 @@
                    System.getProperty("java.home","") + File.separator + "lib";
                jreFontDirName = jreLibDirName + File.separator + "fonts";
 
+                maxSoftRefCnt =
+                    Integer.getInteger("sun.java2d.font.maxSoftRefs", 10);
+
                return null;
            }
         });
@@ -2330,6 +2340,8 @@
     // MACOSX end
     Vector<File> tmpFontFiles = null;
 
+    private int createdFontCount = 0;
+
     public Font2D createFont2D(File fontFile, int fontFormat,
                                boolean isCopy, CreatedFontTracker tracker)
     throws FontFormatException {
@@ -2338,13 +2350,26 @@
         FileFont font2D = null;
         final File fFile = fontFile;
         final CreatedFontTracker _tracker = tracker;
+        boolean weakRefs = false;
+        int maxStrikes = 0;
+        synchronized (this) {
+            if (createdFontCount < maxSoftRefCnt) {
+                createdFontCount++;
+            } else {
+                weakRefs = true;
+                maxStrikes = 10;
+            }
+        }
+
         try {
             switch (fontFormat) {
             case Font.TRUETYPE_FONT:
                 font2D = new TrueTypeFont(fontFilePath, null, 0, true);
+                font2D.setUseWeakRefs(weakRefs, maxStrikes);
                 break;
             case Font.TYPE1_FONT:
                 font2D = new Type1Font(fontFilePath, null, isCopy);
+                font2D.setUseWeakRefs(weakRefs, maxStrikes);
                 break;
             default:
                 throw new FontFormatException("Unrecognised Font Format");
--- a/src/share/classes/sun/launcher/LauncherHelper.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/launcher/LauncherHelper.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -66,6 +66,8 @@
 import java.util.jar.Attributes;
 import java.util.jar.JarFile;
 import java.util.jar.Manifest;
+import jdk.internal.platform.Container;
+import jdk.internal.platform.Metrics;
 
 public enum LauncherHelper {
     INSTANCE;
@@ -114,6 +116,7 @@
      *    this code determine this value, using a suitable method or omit the
      *    line entirely.
      */
+    @SuppressWarnings("fallthrough")
     static void showSettings(boolean printToStderr, String optionFlag,
             long initialHeapSize, long maxHeapSize, long stackSize,
             boolean isServer) {
@@ -134,11 +137,19 @@
             case "locale":
                 printLocale();
                 break;
+            case "system":
+                if (System.getProperty("os.name").contains("Linux")) {
+                    printSystemMetrics();
+                    break;
+                }
             default:
                 printVmSettings(initialHeapSize, maxHeapSize, stackSize,
                                 isServer);
                 printProperties();
                 printLocale();
+                if (System.getProperty("os.name").contains("Linux")) {
+                    printSystemMetrics();
+                }
                 break;
         }
     }
@@ -275,6 +286,101 @@
         }
     }
 
+    public static void printSystemMetrics() {
+        Metrics c = Container.metrics();
+
+        ostream.println("Operating System Metrics:");
+
+        if (c == null) {
+            ostream.println(INDENT + "No metrics available for this platform");
+            return;
+        }
+
+        ostream.println(INDENT + "Provider: " + c.getProvider());
+        ostream.println(INDENT + "Effective CPU Count: " + c.getEffectiveCpuCount());
+        ostream.println(INDENT + "CPU Period: " + c.getCpuPeriod() +
+               (c.getCpuPeriod() == -1 ? "" : "us"));
+        ostream.println(INDENT + "CPU Quota: " + c.getCpuQuota() +
+               (c.getCpuQuota() == -1 ? "" : "us"));
+        ostream.println(INDENT + "CPU Shares: " + c.getCpuShares());
+
+        int cpus[] = c.getCpuSetCpus();
+        ostream.println(INDENT + "List of Processors, "
+                + cpus.length + " total: ");
+
+        ostream.print(INDENT);
+        for (int i = 0; i < cpus.length; i++) {
+            ostream.print(cpus[i] + " ");
+        }
+        if (cpus.length > 0) {
+            ostream.println("");
+        }
+
+        cpus = c.getEffectiveCpuSetCpus();
+        ostream.println(INDENT + "List of Effective Processors, "
+                + cpus.length + " total: ");
+
+        ostream.print(INDENT);
+        for (int i = 0; i < cpus.length; i++) {
+            ostream.print(cpus[i] + " ");
+        }
+        if (cpus.length > 0) {
+            ostream.println("");
+        }
+
+        int mems[] = c.getCpuSetMems();
+        ostream.println(INDENT + "List of Memory Nodes, "
+                + mems.length + " total: ");
+
+        ostream.print(INDENT);
+        for (int i = 0; i < mems.length; i++) {
+            ostream.print(mems[i] + " ");
+        }
+        if (mems.length > 0) {
+            ostream.println("");
+        }
+
+        mems = c.getEffectiveCpuSetMems();
+        ostream.println(INDENT + "List of Available Memory Nodes, "
+                + mems.length + " total: ");
+
+        ostream.print(INDENT);
+        for (int i = 0; i < mems.length; i++) {
+            ostream.print(mems[i] + " ");
+        }
+        if (mems.length > 0) {
+            ostream.println("");
+        }
+
+        ostream.println(INDENT + "CPUSet Memory Pressure Enabled: "
+                + c.isCpuSetMemoryPressureEnabled());
+
+        long limit = c.getMemoryLimit();
+        ostream.println(INDENT + "Memory Limit: " +
+                ((limit >= 0) ? SizePrefix.scaleValue(limit) : "Unlimited"));
+
+        limit = c.getMemorySoftLimit();
+        ostream.println(INDENT + "Memory Soft Limit: " +
+                ((limit >= 0) ? SizePrefix.scaleValue(limit) : "Unlimited"));
+
+        limit = c.getMemoryAndSwapLimit();
+        ostream.println(INDENT + "Memory & Swap Limit: " +
+                ((limit >= 0) ? SizePrefix.scaleValue(limit) : "Unlimited"));
+
+        limit = c.getKernelMemoryLimit();
+        ostream.println(INDENT + "Kernel Memory Limit: " +
+                ((limit >= 0) ? SizePrefix.scaleValue(limit) : "Unlimited"));
+
+        limit = c.getTcpMemoryLimit();
+        ostream.println(INDENT + "TCP Memory Limit: " +
+                ((limit >= 0) ? SizePrefix.scaleValue(limit) : "Unlimited"));
+
+        ostream.println(INDENT + "Out Of Memory Killer Enabled: "
+                + c.isMemoryOOMKillEnabled());
+
+        ostream.println("");
+    }
+
     private enum SizePrefix {
 
         KILO(1024, "K"),
--- a/src/share/classes/sun/launcher/resources/launcher.properties	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/launcher/resources/launcher.properties	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 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
@@ -106,7 +106,11 @@
 \    -XshowSettings    show all settings and continue\n\
 \    -XshowSettings:all\n\
 \                      show all settings and continue\n\
-\    -XshowSettings:vm show all vm related settings and continue\n\
+\    -XshowSettings:vm\n\
+\                      show all vm related settings and continue\n\
+\    -XshowSettings:system\n\
+\                      (Linux Only) show host system or container\n\
+\                      configuration and continue\n\
 \    -XshowSettings:properties\n\
 \                      show all property settings and continue\n\
 \    -XshowSettings:locale\n\
--- a/src/share/classes/sun/management/Flag.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/management/Flag.java	Sat Oct 24 01:11:51 2020 +0100
@@ -111,6 +111,7 @@
     // These set* methods are synchronized on the class object
     // to avoid multiple threads updating the same flag at the same time.
     static synchronized native void setLongValue(String name, long value);
+    static synchronized native void setDoubleValue(String name, double value);
     static synchronized native void setBooleanValue(String name, boolean value);
     static synchronized native void setStringValue(String name, String value);
 
--- a/src/share/classes/sun/management/HotSpotDiagnostic.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/management/HotSpotDiagnostic.java	Sat Oct 24 01:11:51 2020 +0100
@@ -42,6 +42,7 @@
     public HotSpotDiagnostic() {
     }
 
+    @Override
     public void dumpHeap(String outputFile, boolean live) throws IOException {
 
         String propertyName = "jdk.management.heapdump.allowAnyFileSuffix";
@@ -62,6 +63,7 @@
 
     private native void dumpHeap0(String outputFile, boolean live) throws IOException;
 
+    @Override
     public List<VMOption> getDiagnosticOptions() {
         List<Flag> allFlags = Flag.getAllFlags();
         List<VMOption> result = new ArrayList<>();
@@ -73,6 +75,7 @@
         return result;
     }
 
+    @Override
     public VMOption getVMOption(String name) {
         if (name == null) {
             throw new NullPointerException("name cannot be null");
@@ -86,6 +89,7 @@
         return f.getVMOption();
     }
 
+    @Override
     public void setVMOption(String name, String value) {
         if (name == null) {
             throw new NullPointerException("name cannot be null");
@@ -112,12 +116,18 @@
                 long l = Long.parseLong(value);
                 Flag.setLongValue(name, l);
             } catch (NumberFormatException e) {
-                IllegalArgumentException iae =
-                    new IllegalArgumentException("Invalid value:" +
+                throw new IllegalArgumentException("Invalid value:" +
                         " VM Option \"" + name + "\"" +
-                        " expects numeric value");
-                iae.initCause(e);
-                throw iae;
+                        " expects numeric value", e);
+            }
+        } else if (v instanceof Double) {
+            try {
+                double d = Double.parseDouble(value);
+                Flag.setDoubleValue(name, d);
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException("Invalid value:" +
+                        " VM Option \"" + name + "\"" +
+                        " expects numeric value", e);
             }
         } else if (v instanceof Boolean) {
             if (!value.equalsIgnoreCase("true") &&
@@ -136,6 +146,7 @@
         }
     }
 
+    @Override
     public ObjectName getObjectName() {
         return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic");
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/net/ExtendedOptionsHelper.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 sun.net;
+
+import java.net.SocketOption;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import static jdk.net.ExtendedSocketOptions.TCP_KEEPCOUNT;
+import static jdk.net.ExtendedSocketOptions.TCP_KEEPIDLE;
+import static jdk.net.ExtendedSocketOptions.TCP_KEEPINTERVAL;
+
+public class ExtendedOptionsHelper {
+
+    private static final boolean keepAliveOptSupported =
+            ExtendedOptionsImpl.keepAliveOptionsSupported();
+    private static final Set<SocketOption<?>> extendedOptions = options();
+
+    private static Set<SocketOption<?>> options() {
+        Set<SocketOption<?>> options = new HashSet<>();
+        if (keepAliveOptSupported) {
+            options.add(TCP_KEEPCOUNT);
+            options.add(TCP_KEEPIDLE);
+            options.add(TCP_KEEPINTERVAL);
+        }
+        return Collections.unmodifiableSet(options);
+    }
+
+    public static Set<SocketOption<?>> keepAliveOptions() {
+        return extendedOptions;
+    }
+}
--- a/src/share/classes/sun/net/ExtendedOptionsImpl.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/net/ExtendedOptionsImpl.java	Sat Oct 24 01:11:51 2020 +0100
@@ -89,4 +89,12 @@
     public static native void setFlowOption(FileDescriptor fd, SocketFlow f);
     public static native void getFlowOption(FileDescriptor fd, SocketFlow f);
     public static native boolean flowSupported();
+
+    public static native void setTcpKeepAliveProbes(FileDescriptor fd, int value) throws SocketException;
+    public static native void setTcpKeepAliveTime(FileDescriptor fd, int value) throws SocketException;
+    public static native void setTcpKeepAliveIntvl(FileDescriptor fd, int value) throws SocketException;
+    public static native int getTcpKeepAliveProbes(FileDescriptor fd) throws SocketException;
+    public static native int getTcpKeepAliveTime(FileDescriptor fd) throws SocketException;
+    public static native int getTcpKeepAliveIntvl(FileDescriptor fd) throws SocketException;
+    public static native boolean keepAliveOptionsSupported();
 }
--- a/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -39,6 +39,7 @@
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import sun.net.NetHooks;
+import sun.net.ExtendedOptionsHelper;
 
 /**
  * Base implementation of AsynchronousServerSocketChannel.
@@ -231,6 +232,7 @@
             HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(2);
             set.add(StandardSocketOptions.SO_RCVBUF);
             set.add(StandardSocketOptions.SO_REUSEADDR);
+            set.addAll(ExtendedOptionsHelper.keepAliveOptions());
             return Collections.unmodifiableSet(set);
         }
     }
--- a/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -40,6 +40,7 @@
 import java.util.concurrent.locks.*;
 import sun.net.NetHooks;
 import sun.net.ExtendedOptionsImpl;
+import sun.net.ExtendedOptionsHelper;
 
 /**
  * Base implementation of AsynchronousSocketChannel
@@ -512,6 +513,7 @@
             if (ExtendedOptionsImpl.flowSupported()) {
                 set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
             }
+            set.addAll(ExtendedOptionsHelper.keepAliveOptions());
             return Collections.unmodifiableSet(set);
         }
     }
--- a/src/share/classes/sun/nio/ch/Net.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/nio/ch/Net.java	Sat Oct 24 01:11:51 2020 +0100
@@ -34,6 +34,9 @@
 import java.security.PrivilegedAction;
 import java.security.PrivilegedExceptionAction;
 import sun.net.ExtendedOptionsImpl;
+import static jdk.net.ExtendedSocketOptions.TCP_KEEPCOUNT;
+import static jdk.net.ExtendedSocketOptions.TCP_KEEPIDLE;
+import static jdk.net.ExtendedSocketOptions.TCP_KEEPINTERVAL;
 
 
 public class Net {
@@ -279,13 +282,29 @@
         Class<?> type = name.type();
 
         if (type == SocketFlow.class) {
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null) {
-                sm.checkPermission(new NetworkPermission("setOption.SO_FLOW_SLA"));
-            }
+            ExtendedOptionsImpl.checkSetOptionPermission(name);
+            ExtendedOptionsImpl.checkValueType(value, SocketFlow.class);
             ExtendedOptionsImpl.setFlowOption(fd, (SocketFlow)value);
             return;
         }
+        if (name == TCP_KEEPINTERVAL) {
+            ExtendedOptionsImpl.checkSetOptionPermission(name);
+            ExtendedOptionsImpl.checkValueType(value, Integer.class);
+            ExtendedOptionsImpl.setTcpKeepAliveIntvl(fd, (Integer)value);
+            return;
+        }
+        if (name == TCP_KEEPIDLE) {
+            ExtendedOptionsImpl.checkSetOptionPermission(name);
+            ExtendedOptionsImpl.checkValueType(value, Integer.class);
+            ExtendedOptionsImpl.setTcpKeepAliveTime(fd, (Integer)value);
+            return;
+        }
+        if (name == TCP_KEEPCOUNT) {
+            ExtendedOptionsImpl.checkSetOptionPermission(name);
+            ExtendedOptionsImpl.checkValueType(value, Integer.class);
+            ExtendedOptionsImpl.setTcpKeepAliveProbes(fd, (Integer)value);
+            return;
+        }
 
         if (type != Integer.class && type != Boolean.class)
             throw new AssertionError("Should not reach here");
@@ -341,14 +360,23 @@
         Class<?> type = name.type();
 
         if (type == SocketFlow.class) {
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null) {
-                sm.checkPermission(new NetworkPermission("getOption.SO_FLOW_SLA"));
-            }
+            ExtendedOptionsImpl.checkGetOptionPermission(name);
             SocketFlow flow = SocketFlow.create();
             ExtendedOptionsImpl.getFlowOption(fd, flow);
             return flow;
         }
+        if (name == TCP_KEEPINTERVAL) {
+            ExtendedOptionsImpl.checkGetOptionPermission(name);
+            return ExtendedOptionsImpl.getTcpKeepAliveIntvl(fd);
+        }
+        if (name == TCP_KEEPIDLE) {
+            ExtendedOptionsImpl.checkGetOptionPermission(name);
+            return ExtendedOptionsImpl.getTcpKeepAliveTime(fd);
+        }
+        if (name == TCP_KEEPCOUNT) {
+            ExtendedOptionsImpl.checkGetOptionPermission(name);
+            return ExtendedOptionsImpl.getTcpKeepAliveProbes(fd);
+        }
 
         // only simple values supported by this method
         if (type != Integer.class && type != Boolean.class)
--- a/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Sat Oct 24 01:11:51 2020 +0100
@@ -32,6 +32,7 @@
 import java.nio.channels.spi.*;
 import java.util.*;
 import sun.net.NetHooks;
+import sun.net.ExtendedOptionsHelper;
 
 
 /**
@@ -183,6 +184,7 @@
             set.add(StandardSocketOptions.SO_RCVBUF);
             set.add(StandardSocketOptions.SO_REUSEADDR);
             set.add(StandardSocketOptions.IP_TOS);
+            set.addAll(ExtendedOptionsHelper.keepAliveOptions());
             return Collections.unmodifiableSet(set);
         }
     }
--- a/src/share/classes/sun/nio/ch/SocketChannelImpl.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/nio/ch/SocketChannelImpl.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -34,6 +34,7 @@
 import java.util.*;
 import sun.net.NetHooks;
 import sun.net.ExtendedOptionsImpl;
+import sun.net.ExtendedOptionsHelper;
 
 
 /**
@@ -239,6 +240,7 @@
             if (ExtendedOptionsImpl.flowSupported()) {
                 set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
             }
+            set.addAll(ExtendedOptionsHelper.keepAliveOptions());
             return Collections.unmodifiableSet(set);
         }
     }
--- a/src/share/classes/sun/security/krb5/Config.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/security/krb5/Config.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -151,6 +151,7 @@
         KdcComm.initStatic();
         EType.initStatic();
         Checksum.initStatic();
+        KrbAsReqBuilder.ReferralsState.initStatic();
     }
 
 
@@ -275,7 +276,7 @@
      * value does not look like a boolean value.
      * @throws IllegalArgumentException see {@link #get(String...)}
      */
-    private Boolean getBooleanObject(String... keys) {
+    public Boolean getBooleanObject(String... keys) {
         String s = get(keys);
         if (s == null) {
             return null;
--- a/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/security/krb5/KrbAsReqBuilder.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -278,7 +278,9 @@
         }
         options = (options == null) ? new KDCOptions() : options;
         if (referralsState.isEnabled()) {
-            options.set(KDCOptions.CANONICALIZE, true);
+            if (referralsState.sendCanonicalize()) {
+                options.set(KDCOptions.CANONICALIZE, true);
+            }
             extraPAs = new PAData[]{ new PAData(Krb5.PA_REQ_ENC_PA_REP,
                     new byte[]{}) };
         } else {
@@ -333,7 +335,7 @@
         boolean preAuthFailedOnce = false;
         KdcComm comm = null;
         EncryptionKey pakey = null;
-        ReferralsState referralsState = new ReferralsState();
+        ReferralsState referralsState = new ReferralsState(this);
         while (true) {
             if (referralsState.refreshComm()) {
                 comm = new KdcComm(refCname.getRealmAsString());
@@ -379,43 +381,88 @@
         }
     }
 
-    private final class ReferralsState {
+    static final class ReferralsState {
+        private static boolean canonicalizeConfig;
         private boolean enabled;
+        private boolean sendCanonicalize;
+        private boolean isEnterpriseCname;
         private int count;
         private boolean refreshComm;
+        private KrbAsReqBuilder reqBuilder;
 
-        ReferralsState() throws KrbException {
-            if (Config.DISABLE_REFERRALS) {
-                if (refCname.getNameType() == PrincipalName.KRB_NT_ENTERPRISE) {
-                    throw new KrbException("NT-ENTERPRISE principals only allowed" +
-                            " when referrals are enabled.");
+        static {
+            initStatic();
+        }
+
+        // Config may be refreshed while running so the setting
+        // value may need to be updated. See Config::refresh.
+        static void initStatic() {
+            canonicalizeConfig = false;
+            try {
+                canonicalizeConfig = Config.getInstance()
+                        .getBooleanObject("libdefaults", "canonicalize") ==
+                        Boolean.TRUE;
+            } catch (KrbException e) {
+                if (Krb5.DEBUG) {
+                    System.out.println("Exception in getting canonicalize," +
+                            " using default value " +
+                            Boolean.valueOf(canonicalizeConfig) + ": " +
+                            e.getMessage());
                 }
-                enabled = false;
-            } else {
-                enabled = true;
+            }
+        }
+
+        ReferralsState(KrbAsReqBuilder reqBuilder) throws KrbException {
+            this.reqBuilder = reqBuilder;
+            sendCanonicalize = canonicalizeConfig;
+            isEnterpriseCname = reqBuilder.refCname.getNameType() ==
+                    PrincipalName.KRB_NT_ENTERPRISE;
+            updateStatus();
+            if (!enabled && isEnterpriseCname) {
+                throw new KrbException("NT-ENTERPRISE principals only" +
+                        " allowed when referrals are enabled.");
             }
             refreshComm = true;
         }
 
+        private void updateStatus() {
+            enabled = !Config.DISABLE_REFERRALS &&
+                    (isEnterpriseCname || sendCanonicalize);
+        }
+
         boolean handleError(KrbException ke) throws RealmException {
             if (enabled) {
                 if (ke.returnCode() == Krb5.KRB_ERR_WRONG_REALM) {
                     Realm referredRealm = ke.getError().getClientRealm();
-                    if (req.getMessage().reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) &&
-                            referredRealm != null && referredRealm.toString().length() > 0 &&
+                    if (referredRealm != null &&
+                            !referredRealm.toString().isEmpty() &&
                             count < Config.MAX_REFERRALS) {
-                        refCname = new PrincipalName(refCname.getNameType(),
-                                refCname.getNameStrings(), referredRealm);
+                        // A valid referral was received while referrals
+                        // were enabled. Change the cname realm to the referred
+                        // realm and set refreshComm to send a new request.
+                        reqBuilder.refCname = new PrincipalName(
+                                reqBuilder.refCname.getNameType(),
+                                reqBuilder.refCname.getNameStrings(),
+                                referredRealm);
                         refreshComm = true;
                         count++;
                         return true;
                     }
                 }
-                if (count < Config.MAX_REFERRALS &&
-                        refCname.getNameType() != PrincipalName.KRB_NT_ENTERPRISE) {
-                    // Server may raise an error if CANONICALIZE is true.
-                    // Try CANONICALIZE false.
-                    enabled = false;
+                if (count < Config.MAX_REFERRALS && sendCanonicalize) {
+                    if (Krb5.DEBUG) {
+                        System.out.println("KrbAsReqBuilder: AS-REQ failed." +
+                                " Retrying with CANONICALIZE false.");
+                    }
+
+                    // Server returned an unexpected error with
+                    // CANONICALIZE true. Retry with false.
+                    sendCanonicalize = false;
+
+                    // Setting CANONICALIZE to false may imply that referrals
+                    // are now disabled (if cname is not of NT-ENTERPRISE type).
+                    updateStatus();
+
                     return true;
                 }
             }
@@ -431,6 +478,10 @@
         boolean isEnabled() {
             return enabled;
         }
+
+        boolean sendCanonicalize() {
+            return sendCanonicalize;
+        }
     }
 
     /**
--- a/src/share/classes/sun/security/krb5/KrbKdcRep.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/security/krb5/KrbKdcRep.java	Sat Oct 24 01:11:51 2020 +0100
@@ -44,11 +44,13 @@
                       ) throws KrbApErrException {
 
         // cname change in AS-REP is allowed only if the client
-        // sent CANONICALIZE and the server supports RFC 6806 - Section 11
-        // FAST scheme (ENC-PA-REP flag).
+        // sent CANONICALIZE or an NT-ENTERPRISE cname in the request, and the
+        // server supports RFC 6806 - Section 11 FAST scheme (ENC-PA-REP flag).
         if (isAsReq && !req.reqBody.cname.equals(rep.cname) &&
-                (!req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) ||
-                 !rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP))) {
+                ((!req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) &&
+                req.reqBody.cname.getNameType() !=
+                PrincipalName.KRB_NT_ENTERPRISE) ||
+                !rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP))) {
             rep.encKDCRepPart.key.destroy();
             throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
         }
@@ -126,14 +128,16 @@
         }
 
         // RFC 6806 - Section 11 mechanism check
-        if (rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP) &&
-                req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE)) {
+        // The availability of the ENC-PA-REP flag in the KDC response is
+        // mandatory on some cases (see Krb5.TKT_OPTS_ENC_PA_REP check above).
+        if (rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP)) {
             boolean reqPaReqEncPaRep = false;
             boolean repPaReqEncPaRepValid = false;
 
-            // PA_REQ_ENC_PA_REP only required for AS requests
             for (PAData pa : req.pAData) {
                 if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {
+                    // The KDC supports RFC 6806 and ENC-PA-REP was sent in
+                    // the request (AS-REQ). A valid checksum is now required.
                     reqPaReqEncPaRep = true;
                     break;
                 }
--- a/src/share/classes/sun/security/rsa/RSAKeyPairGenerator.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/security/rsa/RSAKeyPairGenerator.java	Sat Oct 24 01:11:51 2020 +0100
@@ -70,7 +70,7 @@
     public void initialize(int keySize, SecureRandom random) {
         try {
             initialize(new RSAKeyGenParameterSpec(keySize,
-                    RSAKeyGenParameterSpec.F4), null);
+                    RSAKeyGenParameterSpec.F4), random);
         } catch (InvalidAlgorithmParameterException iape) {
             throw new InvalidParameterException(iape.getMessage());
         }
--- a/src/share/classes/sun/security/smartcardio/ChannelImpl.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/security/smartcardio/ChannelImpl.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -150,6 +150,7 @@
         return res;
     }
 
+    private final static int RESPONSE_ITERATIONS = 256;
     private final static byte[] B0 = new byte[0];
 
     private byte[] doTransmit(byte[] command) throws CardException {
@@ -182,8 +183,9 @@
             int k = 0;
             byte[] result = B0;
             while (true) {
-                if (++k >= 32) {
-                    throw new CardException("Could not obtain response");
+                if (++k > RESPONSE_ITERATIONS) {
+                    throw new CardException("Number of response iterations" +
+                            " exceeded maximum " + RESPONSE_ITERATIONS);
                 }
                 byte[] response = SCardTransmit
                     (card.cardId, card.protocol, command, 0, n);
--- a/src/share/classes/sun/security/validator/PKIXValidator.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/security/validator/PKIXValidator.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -32,9 +32,9 @@
 
 import javax.security.auth.x500.X500Principal;
 import sun.security.action.GetBooleanAction;
-import sun.security.action.GetPropertyAction;
 import sun.security.provider.certpath.AlgorithmChecker;
 import sun.security.provider.certpath.PKIXExtendedParameters;
+import sun.security.util.SecurityProperties;
 
 /**
  * Validator implementation built on the PKIX CertPath API. This
@@ -66,14 +66,14 @@
     private final static boolean TRY_VALIDATOR = true;
 
     /**
-     * System property that if set (or set to "true"), allows trust anchor
-     * certificates to be used if they do not have the proper CA extensions.
-     * Set to false if prop is not set, or set to any other value.
+     * System or security property that if set (or set to "true"), allows trust
+     * anchor certificates to be used if they do not have the proper CA
+     * extensions. Set to false if prop is not set, or set to any other value.
      */
     private static final boolean ALLOW_NON_CA_ANCHOR = allowNonCaAnchor();
     private static boolean allowNonCaAnchor() {
-        String prop = GetPropertyAction
-            .privilegedGetProperty("jdk.security.allowNonCaAnchor");
+        String prop = SecurityProperties
+                .privilegedGetOverridable("jdk.security.allowNonCaAnchor");
         return prop != null && (prop.isEmpty() || prop.equalsIgnoreCase("true"));
     }
 
--- a/src/share/classes/sun/security/x509/AlgorithmId.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/classes/sun/security/x509/AlgorithmId.java	Sat Oct 24 01:11:51 2020 +0100
@@ -121,9 +121,9 @@
     }
 
     protected void decodeParams() throws IOException {
-        String algidString = algid.toString();
+        String algidName = getName();
         try {
-            algParams = AlgorithmParameters.getInstance(algidString);
+            algParams = AlgorithmParameters.getInstance(algidName);
         } catch (NoSuchAlgorithmException e) {
             /*
              * This algorithm parameter type is not supported, so we cannot
--- a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipConstants.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipConstants.java	Sat Oct 24 01:11:51 2020 +0100
@@ -200,10 +200,19 @@
         return (LG(b, n)) | (LG(b, n + 4) << 32);
     }
 
-    static final long GETSIG(byte[] b) {
-        return LG(b, 0);
+    static long getSig(byte[] b, int n) { return LG(b, n); }
+
+    private static boolean pkSigAt(byte[] b, int n, int b1, int b2) {
+        return b[n] == 'P' & b[n + 1] == 'K' & b[n + 2] == b1 & b[n + 3] == b2;
     }
 
+    static boolean cenSigAt(byte[] b, int n) { return pkSigAt(b, n, 1, 2); }
+    static boolean locSigAt(byte[] b, int n) { return pkSigAt(b, n, 3, 4); }
+    static boolean endSigAt(byte[] b, int n) { return pkSigAt(b, n, 5, 6); }
+    static boolean extSigAt(byte[] b, int n) { return pkSigAt(b, n, 7, 8); }
+    static boolean end64SigAt(byte[] b, int n) { return pkSigAt(b, n, 6, 6); }
+    static boolean locator64SigAt(byte[] b, int n) { return pkSigAt(b, n, 6, 7); }
+
     // local file (LOC) header fields
     static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature
     static final int  LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract
--- a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1073,7 +1073,7 @@
         int pos = 0;
         int limit = cen.length - ENDHDR;
         while (pos < limit) {
-            if (CENSIG(cen, pos) != CENSIG)
+            if (!cenSigAt(cen, pos))
                 zerror("invalid CEN header (bad signature)");
             int method = CENHOW(cen, pos);
             int nlen   = CENNAM(cen, pos);
@@ -1921,7 +1921,7 @@
             throws IOException
         {
             byte[] cen = zipfs.cen;
-            if (CENSIG(cen, pos) != CENSIG)
+            if (!cenSigAt(cen, pos))
                 zerror("invalid CEN header (bad signature)");
             versionMade = CENVEM(cen, pos);
             version     = CENVER(cen, pos);
@@ -2084,9 +2084,9 @@
             assert (buf.length >= LOCHDR);
             if (zipfs.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR)
                 throw new ZipException("loc: reading failed");
-            if (LOCSIG(buf) != LOCSIG)
+            if (!locSigAt(buf, 0))
                 throw new ZipException("loc: wrong sig ->"
-                                       + Long.toString(LOCSIG(buf), 16));
+                                       + Long.toString(getSig(buf, 0), 16));
             //startPos = pos;
             version  = LOCVER(buf);
             flag     = LOCFLG(buf);
@@ -2318,9 +2318,9 @@
                     if (zipfs.readFullyAt(buf, 0, buf.length , locoff)
                         != buf.length)
                         throw new ZipException("loc: reading failed");
-                    if (LOCSIG(buf) != LOCSIG)
+                    if (!locSigAt(buf, 0))
                         throw new ZipException("loc: wrong sig ->"
-                                           + Long.toString(LOCSIG(buf), 16));
+                                           + Long.toString(getSig(buf, 0), 16));
 
                     int locElen = LOCEXT(buf);
                     if (locElen < 9)    // EXTT is at lease 9 bytes
--- a/src/share/javavm/export/jmm.h	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/javavm/export/jmm.h	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
  * 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,7 +143,8 @@
   JMM_VMGLOBAL_TYPE_UNKNOWN  = 0,
   JMM_VMGLOBAL_TYPE_JBOOLEAN = 1,
   JMM_VMGLOBAL_TYPE_JSTRING  = 2,
-  JMM_VMGLOBAL_TYPE_JLONG    = 3
+  JMM_VMGLOBAL_TYPE_JLONG    = 3,
+  JMM_VMGLOBAL_TYPE_JDOUBLE  = 4
 } jmmVMGlobalType;
 
 typedef enum {
--- a/src/share/lib/security/java.security-aix	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/lib/security/java.security-aix	Sat Oct 24 01:11:51 2020 +0100
@@ -1100,4 +1100,17 @@
 # If a system property of the same name is also specified, it supersedes the
 # security property value defined here.
 #
-#jdk.security.krb5.default.initiate.credential=always-impersonate
\ No newline at end of file
+#jdk.security.krb5.default.initiate.credential=always-impersonate
+
+#
+# Trust Anchor Certificates - CA Basic Constraint check
+#
+# X.509 v3 certificates used as Trust Anchors (to validate signed code or TLS
+# connections) must have the cA Basic Constraint field set to 'true'. Also, if
+# they include a Key Usage extension, the keyCertSign bit must be set. These
+# checks, enabled by default, can be disabled for backward-compatibility
+# purposes with the jdk.security.allowNonCaAnchor System and Security
+# properties. In the case that both properties are simultaneously set, the
+# System value prevails. The default value of the property is "false".
+#
+#jdk.security.allowNonCaAnchor=true
\ No newline at end of file
--- a/src/share/lib/security/java.security-linux	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/lib/security/java.security-linux	Sat Oct 24 01:11:51 2020 +0100
@@ -1106,4 +1106,17 @@
 # If a system property of the same name is also specified, it supersedes the
 # security property value defined here.
 #
-#jdk.security.krb5.default.initiate.credential=always-impersonate
\ No newline at end of file
+#jdk.security.krb5.default.initiate.credential=always-impersonate
+
+#
+# Trust Anchor Certificates - CA Basic Constraint check
+#
+# X.509 v3 certificates used as Trust Anchors (to validate signed code or TLS
+# connections) must have the cA Basic Constraint field set to 'true'. Also, if
+# they include a Key Usage extension, the keyCertSign bit must be set. These
+# checks, enabled by default, can be disabled for backward-compatibility
+# purposes with the jdk.security.allowNonCaAnchor System and Security
+# properties. In the case that both properties are simultaneously set, the
+# System value prevails. The default value of the property is "false".
+#
+#jdk.security.allowNonCaAnchor=true
\ No newline at end of file
--- a/src/share/lib/security/java.security-macosx	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/lib/security/java.security-macosx	Sat Oct 24 01:11:51 2020 +0100
@@ -1104,4 +1104,17 @@
 # If a system property of the same name is also specified, it supersedes the
 # security property value defined here.
 #
-#jdk.security.krb5.default.initiate.credential=always-impersonate
\ No newline at end of file
+#jdk.security.krb5.default.initiate.credential=always-impersonate
+
+#
+# Trust Anchor Certificates - CA Basic Constraint check
+#
+# X.509 v3 certificates used as Trust Anchors (to validate signed code or TLS
+# connections) must have the cA Basic Constraint field set to 'true'. Also, if
+# they include a Key Usage extension, the keyCertSign bit must be set. These
+# checks, enabled by default, can be disabled for backward-compatibility
+# purposes with the jdk.security.allowNonCaAnchor System and Security
+# properties. In the case that both properties are simultaneously set, the
+# System value prevails. The default value of the property is "false".
+#
+#jdk.security.allowNonCaAnchor=true
\ No newline at end of file
--- a/src/share/lib/security/java.security-solaris	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/lib/security/java.security-solaris	Sat Oct 24 01:11:51 2020 +0100
@@ -1102,4 +1102,17 @@
 # If a system property of the same name is also specified, it supersedes the
 # security property value defined here.
 #
-#jdk.security.krb5.default.initiate.credential=always-impersonate
\ No newline at end of file
+#jdk.security.krb5.default.initiate.credential=always-impersonate
+
+#
+# Trust Anchor Certificates - CA Basic Constraint check
+#
+# X.509 v3 certificates used as Trust Anchors (to validate signed code or TLS
+# connections) must have the cA Basic Constraint field set to 'true'. Also, if
+# they include a Key Usage extension, the keyCertSign bit must be set. These
+# checks, enabled by default, can be disabled for backward-compatibility
+# purposes with the jdk.security.allowNonCaAnchor System and Security
+# properties. In the case that both properties are simultaneously set, the
+# System value prevails. The default value of the property is "false".
+#
+#jdk.security.allowNonCaAnchor=true
\ No newline at end of file
--- a/src/share/lib/security/java.security-windows	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/lib/security/java.security-windows	Sat Oct 24 01:11:51 2020 +0100
@@ -1104,4 +1104,17 @@
 # If a system property of the same name is also specified, it supersedes the
 # security property value defined here.
 #
-#jdk.security.krb5.default.initiate.credential=always-impersonate
\ No newline at end of file
+#jdk.security.krb5.default.initiate.credential=always-impersonate
+
+#
+# Trust Anchor Certificates - CA Basic Constraint check
+#
+# X.509 v3 certificates used as Trust Anchors (to validate signed code or TLS
+# connections) must have the cA Basic Constraint field set to 'true'. Also, if
+# they include a Key Usage extension, the keyCertSign bit must be set. These
+# checks, enabled by default, can be disabled for backward-compatibility
+# purposes with the jdk.security.allowNonCaAnchor System and Security
+# properties. In the case that both properties are simultaneously set, the
+# System value prevails. The default value of the property is "false".
+#
+#jdk.security.allowNonCaAnchor=true
\ No newline at end of file
--- a/src/share/native/sun/font/freetypeScaler.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/native/sun/font/freetypeScaler.c	Sat Oct 24 01:11:51 2020 +0100
@@ -617,6 +617,12 @@
     return metrics;
 }
 
+static jlong
+    getGlyphImageNativeInternal(
+        JNIEnv *env, jobject scaler, jobject font2D,
+        jlong pScalerContext, jlong pScaler, jint glyphCode,
+        jboolean renderImage);
+
 /*
  * Class:     sun_font_FreetypeFontScaler
  * Method:    getGlyphAdvanceNative
@@ -628,24 +634,23 @@
         jlong pScalerContext, jlong pScaler, jint glyphCode) {
 
    /* This method is rarely used because requests for metrics are usually
-      coupled with request for bitmap and to large extend work can be reused
-      (to find out metrics we need to hint glyph).
-      So, we typically go through getGlyphImage code path.
-
-      For initial freetype implementation we delegate
-      all work to getGlyphImage but drop result image.
-      This is waste of work related to scan conversion and conversion from
-      freetype format to our format but for now this seems to be ok.
-
-      NB: investigate performance benefits of refactoring code
-      to avoid unnecesary work with bitmaps. */
+    * coupled with a request for the bitmap and to a large extent the
+    * work can be reused (to find out metrics we may need to hint the glyph).
+    * So, we typically go through the getGlyphImage code path.
+    * When we do get here, we need to pass a parameter which indicates
+    * that we don't need freetype to render the bitmap, and consequently
+    * don't need to allocate our own storage either.
+    * This is also important when enter here requesting metrics for sizes
+    * of text which a large size would be rejected for a bitmap but we
+    * still need the metrics.
+    */
 
     GlyphInfo *info;
     jfloat advance = 0.0f;
     jlong image;
 
-    image = Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
-                 env, scaler, font2D, pScalerContext, pScaler, glyphCode);
+    image = getGlyphImageNativeInternal(
+          env, scaler, font2D, pScalerContext, pScaler, glyphCode, JNI_FALSE);
     info = (GlyphInfo*) jlong_to_ptr(image);
 
     if (info != NULL) {
@@ -666,17 +671,12 @@
         JNIEnv *env, jobject scaler, jobject font2D, jlong pScalerContext,
         jlong pScaler, jint glyphCode, jobject metrics) {
 
-     /* As initial implementation we delegate all work to getGlyphImage
-        but drop result image. This is clearly waste of resorces.
-
-        TODO: investigate performance benefits of refactoring code
-              by avoiding bitmap generation and conversion from FT
-              bitmap format. */
+     /* See the comments in getGlyphMetricsNative. They apply here too. */
      GlyphInfo *info;
 
-     jlong image = Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
+     jlong image = getGlyphImageNativeInternal(
                                  env, scaler, font2D,
-                                 pScalerContext, pScaler, glyphCode);
+                                 pScalerContext, pScaler, glyphCode, JNI_FALSE);
      info = (GlyphInfo*) jlong_to_ptr(image);
 
      if (info != NULL) {
@@ -966,6 +966,17 @@
         JNIEnv *env, jobject scaler, jobject font2D,
         jlong pScalerContext, jlong pScaler, jint glyphCode) {
 
+    return getGlyphImageNativeInternal(
+        env, scaler, font2D,
+        pScalerContext, pScaler, glyphCode, JNI_TRUE);
+}
+
+static jlong
+     getGlyphImageNativeInternal(
+        JNIEnv *env, jobject scaler, jobject font2D,
+        jlong pScalerContext, jlong pScaler, jint glyphCode,
+        jboolean renderImage) {
+
     int error, imageSize;
     UInt16 width, height;
     GlyphInfo *glyphInfo;
@@ -1053,7 +1064,7 @@
 #ifdef IMPROVED_FONT_RENDERING
     FT_Render_Glyph(ftglyph, renderingProperties.ftRenderMode);
 #else
-    if (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE) {
+    if (renderImage && (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE)) {
         FT_BBox bbox;
         int w, h;
         FT_Outline_Get_CBox(&(ftglyph->outline), &bbox);
@@ -1070,12 +1081,17 @@
     }
 #endif
 
-    width  = (UInt16) ftglyph->bitmap.width;
-    height = (UInt16) ftglyph->bitmap.rows;
-    if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) {
-        glyphInfo = getNullGlyphImage();
-        return ptr_to_jlong(glyphInfo);
-    }
+    if (renderImage) {
+        width  = (UInt16) ftglyph->bitmap.width;
+        height = (UInt16) ftglyph->bitmap.rows;
+            if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) {
+              glyphInfo = getNullGlyphImage();
+              return ptr_to_jlong(glyphInfo);
+            }
+     } else {
+        width = 0;
+        height = 0;
+     }
 
 
     imageSize = width*height;
@@ -1089,13 +1105,16 @@
     glyphInfo->rowBytes  = width;
     glyphInfo->width     = width;
     glyphInfo->height    = height;
-    glyphInfo->topLeftX  = (float)  ftglyph->bitmap_left;
-    glyphInfo->topLeftY  = (float) -ftglyph->bitmap_top;
+
+    if (renderImage) {
+        glyphInfo->topLeftX  = (float)  ftglyph->bitmap_left;
+        glyphInfo->topLeftY  = (float) -ftglyph->bitmap_top;
 
-    if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD) {
-        glyphInfo->width = width/3;
-    } else if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD_V) {
-        glyphInfo->height = glyphInfo->height/3;
+        if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD) {
+            glyphInfo->width = width/3;
+        } else if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD_V) {
+            glyphInfo->height = glyphInfo->height/3;
+        }
     }
 
     if (context->fmType == TEXT_FM_ON) {
--- a/src/share/native/sun/management/Flag.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/share/native/sun/management/Flag.c	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -131,6 +131,10 @@
             valueObj = JNU_NewObjectByName(env, "java/lang/Long", "(J)V",
                                            globals[i].value.j);
             break;
+        case JMM_VMGLOBAL_TYPE_JDOUBLE:
+            valueObj = JNU_NewObjectByName(env, "java/lang/Double", "(D)V",
+                                           globals[i].value.d);
+            break;
         default:
             // ignore unsupported type
             continue;
@@ -197,6 +201,16 @@
 }
 
 JNIEXPORT void JNICALL
+Java_sun_management_Flag_setDoubleValue
+  (JNIEnv *env, jclass cls, jstring name, jdouble value)
+{
+   jvalue v;
+   v.d = value;
+
+   jmm_interface->SetVMGlobal(env, name, v);
+}
+
+JNIEXPORT void JNICALL
 Java_sun_management_Flag_setBooleanValue
   (JNIEnv *env, jclass cls, jstring name, jboolean value)
 {
--- a/src/solaris/back/linker_md.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/solaris/back/linker_md.c	Sat Oct 24 01:11:51 2020 +0100
@@ -42,6 +42,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "util.h"
 #include "path_md.h"
 #ifndef NATIVE
 #include "iomgr.h"
@@ -57,8 +58,10 @@
 static void dll_build_name(char* buffer, size_t buflen,
                            const char* paths, const char* fname) {
     char *path, *paths_copy, *next_token;
+    *buffer = '\0';
 
-    paths_copy = strdup(paths);
+    paths_copy = jvmtiAllocate((int)strlen(paths) + 1);
+    strcpy(paths_copy, paths);
     if (paths_copy == NULL) {
         return;
     }
@@ -67,15 +70,18 @@
     path = strtok_r(paths_copy, PATH_SEPARATOR, &next_token);
 
     while (path != NULL) {
-        snprintf(buffer, buflen, "%s/lib%s." LIB_SUFFIX, path, fname);
-        if (access(buffer, F_OK) == 0) {
+        size_t result_len = (size_t)snprintf(buffer, buflen, "%s/lib%s." LIB_SUFFIX, path, fname);
+        if (result_len >= buflen) {
+            EXIT_ERROR(JVMTI_ERROR_INVALID_LOCATION, "One or more of the library paths supplied to jdwp, "
+                                                     "likely by sun.boot.library.path, is too long.");
+        } else if (access(buffer, F_OK) == 0) {
             break;
         }
         *buffer = '\0';
         path = strtok_r(NULL, PATH_SEPARATOR, &next_token);
     }
 
-    free(paths_copy);
+    jvmtiDeallocate(paths_copy);
 }
 
 /*
@@ -100,13 +106,11 @@
 {
     const int pnamelen = pname ? strlen(pname) : 0;
 
-    *holder = '\0';
-    /* Quietly truncate on buffer overflow.  Should be an error. */
-    if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
-        return;
-    }
-
     if (pnamelen == 0) {
+        if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
+            EXIT_ERROR(JVMTI_ERROR_INVALID_LOCATION, "One or more of the library paths supplied to jdwp, "
+                                                     "likely by sun.boot.library.path, is too long.");
+        }
         (void)snprintf(holder, holderlen, "lib%s." LIB_SUFFIX, fname);
     } else {
       dll_build_name(holder, holderlen, pname, fname);
--- a/src/solaris/classes/java/net/PlainSocketImpl.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/solaris/classes/java/net/PlainSocketImpl.java	Sat Oct 24 01:11:51 2020 +0100
@@ -31,7 +31,7 @@
 import java.util.Collections;
 import jdk.net.*;
 
-import static sun.net.ExtendedOptionsImpl.*;
+import sun.net.ExtendedOptionsImpl;
 
 /*
  * On Unix systems we simply delegate to native methods.
@@ -58,29 +58,59 @@
     }
 
     protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
-        if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
-            super.setOption(name, value);
+        if (name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+            checkSetOption(name, value, SocketFlow.class);
+            ExtendedOptionsImpl.setFlowOption(getFileDescriptor(), (SocketFlow)value);
+        } else if (name == ExtendedSocketOptions.TCP_KEEPIDLE) {
+            checkSetOption(name, value, Integer.class);
+            ExtendedOptionsImpl.setTcpKeepAliveTime(getFileDescriptor(), (Integer)value);
+        } else if (name == ExtendedSocketOptions.TCP_KEEPINTERVAL) {
+            checkSetOption(name, value, Integer.class);
+            ExtendedOptionsImpl.setTcpKeepAliveIntvl(getFileDescriptor(), (Integer)value);
+        } else if (name == ExtendedSocketOptions.TCP_KEEPCOUNT) {
+            checkSetOption(name, value, Integer.class);
+            ExtendedOptionsImpl.setTcpKeepAliveProbes(getFileDescriptor(), (Integer)value);
         } else {
-            if (isClosedOrPending()) {
-                throw new SocketException("Socket closed");
-            }
-            checkSetOptionPermission(name);
-            checkValueType(value, SocketFlow.class);
-            setFlowOption(getFileDescriptor(), (SocketFlow)value);
+            super.setOption(name, value);
         }
     }
 
-    protected <T> T getOption(SocketOption<T> name) throws IOException {
-        if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
-            return super.getOption(name);
+    private <T> void checkSetOption(SocketOption<T> name, T value, Class<?> expected) throws IOException {
+        if (isClosedOrPending()) {
+            throw new SocketException("Socket closed");
         }
+        ExtendedOptionsImpl.checkSetOptionPermission(name);
+        ExtendedOptionsImpl.checkValueType(value, expected);
+    }
+
+    private <T> void checkGetOption(SocketOption<T> name) throws IOException {
         if (isClosedOrPending()) {
             throw new SocketException("Socket closed");
         }
-        checkGetOptionPermission(name);
-        SocketFlow flow = SocketFlow.create();
-        getFlowOption(getFileDescriptor(), flow);
-        return (T)flow;
+        ExtendedOptionsImpl.checkGetOptionPermission(name);
+    }
+
+    protected <T> T getOption(SocketOption<T> name) throws IOException {
+        if (name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+            checkGetOption(name);
+            SocketFlow flow = SocketFlow.create();
+            ExtendedOptionsImpl.getFlowOption(getFileDescriptor(), flow);
+            return (T)flow;
+        } else if (name == ExtendedSocketOptions.TCP_KEEPIDLE) {
+            checkGetOption(name);
+            int retVal = ExtendedOptionsImpl.getTcpKeepAliveTime(getFileDescriptor());
+            return (T)Integer.valueOf(retVal);
+        } else if (name == ExtendedSocketOptions.TCP_KEEPINTERVAL) {
+            checkGetOption(name);
+            int retVal = ExtendedOptionsImpl.getTcpKeepAliveIntvl(getFileDescriptor());
+            return (T)Integer.valueOf(retVal);
+        } else if (name == ExtendedSocketOptions.TCP_KEEPCOUNT) {
+            checkGetOption(name);
+            int retVal = ExtendedOptionsImpl.getTcpKeepAliveProbes(getFileDescriptor());
+            return (T)Integer.valueOf(retVal);
+        } else {
+            return super.getOption(name);
+        }
     }
 
     protected void socketSetOption(int opt, boolean b, Object val) throws SocketException {
--- a/src/solaris/classes/sun/awt/X11/XIconWindow.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/solaris/classes/sun/awt/X11/XIconWindow.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -24,13 +24,26 @@
  */
 package sun.awt.X11;
 
-import java.awt.*;
-import java.awt.image.*;
+import java.awt.AlphaComposite;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.SystemColor;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferUShort;
+import java.awt.image.ImageObserver;
+import java.awt.image.WritableRaster;
 
 import sun.awt.IconInfo;
+import sun.awt.image.ImageRepresentation;
 import sun.awt.image.ToolkitImage;
-import sun.awt.image.ImageRepresentation;
-
 import sun.util.logging.PlatformLogger;
 
 public class XIconWindow extends XBaseWindow {
@@ -479,7 +492,7 @@
             if (window == 0) {
                 log.finest("Icon window wasn't set");
                 XCreateWindowParams params = getDelayedParams();
-                params.add(BORDER_PIXEL, Long.valueOf(XToolkit.getAwtDefaultFg()));
+                params.add(BORDER_PIXEL, Long.valueOf(0));
                 params.add(BACKGROUND_PIXMAP, iconPixmap);
                 params.add(COLORMAP, adata.get_awt_cmap());
                 params.add(DEPTH, awtImage.get_Depth());
--- a/src/solaris/classes/sun/awt/X11/XToolkit.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/solaris/classes/sun/awt/X11/XToolkit.java	Sat Oct 24 01:11:51 2020 +0100
@@ -112,7 +112,6 @@
     static boolean securityWarningEnabled;
 
     private static volatile int screenWidth = -1, screenHeight = -1; // Dimensions of default screen
-    static long awt_defaultFg; // Pixel
     private static XMouseInfoPeer xPeer;
 
     /**
@@ -242,9 +241,6 @@
             }
             tryXKB();
 
-            AwtScreenData defaultScreen = new AwtScreenData(XToolkit.getDefaultScreenData());
-            awt_defaultFg = defaultScreen.get_blackpixel();
-
             arrowCursor = XlibWrapper.XCreateFontCursor(XToolkit.getDisplay(),
                 XCursorFontConstants.XC_arrow);
             areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true"));
@@ -1349,7 +1345,6 @@
     }
 
     static native long getDefaultXColormap();
-    static native long getDefaultScreenData();
 
     static ColorModel screenmodel;
 
@@ -2040,10 +2035,6 @@
         }
     }
 
-    static long getAwtDefaultFg() {
-        return awt_defaultFg;
-    }
-
     static boolean isLeftMouseButton(MouseEvent me) {
         switch (me.getID()) {
           case MouseEvent.MOUSE_PRESSED:
--- a/src/solaris/native/java/net/ExtendedOptionsImpl.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/solaris/native/java/net/ExtendedOptionsImpl.c	Sat Oct 24 01:11:51 2020 +0100
@@ -25,6 +25,10 @@
 
 #include <jni.h>
 #include <string.h>
+#if defined(__linux__) || defined(MACOSX)
+#include <netinet/tcp.h>
+#include <netinet/in.h>
+#endif
 
 #include "net_util.h"
 #include "jdk_net_SocketFlow.h"
@@ -191,7 +195,8 @@
     int fd = getFD(env, fileDesc);
 
     if (fd < 0) {
-        NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
+        JNU_ThrowByNameWithLastError(env, "java/net/SocketException",
+				     "socket closed");
         return;
     } else {
         sock_flow_props_t props;
@@ -217,11 +222,11 @@
                 JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
                         "unsupported socket option");
             } else if (errno == EACCES || errno == EPERM) {
-                NET_ERROR(env, JNU_JAVANETPKG "SocketException",
-                                "Permission denied");
+                JNU_ThrowByNameWithLastError(env, "java/net/SocketException",
+					     "Permission denied");
             } else {
-                NET_ERROR(env, JNU_JAVANETPKG "SocketException",
-                                "set option SO_FLOW_SLA failed");
+                JNU_ThrowByNameWithLastError(env, "java/net/SocketException",
+					     "set option SO_FLOW_SLA failed");
             }
             return;
         }
@@ -239,7 +244,7 @@
     int fd = getFD(env, fileDesc);
 
     if (fd < 0) {
-        NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
+        JNU_ThrowByNameWithLastError(env, "java/net/SocketException", "socket closed");
         return;
     } else {
         sock_flow_props_t props;
@@ -252,11 +257,11 @@
                 JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
                         "unsupported socket option");
             } else if (errno == EACCES || errno == EPERM) {
-                NET_ERROR(env, JNU_JAVANETPKG "SocketException",
-                                "Permission denied");
+                JNU_ThrowByNameWithLastError(env, "java/net/SocketException",
+					     "Permission denied");
             } else {
-                NET_ERROR(env, JNU_JAVANETPKG "SocketException",
-                                "set option SO_FLOW_SLA failed");
+                JNU_ThrowByNameWithLastError(env, "java/net/SocketException",
+					     "set option SO_FLOW_SLA failed");
             }
             return;
         }
@@ -328,9 +333,193 @@
     return JNI_FALSE;
 }
 
+// Keep alive options are available for MACOSX and Linux only for
+// the time being.
+#if defined(__linux__) || defined(MACOSX)
+
+// Map socket option level/name to OS specific constant
+#ifdef __linux__
+#define SOCK_OPT_LEVEL SOL_TCP
+#define SOCK_OPT_NAME_KEEPIDLE TCP_KEEPIDLE
+#define SOCK_OPT_NAME_KEEPIDLE_STR "TCP_KEEPIDLE"
+#endif
+#ifdef MACOSX
+#define SOCK_OPT_LEVEL IPPROTO_TCP
+#define SOCK_OPT_NAME_KEEPIDLE TCP_KEEPALIVE
+#define SOCK_OPT_NAME_KEEPIDLE_STR "TCP_KEEPALIVE"
+#endif
+
+static jint socketOptionSupported(jint sockopt) {
+    jint one = 1;
+    jint rv, s;
+    s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (s < 0) {
+        return 0;
+    }
+    rv = setsockopt(s, SOCK_OPT_LEVEL, sockopt, (void *) &one, sizeof (one));
+    if (rv != 0 && errno == ENOPROTOOPT) {
+        rv = 0;
+    } else {
+        rv = 1;
+    }
+    close(s);
+    return rv;
+}
+
+static void handleError(JNIEnv *env, jint rv, const char *errmsg) {
+    if (rv < 0) {
+        if (errno == ENOPROTOOPT) {
+            JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+                    "unsupported socket option");
+        } else {
+            JNU_ThrowByNameWithLastError(env, "java/net/SocketException", errmsg);
+        }
+    }
+}
+
+static void setTcpSocketOption
+(JNIEnv *env, jobject fileDesc, jint optval, int opt, int optlevel, const char* errmsg) {
+    int fd = getFD(env, fileDesc);
+
+    if (fd < 0) {
+        JNU_ThrowByNameWithLastError(env, "java/net/SocketException", "socket closed");
+        return;
+    } else {
+        jint rv = setsockopt(fd, optlevel, opt, &optval, sizeof (optval));
+        handleError(env, rv, errmsg);
+    }
+}
+
+static jint getTcpSocketOption
+(JNIEnv *env, jobject fileDesc, int opt, int optlevel, const char* errmsg) {
+    int fd = getFD(env, fileDesc);
+
+    if (fd < 0) {
+        JNU_ThrowByNameWithLastError(env, "java/net/SocketException", "socket closed");
+        return -1;
+    } else {
+        jint optval, rv;
+        socklen_t sz = sizeof (optval);
+        rv = getsockopt(fd, optlevel, opt, &optval, &sz);
+        handleError(env, rv, errmsg);
+        return optval;
+    }
+}
+
+#else /* __linux__ || MACOSX */
+
+/* Keep alive options not supported for non-linux/non-macosx so throw UnsupportedOpExc */
+
+static void setTcpSocketOption
+(JNIEnv *env, jobject fileDesc, jint optval, int opt, int optlevel, const char* errmsg) {
+    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+        "unsupported socket option");
+}
+
+static jint getTcpSocketOption
+(JNIEnv *env, jobject fileDesc, int opt, int optlevel, const char* errmsg) {
+    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+        "unsupported socket option");
+}
+
+#endif /* __linux__ || MACOSX*/
+
 #endif /* __solaris__ */
 
 JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported
   (JNIEnv *env, jclass UNUSED) {
     return flowSupported0();
 }
+
+#if defined(__linux__) || defined(MACOSX)
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    keepAliveOptionsSupported
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_keepAliveOptionsSupported
+(JNIEnv *env, jobject unused) {
+    return socketOptionSupported(SOCK_OPT_NAME_KEEPIDLE) && socketOptionSupported(TCP_KEEPCNT)
+            && socketOptionSupported(TCP_KEEPINTVL);
+}
+
+#else
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    keepAliveOptionsSupported
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_keepAliveOptionsSupported
+(JNIEnv *env, jobject unused) {
+    return JNI_FALSE;
+}
+
+#endif /* __linux__ || MACOSX */
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    setTcpKeepAliveProbes
+ * Signature: (Ljava/io/FileDescriptor;I)V
+ */
+JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setTcpKeepAliveProbes
+(JNIEnv *env, jobject unused, jobject fileDesc, jint optval) {
+    setTcpSocketOption(env, fileDesc, optval, TCP_KEEPCNT, SOCK_OPT_LEVEL,
+                       "set option TCP_KEEPCNT failed");
+}
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    setTcpKeepAliveTime
+ * Signature: (Ljava/io/FileDescriptor;I)V
+ */
+JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setTcpKeepAliveTime
+(JNIEnv *env, jobject unused, jobject fileDesc, jint optval) {
+    setTcpSocketOption(env, fileDesc, optval, SOCK_OPT_NAME_KEEPIDLE, SOCK_OPT_LEVEL,
+                       "set option " SOCK_OPT_NAME_KEEPIDLE_STR " failed");
+}
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    setTcpKeepAliveIntvl
+ * Signature: (Ljava/io/FileDescriptor;I)V
+ */
+JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setTcpKeepAliveIntvl
+(JNIEnv *env, jobject unused, jobject fileDesc, jint optval) {
+    setTcpSocketOption(env, fileDesc, optval, TCP_KEEPINTVL, SOCK_OPT_LEVEL,
+                       "set option TCP_KEEPINTVL failed");
+}
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    getTcpKeepAliveProbes
+ * Signature: (Ljava/io/FileDescriptor;)I
+ */
+JNIEXPORT jint JNICALL Java_sun_net_ExtendedOptionsImpl_getTcpKeepAliveProbes
+(JNIEnv *env, jobject unused, jobject fileDesc) {
+    return getTcpSocketOption(env, fileDesc, TCP_KEEPCNT, SOCK_OPT_LEVEL,
+                              "get option TCP_KEEPCNT failed");
+}
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    getTcpKeepAliveTime
+ * Signature: (Ljava/io/FileDescriptor;)I
+ */
+JNIEXPORT jint JNICALL Java_sun_net_ExtendedOptionsImpl_getTcpKeepAliveTime
+(JNIEnv *env, jobject unused, jobject fileDesc) {
+    return getTcpSocketOption(env, fileDesc, SOCK_OPT_NAME_KEEPIDLE, SOCK_OPT_LEVEL,
+                              "get option " SOCK_OPT_NAME_KEEPIDLE_STR " failed");
+}
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    getTcpKeepAliveIntvl
+ * Signature: (Ljava/io/FileDescriptor;)I
+ */
+JNIEXPORT jint JNICALL Java_sun_net_ExtendedOptionsImpl_getTcpKeepAliveIntvl
+(JNIEnv *env, jobject unused, jobject fileDesc) {
+    return getTcpSocketOption(env, fileDesc, TCP_KEEPINTVL, SOCK_OPT_LEVEL,
+                              "get option TCP_KEEPINTVL failed");
+}
--- a/src/solaris/native/java/util/TimeZone_md.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/solaris/native/java/util/TimeZone_md.c	Sat Oct 24 01:11:51 2020 +0100
@@ -122,6 +122,7 @@
     struct dirent64 *entry = NULL;
     char *pathname = NULL;
     char *tz = NULL;
+    long name_max = 0;
 
     if (strcmp(dir, ZONEINFO_DIR) == 0) {
         /* fast path for 1st iteration */
@@ -145,7 +146,13 @@
         return NULL;
     }
 
-    entry = (struct dirent64 *) malloc((size_t) pathconf(dir, _PC_NAME_MAX));
+    name_max = pathconf(dir, _PC_NAME_MAX);
+    // If pathconf did not work, fall back to a mimimum buffer size.
+    if (name_max < 1024) {
+        name_max = 1024;
+    }
+
+    entry = (struct dirent64 *)malloc(offsetof(struct dirent64, d_name) + name_max + 1);
     if (entry == NULL) {
         (void) closedir(dirp);
         return NULL;
--- a/src/solaris/native/sun/xawt/XToolkit.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/solaris/native/sun/xawt/XToolkit.c	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -143,13 +143,6 @@
     return (jlong) defaultConfig->awt_cmap;
 }
 
-JNIEXPORT jlong JNICALL Java_sun_awt_X11_XToolkit_getDefaultScreenData
-  (JNIEnv *env, jclass clazz)
-{
-    return ptr_to_jlong(getDefaultConfig(DefaultScreen(awt_display)));
-}
-
-
 JNIEXPORT jint JNICALL
 JNI_OnLoad(JavaVM *vm, void *reserved)
 {
--- a/src/windows/back/linker_md.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/windows/back/linker_md.c	Sat Oct 24 01:11:51 2020 +0100
@@ -36,13 +36,16 @@
 
 #include "sys.h"
 
+#include "util.h"
 #include "path_md.h"
 
 static void dll_build_name(char* buffer, size_t buflen,
                            const char* paths, const char* fname) {
     char *path, *paths_copy, *next_token;
+    *buffer = '\0';
 
-    paths_copy = strdup(paths);
+    paths_copy = jvmtiAllocate((int)strlen(paths) + 1);
+    strcpy(paths_copy, paths);
     if (paths_copy == NULL) {
         return;
     }
@@ -51,15 +54,18 @@
     path = strtok_s(paths_copy, PATH_SEPARATOR, &next_token);
 
     while (path != NULL) {
-        _snprintf(buffer, buflen, "%s\\%s.dll", path, fname);
-        if (_access(buffer, 0) == 0) {
+        size_t result_len = (size_t)_snprintf(buffer, buflen, "%s\\%s.dll", path, fname);
+        if (result_len >= buflen) {
+            EXIT_ERROR(JVMTI_ERROR_INVALID_LOCATION, "One or more of the library paths supplied to jdwp, "
+                                                     "likely by sun.boot.library.path, is too long.");
+        } else if (_access(buffer, 0) == 0) {
             break;
         }
         *buffer = '\0';
         path = strtok_s(NULL, PATH_SEPARATOR, &next_token);
     }
 
-    free(paths_copy);
+    jvmtiDeallocate(paths_copy);
 }
 
 /*
@@ -106,13 +112,11 @@
 {
     const int pnamelen = pname ? (int)strlen(pname) : 0;
 
-    *holder = '\0';
-    /* Quietly truncates on buffer overflow. Should be an error. */
-    if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
-        return;
-    }
-
     if (pnamelen == 0) {
+        if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
+                EXIT_ERROR(JVMTI_ERROR_INVALID_LOCATION, "One or more of the library paths supplied to jdwp, "
+                                                         "likely by sun.boot.library.path, is too long.");
+        }
         sprintf(holder, "%s.dll", fname);
     } else {
       dll_build_name(holder, holderlen, pname, fname);
--- a/src/windows/native/java/net/ExtendedOptionsImpl.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/windows/native/java/net/ExtendedOptionsImpl.c	Sat Oct 24 01:11:51 2020 +0100
@@ -60,3 +60,81 @@
   (JNIEnv *env, jclass UNUSED) {
     return JNI_FALSE;
 }
+
+/* Keepalive options not supported */
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    keepAliveOptionsSupported
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_keepAliveOptionsSupported
+(JNIEnv *env, jobject unused) {
+    return JNI_FALSE;
+}
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    setTcpKeepAliveProbes
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setTcpKeepAliveProbes
+(JNIEnv *env, jobject unused, jobject fileDesc, jint optval) {
+    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+        "unsupported socket option");
+}
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    setTcpKeepAliveTime
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setTcpKeepAliveTime
+(JNIEnv *env, jobject unused, jobject fileDesc, jint optval) {
+    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+        "unsupported socket option");
+}
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    setTcpKeepAliveIntvl
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setTcpKeepAliveIntvl
+(JNIEnv *env, jobject unused, jobject fileDesc, jint optval) {
+    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+        "unsupported socket option");
+}
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    getTcpKeepAliveProbes
+ * Signature: (I)I;
+ */
+JNIEXPORT jint JNICALL Java_sun_net_ExtendedOptionsImpl_getTcpKeepAliveProbes
+(JNIEnv *env, jobject unused, jobject fileDesc) {
+    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+        "unsupported socket option");
+}
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    getTcpKeepAliveTime
+ * Signature: (I)I;
+ */
+JNIEXPORT jint JNICALL Java_sun_net_ExtendedOptionsImpl_getTcpKeepAliveTime
+(JNIEnv *env, jobject unused, jobject fileDesc) {
+    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+        "unsupported socket option");
+}
+
+/*
+ * Class:     sun_net_ExtendedOptionsImpl
+ * Method:    getTcpKeepAliveIntvl
+ * Signature: (I)I;
+ */
+JNIEXPORT jint JNICALL Java_sun_net_ExtendedOptionsImpl_getTcpKeepAliveIntvl
+(JNIEnv *env, jobject unused, jobject fileDesc) {
+    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+        "unsupported socket option");
+}
--- a/src/windows/native/java/net/Inet4AddressImpl.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/windows/native/java/net/Inet4AddressImpl.c	Sat Oct 24 01:11:51 2020 +0100
@@ -472,7 +472,7 @@
     ReplyBuffer = (VOID*) malloc(ReplySize);
     if (ReplyBuffer == NULL) {
         IcmpCloseHandle(hIcmpFile);
-        NET_ThrowNew(env, WSAGetLastError(), "Unable to allocate memory");
+        NET_ThrowNew(env, -1, "Unable to allocate memory");
         return JNI_FALSE;
     }
 
--- a/src/windows/native/java/net/Inet6AddressImpl.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/windows/native/java/net/Inet6AddressImpl.c	Sat Oct 24 01:11:51 2020 +0100
@@ -435,7 +435,7 @@
     ReplyBuffer = (VOID*) malloc(ReplySize);
     if (ReplyBuffer == NULL) {
         IcmpCloseHandle(hIcmpFile);
-        NET_ThrowNew(env, WSAGetLastError(), "Unable to allocate memory");
+        NET_ThrowNew(env, -1, "Unable to allocate memory");
         return JNI_FALSE;
     }
 
--- a/src/windows/native/java/net/SocketInputStream.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/windows/native/java/net/SocketInputStream.c	Sat Oct 24 01:11:51 2020 +0100
@@ -122,12 +122,13 @@
         (*env)->SetByteArrayRegion(env, data, off, nread, (jbyte *)bufP);
     } else {
         if (nread < 0) {
+            int err = WSAGetLastError();
             // Check if the socket has been closed since we last checked.
             // This could be a reason for recv failing.
             if ((*env)->GetIntField(env, fdObj, IO_fd_fdID) == -1) {
                 NET_ThrowSocketException(env, "Socket closed");
             } else {
-                switch (WSAGetLastError()) {
+                switch (err) {
                     case WSAEINTR:
                         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                             "socket closed");
--- a/src/windows/native/sun/net/spi/DefaultProxySelector.c	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/windows/native/sun/net/spi/DefaultProxySelector.c	Sat Oct 24 01:11:51 2020 +0100
@@ -127,12 +127,13 @@
   char regserver[MAX_STR_LEN];
   char override[MAX_STR_LEN];
   char *s, *s2;
+  char *ctx = NULL;
   int pport = 0;
   int defport = 0;
   char *phost;
 
   /**
-   * Let's opem the Registry entry. We'll check a few values in it:
+   * Let's open the Registry entry. We'll check a few values in it:
    *
    * - ProxyEnable: 0 means no proxy, 1 means use the proxy
    * - ProxyServer: a string that can take 2 forms:
@@ -177,7 +178,7 @@
            * The semicolons (;) separated entries have to be matched with the
            * the beginning of the hostname.
            */
-          s = strtok(override, "; ");
+          s = strtok_s(override, "; ", &ctx);
           urlhost = (*env)->GetStringUTFChars(env, host, &isCopy);
           if (urlhost == NULL) {
             if (!(*env)->ExceptionCheck(env))
@@ -194,7 +195,7 @@
                 (*env)->ReleaseStringUTFChars(env, host, urlhost);
               goto noproxy;
             }
-            s = strtok(NULL, "; ");
+            s = strtok_s(NULL, "; ", &ctx);
           }
           if (isCopy == JNI_TRUE)
             (*env)->ReleaseStringUTFChars(env, host, urlhost);
--- a/src/windows/native/sun/windows/awt_Window.cpp	Wed Oct 14 03:38:19 2020 +0100
+++ b/src/windows/native/sun/windows/awt_Window.cpp	Sat Oct 24 01:11:51 2020 +0100
@@ -1544,6 +1544,15 @@
         CHECK_NULL(sequencedEventConst);
     }
 
+    static jclass windowCls = NULL;
+    if (windowCls == NULL) {
+        jclass windowClsLocal = env->FindClass("java/awt/Window");
+        CHECK_NULL(windowClsLocal);
+        windowCls = (jclass)env->NewGlobalRef(windowClsLocal);
+        env->DeleteLocalRef(windowClsLocal);
+        CHECK_NULL(windowCls);
+    }
+
     if (env->EnsureLocalCapacity(3) < 0) {
         return;
     }
@@ -1554,6 +1563,28 @@
         AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite);
         if (awtOpposite != NULL) {
             jOpposite = awtOpposite->GetTarget(env);
+            if ((jOpposite != NULL) &&
+                !env->IsInstanceOf(jOpposite, windowCls)) {
+                env->DeleteLocalRef(jOpposite);
+                jOpposite = NULL;
+
+                HWND parent = AwtComponent::GetTopLevelParentForWindow(opposite);
+                if ((parent != NULL) && (parent != opposite)) {
+                    if (parent == GetHWnd()) {
+                        jOpposite = env->NewLocalRef(target);
+                    } else {
+                        AwtComponent* awtParent = AwtComponent::GetComponent(parent);
+                        if (awtParent != NULL) {
+                            jOpposite = awtParent->GetTarget(env);
+                            if ((jOpposite != NULL) &&
+                                !env->IsInstanceOf(jOpposite, windowCls)) {
+                                env->DeleteLocalRef(jOpposite);
+                                jOpposite = NULL;
+                            }
+                        }
+                    }
+                }
+            }
         }
     }
     jobject event = env->NewObject(wClassEvent, wEventInitMID, target, id,
--- a/test/ProblemList.txt	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/ProblemList.txt	Sat Oct 24 01:11:51 2020 +0100
@@ -318,6 +318,13 @@
 ############################################################################
 
 # jdk_sound
+javax/sound/sampled/DirectAudio/bug6372428.java        8055097 generic-all
+javax/sound/sampled/Clip/bug5070081.java               8055097 generic-all
+javax/sound/sampled/DataLine/LongFramePosition.java    8055097 generic-all
+
+javax/sound/sampled/Clip/Drain/ClipDrain.java          7062792 generic-all
+
+javax/sound/sampled/Mixers/DisabledAssertionCrash.java 7067310 generic-all
 
 ############################################################################
 
--- a/test/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -25,6 +25,7 @@
  * @test
  * @bug 8007267
  * @summary [macosx] com.apple.eawt.Application.setDefaultMenuBar is not working
+ * @requires (os.family == "mac")
  * @author leonid.romanov@oracle.com
  * @run main DefaultMenuBarTest
  */
@@ -32,7 +33,6 @@
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import sun.awt.*;
 import java.lang.reflect.Method;
 
 
@@ -41,7 +41,7 @@
 
     static volatile int listenerCallCounter = 0;
     public static void main(String[] args) throws Exception {
-        if (sun.awt.OSInfo.getOSType() != sun.awt.OSInfo.OSType.MACOSX) {
+        if (!System.getProperty("os.name").contains("OS X")) {
             System.out.println("This test is for MacOS only. Automatically passed on other platforms.");
             return;
         }
@@ -53,7 +53,6 @@
             }
         });
 
-        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
         Robot robot = new Robot();
         robot.setAutoDelay(100);
 
@@ -62,7 +61,7 @@
         robot.keyRelease(ks.getKeyCode());
         robot.keyRelease(KeyEvent.VK_META);
 
-        toolkit.realSync();
+        robot.waitForIdle();
 
         if (listenerCallCounter != 1) {
             throw new Exception("Test failed: ActionListener either wasn't called or was called more than once");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/AEAD/GCMLargeDataKAT.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.MessageDigest;
+import java.util.HashMap;
+
+/*
+ * @test
+ * @bug 8220165
+ * @summary Verify correctness of large data sizes for GCM.
+ */
+
+/**
+ * This test stores the MD5 hash of correctly encrypted AES/GCM data for
+ * particular data lengths.  Those lengths are run on SunJCE to verify returns
+ * the same MD5 hash of the encrypted data.  These are not NIST data sets or
+ * provided by any other organization.  The data sets are known good values,
+ * verified with two different JCE providers (solaris-sparcv9 ucrypto and
+ * linux SunJCE).
+ *
+ * Lengths around 64k are chosen because 64k is the point where
+ * com.sun.crypto.provider.GaloisCounterMode#doLastBlock() starts it's
+ * intrinsic warmup
+ *
+ * Plaintext is all zeros.  Preset key and IV.
+ *
+ * The choice of MD5 is for speed.  Shortcoming of the algorithm are
+ * not relevant for this test.
+ */
+
+public class GCMLargeDataKAT {
+
+    // Hash of encrypted results of AES/GCM for particular lengths.
+    // <data size, hash>
+    static final HashMap<Integer, String> results = new HashMap<Integer, String>() {{
+        put(65534, "1397b91c31ce793895edace4e175bfee");  //64k-2
+        put(65535, "4ad101c9f450e686668b3f8f05db96f0");  //64k-1
+        put(65536, "fbfaee3451acd3f603200d6be0f39b24");  //64k
+        put(65537, "e7dfca4a71495c65d20982c3c9b9813f");  //64k+1
+        put(67583, "c8ebdcb3532ec6c165de961341af7635");  //66k-1
+        put(67584, "36559d108dfd25dd29da3fec3455b9e5");  //66k
+        put(67585, "1d21b42d80ea179810744fc23dc228b6");  //66k+1
+        put(102400, "0d1544fcab20bbd4c8103b9d273f2c82"); //100k
+        put(102401, "f2d53ef65fd12d0a861368659b23ea2e"); //100k+1
+        put(102402, "97f0f524cf63d2d9d23d81e64d416ee0"); //100k+2
+        put(102403, "4a6b4af55b7d9016b64114d6813d639c"); //100k+3
+        put(102404, "ba63cc131fcde2f12ddf2ac634201be8"); //100k+4
+        put(102405, "673d05c7fe5e283e42e5c0d049fdcea6"); //100k+5
+        put(102406, "76cc99a7850ce857eb3cb43049cf9877"); //100k+6
+        put(102407, "65863f99072cf2eb7fce18bd78b33f4e"); //100k+7
+        put(102408, "b9184f0f272682cc1f791fa7070eddd4"); //100k+8
+        put(102409, "45fe36afef43cc665bf22a9ca200c3c2"); //100k+9
+        put(102410, "67249e41646edcb37a78a61b0743cf11"); //100k+0
+        put(102411, "ffdc611e29c8849842e81ec78f32c415"); //100k+11
+        put(102412, "b7fde7fd52221057dccc1c181a140125"); //100k+12
+        put(102413, "4b1d6c64d56448105e5613157e69c0ae"); //100k+13
+        put(102414, "6d2c0b26c0c8785c8eec3298a5f0080c"); //100k+14
+        put(102415, "1df2061b114fbe56bdf3717e3ee61ef9"); //100k+15
+        put(102416, "a691742692c683ac9d1254df5fc5f768"); //100k+16
+    }};
+    static final int HIGHLEN = 102416;
+
+    static final int GCM_TAG_LENGTH = 16;
+    static final byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+    static final byte[] key_code = {
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+    };
+    static final GCMParameterSpec spec =
+            new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
+    static final SecretKey key = new SecretKeySpec(key_code, "AES");
+    static boolean testresult = true;
+    static byte[] plaintext = new byte[HIGHLEN];
+    static MessageDigest md5;
+    Cipher cipher;
+
+    GCMLargeDataKAT() {
+    }
+
+    byte[] encrypt(int inLen) {
+        try {
+            cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
+            cipher.init(Cipher.ENCRYPT_MODE, key, spec);
+            return cipher.doFinal(plaintext, 0, inLen);
+        } catch (Exception e) {
+            System.err.println("Encrypt Failure (length = " + inLen + ") : " +
+                    e.getMessage());
+            e.printStackTrace();
+        }
+        return new byte[0];
+    }
+
+    static byte[] hash(byte[] data) {
+        return md5.digest(data);
+    }
+
+    // Decrypt the data and return a boolean if the plaintext is all 0's.
+    boolean decrypt(byte[] data) {
+        byte[] result = null;
+        int len = data.length - GCM_TAG_LENGTH;
+        if (data.length == 0) {
+            return false;
+        }
+        try {
+            cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
+            cipher.init(Cipher.DECRYPT_MODE, key, spec);
+            result = cipher.doFinal(data);
+        } catch (Exception e) {
+            System.err.println("Decrypt Failure (length = " + len + ") : " +
+                    e.getMessage());
+            e.printStackTrace();
+            return false;
+        }
+
+        if (result.length != len) {
+            System.err.println("Decrypt Failure (length = " + len +
+                    ") : plaintext length invalid = " + result.length);
+        }
+        // Return false if we find a non zero.
+        int i = 0;
+        while (result.length > i) {
+            if (result[i++] != 0) {
+                System.err.println("Decrypt Failure (length = " + len +
+                        ") : plaintext invalid, char index " + i);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    void test() throws Exception {
+
+        // results order is not important
+        for (int l : results.keySet()) {
+            byte[] enc = new GCMLargeDataKAT().encrypt(l);
+
+            // verify hash with stored hash of that length
+            String hashstr = toHex(hash(enc));
+            boolean r = (hashstr.compareTo(results.get(l)) == 0);
+
+            System.out.println("---------------------------------------------");
+
+            // Encrypted test & results
+            System.out.println("Encrypt data size " + l + " \tResult: " +
+                    (r ? "Pass" : "Fail"));
+            if (!r) {
+                if (enc.length != 0) {
+                    System.out.println("\tExpected: " + results.get(l));
+                    System.out.println("\tReturned: " + hashstr);
+                }
+                testresult = false;
+                continue;
+            }
+
+            // Decrypted test & results
+            r = decrypt(enc);
+            System.out.println("Decrypt data size " + l + " \tResult: " +
+                    (r ? "Pass" : "Fail"));
+            if (!r) {
+                testresult = false;
+            }
+        }
+
+        // After test complete, throw an error if there was a failure
+        if (!testresult) {
+            throw new Exception("Tests failed");
+        }
+    }
+
+    /**
+     * With no argument, the test will run the predefined data lengths
+     *
+     * With an integer argument, this test will print the hash of the encrypted
+     * data of that integer length.
+     *
+     */
+    public static void main(String args[]) throws Exception {
+        md5 = MessageDigest.getInstance("MD5");
+
+        if (args.length > 0) {
+            int len = Integer.parseInt(args[0]);
+            byte[] e = new GCMLargeDataKAT().encrypt(len);
+            System.out.println(toHex(hash(e)));
+            return;
+        }
+
+        new GCMLargeDataKAT().test();
+    }
+
+    // bytes to hex string
+    static String toHex(byte[] bytes) {
+        StringBuffer hexStringBuffer = new StringBuffer(32);
+        for (int i = 0; i < bytes.length; i++) {
+            hexStringBuffer.append(byteToHex(bytes[i]));
+        }
+        return hexStringBuffer.toString();
+    }
+    // byte to hex
+    static String byteToHex(byte num) {
+        char[] hexDigits = new char[2];
+        hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16);
+        hexDigits[1] = Character.forDigit((num & 0xF), 16);
+        return new String(hexDigits);
+    }
+}
--- a/test/com/sun/java/swing/plaf/gtk/4928019/bug4928019.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/com/sun/java/swing/plaf/gtk/4928019/bug4928019.java	Sat Oct 24 01:11:51 2020 +0100
@@ -24,6 +24,7 @@
 /*
  * @test
  * @bug 4928019
+ * @key headful
  * @summary Makes sure all the basic classes can be created with GTK.
  * @author Scott Violet
  */
--- a/test/com/sun/java/swing/plaf/gtk/Test6635110.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/com/sun/java/swing/plaf/gtk/Test6635110.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,6 +23,7 @@
 
 /* @test
    @bug 6635110
+   @key headful
    @summary GTK icons should not throw NPE when called by non-GTK UI
    @author Peter Zhelezniakov
    @run main Test6635110
--- a/test/com/sun/java/swing/plaf/gtk/Test6963870.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/com/sun/java/swing/plaf/gtk/Test6963870.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,6 +23,7 @@
 
 /* @test
    @bug 6963870
+   @key headful
    @summary Tests that GTKPainter.ListTableFocusBorder.getBorderInsets()
             doesn't return null
    @author Peter Zhelezniakov
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/jndi/ldap/LdapCtx/Reconnect.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import javax.naming.Context;
+import javax.naming.ldap.InitialLdapContext;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.Hashtable;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/*
+ * @test
+ * @bug 8217606
+ * @summary The LdapContext.reconnect method allows LDAP clients to initiate an
+ *          LDAP bind operation on the existing connection. Invoking this method
+ *          should not open a new connection under those circumstances.
+ *
+ * @library ../lib/
+ * @run main Reconnect
+ */
+public class Reconnect {
+
+    private static final byte[] BIND_RESPONSE = {
+            0x30, 0x0C, 0x02, 0x01, 0x01, 0x61, 0x07, 0x0A,
+            0x01, 0x00, 0x04, 0x00, 0x04, 0x00
+    };
+
+    /*
+     * This test checks that there's only one connection from the client to
+     * the server.
+     *
+     * The mechanics is as follows. The first connection is awaited for some
+     * generous timeout to factor in a possibility of running on a slow system.
+     * Once the connection has been made, the second timeout begins. This
+     * second timeout is smaller. The test then verifies that no further
+     * connections have been made for that amount of time.
+     */
+    public static void main(String[] args) throws Exception {
+
+        final Semaphore s = new Semaphore(0);
+
+        BaseLdapServer server = new BaseLdapServer() {
+
+            @Override
+            protected void beforeConnectionHandled(Socket socket) {
+                // Increment the number of connections from LDAP client
+                s.release(1);
+            }
+
+            @Override
+            protected void handleRequest(Socket socket,
+                                         LdapMessage msg,
+                                         OutputStream out)
+                    throws IOException
+            {
+                switch (msg.getOperation()) {
+                    case BIND_REQUEST:
+                        out.write(BIND_RESPONSE);
+                    default:
+                        break;
+                }
+            }
+        };
+
+        try (BaseLdapServer s1 = server.start()) {
+            Hashtable<String, Object> env = new Hashtable<>();
+            env.put(Context.INITIAL_CONTEXT_FACTORY,
+                    "com.sun.jndi.ldap.LdapCtxFactory");
+            env.put(Context.PROVIDER_URL,
+                    "ldap://" + InetAddress.getLoopbackAddress().getHostName()
+                            + ":" + server.getPort());
+            env.put("java.naming.ldap.version", "3");
+
+            // open connection
+            InitialLdapContext context = new InitialLdapContext(env, null);
+
+            // send bind request
+            context.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
+            context.addToEnvironment(Context.SECURITY_PRINCIPAL, "test");
+            context.addToEnvironment(Context.SECURITY_CREDENTIALS, "secret");
+
+            context.reconnect(null);
+        }
+
+        if (!s.tryAcquire(60L, TimeUnit.SECONDS)) {
+            throw new RuntimeException("No connection has been made");
+        }
+
+        if (s.tryAcquire(5L, TimeUnit.SECONDS)) {
+            throw new RuntimeException("Expected 1 connection, but found: "
+                                               + (s.availablePermits() + 2));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/jndi/ldap/lib/BaseLdapServer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.logging.*;
+import static java.util.logging.Level.*;
+
+/*
+ * A bare-bones (testing aid) server for LDAP scenarios.
+ *
+ * Override the following methods to provide customized behavior
+ *
+ *     * beforeConnectionHandled
+ *     * handleRequest (or handleRequestEx)
+ *
+ * Instances of this class are safe for use by multiple threads.
+ */
+public class BaseLdapServer implements Closeable {
+
+    private static final Logger logger = Logger.getLogger("BaseLdapServer");
+
+    private final Thread acceptingThread = new Thread(this::acceptConnections);
+    private final ServerSocket serverSocket;
+    private final List<Socket> socketList = new ArrayList<>();
+    private final ExecutorService connectionsPool;
+
+    private final Object lock = new Object();
+    /*
+     * 3-valued state to detect restarts and other programming errors.
+     */
+    private State state = State.NEW;
+
+    private enum State {
+        NEW,
+        STARTED,
+        STOPPED
+    }
+
+    public BaseLdapServer() throws IOException {
+        this(new ServerSocket(0, 0, InetAddress.getLoopbackAddress()));
+    }
+
+    public BaseLdapServer(ServerSocket serverSocket) {
+        this.serverSocket = Objects.requireNonNull(serverSocket);
+        this.connectionsPool = Executors.newCachedThreadPool();
+    }
+
+    private void acceptConnections() {
+        logger().log(INFO, "Server is accepting connections at port {0}",
+                     getPort());
+        try {
+            while (isRunning()) {
+                Socket socket = serverSocket.accept();
+                logger().log(INFO, "Accepted new connection at {0}", socket);
+                synchronized (lock) {
+                    // Recheck if the server is still running
+                    // as someone has to close the `socket`
+                    if (isRunning()) {
+                        socketList.add(socket);
+                    } else {
+                        closeSilently(socket);
+                    }
+                }
+                connectionsPool.submit(() -> handleConnection(socket));
+            }
+        } catch (IOException | RejectedExecutionException e) {
+            if (isRunning()) {
+                throw new RuntimeException(
+                        "Unexpected exception while accepting connections", e);
+            }
+        } finally {
+            logger().log(INFO, "Server stopped accepting connections at port {0}",
+                                getPort());
+        }
+    }
+
+    /*
+     * A "Template Method" describing how a connection (represented by a socket)
+     * is handled.
+     *
+     * The socket is closed immediately before the method returns (normally or
+     * abruptly).
+     */
+    private void handleConnection(Socket socket) {
+        // No need to close socket's streams separately, they will be closed
+        // automatically when `socket.close()` is called
+        beforeConnectionHandled(socket);
+        ConnWrapper connWrapper = new ConnWrapper(socket);
+        try {
+            OutputStream out = socket.getOutputStream();
+            InputStream in = socket.getInputStream();
+            byte[] inBuffer = new byte[1024];
+            int count;
+            byte[] request;
+
+            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+            int msgLen = -1;
+
+            // As inBuffer.length > 0, at least 1 byte is read
+            while ((count = in.read(inBuffer)) > 0) {
+                buffer.write(inBuffer, 0, count);
+                if (msgLen <= 0) {
+                    msgLen = LdapMessage.getMessageLength(buffer.toByteArray());
+                }
+
+                if (msgLen > 0 && buffer.size() >= msgLen) {
+                    if (buffer.size() > msgLen) {
+                        byte[] tmpBuffer = buffer.toByteArray();
+                        request = Arrays.copyOf(tmpBuffer, msgLen);
+                        buffer.reset();
+                        buffer.write(tmpBuffer, msgLen, tmpBuffer.length - msgLen);
+                    } else {
+                        request = buffer.toByteArray();
+                        buffer.reset();
+                    }
+                    msgLen = -1;
+                } else {
+                    logger.log(INFO, "Request message incomplete, " +
+                            "bytes received {0}, expected {1}", new Integer[] { buffer.size(), msgLen});
+                    continue;
+                }
+                handleRequestEx(socket, new LdapMessage(request), out, connWrapper);
+                if (connWrapper.updateRequired()) {
+                    Socket wrapper = connWrapper.getWrapper();
+                    in = wrapper.getInputStream();
+                    out = wrapper.getOutputStream();
+                    connWrapper.clearFlag();
+                }
+            }
+        } catch (Throwable t) {
+            if (!isRunning()) {
+                logger.log(INFO, "Connection Handler exit {0}", t.getMessage());
+            } else {
+                t.printStackTrace();
+            }
+        } finally {
+            if (socket != null) {
+                try {
+                    socket.close();
+                } catch (Exception e) {
+                }
+            }
+        }
+
+        if (connWrapper.getWrapper() != null) {
+            closeSilently(connWrapper.getWrapper());
+        }
+    }
+
+    /*
+     * Called first thing in `handleConnection()`.
+     *
+     * Override to customize the behavior.
+     */
+    protected void beforeConnectionHandled(Socket socket) { /* empty */ }
+
+    /*
+     * Called after an LDAP request has been read in `handleConnection()`.
+     *
+     * Override to customize the behavior.
+     */
+    protected void handleRequest(Socket socket,
+                                 LdapMessage request,
+                                 OutputStream out)
+            throws IOException
+    {
+        logger().log(INFO, "Discarding message {0} from {1}. "
+                             + "Override {2}.handleRequest to change this behavior.",
+                     new Object[] {request, socket, getClass().getName()});
+    }
+
+    /*
+     * Called after an LDAP request has been read in `handleConnection()`.
+     *
+     * Override to customize the behavior if you want to handle starttls
+     * extended op, otherwise override handleRequest method instead.
+     *
+     * This is extended handleRequest method which provide possibility to
+     * wrap current socket connection, that's necessary to handle starttls
+     * extended request, here is sample code about how to wrap current socket
+     *
+     * switch (request.getOperation()) {
+     *     ......
+     *     case EXTENDED_REQUEST:
+     *         if (new String(request.getMessage()).endsWith(STARTTLS_REQ_OID)) {
+     *             out.write(STARTTLS_RESPONSE);
+     *             SSLSocket sslSocket = (SSLSocket) sslSocketFactory
+     *                     .createSocket(socket, null, socket.getLocalPort(),
+     *                             false);
+     *             sslSocket.setUseClientMode(false);
+     *             connWrapper.setWrapper(sslSocket);
+     *         }
+     *         break;
+     *     ......
+     * }
+     */
+    protected void handleRequestEx(Socket socket,
+            LdapMessage request,
+            OutputStream out,
+            ConnWrapper connWrapper)
+            throws IOException {
+        // by default, just call handleRequest to keep compatibility
+        handleRequest(socket, request, out);
+    }
+
+    /*
+     * To be used by subclasses.
+     */
+    protected final Logger logger() {
+        return logger;
+    }
+
+    /*
+     * Starts this server. May be called only once.
+     */
+    public BaseLdapServer start() {
+        synchronized (lock) {
+            if (state != State.NEW) {
+                throw new IllegalStateException(state.toString());
+            }
+            state = State.STARTED;
+            logger().log(INFO, "Starting server at port {0}", getPort());
+            acceptingThread.start();
+            return this;
+        }
+    }
+
+    /*
+     * Stops this server.
+     *
+     * May be called at any time, even before a call to `start()`. In the latter
+     * case the subsequent call to `start()` will throw an exception. Repeated
+     * calls to this method have no effect.
+     *
+     * Stops accepting new connections, interrupts the threads serving already
+     * accepted connections and closes all the sockets.
+     */
+    @Override
+    public void close() {
+        synchronized (lock) {
+            if (state == State.STOPPED) {
+                return;
+            }
+            state = State.STOPPED;
+            logger().log(INFO, "Stopping server at port {0}", getPort());
+            acceptingThread.interrupt();
+            closeSilently(serverSocket);
+            // It's important to signal an interruption so that overridden
+            // methods have a chance to return if they use
+            // interruption-sensitive blocking operations. However, blocked I/O
+            // operations on the socket will NOT react on that, hence the socket
+            // also has to be closed to propagate shutting down.
+            connectionsPool.shutdownNow();
+            socketList.forEach(BaseLdapServer.this::closeSilently);
+        }
+    }
+
+    /**
+     * Returns the local port this server is listening at.
+     *
+     * @return the port this server is listening at
+     */
+    public int getPort() {
+        return serverSocket.getLocalPort();
+    }
+
+    /*
+     * Returns a flag to indicate whether this server is running or not.
+     *
+     * @return {@code true} if this server is running, {@code false} otherwise.
+     */
+    public boolean isRunning() {
+        synchronized (lock) {
+            return state == State.STARTED;
+        }
+    }
+
+    /*
+     * To be used by subclasses.
+     */
+    protected final void closeSilently(Closeable resource) {
+        try {
+            resource.close();
+        } catch (IOException ignored) { }
+    }
+
+    /*
+     * To be used for handling starttls extended request
+     */
+    protected class ConnWrapper {
+        private Socket original;
+        private Socket wrapper;
+        private boolean flag = false;
+
+        public ConnWrapper(Socket socket) {
+            original = socket;
+        }
+
+        public Socket getWrapper() {
+            return wrapper;
+        }
+
+        public void setWrapper(Socket wrapper) {
+            if (wrapper != null && wrapper != original) {
+                this.wrapper = wrapper;
+                flag = true;
+            }
+        }
+
+        public boolean updateRequired() {
+            return flag;
+        }
+
+        public void clearFlag() {
+            flag = false;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/jndi/ldap/lib/LdapMessage.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+/**
+ * An LDAP message.
+ */
+public class LdapMessage {
+
+    private final byte[] message;
+    private int messageID;
+    private Operation operation;
+
+    public enum Operation {
+        BIND_REQUEST(0x60, "BindRequest"),                      // [APPLICATION 0]
+        BIND_RESPONSE(0x61, "BindResponse"),                    // [APPLICATION 1]
+        UNBIND_REQUEST(0x42, "UnbindRequest"),                  // [APPLICATION 2]
+        SEARCH_REQUEST(0x63, "SearchRequest"),                  // [APPLICATION 3]
+        SEARCH_RESULT_ENTRY(0x64, "SearchResultEntry"),         // [APPLICATION 4]
+        SEARCH_RESULT_DONE(0x65, "SearchResultDone"),           // [APPLICATION 5]
+        MODIFY_REQUEST(0x66, "ModifyRequest"),                  // [APPLICATION 6]
+        MODIFY_RESPONSE(0x67, "ModifyResponse"),                // [APPLICATION 7]
+        ADD_REQUEST(0x68, "AddRequest"),                        // [APPLICATION 8]
+        ADD_RESPONSE(0x69, "AddResponse"),                      // [APPLICATION 9]
+        DELETE_REQUEST(0x4A, "DeleteRequest"),                  // [APPLICATION 10]
+        DELETE_RESPONSE(0x6B, "DeleteResponse"),                // [APPLICATION 11]
+        MODIFY_DN_REQUEST(0x6C, "ModifyDNRequest"),             // [APPLICATION 12]
+        MODIFY_DN_RESPONSE(0x6D, "ModifyDNResponse"),           // [APPLICATION 13]
+        COMPARE_REQUEST(0x6E, "CompareRequest"),                // [APPLICATION 14]
+        COMPARE_RESPONSE(0x6F, "CompareResponse"),              // [APPLICATION 15]
+        ABANDON_REQUEST(0x50, "AbandonRequest"),                // [APPLICATION 16]
+        SEARCH_RESULT_REFERENCE(0x73, "SearchResultReference"), // [APPLICATION 19]
+        EXTENDED_REQUEST(0x77, "ExtendedRequest"),              // [APPLICATION 23]
+        EXTENDED_RESPONSE(0x78, "ExtendedResponse"),            // [APPLICATION 24]
+        INTERMEDIATE_RESPONSE(0x79, "IntermediateResponse");    // [APPLICATION 25]
+
+        private final int id;
+        private final String name;
+
+        Operation(int id, String name) {
+            this.id = id;
+            this.name = name;
+        }
+
+        public int getId() {
+            return id;
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+
+        private static Operation fromId(int id) {
+            Optional<Operation> optional = Stream.of(Operation.values())
+                    .filter(o -> o.id == id).findFirst();
+            if (optional.isPresent()) {
+                return optional.get();
+            } else {
+                throw new RuntimeException(
+                        "Unknown id " + id + " for enum Operation.");
+            }
+        }
+    }
+
+    public LdapMessage(byte[] message) {
+        this.message = message;
+        parse();
+    }
+
+    public LdapMessage(String hexString) {
+        this(parseHexBinary(hexString));
+    }
+
+    // Extracts the message ID and operation ID from an LDAP protocol encoding
+    private void parse() {
+        if (message == null || message.length < 2) {
+            throw new RuntimeException(
+                    "Invalid ldap message: " + Arrays.toString(message));
+        }
+
+        if (message[0] != 0x30) {
+            throw new RuntimeException("Bad LDAP encoding in message, "
+                    + "expected ASN.1 SEQUENCE tag (0x30), encountered "
+                    + message[0]);
+        }
+
+        int index = 2;
+        if ((message[1] & 0x80) == 0x80) {
+            index += (message[1] & 0x0F);
+        }
+
+        if (message[index] != 0x02) {
+            throw new RuntimeException("Bad LDAP encoding in message, "
+                    + "expected ASN.1 INTEGER tag (0x02), encountered "
+                    + message[index]);
+        }
+        int length = message[index + 1];
+        index += 2;
+        messageID = new BigInteger(1,
+                                   Arrays.copyOfRange(message, index, index + length)).intValue();
+        index += length;
+        int operationID = message[index];
+        operation = Operation.fromId(operationID);
+    }
+
+    /**
+     * Return original ldap message in byte array.
+     *
+     * @return original ldap message
+     */
+    public byte[] getMessage() {
+        return Arrays.copyOf(message, message.length);
+    }
+
+    /**
+     * Return ldap message id.
+     *
+     * @return ldap message id.
+     */
+    public int getMessageID() {
+        return messageID;
+    }
+
+    /**
+     * Return ldap message's operation.
+     *
+     * @return ldap message's operation.
+     */
+    public Operation getOperation() {
+        return operation;
+    }
+
+    private static byte[] parseHexBinary(String s) {
+
+        final int len = s.length();
+
+        // "111" is not a valid hex encoding.
+        if (len % 2 != 0) {
+            throw new IllegalArgumentException(
+                    "hexBinary needs to be even-length: " + s);
+        }
+
+        byte[] out = new byte[len / 2];
+
+        for (int i = 0; i < len; i += 2) {
+            int h = Character.digit(s.charAt(i), 16);
+            int l = Character.digit(s.charAt(i + 1), 16);
+            if (h == -1 || l == -1) {
+                throw new IllegalArgumentException(
+                        "contains illegal character for hexBinary: " + s);
+            }
+
+            out[i / 2] = (byte) (h * 16 + l);
+        }
+
+        return out;
+    }
+
+    public static int getMessageLength(byte[] encoding) {
+        if (encoding.length < 2) {
+            // not enough data to extract msg len, just return -1
+            return -1;
+        }
+
+        if (encoding[0] != 0x30) {
+            throw new RuntimeException("Error: bad LDAP encoding message: "
+                                               + "expected ASN.1 SEQUENCE tag (0x30), encountered "
+                                               + encoding[0]);
+        }
+
+        int len;
+        int index = 1;
+        int payloadLen = 0;
+
+        if ((encoding[1] & 0x80) == 0x80) {
+            len = (encoding[1] & 0x0F);
+            index++;
+        } else {
+            len = 1;
+        }
+
+        if (len > 4) {
+            throw new RuntimeException(
+                    "Error: LDAP encoding message payload too large");
+        }
+
+        if (encoding.length < index + len) {
+            // additional data required to extract payload len, return -1
+            return -1;
+        }
+
+        for (byte b : Arrays.copyOfRange(encoding, index, index + len)) {
+            payloadLen = payloadLen << 8 | (b & 0xFF);
+        }
+
+        if (payloadLen <= 0) {
+            throw new RuntimeException(
+                    "Error: invalid LDAP encoding message length or payload too large");
+        }
+
+        return index + len + payloadLen;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/management/HotSpotDiagnosticMXBean/GetDoubleVMOption.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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     8061616
+ * @summary Basic Test for HotSpotDiagnosticMXBean.getVMOption() and double values
+ * @author  Jaroslav Bachorik
+ *
+ * @run main/othervm -XX:InitialRAMPercentage=1.5 GetDoubleVMOption
+ */
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import java.lang.management.ManagementFactory;
+import java.util.List;
+import javax.management.MBeanServer;
+
+public class GetDoubleVMOption {
+    private static final String INITIAL_RAM_PERCENTAGE = "InitialRAMPercentage";
+    private static final String EXPECTED_VALUE = "1.5";
+    private static final String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
+        "com.sun.management:type=HotSpotDiagnostic";
+
+    public static void main(String[] args) throws Exception {
+        List<HotSpotDiagnosticMXBean> list =
+            ManagementFactory.getPlatformMXBeans(HotSpotDiagnosticMXBean.class);
+        HotSpotDiagnosticMXBean mbean = list.get(0);
+        checkVMOption(mbean);
+
+        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+        mbean = ManagementFactory.newPlatformMXBeanProxy(mbs,
+                    HOTSPOT_DIAGNOSTIC_MXBEAN_NAME,
+                    HotSpotDiagnosticMXBean.class);
+        checkVMOption(mbean);
+    }
+
+    private static void checkVMOption(HotSpotDiagnosticMXBean mbean) {
+        VMOption option = mbean.getVMOption(INITIAL_RAM_PERCENTAGE);
+        if (!option.getValue().equalsIgnoreCase(EXPECTED_VALUE)) {
+            throw new RuntimeException("Unexpected value: " +
+                option.getValue() + " expected: " + EXPECTED_VALUE);
+        }
+    }
+}
--- a/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
  * 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,16 +32,15 @@
 
 import com.sun.management.HotSpotDiagnosticMXBean;
 import com.sun.management.VMOption;
-import com.sun.management.VMOption.Origin;
 import java.lang.management.ManagementFactory;
 import java.util.List;
 import javax.management.MBeanServer;
 
 public class GetVMOption {
-    private static String PRINT_GC_DETAILS = "PrintGCDetails";
-    private static String EXPECTED_VALUE = "true";
-    private static String BAD_OPTION = "BadOption";
-    private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
+    private static final String PRINT_GC_DETAILS = "PrintGCDetails";
+    private static final String EXPECTED_VALUE = "true";
+    private static final String BAD_OPTION = "BadOption";
+    private static final String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
         "com.sun.management:type=HotSpotDiagnostic";
 
     public static void main(String[] args) throws Exception {
--- a/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
  * 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,11 +39,11 @@
 import com.sun.management.VMOption.Origin;
 
 public class SetVMOption {
-    private static String PRINT_GC_DETAILS = "PrintGCDetails";
-    private static String EXPECTED_VALUE = "true";
-    private static String BAD_VALUE = "yes";
-    private static String NEW_VALUE = "false";
-    private static String MANAGEMENT_SERVER = "ManagementServer";
+    private static final String PRINT_GC_DETAILS = "PrintGCDetails";
+    private static final String EXPECTED_VALUE = "true";
+    private static final String BAD_VALUE = "yes";
+    private static final String NEW_VALUE = "false";
+    private static final String MANAGEMENT_SERVER = "ManagementServer";
     private static HotSpotDiagnosticMXBean mbean;
 
     public static void main(String[] args) throws Exception {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/EmbeddedFrame/DisplayChangedTest/DisplayChangedTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 4980592
+ @summary   switching user in XP causes an NPE in
+            sun.awt.windows.WWindowPeer.displayChanged
+ @requires (os.family == "windows")
+ @author son@sparc.spb.su: area=embedded
+ @run main DisplayChangedTest
+ */
+/**
+ * DisplayChangedTest.java
+ *
+ * summary: switching user in XP causes an NPE in
+ * sun.awt.windows.WWindowPeer.displayChanged
+ */
+import java.awt.Frame;
+import java.awt.Dialog;
+import java.awt.TextArea;
+import java.awt.peer.ComponentPeer;
+import java.awt.peer.FramePeer;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+
+import sun.awt.AWTAccessor;
+
+public class DisplayChangedTest {
+
+    /**
+     * Test fails if it throws any exception.
+     *
+     * @throws Exception
+     */
+    private void init() throws Exception {
+
+        if (!System.getProperty("os.name").startsWith("Windows")) {
+            System.out.println("This is Windows only test.");
+            return;
+        }
+
+        Frame frame = new Frame("AWT Frame");
+        frame.pack();
+
+        FramePeer frame_peer = (FramePeer) AWTAccessor.getComponentAccessor()
+                .getPeer(frame);
+        Class comp_peer_class = Class.forName("sun.awt.windows.WComponentPeer");
+        Field hwnd_field = comp_peer_class.getDeclaredField("hwnd");
+        hwnd_field.setAccessible(true);
+        long hwnd = hwnd_field.getLong(frame_peer);
+
+        Class clazz = Class.forName("sun.awt.windows.WEmbeddedFrame");
+        Constructor constructor = clazz
+                .getConstructor(new Class[]{long.class});
+        Frame embedded_frame = (Frame) constructor
+                .newInstance(new Object[]{new Long(hwnd)});
+        frame.setVisible(true);
+
+        ComponentPeer peer = AWTAccessor.getComponentAccessor().getPeer(
+                embedded_frame);
+        Class peerClass = peer.getClass();
+        Method displayChangedM = peerClass.getMethod("displayChanged",
+                new Class[0]);
+        displayChangedM.invoke(peer, null);
+        embedded_frame.dispose();
+        frame.dispose();
+
+    }
+
+    public static void main(String args[]) throws Exception {
+        new DisplayChangedTest().init();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 6345002
+ @summary grab problems with EmbeddedFrame
+ @requires (os.family == "windows")
+ @author Oleg.Semenov@sun.com area=EmbeddedFrame
+ @run main EmbeddedFrameGrabTest
+ */
+/**
+ * EmbeddedFrameGrabTest.java
+ *
+ * summary: grab problems with EmbeddedFrame
+ */
+import java.awt.Frame;
+import java.awt.peer.FramePeer;
+import javax.swing.JComboBox;
+import java.awt.Panel;
+import java.awt.BorderLayout;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.Rectangle;
+import java.awt.TextArea;
+import java.awt.Dialog;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+
+import sun.awt.AWTAccessor;
+
+public class EmbeddedFrameGrabTest {
+
+    /**
+     * Test fails if it throws any exception.
+     *
+     * @throws Exception
+     */
+    private void init() throws Exception {
+
+        if (!System.getProperty("os.name").startsWith("Windows")) {
+            System.out.println("This is Windows only test.");
+            return;
+        }
+
+        final Frame frame = new Frame("AWT Frame");
+        frame.pack();
+        frame.setSize(200, 200);
+        FramePeer frame_peer = (FramePeer) AWTAccessor.getComponentAccessor()
+                                    .getPeer(frame);
+        Class comp_peer_class
+                = Class.forName("sun.awt.windows.WComponentPeer");
+        Field hwnd_field = comp_peer_class.getDeclaredField("hwnd");
+        hwnd_field.setAccessible(true);
+        long hwnd = hwnd_field.getLong(frame_peer);
+
+        Class clazz = Class.forName("sun.awt.windows.WEmbeddedFrame");
+        Constructor constructor
+                = clazz.getConstructor(new Class[]{long.class});
+        final Frame embedded_frame
+                = (Frame) constructor.newInstance(new Object[]{
+                    new Long(hwnd)});;
+        final JComboBox<String> combo = new JComboBox<>(new String[]{
+            "Item 1", "Item 2"
+        });
+        combo.setSelectedIndex(1);
+        final Panel p = new Panel();
+        p.setLayout(new BorderLayout());
+        embedded_frame.add(p, BorderLayout.CENTER);
+        embedded_frame.validate();
+        p.add(combo);
+        p.validate();
+        frame.setVisible(true);
+        Robot robot = new Robot();
+        robot.delay(2000);
+        Rectangle clos = new Rectangle(
+                combo.getLocationOnScreen(), combo.getSize());
+        robot.mouseMove(clos.x + clos.width / 2, clos.y + clos.height / 2);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.delay(1000);
+        if (!combo.isPopupVisible()) {
+            throw new RuntimeException("Combobox popup is not visible!");
+        }
+        robot.mouseMove(clos.x + clos.width / 2, clos.y + clos.height + 3);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.delay(1000);
+        if (combo.getSelectedIndex() != 0) {
+            throw new RuntimeException("Combobox selection has not changed!");
+        }
+        embedded_frame.remove(p);
+        embedded_frame.dispose();
+        frame.dispose();
+
+    }
+
+    public static void main(String args[]) throws Exception {
+        new EmbeddedFrameGrabTest().init();
+    }
+
+}
--- a/test/java/awt/Focus/FocusTransitionTest/FocusTransitionTest.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/java/awt/Focus/FocusTransitionTest/FocusTransitionTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -21,10 +21,12 @@
  * questions.
  */
 
-/* @test
+/**
+ * @test
  * @bug 8155197
  * @summary Tests whether the value of mostRecentFocusOwner for a window is correct, if
  *          another window is displayed during focus transition
+ * @key headful
  * @library ../../regtesthelpers
  * @build Util
  * @run main FocusTransitionTest
--- a/test/java/awt/FontClass/CreateFont/fileaccess/FontFile.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/java/awt/FontClass/CreateFont/fileaccess/FontFile.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * 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,16 @@
  * @test
  * @bug 6652929
  * @summary verify handling of File.getPath()
+ * @compile FontFile.java
+ * @run shell TestFontFile.sh
+ */
+
+/*
+ * When using jtreg this test needs to be run by shell script,
+ * since otherwise jtreg reflectively invokes the main method
+ * and the codebase for the purposes of the security manager
+ * is that of the jtreg harness, not the codebase (class file location)
+ * of this program, thus access to read to that location is not available.
  */
 
 import java.awt.*;
@@ -34,10 +44,21 @@
     public static void main(String[] args) throws Exception {
         String sep = System.getProperty("file.separator");
         String fname = ".." + sep + "A.ttf";
-        String dir = System.getProperty("test.src");
+        //String dir = System.getProperty("test.src");
+        String dir = System.getenv("TESTSRC");
         if (dir != null) {
             fname = dir + sep + fname;
         }
+        //String classesDir = System.getProperty("test.classes");
+        String classesDir = System.getenv("TESTCLASSES");
+        System.out.println("classesDir="+classesDir);
+        String testfile = "somefile";
+        if (classesDir != null) {
+            testfile = classesDir + sep + testfile;
+        }
+        final String somefile = testfile;
+        System.out.println("somefile="+somefile);
+        System.out.println("userdir="+System.getProperty("user.dir"));
         final String name = fname;
         System.out.println("Will try to access " + name);
         if (!(new File(name)).canRead()) {
@@ -66,7 +87,7 @@
                             return name;
                         } else {
                             read = true;
-                            return "somefile";
+                            return somefile;
                         }
                     }
                     @Override public boolean canRead() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/FontClass/CreateFont/fileaccess/TestFontFile.sh	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,84 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# 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.
+#
+
+#!/bin/sh
+
+if [ "${TESTSRC}" = "" ]
+then TESTSRC=.
+fi
+
+if [ "${TESTJAVA}" = "" ]
+then
+  PARENT=`dirname \`which java\``
+  TESTJAVA=`dirname ${PARENT}`
+  echo "TESTJAVA not set, selecting " ${TESTJAVA}
+  echo "If this is incorrect, try setting the variable manually."
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+
+BIT_FLAG=""
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  SunOS | Linux | Darwin )
+    NULL=/dev/null
+    PS=":"
+    FS="/"
+    ## for solaris, linux it's HOME
+    FILE_LOCATION=$HOME
+    if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" ]
+    then
+        BIT_FLAG=`cat ${FILE_LOCATION}${FS}JDK64BIT`
+    fi
+    ;;
+  Windows_* | CYGWIN* )
+    NULL=NUL
+    PS=";"
+    FS="\\"
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+JEMMYPATH=${CPAPPEND}
+CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH
+
+THIS_DIR=`pwd`
+
+${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -version
+
+${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} FontFile > test.out 2>&1
+
+STATUS=$?
+
+cat test.out
+
+exit $STATUS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/FontClass/MassiveMetricsTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * @test
+ * @bug 8233097
+ * @summary Test we get non-zero metrics with large sizes.
+ * @run main MassiveMetricsTest
+ */
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.image.BufferedImage;
+
+public class MassiveMetricsTest {
+
+    public static void main(String [] args) {
+
+        GraphicsEnvironment ge =
+            GraphicsEnvironment.getLocalGraphicsEnvironment();
+        Font[] fonts = ge.getAllFonts();
+        BufferedImage bi = new BufferedImage(1,1,1);
+        Graphics2D g2d = bi.createGraphics();
+        int[] sizes = { 80, 100, 120, 600, 1600, 2400, 3600, 7200, 12000 };
+        String s = "m";
+
+        for (Font f : fonts) {
+            Font sz12Font = f.deriveFont(Font.PLAIN, 12);
+            FontMetrics sz12 = g2d.getFontMetrics(sz12Font);
+            if (sz12.stringWidth(s) == 0) {
+                continue; // code point not supported or similar.
+            }
+            boolean fail = false;
+            for (int sz : sizes) {
+                Font font = f.deriveFont(Font.PLAIN, sz);
+                FontMetrics fm = g2d.getFontMetrics(font);
+                if (fm.stringWidth(s) == 0) {
+                  fail = true;
+                  System.err.println("zero for " + font);
+                }
+            }
+            if (fail) {
+                throw new RuntimeException("Zero stringwidth");
+            }
+        }
+    }
+}
--- a/test/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,7 +23,7 @@
 
 /*
   @test
-  @bug 5089429 6982632
+  @bug 5089429 6982632 8145808
   @summary Checks that we don't crash if rendering operations and state
   changes are performed on a graphics context from different threads.
 
@@ -34,6 +34,7 @@
 import java.awt.*;
 import java.awt.image.*;
 import java.awt.geom.*;
+import java.util.concurrent.atomic.AtomicInteger;
 
 public class MTGraphicsAccessTest {
 
@@ -46,7 +47,7 @@
     static long testRunTime;
 
     volatile boolean done;
-    volatile int stillRunning;
+    AtomicInteger stillRunning = new AtomicInteger(0);
     volatile int numexceptions;
 
     Graphics2D sharedGraphics;
@@ -108,7 +109,7 @@
 
         mysleep(testRunTime);
         done = true;
-        while (stillRunning > 0) { mysleep(500); }
+        while (stillRunning.get() > 0) { mysleep(500); }
 
         if (numexceptions == 0) {
             System.err.println("Test passed");
@@ -187,7 +188,7 @@
         Runnable testRunnable;
 
         public TesterThread(Runnable testRunnable) {
-            stillRunning++;
+            stillRunning.incrementAndGet();
             this.testRunnable = testRunnable;
         }
 
@@ -203,7 +204,7 @@
                     }
                 }
             } finally {
-                stillRunning--;
+                stillRunning.decrementAndGet();
             }
         }
     }
--- a/test/java/awt/Gtk/GtkVersionTest/GtkVersionTest.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/java/awt/Gtk/GtkVersionTest/GtkVersionTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 8156121
+ * @bug 8156121 8200313
  * @summary "Fail forward" fails for GTK3 if no GTK2 available
  * @modules java.desktop/sun.awt
  * @requires (os.family == "linux")
@@ -31,8 +31,9 @@
 
 import sun.awt.UNIXToolkit;
 
-import java.awt.*;
-import java.io.*;
+import java.awt.Toolkit;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
 
 public class GtkVersionTest {
     public static class LoadGtk {
@@ -42,7 +43,7 @@
     }
 
     public static void main(String[] args) throws Exception {
-        test(null, "2");
+        test(null, "3");
         test("2", "2");
         test("2.2", "2");
         test("3", "3");
--- a/test/java/awt/Mouse/EnterExitEvents/FullscreenEnterEventTest.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/java/awt/Mouse/EnterExitEvents/FullscreenEnterEventTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -38,6 +38,7 @@
  * @bug 8013468
  * @summary Cursor does not update properly when in fullscreen mode on Mac
  *    The core reason of the issue was the lack of a mouse entered event in fullscreen
+ * @requires (os.family == "mac")
  * @library ../../regtesthelpers
  * @build Util
  * @author Petr Pchelko area=awt.event
--- a/test/java/awt/SplashScreen/FullscreenAfterSplash/FullScreenAfterSplash.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/java/awt/SplashScreen/FullscreenAfterSplash/FullScreenAfterSplash.java	Sat Oct 24 01:11:51 2020 +0100
@@ -37,6 +37,7 @@
  * @test
  * @bug 8024185
  * @summary Native Mac OS X full screen does not work after showing the splash
+ * @requires (os.family == "mac")
  * @library ../
  * @build GenerateTestImage
  * @run main GenerateTestImage
--- a/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
 # 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,7 @@
 #!/bin/ksh -p
 #
 #   @test    IOExceptionIfEncodedURLTest.sh
-#   @bug     6193279 6619458
+#   @bug     6193279 6619458 8137087
 #   @summary REGRESSION: AppletViewer throws IOException when path is encoded URL
 #   @author  Dmitry Cherepanov: area=appletviewer
 #   @run compile IOExceptionIfEncodedURLTest.java
@@ -54,7 +54,7 @@
 #Call this to run the test with a file name
 test()
  {
-   ${TESTJAVA}${FILESEP}bin${FILESEP}appletviewer -Xnosecurity ${URL} > err 2>&1 &
+   "${TESTJAVA}"${FILESEP}bin${FILESEP}appletviewer -Xnosecurity ${URL} > err 2>&1 &
    APPLET_ID=$!
    sleep 15
    kill -9 $APPLET_ID
@@ -132,7 +132,9 @@
       DEFAULT_JDK="/cygdrive/c/Program\ Files/Java/jdk1.8.0"
       FILESEP="/"
       PATHSEP=";"
-      TMP=`cd "${SystemRoot}/Temp"; echo ${PWD}`
+      TMP=`cd "${SYSTEMROOT}/Temp"; echo ${PWD}`
+      x="cygpath -m $PWD"
+      PWD=$(eval $x)
       ;;
 
     AIX )
--- a/test/java/awt/dnd/BadSerializaionTest/BadSerializationTest.java	Wed Oct 14 03:38:19 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * 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 8030050
- * @summary Validate fields on DnD class deserialization
- * @author petr.pchelko@oracle.com
- */
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
-import java.util.stream.Stream;
-
-public class BadSerializationTest {
-
-    private static final String[] badSerialized = new String[] {
-            "badAction",
-            "noEvents",
-            "nullComponent",
-            "nullDragSource",
-            "nullOrigin"
-    };
-
-    private static final String goodSerialized = "good";
-
-    public static void main(String[] args) throws Exception {
-        String testSrc = System.getProperty("test.src") + File.separator;
-        testReadObject(testSrc + goodSerialized, false);
-        Stream.of(badSerialized).forEach(file -> testReadObject(testSrc + file, true));
-    }
-
-    private static void testReadObject(String filename, boolean expectException) {
-        Exception exceptionCaught = null;
-        try (FileInputStream fileInputStream = new FileInputStream(filename);
-             ObjectInputStream ois = new ObjectInputStream(fileInputStream)) {
-            ois.readObject();
-        } catch (InvalidObjectException e) {
-            exceptionCaught = e;
-        } catch (IOException e) {
-            throw new RuntimeException("FAILED: IOException", e);
-        } catch (ClassNotFoundException e) {
-            throw new RuntimeException("FAILED: ClassNotFoundException", e);
-        }
-        if (exceptionCaught != null && !expectException) {
-            throw new RuntimeException("FAILED: UnexpectedException", exceptionCaught);
-        }
-        if (exceptionCaught == null && expectException) {
-            throw new RuntimeException("FAILED: Invalid object was created with no exception");
-        }
-    }
-}
Binary file test/java/awt/dnd/BadSerializaionTest/badAction has changed
Binary file test/java/awt/dnd/BadSerializaionTest/good has changed
Binary file test/java/awt/dnd/BadSerializaionTest/noEvents has changed
Binary file test/java/awt/dnd/BadSerializaionTest/nullComponent has changed
Binary file test/java/awt/dnd/BadSerializaionTest/nullDragSource has changed
Binary file test/java/awt/dnd/BadSerializaionTest/nullOrigin has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/dnd/BadSerializationTest/BadSerializationTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2014, 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 headful
+ * @bug 8030050 8039082
+ * @summary Validate fields on DnD class deserialization
+ */
+
+import java.awt.Point;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureRecognizer;
+import java.awt.dnd.DragSource;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.stream.Stream;
+
+import javax.swing.JPanel;
+
+import static java.awt.dnd.DnDConstants.ACTION_COPY;
+
+public class BadSerializationTest {
+
+    private static final String[] badSerialized = new String[] {
+            "badAction",
+            "noEvents",
+            "nullComponent",
+            "nullDragSource",
+            "nullOrigin"
+    };
+
+    private static final String goodSerialized = "good";
+
+    public static void main(String[] args) throws Exception {
+        if (args.length > 0 && args[0].equals("-write")) {
+            writeObjects(); //Creates the binary files for the test.
+        } else {
+            String testSrc = System.getProperty("test.src") + File.separator;
+            testReadObject(testSrc + goodSerialized, false);
+            Stream.of(badSerialized).forEach(
+                    file -> testReadObject(testSrc + file, true));
+        }
+    }
+
+    private static void testReadObject(String filename, boolean expectException) {
+        Exception exceptionCaught = null;
+        try (FileInputStream fileInputStream = new FileInputStream(filename);
+             ObjectInputStream ois = new ObjectInputStream(fileInputStream)) {
+            ois.readObject();
+        } catch (InvalidObjectException e) {
+            exceptionCaught = e;
+        } catch (IOException e) {
+            throw new RuntimeException("FAILED: IOException", e);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException("FAILED: ClassNotFoundException", e);
+        }
+        if (exceptionCaught != null && !expectException) {
+            throw new RuntimeException("FAILED: UnexpectedException", exceptionCaught);
+        }
+        if (exceptionCaught == null && expectException) {
+            throw new RuntimeException("FAILED: Invalid object was created with no exception");
+        }
+    }
+
+    /**
+     * Creates the stubs for the test. It is necessary to disable all checks in
+     * the constructors of DragGestureEvent/DragGestureRecognizer before run.
+     */
+    private static void writeObjects() throws Exception {
+        ArrayList<InputEvent> evs = new ArrayList<>();
+        Point ori = new Point();
+
+        write(new DragGestureEvent(new NothingNull(), ACTION_COPY, ori, evs),
+              "noEvents");
+
+        evs.add(new KeyEvent(new JPanel(), 0, 0, 0, 0, 'a', 0));
+
+        write(new DragGestureEvent(new NullComponent(), ACTION_COPY, ori, evs),
+              "nullComponent");
+
+        write(new DragGestureEvent(new NothingNull(), 100, ori, evs),
+              "badAction");
+
+        write(new DragGestureEvent(new NullDragSource(), ACTION_COPY, ori, evs),
+              "nullDragSource");
+
+        write(new DragGestureEvent(new NothingNull(), ACTION_COPY, null, evs),
+              "nullOrigin");
+
+        write(new DragGestureEvent(new NothingNull(), ACTION_COPY, ori, evs),
+              "good");
+    }
+
+    private static void write(Object obj, String file) throws Exception {
+        try (FileOutputStream fis = new FileOutputStream(file);
+             ObjectOutputStream ois = new ObjectOutputStream(fis)) {
+            ois.writeObject(obj);
+        }
+    }
+
+    public static final class NullDragSource extends DragGestureRecognizer {
+
+        public NullDragSource() {
+            super(null, new JPanel());
+        }
+
+        protected void registerListeners() {
+        }
+
+        protected void unregisterListeners() {
+        }
+    }
+
+    public static final class NullComponent extends DragGestureRecognizer {
+
+        public NullComponent() {
+            super(new DragSource(), null);
+        }
+
+        protected void registerListeners() {
+        }
+
+        protected void unregisterListeners() {
+        }
+    }
+
+    public static final class NothingNull extends DragGestureRecognizer {
+
+        public NothingNull() {
+            super(new DragSource(), new JPanel());
+        }
+
+        protected void registerListeners() {
+        }
+
+        protected void unregisterListeners() {
+        }
+    }
+}
Binary file test/java/awt/dnd/BadSerializationTest/badAction has changed
Binary file test/java/awt/dnd/BadSerializationTest/good has changed
Binary file test/java/awt/dnd/BadSerializationTest/noEvents has changed
Binary file test/java/awt/dnd/BadSerializationTest/nullComponent has changed
Binary file test/java/awt/dnd/BadSerializationTest/nullDragSource has changed
Binary file test/java/awt/dnd/BadSerializationTest/nullOrigin has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/SocketOption/TcpKeepAliveTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+ /*
+ * @test
+ * @bug 8194298
+ * @summary Add support for per Socket configuration of TCP keepalive
+ * @run main TcpKeepAliveTest
+ */
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.MulticastSocket;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketOption;
+import java.util.Set;
+import jdk.net.ExtendedSocketOptions;
+import jdk.net.Sockets;
+
+public class TcpKeepAliveTest {
+
+    private static final String LOCAL_HOST = "127.0.0.1";
+    private static final int DEFAULT_KEEP_ALIVE_PROBES = 7;
+    private static final int DEFAULT_KEEP_ALIVE_TIME = 1973;
+    private static final int DEFAULT_KEEP_ALIVE_INTVL = 53;
+
+    public static void main(String args[]) throws IOException {
+
+        try (ServerSocket ss = new ServerSocket(0);
+                Socket s = new Socket(LOCAL_HOST, ss.getLocalPort());
+                DatagramSocket ds = new DatagramSocket(0);
+                MulticastSocket mc = new MulticastSocket(0)) {
+            Set<SocketOption<?>> supportedOpts = Sockets.supportedOptions(ss.getClass());
+            Set<SocketOption<?>> supportedOptsClient = Sockets.supportedOptions(s.getClass());
+            Set<SocketOption<?>> supportedOptsDG = Sockets.supportedOptions(ds.getClass());
+            Set<SocketOption<?>> supportedOptsMC = Sockets.supportedOptions(mc.getClass());
+            if (supportedOpts.contains(ExtendedSocketOptions.TCP_KEEPIDLE)) {
+                Sockets.setOption(ss, ExtendedSocketOptions.TCP_KEEPIDLE, DEFAULT_KEEP_ALIVE_TIME);
+                if (Sockets.getOption(ss, ExtendedSocketOptions.TCP_KEEPIDLE) != DEFAULT_KEEP_ALIVE_TIME) {
+                    throw new RuntimeException("Test failed, TCP_KEEPIDLE should have been " + DEFAULT_KEEP_ALIVE_TIME);
+                }
+            }
+            if (supportedOpts.contains(ExtendedSocketOptions.TCP_KEEPCOUNT)) {
+                Sockets.setOption(ss, ExtendedSocketOptions.TCP_KEEPCOUNT, DEFAULT_KEEP_ALIVE_PROBES);
+                if (Sockets.getOption(ss, ExtendedSocketOptions.TCP_KEEPCOUNT) != DEFAULT_KEEP_ALIVE_PROBES) {
+                    throw new RuntimeException("Test failed, TCP_KEEPCOUNT should have been " + DEFAULT_KEEP_ALIVE_PROBES);
+                }
+            }
+            if (supportedOpts.contains(ExtendedSocketOptions.TCP_KEEPINTERVAL)) {
+                Sockets.setOption(ss, ExtendedSocketOptions.TCP_KEEPINTERVAL, DEFAULT_KEEP_ALIVE_INTVL);
+                if (Sockets.getOption(ss, ExtendedSocketOptions.TCP_KEEPINTERVAL) != DEFAULT_KEEP_ALIVE_INTVL) {
+                    throw new RuntimeException("Test failed, TCP_KEEPINTERVAL should have been " + DEFAULT_KEEP_ALIVE_INTVL);
+                }
+            }
+            if (supportedOptsClient.contains(ExtendedSocketOptions.TCP_KEEPIDLE)) {
+                Sockets.setOption(s, ExtendedSocketOptions.TCP_KEEPIDLE, DEFAULT_KEEP_ALIVE_TIME);
+                if (Sockets.getOption(s, ExtendedSocketOptions.TCP_KEEPIDLE) != DEFAULT_KEEP_ALIVE_TIME) {
+                    throw new RuntimeException("Test failed, TCP_KEEPIDLE should have been " + DEFAULT_KEEP_ALIVE_TIME);
+                }
+            }
+            if (supportedOptsClient.contains(ExtendedSocketOptions.TCP_KEEPCOUNT)) {
+                Sockets.setOption(s, ExtendedSocketOptions.TCP_KEEPCOUNT, DEFAULT_KEEP_ALIVE_PROBES);
+                if (Sockets.getOption(s, ExtendedSocketOptions.TCP_KEEPCOUNT) != DEFAULT_KEEP_ALIVE_PROBES) {
+                    throw new RuntimeException("Test failed, TCP_KEEPCOUNT should have been " + DEFAULT_KEEP_ALIVE_PROBES);
+                }
+            }
+            if (supportedOptsClient.contains(ExtendedSocketOptions.TCP_KEEPINTERVAL)) {
+                Sockets.setOption(s, ExtendedSocketOptions.TCP_KEEPINTERVAL, DEFAULT_KEEP_ALIVE_INTVL);
+                if (Sockets.getOption(s, ExtendedSocketOptions.TCP_KEEPINTERVAL) != DEFAULT_KEEP_ALIVE_INTVL) {
+                    throw new RuntimeException("Test failed, TCP_KEEPINTERVAL should have been " + DEFAULT_KEEP_ALIVE_INTVL);
+                }
+            }
+            if (supportedOptsDG.contains(ExtendedSocketOptions.TCP_KEEPCOUNT)) {
+                throw new RuntimeException("Test failed, TCP_KEEPCOUNT is applicable"
+                        + " for TCP Sockets only.");
+            }
+            if (supportedOptsDG.contains(ExtendedSocketOptions.TCP_KEEPIDLE)) {
+                throw new RuntimeException("Test failed, TCP_KEEPIDLE is applicable"
+                        + " for TCP Sockets only.");
+            }
+            if (supportedOptsDG.contains(ExtendedSocketOptions.TCP_KEEPINTERVAL)) {
+                throw new RuntimeException("Test failed, TCP_KEEPINTERVAL is applicable"
+                        + " for TCP Sockets only.");
+            }
+            if (supportedOptsMC.contains(ExtendedSocketOptions.TCP_KEEPCOUNT)) {
+                throw new RuntimeException("Test failed, TCP_KEEPCOUNT is applicable"
+                        + " for TCP Sockets only");
+            }
+            if (supportedOptsMC.contains(ExtendedSocketOptions.TCP_KEEPIDLE)) {
+                throw new RuntimeException("Test failed, TCP_KEEPIDLE is applicable"
+                        + " for TCP Sockets only");
+            }
+            if (supportedOptsMC.contains(ExtendedSocketOptions.TCP_KEEPINTERVAL)) {
+                throw new RuntimeException("Test failed, TCP_KEEPINTERVAL is applicable"
+                        + " for TCP Sockets only");
+            }
+        }
+    }
+}
--- a/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -31,10 +31,15 @@
 import java.net.*;
 import static java.net.StandardSocketOptions.*;
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicReference;
+import static jdk.net.ExtendedSocketOptions.TCP_KEEPCOUNT;
+import static jdk.net.ExtendedSocketOptions.TCP_KEEPIDLE;
+import static jdk.net.ExtendedSocketOptions.TCP_KEEPINTERVAL;
 
 public class Basic {
 
@@ -156,6 +161,16 @@
             checkOption(ch, SO_REUSEADDR, true);
             ch.setOption(SO_REUSEADDR, false);
             checkOption(ch, SO_REUSEADDR, false);
+            List<SocketOption<?>> extOptions = Arrays.asList(TCP_KEEPCOUNT,
+                    TCP_KEEPIDLE, TCP_KEEPINTERVAL);
+            if (options.containsAll(extOptions)) {
+                ch.setOption(TCP_KEEPIDLE, 1234);
+                checkOption(ch, TCP_KEEPIDLE, 1234);
+                ch.setOption(TCP_KEEPINTERVAL, 123);
+                checkOption(ch, TCP_KEEPINTERVAL, 123);
+                ch.setOption(TCP_KEEPCOUNT, 7);
+                checkOption(ch, TCP_KEEPCOUNT, 7);
+            }
         } finally {
             ch.close();
         }
--- a/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Sat Oct 24 01:11:51 2020 +0100
@@ -30,13 +30,17 @@
 
 import java.nio.ByteBuffer;
 import java.nio.channels.*;
-import static java.net.StandardSocketOptions.*;
 import java.net.*;
+import java.util.Arrays;
 import java.util.Random;
+import java.util.Set;
+import java.util.List;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
 import java.io.Closeable;
 import java.io.IOException;
+import static java.net.StandardSocketOptions.*;
+import static jdk.net.ExtendedSocketOptions.*;
 
 public class Basic {
     static final Random rand = new Random();
@@ -165,6 +169,25 @@
             // read others (can't check as actual value is implementation dependent)
             ch.getOption(SO_RCVBUF);
             ch.getOption(SO_SNDBUF);
+            Set<SocketOption<?>> options = ch.supportedOptions();
+            List<SocketOption<?>> extOptions = Arrays.asList(TCP_KEEPCOUNT,
+                    TCP_KEEPIDLE, TCP_KEEPINTERVAL);
+            if (options.containsAll(extOptions)) {
+                ch.setOption(TCP_KEEPIDLE, 1234);
+                checkOption(ch, TCP_KEEPIDLE, 1234);
+                ch.setOption(TCP_KEEPINTERVAL, 123);
+                checkOption(ch, TCP_KEEPINTERVAL, 123);
+                ch.setOption(TCP_KEEPCOUNT, 7);
+                checkOption(ch, TCP_KEEPCOUNT, 7);
+            }
+        }
+    }
+
+    static void checkOption(AsynchronousSocketChannel sc, SocketOption name, Object expectedValue)
+            throws IOException {
+        Object value = sc.getOption(name);
+        if (!value.equals(expectedValue)) {
+            throw new RuntimeException("value not as expected");
         }
     }
 
--- a/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -33,9 +33,14 @@
 import java.io.IOException;
 import java.util.*;
 import static java.net.StandardSocketOptions.*;
+import static jdk.net.ExtendedSocketOptions.*;
 
 public class SocketOptionTests {
 
+    private static final int DEFAULT_KEEP_ALIVE_PROBES = 7;
+    private static final int DEFAULT_KEEP_ALIVE_TIME = 1973;
+    private static final int DEFAULT_KEEP_ALIVE_INTVL = 53;
+
     static void checkOption(ServerSocketChannel ssc, SocketOption name, Object expectedValue)
         throws IOException
     {
@@ -76,6 +81,17 @@
             throw new RuntimeException("NullPointerException not thrown");
         } catch (NullPointerException x) {
         }
+        List<SocketOption<?>> keepAliveOpts = Arrays.asList(TCP_KEEPCOUNT, TCP_KEEPIDLE,
+                                                            TCP_KEEPINTERVAL);
+        if (ssc.supportedOptions().containsAll(keepAliveOpts)) {
+            ssc.setOption(TCP_KEEPCOUNT, DEFAULT_KEEP_ALIVE_PROBES);
+            checkOption(ssc, TCP_KEEPCOUNT, DEFAULT_KEEP_ALIVE_PROBES);
+            ssc.setOption(TCP_KEEPIDLE, DEFAULT_KEEP_ALIVE_TIME);
+            checkOption(ssc, TCP_KEEPIDLE, DEFAULT_KEEP_ALIVE_TIME);
+            ssc.setOption(TCP_KEEPINTERVAL, DEFAULT_KEEP_ALIVE_INTVL);
+            checkOption(ssc, TCP_KEEPINTERVAL, DEFAULT_KEEP_ALIVE_INTVL);
+
+        }
 
         // ClosedChannelException
         ssc.close();
--- a/test/java/nio/channels/SocketChannel/SocketOptionTests.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/java/nio/channels/SocketChannel/SocketOptionTests.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -32,7 +32,9 @@
 import java.net.*;
 import java.io.IOException;
 import java.util.*;
+import sun.net.ExtendedOptionsHelper;
 import static java.net.StandardSocketOptions.*;
+import static jdk.net.ExtendedSocketOptions.*;
 
 public class SocketOptionTests {
 
@@ -49,8 +51,20 @@
 
         // check supported options
         Set<SocketOption<?>> options = sc.supportedOptions();
-        List<? extends SocketOption> expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF,
-            SO_KEEPALIVE, SO_REUSEADDR, SO_LINGER, TCP_NODELAY);
+
+        List<SocketOption<?>> extOptions = Arrays.asList(TCP_KEEPCOUNT, TCP_KEEPIDLE,
+                                                         TCP_KEEPINTERVAL);
+        List<? extends SocketOption> expected;
+        boolean keepAliveOptsupported;
+        if (keepAliveOptsupported=ExtendedOptionsHelper.keepAliveOptions()
+                .containsAll(extOptions)) {
+            expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF, SO_KEEPALIVE,
+                    SO_REUSEADDR, SO_LINGER, TCP_NODELAY, TCP_KEEPCOUNT,
+                    TCP_KEEPIDLE, TCP_KEEPINTERVAL);
+        } else {
+            expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF, SO_KEEPALIVE,
+                    SO_REUSEADDR, SO_LINGER, TCP_NODELAY);
+        }
         for (SocketOption opt: expected) {
             if (!options.contains(opt))
                 throw new RuntimeException(opt.name() + " should be supported");
@@ -114,7 +128,14 @@
             throw new RuntimeException("expected linger to be disabled");
         sc.setOption(TCP_NODELAY, true);        // can't check
         sc.setOption(TCP_NODELAY, false);       // can't check
-
+        if (keepAliveOptsupported) {
+            sc.setOption(TCP_KEEPIDLE, 1234);
+            checkOption(sc, TCP_KEEPIDLE, 1234);
+            sc.setOption(TCP_KEEPINTERVAL, 123);
+            checkOption(sc, TCP_KEEPINTERVAL, 123);
+            sc.setOption(TCP_KEEPCOUNT, 7);
+            checkOption(sc, TCP_KEEPCOUNT, 7);
+        }
         // NullPointerException
         try {
             sc.setOption(null, "value");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Scanner/ScanTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,1502 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 4313885 4926319 4927634 5032610 5032622 5049968 5059533 6223711 6277261 6269946 6288823
+ * @summary Basic tests of java.util.Scanner methods
+ * @key randomness
+ * @run main/othervm ScanTest
+ */
+
+import java.util.*;
+import java.text.*;
+import java.io.*;
+import java.nio.*;
+import java.util.regex.*;
+import java.math.*;
+
+public class ScanTest {
+
+    private static boolean failure = false;
+    private static int failCount = 0;
+    private static int NUM_SOURCE_TYPES = 2;
+
+    public static void main(String[] args) throws Exception {
+        Locale reservedLocale = Locale.getDefault();
+        String lang = reservedLocale.getLanguage();
+        try {
+            if (!"en".equals(lang) &&
+                !"zh".equals(lang) &&
+                !"ko".equals(lang) &&
+                !"ja".equals(lang)) {
+                //Before we have resource to improve the test to be ready for
+                //arbitrary locale, force the default locale to be "English"
+                //for now.
+                Locale.setDefault(Locale.ENGLISH);
+            }
+            skipTest();
+            findInLineTest();
+            findWithinHorizonTest();
+            findInEmptyLineTest();
+            removeTest();
+            fromFileTest();
+            ioExceptionTest();
+            matchTest();
+            delimiterTest();
+            useLocaleTest();
+            closeTest();
+            cacheTest();
+            cacheTest2();
+            nonASCIITest();
+            resetTest();
+
+            for (int j=0; j<NUM_SOURCE_TYPES; j++) {
+                hasNextTest(j);
+                nextTest(j);
+                hasNextPatternTest(j);
+                nextPatternTest(j);
+                booleanTest(j);
+                byteTest(j);
+                shortTest(j);
+                intTest(j);
+                longTest(j);
+                floatTest(j);
+                doubleTest(j);
+                integerPatternTest(j);
+                floatPatternTest(j);
+                bigIntegerPatternTest(j);
+                bigDecimalPatternTest(j);
+                hasNextLineTest(j);
+                nextLineTest(j);
+                singleDelimTest(j);
+            }
+
+            // Examples
+            //example1();
+            //example2();
+            //example3();
+
+            // Usage cases
+            useCase1();
+            useCase2();
+            useCase3();
+            useCase4();
+            useCase5();
+
+            if (failure)
+                throw new RuntimeException("Failure in the scanning tests.");
+            else
+                System.err.println("OKAY: All tests passed.");
+        } finally {
+            // restore the default locale
+            Locale.setDefault(reservedLocale);
+        }
+    }
+
+    public static void useCase1() throws Exception {
+        File f = new File(System.getProperty("test.src", "."), "input.txt");
+        Scanner sc = new Scanner(f);
+        sc.findWithinHorizon("usage case 1", 0);
+        String[] names = new String[4];
+        for (int i=0; i<4; i++) {
+            while(sc.hasNextFloat())
+                sc.nextFloat();
+            names[i] = sc.next();
+            sc.nextLine();
+        }
+        if (!names[0].equals("Frank"))
+            failCount++;
+        if (!names[1].equals("Joe"))
+            failCount++;
+        if (!names[2].equals("Mary"))
+            failCount++;
+        if (!names[3].equals("Michelle"))
+            failCount++;
+        sc.close();
+        report("Use case 1");
+    }
+
+    public static void useCase2() throws Exception {
+        File f = new File(System.getProperty("test.src", "."), "input.txt");
+        Scanner sc = new Scanner(f).useDelimiter("-");
+        String testDataTag = sc.findWithinHorizon("usage case 2\n", 0);
+        if (!testDataTag.equals("usage case 2\n"))
+            failCount++;
+        if (!sc.next().equals("cat"))
+            failCount++;
+        if (sc.nextInt() != 9)
+            failCount++;
+        if (!sc.next().equals("dog"))
+            failCount++;
+        if (sc.nextInt() != 6)
+            failCount++;
+        if (!sc.next().equals("pig"))
+            failCount++;
+        if (sc.nextInt() != 2)
+            failCount++;
+        if (!sc.next().equals(""))
+            failCount++;
+        if (sc.nextInt() != 5)
+            failCount++;
+        sc.close();
+        report("Use case 2");
+    }
+
+    public static void useCase3() throws Exception {
+        File f = new File(System.getProperty("test.src", "."), "input.txt");
+        Scanner sc = new Scanner(f);
+        String testDataTag = sc.findWithinHorizon("usage case 3\n", 0);
+        if (!testDataTag.equals("usage case 3\n"))
+            failCount++;
+        Pattern tagPattern = Pattern.compile("@[a-z]+");
+        Pattern endPattern = Pattern.compile("\\*\\/");
+        String tag;
+        String end = sc.findInLine(endPattern);
+
+        while (end == null) {
+            if ((tag = sc.findInLine(tagPattern)) != null) {
+                String text = sc.nextLine();
+                text = text.substring(0, text.length() - 1);
+                //System.out.println(text);
+            } else {
+                sc.nextLine();
+            }
+            end = sc.findInLine(endPattern);
+        }
+        report("Use case 3");
+    }
+
+    public static void useCase4() throws Exception {
+        File f = new File(System.getProperty("test.src", "."), "input.txt");
+        Scanner sc = new Scanner(f);
+        String testDataTag = sc.findWithinHorizon("usage case 4\n", 0);
+        if (!testDataTag.equals("usage case 4\n"))
+            failCount++;
+
+        // Read some text parts of four hrefs
+        String[] expected = { "Diffs", "Sdiffs", "Old", "New" };
+        for (int i=0; i<4; i++) {
+            sc.findWithinHorizon("<a href", 1000);
+            sc.useDelimiter("[<>\n]+");
+            sc.next();
+            String textOfRef = sc.next();
+            if (!textOfRef.equals(expected[i]))
+                failCount++;
+        }
+        // Read some html tags using < and > as delimiters
+        if (!sc.next().equals("/a"))
+            failCount++;
+        if (!sc.next().equals("b"))
+            failCount++;
+
+        // Scan some html tags using skip and next
+        Pattern nonTagStart = Pattern.compile("[^<]+");
+        Pattern tag = Pattern.compile("<[^>]+?>");
+        Pattern spotAfterTag = Pattern.compile("(?<=>)");
+        String[] expected2 = { "</b>", "<p>", "<ul>", "<li>" };
+        sc.useDelimiter(spotAfterTag);
+        int tagsFound = 0;
+        while(tagsFound < 4) {
+            if (!sc.hasNext(tag)) {
+                // skip text between tags
+                sc.skip(nonTagStart);
+            }
+            String tagContents = sc.next(tag);
+            if (!tagContents.equals(expected2[tagsFound]))
+                failCount++;
+            tagsFound++;
+        }
+
+        report("Use case 4");
+    }
+
+    public static void useCase5() throws Exception {
+        File f = new File(System.getProperty("test.src", "."), "input.txt");
+        Scanner sc = new Scanner(f);
+        String testDataTag = sc.findWithinHorizon("usage case 5\n", 0);
+        if (!testDataTag.equals("usage case 5\n"))
+            failCount++;
+
+        sc.findWithinHorizon("Share Definitions", 0);
+        sc.nextLine();
+        sc.next("\\[([a-z]+)\\]");
+        String shareName = sc.match().group(1);
+        if (!shareName.equals("homes"))
+            failCount++;
+
+        String[] keys = { "comment", "browseable", "writable", "valid users" };
+        String[] vals = { "Home Directories", "no", "yes", "%S" };
+        for (int i=0; i<4; i++) {
+            sc.useDelimiter("=");
+            String key = sc.next().trim();
+            if (!key.equals(keys[i]))
+                failCount++;
+            sc.skip("[ =]+");
+            sc.useDelimiter("\n");
+            String value = sc.next();
+            if (!value.equals(vals[i]))
+                failCount++;
+            sc.nextLine();
+        }
+
+        report("Use case 5");
+    }
+
+    public static void nonASCIITest() throws Exception {
+        String yourBasicTibetanNumberZero = "\u0f20";
+        String yourBasicTibetanFloatingNumber = "\u0f23.\u0f27";
+        String weirdMixtureOfTibetanAndASCII = "\u0f23.7";
+        String weirdMixtureOfASCIIAndTibetan = "3.\u0f27";
+        Scanner sc = new Scanner(yourBasicTibetanNumberZero);
+        int i = sc.nextInt();
+        if (i != 0)
+            failCount++;
+        sc = new Scanner(yourBasicTibetanFloatingNumber);
+        float f = sc.nextFloat();
+        if (f != Float.parseFloat("3.7"))
+            failCount++;
+        sc = new Scanner(weirdMixtureOfTibetanAndASCII);
+        f = sc.nextFloat();
+        if (f != Float.parseFloat("3.7"))
+            failCount++;
+        sc = new Scanner(weirdMixtureOfASCIIAndTibetan);
+        f = sc.nextFloat();
+        if (f != Float.parseFloat("3.7"))
+            failCount++;
+        report("Scanning non ASCII digits");
+    }
+
+    public static void findWithinHorizonTest() throws Exception {
+        // Test with a string source
+        Scanner sc = new Scanner("dog  cat     cat    dog     cat");
+        try {
+            sc.findWithinHorizon("dog", -1);
+            failCount++;
+        } catch (IllegalArgumentException iae) {
+            // Correct result
+        }
+        if (sc.findWithinHorizon("dog", 2) != null)
+            failCount++;
+        if (!sc.findWithinHorizon("dog", 3).equals("dog"))
+            failCount++;
+        if (sc.findWithinHorizon("cat", 4) != null)
+            failCount++;
+        if (!sc.findWithinHorizon("cat", 5).equals("cat"))
+            failCount++;
+         if (sc.findWithinHorizon("cat", 7) != null)
+            failCount++;
+        if (sc.findWithinHorizon("dog", 7) != null)
+            failCount++;
+        if (!sc.findWithinHorizon("cat", 0).equals("cat"))
+            failCount++;
+        if (!sc.findWithinHorizon("dog", 0).equals("dog"))
+            failCount++;
+        if (!sc.findWithinHorizon("cat", 0).equals("cat"))
+            failCount++;
+
+        // Test with a stream source
+        StutteringInputStream stutter = new StutteringInputStream();
+        for (int index=0; index<stutter.length(); index++) {
+            //System.out.println("index is now "+index);
+            sc = new Scanner(stutter);
+            String word = stutter.wordInIndex(index);
+            if (word != null) {
+                String result = sc.findWithinHorizon(word, index);
+                if ((result == null) || (!result.equals(word)))
+                    failCount++;
+            }
+            stutter.reset();
+            word = stutter.wordBeyondIndex(index);
+            sc = new Scanner(stutter);
+            String result = sc.findWithinHorizon(word, index);
+            if ((result != null) && (index > 0))
+                failCount++;
+            stutter.reset();
+        }
+
+        // We must loop to let StutteringInputStream do its magic
+        for (int j=0; j<10; j++) {
+            // An anchor at the end of stream should work
+            stutter.reset();
+            sc = new Scanner(stutter);
+            String result = sc.findWithinHorizon("phant$", 0);
+            if (!result.equals("phant"))
+                failCount++;
+            stutter.reset();
+            sc = new Scanner(stutter);
+            result = sc.findWithinHorizon("phant$", 54);
+            if (!result.equals("phant"))
+                failCount++;
+            // An anchor at the end of horizon should not
+            stutter.reset();
+            sc = new Scanner(stutter);
+            result = sc.findWithinHorizon("brummer$", 7);
+            if (result != null)
+                failCount++;
+            // An anchor at start should work
+            stutter.reset();
+            sc = new Scanner(stutter);
+            result = sc.findWithinHorizon("^brummer", 0);
+            if (!result.equals("brummer"))
+                failCount++;
+        }
+
+        report("Find to horizon test");
+    }
+
+    // StutteringInputStream returns 1 to 3 characters at a time
+    static class StutteringInputStream implements Readable {
+        StutteringInputStream() {
+            text = "brummer hisser tort zardzard rantrant caimagator phant";
+            datalen = 54;
+        }
+        StutteringInputStream(String text) {
+            this.text = text;
+            datalen = text.length();
+        }
+        Random generator = new Random();
+        String text;
+        int datalen;
+        int index = 0;
+        public int length() {
+            return datalen;
+        }
+        public void reset() {
+            index = 0;
+        }
+        public String wordInIndex(int index) {
+            if (index < 7)  return null;
+            if (index < 14) return "brummer";
+            if (index < 19) return "hisser";
+            if (index < 28) return "tort";
+            if (index < 37) return "zardzard";
+            if (index < 48) return "rantrant";
+            return "caimagator";
+        }
+        public String wordBeyondIndex(int index) {
+            if (index < 7)  return "brummer";
+            if (index < 14) return "hisser";
+            if (index < 19) return "tort";
+            if (index < 28) return "zardzard";
+            if (index < 37) return "rantrant";
+            if (index < 48) return "caimagator";
+            return "phantphant";
+        }
+        public int read(java.nio.CharBuffer target) throws IOException {
+            if (index > datalen-1)
+                return -1; // EOS
+            int len = target.remaining();
+            if (len > 4) // return 1 to 3 characters
+                len = generator.nextInt(3) + 1;
+            while ((index + len) > datalen)
+                len--;
+            for (int i=0; i<len; i++)
+                target.put(text.charAt(index++));
+            return len;
+        }
+    }
+
+    public static void hasNextLineTest(int sourceType) throws Exception {
+        Scanner sc = scannerFor("1\n2\n3 3\r\n4 4 4\r5", sourceType);
+        if (!sc.hasNextLine()) failCount++;
+        if (!sc.nextLine().equals("1")) failCount++;
+        if (!sc.hasNextLine()) failCount++;
+        if (sc.nextInt() != 2) failCount++;
+        if (!sc.hasNextLine()) failCount++;
+        if (!sc.nextLine().equals("")) failCount++;
+        if (!sc.hasNextLine()) failCount++;
+        if (sc.nextInt() != 3) failCount++;
+        if (!sc.hasNextLine()) failCount++;
+        if (!sc.nextLine().equals(" 3")) failCount++;
+        if (!sc.hasNextLine()) failCount++;
+        if (sc.nextInt() != 4) failCount++;
+        if (!sc.hasNextLine()) failCount++;
+        if (sc.nextInt() != 4) failCount++;
+        if (!sc.hasNextLine()) failCount++;
+        if (!sc.nextLine().equals(" 4")) failCount++;
+        if (!sc.hasNextLine()) failCount++;
+        if (!sc.nextLine().equals("5")) failCount++;
+        if (sc.hasNextLine()) failCount++;
+        sc = new Scanner("blah blah blah blah blah blah");
+        if (!sc.hasNextLine()) failCount++;
+        if (!sc.nextLine().equals("blah blah blah blah blah blah"))
+           failCount++;
+        if (sc.hasNextLine()) failCount++;
+
+        // Go through all the lines in a file
+        File f = new File(System.getProperty("test.src", "."), "input.txt");
+        sc = new Scanner(f);
+        String lastLine = "blah";
+        while(sc.hasNextLine())
+            lastLine = sc.nextLine();
+        if (!lastLine.equals("# Data for usage case 6")) failCount++;
+
+        report("Has next line test");
+    }
+
+    public static void nextLineTest(int sourceType) throws Exception {
+        Scanner sc = scannerFor("1\n2\n3 3\r\n4 4 4\r5", sourceType);
+        if (!sc.nextLine().equals("1"))
+            failCount++;
+        if (sc.nextInt() != 2)
+            failCount++;
+        if (!sc.nextLine().equals(""))
+           failCount++;
+        if (sc.nextInt() != 3)
+            failCount++;
+        if (!sc.nextLine().equals(" 3"))
+           failCount++;
+        if (sc.nextInt() != 4)
+            failCount++;
+        if (sc.nextInt() != 4)
+            failCount++;
+        if (!sc.nextLine().equals(" 4"))
+           failCount++;
+        if (!sc.nextLine().equals("5"))
+           failCount++;
+        sc = new Scanner("blah blah blah blah blah blah");
+        if (!sc.nextLine().equals("blah blah blah blah blah blah"))
+           failCount++;
+        report("Next line test");
+    }
+
+    public static void singleDelimTest(int sourceType) throws Exception {
+        Scanner sc = scannerFor("12 13  14   15    16     17      ",
+                                sourceType);
+        sc.useDelimiter(" ");
+        for (int i=0; i<6; i++) {
+            int j = sc.nextInt();
+            if (j != 12 + i)
+                failCount++;
+            for (int k=0; k<i; k++) {
+                String empty = sc.next();
+                if (!empty.equals(""))
+                    failCount++;
+            }
+        }
+        report("Single delim test");
+    }
+
+    /*
+     * The hasNextPattern caches a match of a pattern called the regular cache
+     * The hasNextType caches a match of that type called the type cache
+     * Any next must clear the caches whether it uses them or not, because
+     * it advances past a token thus invalidating any cached token; any
+     * hasNext must set a cache to what it finds.
+     */
+    public static void cacheTest() throws Exception {
+        // Test clearing of the type cache
+        Scanner scanner = new Scanner("777 dog");
+        scanner.hasNextInt();
+        scanner.findInLine("777");
+        try {
+            scanner.nextInt();
+            System.out.println("type cache not cleared by find");
+            failCount++;
+        } catch (InputMismatchException ime) {
+            // Correct
+        }
+
+        scanner = new Scanner("777 dog");
+        scanner.hasNextInt();
+        scanner.skip("777");
+        try {
+            scanner.nextInt();
+            System.out.println("type cache not cleared by skip");
+            failCount++;
+        } catch (InputMismatchException ime) {
+            // Correct
+        }
+
+        // Test clearing of the regular cache
+        scanner = new Scanner("777 dog");
+        scanner.hasNext("777");
+        scanner.findInLine("777");
+        try {
+            scanner.next("777");
+            System.out.println("regular cache not cleared by find");
+            failCount++;
+        } catch (InputMismatchException ime) {
+            // Correct
+        }
+
+        // Test two primitive next clearing of type cache
+        scanner = new Scanner("777 dog");
+        scanner.hasNextInt();
+        scanner.nextLong();
+        try {
+            scanner.nextInt();
+            System.out.println("type cache not cleared by primitive next");
+            failCount++;
+        } catch (InputMismatchException ime) {
+            // Correct
+        }
+
+        // Test using both of them, type first
+        scanner = new Scanner("777 dog");
+        scanner.hasNext("777");
+        scanner.nextInt();
+        try {
+            scanner.next("777");
+            System.out.println("regular cache not cleared by primitive next");
+            failCount++;
+        } catch (InputMismatchException ime) {
+            // Correct
+        }
+
+        // Test using both of them, regular first
+        scanner = new Scanner("777 dog");
+        scanner.hasNext("777");
+        scanner.hasNextInt();
+        scanner.next("777");
+        try {
+            scanner.nextInt();
+            System.out.println("type cache not cleared by regular next");
+            failCount++;
+        } catch (InputMismatchException ime) {
+            // Correct
+        }
+        report("Cache test");
+    }
+
+    /*
+     * The hasNext<IntegerType>(radix) method caches a matched integer type
+     * with specified radix for the next next<IntegerType>(radix) invoke.
+     * The cache value should not be used if the next<IntegerType>(radix)
+     * has different radix value with the last hasNext<IntegerType>(radix).
+     */
+    public static void cacheTest2() throws Exception {
+        // Test clearing of the type cache
+        Scanner scanner = new Scanner("10");
+        scanner.hasNextByte(16);
+        if (scanner.nextByte(10) != 10) {
+            System.out.println("wrong radix cache is used");
+            failCount++;
+        }
+        scanner = new Scanner("10");
+        scanner.hasNextShort(16);
+        if (scanner.nextShort(10) != 10) {
+            System.out.println("wrong radix cache is used");
+            failCount++;
+        }
+        scanner = new Scanner("10");
+        scanner.hasNextInt(16);
+        if (scanner.nextInt(10) != 10) {
+            System.out.println("wrong radix cache is used");
+            failCount++;
+        }
+        scanner = new Scanner("10");
+        scanner.hasNextLong(16);
+        if (scanner.nextLong(10) != 10) {
+            System.out.println("wrong radix cache is used");
+            failCount++;
+        }
+        scanner = new Scanner("10");
+        scanner.hasNextBigInteger(16);
+        if (scanner.nextBigInteger(10).intValue() != 10) {
+            System.out.println("wrong radix cache is used");
+            failCount++;
+        }
+        report("Cache test2");
+    }
+
+
+    public static void closeTest() throws Exception {
+        Scanner sc = new Scanner("testing");
+        sc.close();
+        sc.ioException();
+        sc.delimiter();
+        sc.useDelimiter("blah");
+        sc.useDelimiter(Pattern.compile("blah"));
+        for (int i=0; i<NUM_METHODS; i++) {
+            try {
+                methodCall(sc, i);
+                failCount++;
+            } catch (IllegalStateException ise) {
+                // Correct
+            }
+        }
+        report("Close test");
+    }
+
+    private static int NUM_METHODS = 23;
+
+    private static void methodCall(Scanner sc, int i) {
+        switch(i) {
+            case 0: sc.hasNext(); break;
+            case 1: sc.next(); break;
+            case 2: sc.hasNext(Pattern.compile("blah")); break;
+            case 3: sc.next(Pattern.compile("blah")); break;
+            case 4: sc.hasNextBoolean(); break;
+            case 5: sc.nextBoolean(); break;
+            case 6: sc.hasNextByte(); break;
+            case 7: sc.nextByte(); break;
+            case 8: sc.hasNextShort(); break;
+            case 9: sc.nextShort(); break;
+            case 10: sc.hasNextInt(); break;
+            case 11: sc.nextInt(); break;
+            case 12: sc.hasNextLong(); break;
+            case 13: sc.nextLong(); break;
+            case 14: sc.hasNextFloat(); break;
+            case 15: sc.nextFloat(); break;
+            case 16: sc.hasNextDouble(); break;
+            case 17: sc.nextDouble(); break;
+            case 18: sc.hasNextBigInteger(); break;
+            case 19: sc.nextBigInteger(); break;
+            case 20: sc.hasNextBigDecimal(); break;
+            case 21: sc.nextBigDecimal(); break;
+            case 22: sc.hasNextLine(); break;
+            default:
+                break;
+        }
+    }
+
+    public static void removeTest() throws Exception {
+        Scanner sc = new Scanner("testing");
+        try {
+            sc.remove();
+            failCount++;
+        } catch (UnsupportedOperationException uoe) {
+            // Correct result
+        }
+        report("Remove test");
+    }
+
+    public static void delimiterTest() throws Exception {
+        Scanner sc = new Scanner("blah");
+        Pattern test = sc.delimiter();
+        if (!test.toString().equals("\\p{javaWhitespace}+"))
+            failCount++;
+        sc.useDelimiter("a");
+        test = sc.delimiter();
+        if (!test.toString().equals("a"))
+            failCount++;
+        sc.useDelimiter(Pattern.compile("b"));
+        test = sc.delimiter();
+        if (!test.toString().equals("b"))
+            failCount++;
+        report("Delimiter test");
+    }
+
+    public static void ioExceptionTest() throws Exception {
+        Readable thrower = new ThrowingReadable();
+        Scanner sc = new Scanner(thrower);
+        try {
+            sc.nextInt();
+            failCount++;
+        } catch (NoSuchElementException nsee) {
+            // Correct result
+        }
+        Exception thrown = sc.ioException();
+        String detail = thrown.getMessage();
+        if (!detail.equals("ThrowingReadable always throws"))
+            failCount++;
+
+        report("IOException test");
+    }
+
+    public static void bigIntegerPatternTest(int sourceType) throws Exception {
+        Scanner sc = scannerFor("23 9223372036854775817", sourceType);
+        if (!sc.nextBigInteger().equals(BigInteger.valueOf(23)))
+            failCount++;
+        if (!sc.nextBigInteger().equals(new BigInteger(
+            "9223372036854775817", 10)))
+            failCount++;
+
+        // Test another radix
+        sc = new Scanner("4a4 4A4").useRadix(16);
+        if (!sc.nextBigInteger().equals(new BigInteger("4a4", 16)))
+            failCount++;
+        if (!sc.nextBigInteger().equals(new BigInteger("4A4", 16)))
+            failCount++;
+
+        // Test alternating radices
+        sc = new Scanner("12 4a4 14 4f4");
+        if (!sc.nextBigInteger(10).equals(new BigInteger("12", 10)))
+            failCount++;
+        if (!sc.nextBigInteger(16).equals(new BigInteger("4a4", 16)))
+            failCount++;
+        if (!sc.nextBigInteger(10).equals(new BigInteger("14", 10)))
+            failCount++;
+        if (!sc.nextBigInteger(16).equals(new BigInteger("4f4", 16)))
+            failCount++;
+
+        // Test use of a lot of radices
+        for (int i=2; i<17; i++) {
+            sc = new Scanner("1111");
+            if (!sc.nextBigInteger(i).equals(new BigInteger("1111", i)))
+                failCount++;
+        }
+
+        report("BigInteger pattern");
+    }
+
+    public static void bigDecimalPatternTest(int sourceType) throws Exception {
+        Scanner sc = scannerFor("23 45.99 -45,067.444 3.4e10", sourceType);
+        if (!sc.nextBigDecimal().equals(BigDecimal.valueOf(23)))
+            failCount++;
+        if (!sc.nextBigDecimal().equals(new BigDecimal("45.99")))
+            failCount++;
+        if (!sc.nextBigDecimal().equals(new BigDecimal("-45067.444")))
+            failCount++;
+        if (!sc.nextBigDecimal().equals(new BigDecimal("3.4e10")))
+            failCount++;
+        report("BigDecimal pattern");
+    }
+
+    public static void integerPatternTest(int sourceType) throws Exception {
+        String input =
+            "1 22 f FF Z -3 -44 123 1,200 -123 -3,400,000 5,40 ,500 ";
+        Scanner sc = scannerFor(input, sourceType);
+        integerPatternBody(sc);
+        CharBuffer cb = CharBuffer.wrap(input);
+        sc = new Scanner(cb);
+        integerPatternBody(sc);
+        report("Integer pattern");
+    }
+
+    public static void integerPatternBody(Scanner sc) throws Exception {
+        if (sc.nextInt() != 1)        failCount++;
+        if (sc.nextShort() != 22)     failCount++;
+        if (sc.nextShort(16) != 15)   failCount++;
+        if (sc.nextShort(16) != 255)  failCount++;
+        if (sc.nextShort(36) != 35)   failCount++;
+        if (!sc.hasNextInt())         failCount++;
+        if (sc.nextInt() != -3)       failCount++;
+        if (sc.nextInt() != -44)      failCount++;
+        if (sc.nextLong() != 123)     failCount++;
+        if (!sc.hasNextInt())         failCount++;
+        if (sc.nextInt() != 1200)     failCount++;
+        if (sc.nextInt() != -123)     failCount++;
+        if (sc.nextInt() != -3400000) failCount++;
+        try {
+            sc.nextInt();
+            failCount++;
+        } catch (InputMismatchException ime) {
+            // Correct result
+        }
+        sc.next();
+        try {
+            sc.nextLong();
+            failCount++;
+        } catch (InputMismatchException ime) {
+            // Correct result
+        }
+        sc.next();
+        try {
+            sc.next();
+            failCount++;
+        } catch (InputMismatchException ime) {
+            failCount++;
+        } catch (NoSuchElementException nse) {
+            // Correct result
+        }
+    }
+
+    public static void floatPatternTest(int sourceType) throws Exception {
+        String input =
+            "090.090 1 22.0 -3 -44.05 +.123 -.1234 -3400000 56,566.6 " +
+            "Infinity +Infinity -Infinity NaN -NaN +NaN 5.4.0 5-.00 ++6.07";
+        Scanner sc = scannerFor(input, sourceType);
+        floatPatternBody(sc);
+        CharBuffer cb = CharBuffer.wrap(input);
+        sc = new Scanner(cb);
+        floatPatternBody(sc);
+        report("Float pattern");
+    }
+
+    public static void floatPatternBody(Scanner sc) throws Exception {
+        if (sc.nextFloat() != 090.090f)                   failCount++;
+        if (sc.nextFloat() != 1f)                         failCount++;
+        if (sc.nextFloat() != 22.0f)                      failCount++;
+        if (sc.nextDouble() != -3d)                       failCount++;
+        if (sc.nextDouble() != -44.05d)                   failCount++;
+        if (sc.nextFloat() != .123f)                      failCount++;
+        if (sc.nextFloat() != -.1234f)                    failCount++;
+        if (sc.nextDouble() != -3400000d)                 failCount++;
+        if (sc.nextDouble() != 56566.6d)                  failCount++;
+        if (sc.nextDouble() != Double.POSITIVE_INFINITY)  failCount++;
+        if (sc.nextDouble() != Double.POSITIVE_INFINITY)  failCount++;
+        if (sc.nextDouble() != Double.NEGATIVE_INFINITY)  failCount++;
+        if (!Double.valueOf(sc.nextDouble()).isNaN())     failCount++;
+        if (!Double.valueOf(sc.nextDouble()).isNaN())     failCount++;
+        if (!Double.valueOf(sc.nextDouble()).isNaN())     failCount++;
+        try {
+            sc.nextFloat();
+            failCount++;
+        } catch (NoSuchElementException nse) {
+            // Correct result
+        }
+        try {
+            sc.nextDouble();
+            failCount++;
+        } catch (NoSuchElementException nse) {
+            // Correct result
+        }
+        try {
+            sc.nextDouble();
+            failCount++;
+        } catch (NoSuchElementException nse) {
+            // Correct result
+        }
+    }
+
+    public static void fromFileTest() throws Exception {
+        File f = new File(System.getProperty("test.src", "."), "input.txt");
+        Scanner sc = new Scanner(f).useDelimiter("\n+");
+        String testDataTag = sc.findWithinHorizon("fromFileTest", 0);
+        if (!testDataTag.equals("fromFileTest"))
+            failCount++;
+
+        int count = 0;
+        while (sc.hasNextLong()) {
+            long blah = sc.nextLong();
+            count++;
+        }
+        if (count != 7)
+            failCount++;
+        sc.close();
+        report("From file");
+    }
+
+    private static void example1() throws Exception {
+        Scanner s = new Scanner("1 fish 2 fish red fish blue fish");
+        s.useDelimiter("\\s*fish\\s*");
+        List <String> results = new ArrayList<String>();
+        while(s.hasNext())
+            results.add(s.next());
+        System.out.println(results);
+    }
+
+    private static void example2() throws Exception {
+        Scanner s = new Scanner("1 fish 2 fish red fish blue fish");
+        s.useDelimiter("\\s*fish\\s*");
+        System.out.println(s.nextInt());
+        System.out.println(s.nextInt());
+        System.out.println(s.next());
+        System.out.println(s.next());
+    }
+
+    private static void example3() throws Exception {
+        Scanner s = new Scanner("1 fish 2 fish red fish blue fish");
+        s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
+        for (int i=1; i<=s.match().groupCount(); i++)
+            System.out.println(s.match().group(i));
+    }
+
+    private static void findInLineTest() throws Exception {
+        Scanner s = new Scanner("abc def ghi jkl mno");
+        Pattern letters = Pattern.compile("[a-z]+");
+        Pattern frogs = Pattern.compile("frogs");
+        String str = s.findInLine(letters);
+        if (!str.equals("abc"))
+            failCount++;
+        if (!s.hasNext(letters))
+            failCount++;
+        try {
+            str = s.findInLine(frogs);
+        } catch (NoSuchElementException nsee) {
+            // Correct
+        }
+        if (!s.hasNext())
+            failCount++;
+        if (!s.hasNext(letters))
+            failCount++;
+        str = s.findInLine(letters);
+        if (!str.equals("def"))
+            failCount++;
+
+        report("Find patterns");
+    }
+
+    private static void findInEmptyLineTest() throws Exception {
+        String eol = System.getProperty("line.separator");
+        Scanner s = new Scanner("line 1" + eol + "" + eol + "line 3" + eol);
+        int lineNo = 0;
+        while (s.hasNextLine()) {
+            lineNo++;
+            s.findInLine("3");
+            s.nextLine();
+        }
+        if (lineNo != 3)
+            failCount++;
+        report("findInEmptyLine test");
+    }
+
+    private static void matchTest() throws Exception {
+        Scanner s = new Scanner("1 fish 2 fish red fish blue fish");
+        s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
+
+        MatchResult result = s.match();
+        if (!result.group(1).equals("1"))
+            failCount++;
+        if (!result.group(2).equals("2"))
+            failCount++;
+        if (!result.group(3).equals("red"))
+            failCount++;
+        if (!result.group(4).equals("blue"))
+            failCount++;
+
+        report("Match patterns");
+    }
+
+    private static void skipTest() throws Exception {
+        Scanner s = new Scanner("abc def ghi jkl mno");
+        Pattern letters = Pattern.compile("[a-z]+");
+        Pattern spaceLetters = Pattern.compile(" [a-z]+");
+        Pattern frogs = Pattern.compile("frogs");
+        try {
+            s.skip(letters);
+        } catch (NoSuchElementException ime) {
+            failCount++;
+        }
+        String token = s.next(letters);
+        if (!token.equals("def")) {
+            System.out.println("expected def");
+            System.out.println("I found "+token);
+            failCount++;
+        }
+        try {
+            s.skip(letters);
+            failCount++;
+        } catch (NoSuchElementException ime) {
+            // Correct result
+        }
+        token = s.next(letters);
+        if (!token.equals("ghi")) {
+            System.out.println("expected ghi");
+            System.out.println("I found "+token);
+            failCount++;
+        }
+        try {
+            s.skip(letters);
+            failCount++;
+        } catch (NoSuchElementException ime) {
+            // Correct result because skip ignores delims
+        }
+        try {
+            s.skip(spaceLetters);
+        } catch (NoSuchElementException ime) {
+            failCount++;
+        }
+        token = s.next(letters);
+        if (!token.equals("mno")) {
+            System.out.println("expected mno");
+            System.out.println("I found "+token);
+            failCount++;
+        }
+        try {
+            s.skip(letters);
+            failCount++;
+        } catch (NoSuchElementException ime) {
+            // Correct result
+        }
+        report("Skip patterns");
+    }
+
+    private static void byteTest(int sourceType) throws Exception {
+        String input = " 3 0 00 b -B 012 44 -55 12 127 129 -131 dog 0x12";
+        Scanner s = scannerFor(input, sourceType);
+        if (!s.hasNextByte())          failCount++;
+        if (s.nextByte() != (byte)3)   failCount++;
+        if (!s.hasNextByte())          failCount++;
+        if (s.nextByte() != (byte)0)   failCount++;
+        if (!s.hasNextByte())          failCount++;
+        if (s.nextByte() != (byte)0)   failCount++;
+        if (!s.hasNextByte(16))        failCount++;
+        if (s.nextByte(16) != (byte)11)failCount++;
+        if (!s.hasNextByte(16))        failCount++;
+        if (s.nextByte(16) != (byte)-11) failCount++;
+        if (!s.hasNextByte())          failCount++;
+        if (s.nextByte() != (byte)12)  failCount++;
+        if (!s.hasNextByte())          failCount++;
+        if (s.nextByte() != (byte)44)  failCount++;
+        if (!s.hasNextByte())          failCount++;
+        if (s.nextByte() != (byte)-55) failCount++;
+        if (!s.hasNextByte())          failCount++;
+        if (s.nextByte() != (byte)12)  failCount++;
+        if (!s.hasNextByte())          failCount++;
+        if (s.nextByte() != (byte)127) failCount++;
+        if (s.hasNextByte())           failCount++;
+
+        try {
+            s.nextByte();
+            failCount++;
+        } catch (InputMismatchException ime) {
+            // Correct result
+        }
+        if (s.hasNextByte())           failCount++;
+        if (s.nextInt() != 129)        failCount++;
+        if (s.hasNextByte())           failCount++;
+        try {
+            s.nextByte();
+            failCount++;
+        } catch (InputMismatchException ime) {
+            // Correct result
+        }
+        if (s.nextInt() != -131)       failCount++;
+        if (s.hasNextByte())           failCount++;
+        try {
+            s.nextByte();
+            failCount++;
+        } catch (InputMismatchException ime) {
+            // Correct result
+        }
+        s.next(Pattern.compile("\\w+"));
+        if (s.hasNextByte())
+            failCount++;
+        try {
+            s.nextByte();
+            failCount++;
+        } catch (NoSuchElementException nsee) {
+            // Correct result
+        }
+        s.next();
+        if (s.hasNextByte())
+            failCount++;
+        try {
+            byte bb = s.nextByte();
+            failCount++;
+        } catch (NoSuchElementException nsee) {
+            // Correct result
+        }
+        report("Scan bytes");
+    }
+
+    private static void shortTest(int sourceType) throws Exception {
+        String input = "  017 22 00E -34 44,333 -53999 0x19 dog";
+        Scanner s = scannerFor(input, sourceType);
+        if (!s.hasNextShort())             failCount++;
+        if (s.nextShort() != (short)17)   failCount++;
+        if (!s.hasNextShort())            failCount++;
+        if (s.nextShort() != (short)22)   failCount++;
+        if (!s.hasNextShort(16))          failCount++;
+        if (s.nextShort(16) != (short)14) failCount++;
+        if (!s.hasNextShort())            failCount++;
+        if (s.nextShort() != (short)-34)  failCount++;
+        for (int i=0; i<4; i++) {
+            if (s.hasNextShort())
+                failCount++;
+            try {
+                s.nextShort();
+                failCount++;
+            } catch (InputMismatchException ime) {
+                // Correct result
+            }
+            s.next();
+        }
+        try {
+            s.next();
+            failCount++;
+        } catch (InputMismatchException ime) {
+            failCount++;
+        } catch (NoSuchElementException nse) {
+            // Correct result
+        }
+        report("Scan shorts");
+    }
+
+    private static void intTest(int sourceType) throws Exception {
+        Scanner s = scannerFor(
+            "22 022 C -34 0x80000000 -2147483649 dog ", sourceType);
+        if (!s.hasNextInt())      failCount++;
+        if (s.nextInt() != 22)    failCount++;
+        if (!s.hasNextInt())      failCount++;
+        if (s.nextInt() != 22)    failCount++;
+        if (!s.hasNextInt(16))    failCount++;
+        if (s.nextInt(16) != 12)  failCount++;
+        if (!s.hasNextInt())      failCount++;
+        if (s.nextInt() != -34)   failCount++;
+        for (int i=0; i<3; i++) {
+            if (s.hasNextInt())
+                failCount++;
+            try {
+                s.nextInt();
+                failCount++;
+            } catch (InputMismatchException ime) {
+                // Correct result
+            }
+            s.next();
+        }
+        try {
+            s.next();
+            failCount++;
+        } catch (InputMismatchException ime) {
+            failCount++;
+        } catch (NoSuchElementException nse) {
+            // Correct result
+        }
+        report("Scan ints");
+    }
+
+    private static void longTest(int sourceType) throws Exception {
+        Scanner s = scannerFor(
+        "022 9223372036854775807 0x8000000000000000 9223372036854775808 dog ",
+              sourceType);
+        if (!s.hasNextLong())                        failCount++;
+        if (s.nextLong() != (long)22)                failCount++;
+        if (!s.hasNextLong())                        failCount++;
+        if (s.nextLong() != 9223372036854775807L)    failCount++;
+        for (int i=0; i<3; i++) {
+            if (s.hasNextLong())
+                failCount++;
+            try {
+                s.nextLong();
+                failCount++;
+            } catch (InputMismatchException ime) {
+                // Correct result
+            }
+            s.next();
+        }
+        try {
+            s.next();
+            failCount++;
+        } catch (InputMismatchException ime) {
+            failCount++;
+        } catch (NoSuchElementException nse) {
+            // Correct result
+        }
+        report("Scan longs");
+    }
+
+    private static void floatTest(int sourceType) throws Exception {
+        Scanner s = scannerFor(
+            "0 0. 0.0 2 2. 2.0 2.3 -2 -2.0 -2.3 -. 2-. 2..3", sourceType);
+        if (!s.hasNextFloat())      failCount++;
+        if (s.nextFloat() != 0f)    failCount++;
+        if (!s.hasNextFloat())      failCount++;
+        if (s.nextFloat() != 0f)    failCount++;
+        if (!s.hasNextFloat())      failCount++;
+        if (s.nextFloat() != 0f)    failCount++;
+        if (!s.hasNextFloat())      failCount++;
+        if (s.nextFloat() != 2f)    failCount++;
+        if (!s.hasNextFloat())      failCount++;
+        if (s.nextFloat() != 2f)    failCount++;
+        if (!s.hasNextFloat())      failCount++;
+        if (s.nextFloat() != 2f)    failCount++;
+        if (!s.hasNextFloat())      failCount++;
+        if (s.nextFloat() != 2.3f)  failCount++;
+        if (!s.hasNextFloat())      failCount++;
+        if (s.nextFloat() != -2f)   failCount++;
+        if (!s.hasNextFloat())      failCount++;
+        if (s.nextFloat() != -2f)   failCount++;
+        if (!s.hasNextFloat())      failCount++;
+        if (s.nextFloat() != -2.3f) failCount++;
+        for (int i=0; i<3; i++) {
+            if (s.hasNextLong())
+                failCount++;
+            try {
+                s.nextFloat();
+                failCount++;
+            } catch (InputMismatchException ime) {
+                // Correct result
+            }
+            s.next();
+        }
+        try {
+            s.next();
+            failCount++;
+        } catch (InputMismatchException ime) {
+            failCount++;
+        } catch (NoSuchElementException nse) {
+            // Correct result
+        }
+        report("Scan floats");
+    }
+
+    private static void doubleTest(int sourceType) throws Exception {
+        Scanner s = scannerFor(
+            "0 0. 0.0 2 2. 2.0 2.3 -2 -2.0 -2.3 -. 2-. 2..3", sourceType);
+        if (!s.hasNextDouble())             failCount++;
+        if (s.nextDouble() != 0d)           failCount++;
+        if (!s.hasNextDouble())             failCount++;
+        if (s.nextDouble() != 0d)           failCount++;
+        if (!s.hasNextDouble())             failCount++;
+        if (s.nextDouble() != 0d)           failCount++;
+        if (!s.hasNextDouble())             failCount++;
+        if (s.nextDouble() != 2d)           failCount++;
+        if (!s.hasNextDouble())             failCount++;
+        if (s.nextDouble() != 2d)           failCount++;
+        if (!s.hasNextDouble())             failCount++;
+        if (s.nextDouble() != 2d)           failCount++;
+        if (!s.hasNextDouble())             failCount++;
+        if (s.nextDouble() != 2.3d)         failCount++;
+        if (!s.hasNextDouble())             failCount++;
+        if (s.nextDouble() != -2d)          failCount++;
+        if (!s.hasNextDouble())             failCount++;
+        if (s.nextDouble() != -2d)          failCount++;
+        if (!s.hasNextDouble())             failCount++;
+        if (s.nextDouble() != -2.3d)        failCount++;
+        for (int i=0; i<3; i++) {
+            if (s.hasNextLong())
+                failCount++;
+            try {
+                s.nextDouble();
+                failCount++;
+            } catch (InputMismatchException ime) {
+                // Correct result
+            }
+            s.next();
+        }
+        try {
+            s.next();
+            failCount++;
+        } catch (InputMismatchException ime) {
+            failCount++;
+        } catch (NoSuchElementException nse) {
+            // Correct result
+        }
+        report("Scan doubles");
+    }
+
+    private static void booleanTest(int sourceType) throws Exception {
+        Scanner s = scannerFor(
+            " true false\t \r\n true FaLse \n  True Tru", sourceType);
+        if (!s.nextBoolean())     failCount++;
+        if (!s.hasNextBoolean())  failCount++;
+        if (s.nextBoolean())      failCount++;
+        if (!s.nextBoolean())     failCount++;
+        if (s.nextBoolean())      failCount++;
+        if (!s.nextBoolean())     failCount++;
+        if (s.hasNextBoolean())   failCount++;
+        try {
+            s.nextBoolean();
+            failCount++;
+        } catch (NoSuchElementException nsee) {
+            // Expected result
+        }
+        report("Scan booleans");
+    }
+
+    private static void hasNextTest(int sourceType) throws Exception {
+        Scanner s = scannerFor(
+            " blah blech\t blather  alongblatherindeed", sourceType);
+        if (!s.hasNext())            failCount++;
+        if (!s.hasNext())            failCount++;
+        String result = s.next();
+        if (!result.equals("blah"))  failCount++;
+        if (!s.hasNext())            failCount++;
+        if (!s.hasNext())            failCount++;
+        result = s.next();
+        if (!result.equals("blech")) failCount++;
+        if (!s.hasNext())            failCount++;
+        result = s.next();
+        if (!result.equals("blather")) failCount++;
+        if (!s.hasNext())              failCount++;
+        if (!s.hasNext())              failCount++;
+        result = s.next();
+        if (!result.equals("alongblatherindeed")) failCount++;
+        if (s.hasNext())                          failCount++;
+        try {
+            result = s.next();
+            failCount++;
+        } catch (NoSuchElementException nsee) {
+            // Correct result
+        }
+        report("Has next test");
+    }
+
+    private static void nextTest(int sourceType) throws Exception {
+        Scanner s = scannerFor(
+            " blah blech\t blather  alongblatherindeed", sourceType);
+        String result = (String)s.next();
+        if (!result.equals("blah"))    failCount++;
+        result = (String)s.next();
+        if (!result.equals("blech"))   failCount++;
+        result = (String)s.next();
+        if (!result.equals("blather")) failCount++;
+        result = (String)s.next();
+        if (!result.equals("alongblatherindeed"))
+            failCount++;
+        try {
+            result = (String)s.next();
+            failCount++;
+        } catch (NoSuchElementException nsee) {
+            // Correct result
+        }
+        report("Next test");
+    }
+
+    private static void hasNextPatternTest(int sourceType) throws Exception {
+        Scanner s = scannerFor(
+            " blah blech\t blather  alongblatherindeed", sourceType);
+        Pattern p1 = Pattern.compile("\\w+");
+        Pattern p2 = Pattern.compile("blech");
+        if (!s.hasNext(p1))    failCount++;
+        if (!s.hasNext(p1))    failCount++;
+        if (s.hasNext(p2))     failCount++;
+        String result = (String)s.next();
+        if (!result.equals("blah"))  failCount++;
+        if (!s.hasNext(p1))          failCount++;
+        if (!s.hasNext(p2))          failCount++;
+        result = (String)s.next();
+        if (!result.equals("blech")) failCount++;
+        if (!s.hasNext(p1))          failCount++;
+        if (s.hasNext(p2))           failCount++;
+        result = (String)s.next();
+        if (!result.equals("blather")) failCount++;
+        if (!s.hasNext(p1))            failCount++;
+        if (s.hasNext(p2))             failCount++;
+        result = (String)s.next();
+        if (!result.equals("alongblatherindeed")) failCount++;
+        if (s.hasNext(p1))  failCount++;
+        if (s.hasNext(p2))  failCount++;
+        report("Has Next Pattern test");
+    }
+
+    private static void nextPatternTest(int sourceType) throws Exception {
+        Scanner s = scannerFor(
+            " blah blech\t blather  alongblatherindeed", sourceType);
+        Pattern p1 = Pattern.compile("blah");
+        Pattern p2 = Pattern.compile("blech");
+        Pattern p3 = Pattern.compile("blather");
+        Pattern p4 = Pattern.compile("alongblatherindeed");
+        String result = null;
+        try {
+            result = (String)s.next(p2);
+            failCount++;
+        } catch (NoSuchElementException nsee) {
+            // Correct result
+        }
+        result = (String)s.next(p1);
+        if (!result.equals("blah"))
+            failCount++;
+        try {
+            result = (String)s.next(p1);
+            failCount++;
+        } catch (NoSuchElementException nsee) {
+            // Correct result
+        }
+        result = (String)s.next(p2);
+        if (!result.equals("blech"))
+            failCount++;
+        try {
+            result = (String)s.next(p4);
+            failCount++;
+        } catch (NoSuchElementException nsee) {
+            // Correct result
+        }
+        result = (String)s.next(p3);
+        if (!result.equals("blather"))
+            failCount++;
+        try {
+            result = (String)s.next(p3);
+            failCount++;
+        } catch (NoSuchElementException nsee) {
+            // Correct result
+        }
+        result = (String)s.next(p4);
+        if (!result.equals("alongblatherindeed"))
+            failCount++;
+        try {
+            result = (String)s.next();
+            failCount++;
+        } catch (NoSuchElementException nsee) {
+            // Correct result
+        }
+        report("Next pattern test");
+    }
+
+    private static void useLocaleTest() throws Exception {
+        Scanner s = new Scanner("334.65").useLocale(Locale.ENGLISH);
+        if (!s.hasNextFloat())           failCount++;
+        if (s.nextFloat() != 334.65f)    failCount++;
+
+        s = new Scanner("334,65").useLocale(Locale.FRENCH);
+        if (!s.hasNextFloat())           failCount++;
+        if (s.nextFloat() != 334.65f)    failCount++;
+
+        s = new Scanner("4.334,65").useLocale(Locale.GERMAN);
+        if (!s.hasNextFloat())           failCount++;
+        if (s.nextFloat() != 4334.65f)    failCount++;
+
+        // Test case reported from India
+        try {
+            String Message = "123978.90 $";
+            Locale locale = new Locale("hi","IN");
+            NumberFormat form = NumberFormat.getInstance(locale);
+            double myNumber = 1902.09;
+            Scanner scanner = new Scanner(form.format(myNumber).toString());
+            scanner.useLocale(locale);
+            double d = scanner.nextDouble();
+        } catch (InputMismatchException ime) {
+            failCount++;
+        }
+        report("Use locale test");
+    }
+
+    public static void resetTest() throws Exception {
+        Scanner sc = new Scanner("");
+        int radix = sc.radix();
+        Locale locale = sc.locale();
+        Pattern delimiter = sc.delimiter();
+        Pattern a = Pattern.compile("A");
+        sc.useDelimiter(a);
+        Locale dummy = new Locale("en", "US", "dummy");
+        sc.useLocale(dummy);
+        sc.useRadix(16);
+        if (sc.radix() != 16 ||
+            !sc.locale().equals(dummy) ||
+            !sc.delimiter().pattern().equals(a.pattern())) {
+            failCount++;
+        } else {
+            sc.reset();
+            if (sc.radix() != radix ||
+                !sc.locale().equals(locale) ||
+                !sc.delimiter().pattern().equals(delimiter.pattern())) {
+                failCount++;
+            }
+        }
+        sc.close();
+        report("Reset test");
+    }
+
+    private static void report(String testName) {
+        int spacesToAdd = 30 - testName.length();
+        StringBuffer paddedNameBuffer = new StringBuffer(testName);
+        for (int i=0; i<spacesToAdd; i++)
+            paddedNameBuffer.append(" ");
+        String paddedName = paddedNameBuffer.toString();
+        System.err.println(paddedName + ": " +
+                           (failCount==0 ? "Passed":"Failed("+failCount+")"));
+        if (failCount > 0)
+            failure = true;
+        failCount = 0;
+    }
+
+    static Scanner scannerFor(String input, int sourceType) {
+        if (sourceType == 1)
+            return new Scanner(input);
+        else
+            return new Scanner(new StutteringInputStream(input));
+    }
+
+    static class ThrowingReadable implements Readable {
+        ThrowingReadable() {
+        }
+        public int read(java.nio.CharBuffer cb) throws IOException {
+            throw new IOException("ThrowingReadable always throws");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Scanner/input.txt	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,438 @@
+# Data for fromFileTest
+14343441
+24134342
+34324233
+43234234
+53423425
+63424326
+74324337
+
+
+# Data for usage case 1
+23.4 Frank 34.8 -9.0
+2.333 6.75 Joe -2
+3.3 -888.8 -16.00 Mary
+Michelle -5 -5.5 -5.555
+
+
+# Data for usage case 2
+cat-9-dog-6-pig-2--5-
+
+
+# Data for usage case 3
+    /**
+     * Returns the next string in the input that matches the specified pattern. 
+     * This method may block while waiting for input 
+     * to scan, even if a previous invocation of {@link #hasNext(Pattern)} 
+     * returned <code>true</code>. If the match is successful, the scanner 
+     * advances past the input that matched the pattern. 
+     *
+     * @param pattern the pattern to scan for
+     * @return the next token
+     * @throws NoSuchElementException if no more tokens are available
+     * @throws IllegalStateException if this scanner is closed
+     */
+
+
+# Data for usage case 4
+<html>
+<body bgcolor="#EEEEEE">
+<title>Source Directory</title>
+<center><h1>tiger</h1></center>
+<p>
+Parent workspace is /java/jdk/1.5/ws/integration/TL/j2se <br>
+Child  workspace is /export/tiger <br>
+<hr>
+<code>
+<p>
+<a href=make/java/java/mapfile-vers.diff.html>Diffs</a>
+<a href=make/java/java/mapfile-vers.sdiff.html>Sdiffs</a>
+<a href=make/java/java/mapfile-vers-.html>Old</a>
+<a href=make/java/java/mapfile-vers.html>New</a>
+<b>make/java/java/mapfile-vers</b><p>
+<ul> 
+<li><a href=http://example.com/cgi-bin/bugtraq_showbug?bugid=4904881>4904881</a>: JVM crash during java.io.File.deleteOnExit()<br>
+</ul>
+<p>
+<a href=src/share/classes/java/lang/Shutdown.java.diff.html>Diffs</a>
+<a href=src/share/classes/java/lang/Shutdown.java.sdiff.html>Sdiffs</a>
+<a href=src/share/classes/java/lang/Shutdown.java-.html>Old</a>
+<a href=src/share/classes/java/lang/Shutdown.java.html>New</a>
+<b>src/share/classes/java/lang/Shutdown.java</b><p>
+<ul>
+<li><a href=http://example.com/cgi-bin/bugtraq_showbug?bugid=4904881>4904881</a>: JVM crash during java.io.File.deleteOnExit()<br>
+</ul>
+<p>
+<a href=src/share/native/java/lang/Shutdown.c.diff.html>Diffs</a>
+<a href=src/share/native/java/lang/Shutdown.c.sdiff.html>Sdiffs</a>
+<a href=src/share/native/java/lang/Shutdown.c-.html>Old</a>
+<a href=src/share/native/java/lang/Shutdown.c.html>New</a>
+<b>src/share/native/java/lang/Shutdown.c</b><p>
+<ul>
+<li><a href=http://example.com/cgi-bin/bugtraq_showbug?bugid=4904881>4904881</a>: JVM crash during java.io.File.deleteOnExit()<br>
+</ul>
+</code>
+<p>
+</font>
+</html>
+
+# Data for usage case 5
+
+# This is the main Samba configuration file. You should read the
+# smb.conf(5) manual page in order to understand the options listed
+# here. Samba has a huge number of configurable options (perhaps too
+# many!) most of which are not shown in this example
+#
+# Any line which starts with a ; (semi-colon) or a # (hash)
+# is a comment and is ignored. In this example we will use a #
+# for commentry and a ; for parts of the config file that you
+# may wish to enable
+#
+# NOTE: Whenever you modify this file you should run the command "testparm"
+# to check that you have not many any basic syntactic errors.
+#
+#======================= Global Settings =====================================
+[global]
+
+##
+## Basic Server Settings
+##
+
+	# workgroup = NT-Domain-Name or Workgroup-Name, eg: REDHAT4
+	workgroup = MYGROUP
+
+	# server string is the equivalent of the NT Description field
+	server string = Samba Server
+
+	# This option is important for security. It allows you to restrict
+	# connections to machines which are on your local network. The
+	# following example restricts access to two C class networks and
+	# the "loopback" interface. For more examples of the syntax see
+	# the smb.conf man page
+	; hosts allow = 192.168.1. 192.168.2.0./24 192.168.3.0/255.255.255.0 127.0.0.1
+
+	# Uncomment this if you want a guest account, you must add this to /etc/passwd
+	# otherwise the user "nobody" is used
+	; guest account = pcguest
+
+	# this tells Samba to use a separate log file for each machine
+	# that connects
+	log file = /usr/local/samba/var/log.%m
+
+	# How much information do you want to see in the logs?
+	# default is only to log critical messages
+	; log level = 1
+
+	# Put a capping on the size of the log files (in Kb).
+	max log size = 50
+
+	# Security mode. Most people will want user level security. See
+	# security_level.txt for details.
+	security = user
+
+	# Using the following line enables you to customise your configuration
+	# on a per machine basis. The %m gets replaced with the netbios name
+	# of the machine that is connecting.
+	# Note: Consider carefully the location in the configuration file of
+	#       this line.  The included file is read at that point.
+	;   include = /usr/local/samba/lib/smb.conf.%m
+
+	# Most people will find that this option gives better performance.
+	# See speed.txt and the manual pages for details
+	# You may want to add the following on a Linux system:
+	#         SO_RCVBUF=8192 SO_SNDBUF=8192
+	; socket options = TCP_NODELAY
+
+	# Configure Samba to use multiple interfaces
+	# If you have multiple network interfaces and want to limit smbd will
+	# use, list the ones desired here.  Otherwise smbd & nmbd will bind to all
+	# active interfaces on the system.  See the man page for details.
+	;   interfaces = 192.168.12.2/24 192.168.13.2/24
+
+	# Should smbd report that it has MS-DFS Capabilities? Only available
+	# if --with-msdfs was passed to ./configure
+	; host msdfs = yes
+
+##
+## Network Browsing
+##
+	# set local master to no if you don't want Samba to become a master
+	# browser on your network. Otherwise the normal election rules apply
+	; local master = no
+
+	# OS Level determines the precedence of this server in master browser
+	# elections. The default value (20) should be reasonable
+	; os level = 20
+
+	# Domain Master specifies Samba to be the Domain Master Browser. This
+	# allows Samba to collate browse lists between subnets. Don't use this
+	# if you already have a Windows NT domain controller doing this job
+	; domain master = yes
+
+	# Preferred Master causes Samba to force a local browser election on startup
+	# and gives it a slightly higher chance of winning the election
+	; preferred master = yes
+
+
+##
+## WINS & Name Resolution
+##
+	# Windows Internet Name Serving Support Section:
+	# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server
+	; wins support = yes
+
+	# WINS Server - Tells the NMBD components of Samba to be a WINS Client
+	#	Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
+	; wins server = w.x.y.z
+
+	# WINS Proxy - Tells Samba to answer name resolution queries on
+	# behalf of a non WINS capable client, for this to work there must be
+	# at least one	WINS Server on the network. The default is NO.
+	; wins proxy = yes
+
+	# DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names
+	# via DNS nslookups.
+	dns proxy = no
+
+
+##
+## Passwords & Authentication
+##
+	# Use password server option only with security = server
+	# The argument list may include:
+	#   password server = My_PDC_Name [My_BDC_Name] [My_Next_BDC_Name]
+	# or to auto-locate the domain controller/s
+	;   password server = *
+	;   password server = <NT-Server-Name>
+
+	# You may wish to use password encryption. Please read
+	# ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation.
+	# Do not enable this option unless you have read those documents
+	;  encrypt passwords = yes
+
+	# Should smbd obey the session and account lines in /etc/pam.d/samba ?
+	# only available if --with-pam was used at compile time
+	; obey pam restrictions = yes
+
+	# When using encrypted passwords, Samba can synchronize the local
+	# UNIX password as well.  You will also need the "passwd chat" parameters
+	; unix password sync = yes
+
+	# how should smbd talk to the local system when changing a UNIX
+	# password?  See smb.conf(5) for details
+	; passwd chat = <custom chat string>
+
+	# This is only available if you compiled Samba to include --with-pam
+	# Use PAM for changing the password
+	; pam password change = yes
+
+##
+## Domain Control
+##
+	# Enable this if you want Samba act as a domain controller.
+	# make sure you have read the Samba-PDC-HOWTO included in the documentation
+	# before enabling this parameter
+	;   domain logons = yes
+
+	# if you enable domain logons then you may want a per-machine or
+	# per user logon script
+	# run a specific logon batch file per workstation (machine)
+	; logon script = %m.bat
+	# run a specific logon batch file per username
+	; logon script = %U.bat
+
+	# Where to store roving profiles (only for Win95 and WinNT)
+	#        %L substitutes for this servers netbios name, %U is username
+	#        You must uncomment the [Profiles] share below
+	; logon path = \\%L\Profiles\%U
+
+	# UNC path specifying the network location of the user's home directory
+	# only used when acting as a DC for WinNT/2k/XP.  Ignored by Win9x clients
+	; logon home = \\%L\%U
+
+	# What drive should the "logon home" be mounted at upon login ?
+	# only used when acting as a DC for WinNT/2k/XP.  Ignored by Win9x clients
+	; logon drive = H:
+
+##
+## Printing
+##
+
+	# If you want to automatically load your printer list rather
+	# than setting them up individually then you'll need this
+	load printers = yes
+
+	# you may wish to override the location of the printcap file
+	; printcap name = /etc/printcap
+
+	# on SystemV system setting printcap name to lpstat should allow
+	# you to automatically obtain a printer list from the SystemV spool
+	# system
+	; printcap name = lpstat
+
+	# It should not be necessary to specify the print system type unless
+	# it is non-standard. Currently supported print systems include:
+	# bsd, sysv, plp, lprng, aix, hpux, qnx
+	; printing = bsd
+
+	# Enable this to make Samba 2.2 behavior just like Samba 2.0
+	# not recommended nuless you are sure of what you are doing
+	; disable spoolss = yes
+
+	# list of users and groups which should be able to remotely manage
+	# printer drivers installed on the server
+	; printer admin = root, +ntadmin
+
+
+##
+## Winbind
+##
+
+	# specify the uid range which can be used by winbindd
+	# to allocate uids for Windows users as necessary
+	; winbind uid = 10000-65000
+
+	# specify the uid range which can be used by winbindd
+	# to allocate uids for Windows users as necessary
+	; winbind gid = 10000-65000
+
+	# Define a home directory to be given to passwd(5) style entries
+	# generated by libnss_winbind.so.  You can use variables here
+	; winbind template homedir = /home/%D/%U
+
+	# Specify a shell for all winbind user entries return by the
+	# libnss_winbind.so library.
+	; winbind template shell = /bin/sh
+
+	# What character should be used to separate the DOMAIN and Username
+	# for a Windows user.  The default is DOMAIN\user, but many people
+	# prefer DOMAIN+user
+	; winbind separator = +
+
+
+#============================ Share Definitions ==============================
+[homes]
+     comment = Home Directories
+     browseable = no
+     writable = yes
+     valid users = %S
+
+# Un-comment the following and create the netlogon directory for Domain Logons
+; [netlogon]
+;    comment = Network Logon Service
+;    path = /usr/local/samba/lib/netlogon
+;    guest ok = yes
+;    writable = no
+;    share modes = no
+
+
+# Un-comment the following to provide a specific roving profile share
+# the default is to use the user's home directory
+;[Profiles]
+;    path = /usr/local/samba/profiles
+;    browseable = no
+;    guest ok = yes
+
+
+# NOTE: If you have a BSD-style print system there is no need to
+# specifically define each individual printer
+[printers]
+   comment = All Printers
+   path = /usr/spool/samba
+   browseable = no
+   # Set public = yes to allow user 'guest account' to print
+   guest ok = no
+   writable = no
+   printable = yes
+
+# This one is useful for people to share files
+#[tmp]
+#   comment = Temporary file space
+#   path = /tmp
+#   read only = no
+#   public = yes
+
+
+# MS-DFS support is only available if Samba was compiled to
+# include --with-msdfs
+;[dfsroot]
+;   dfs root = yes
+
+
+# A publicly accessible directory, but read only, except for people in
+# the "staff" group
+;[public]
+;   comment = Public Stuff
+;   path = /home/samba
+;   public = yes
+;   writable = yes
+;   printable = no
+;   write list = @staff
+
+
+##
+## Other examples.
+##
+
+# A private printer, usable only by fred. Spool data will be placed in fred's
+# home directory. Note that fred must have write access to the spool directory,
+# wherever it is.
+#[fredsprn]
+#   comment = Fred's Printer
+#   valid users = fred
+#   path = /homes/fred
+#   printer = freds_printer
+#   public = no
+#   writable = no
+#   printable = yes
+
+# A private directory, usable only by fred. Note that fred requires write
+# access to the directory.
+#[fredsdir]
+#   comment = Fred's Service
+#   path = /usr/somewhere/private
+#   valid users = fred
+#   public = no
+#   writable = yes
+#   printable = no
+
+# a service which has a different directory for each machine that connects
+# this allows you to tailor configurations to incoming machines. You could
+# also use the %U option to tailor it by user name.
+# The %m gets replaced with the machine name that is connecting.
+#[pchome]
+#  comment = PC Directories
+#  path = /usr/pc/%m
+#  public = no
+#  writable = yes
+
+# A publicly accessible directory, read/write to all users. Note that all files
+# created in the directory by users will be owned by the default user, so
+# any user with access can delete any other user's files. Obviously this
+# directory must be writable by the default user. Another user could of course
+# be specified, in which case all files would be owned by that user instead.
+#[public]
+#   path = /usr/somewhere/else/public
+#   public = yes
+#   only guest = yes
+#   writable = yes
+#   printable = no
+
+# The following two entries demonstrate how to share a directory so that two
+# users can place files there that will be owned by the specific users. In this
+# setup, the directory should be writable by both users and should have the
+# sticky bit set on it to prevent abuse. Obviously this could be extended to
+# as many users as required.
+#[myshare]
+#   comment = Mary's and Fred's stuff
+#   path = /usr/somewhere/shared
+#   valid users = mary fred
+#   public = no
+#   writable = yes
+#   printable = no
+#   create mask = 0765
+
+
+
+
+# Data for usage case 6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/forkjoin/AccessControlContext.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2020, Azul Systems, 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 8249677 8249846
+ * @summary AccessControlContext should not be dropped in ForkJoinThread
+ * @run main/othervm/policy=AccessControlContext.policy/timeout=20 AccessControlContext inherit
+ * @run main/othervm/policy=AccessControlContext.policy/timeout=20 AccessControlContext default
+ */
+
+import java.security.AccessController;
+import java.security.AccessControlException;
+
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.RecursiveTask;
+
+public class AccessControlContext {
+
+    static void testPermission() {
+        System.getProperty("java.version");
+    }
+
+    static void testInherit() {
+        ForkJoinPool pool = new ForkJoinPool(1,
+                new ForkJoinPool.ForkJoinWorkerThreadFactory() {
+                    @Override
+                    public ForkJoinWorkerThread newThread(ForkJoinPool forkJoinPool) {
+                        return new ForkJoinWorkerThread(forkJoinPool) {
+                            @Override
+                            public void run() {
+                                testPermission();
+                                super.run();
+                            }
+                        };
+                    }
+                },
+                null, false);
+
+        pool.invoke(new RecursiveTask<Object>() {
+            @Override
+            protected Object compute() {
+                System.out.println("done");
+                return null;
+            }
+        });
+
+        pool.shutdown();
+    }
+
+    static void testDefault() {
+        ForkJoinPool pool = new ForkJoinPool(1);
+
+        pool.invoke(new RecursiveTask<Object>() {
+            @Override
+            protected Object compute() {
+                testPermission();
+                System.out.println("done");
+                return null;
+            }
+        });
+
+        pool.shutdown();
+    }
+
+    public static void main(String[] args){
+        testPermission();
+
+        switch (args[0]) {
+        case "inherit":
+            testInherit();
+            break;
+        case "default":
+            // Case fails because of "JDK-8249846: Change of behavior after
+            // JDK-8237117: Better ForkJoinPool behavior".
+            System.out.println("Known to fail with AccessControlException since 8u262 (see JDK-8249846)");
+            try {
+                testDefault();
+                throw new RuntimeException("Pool thread has inherited permissions.");
+            } catch (AccessControlException e) {
+                System.out.println("PASSED: " + e);
+            }
+            break;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/forkjoin/AccessControlContext.policy	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,3 @@
+grant {
+    permission java.security.AllPermission;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/AllowSearch.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4420318 8183341
+ * @summary Checks that an IllegalStateException is thrown by getNumImages(true)
+ *          when seekForwardOnly is true
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+
+import com.sun.imageio.plugins.gif.GIFImageReader;
+import com.sun.imageio.plugins.jpeg.JPEGImageReader;
+import com.sun.imageio.plugins.png.PNGImageReader;
+
+public class AllowSearch {
+    private static void test(ImageReader reader, String format)
+        throws IOException {
+        boolean gotISE = false;
+        File f = null;
+        ImageInputStream stream = null;
+        try {
+            f = File.createTempFile("imageio", ".tmp");
+            stream = ImageIO.createImageInputStream(f);
+            reader.setInput(stream, true);
+
+            try {
+                int numImages = reader.getNumImages(true);
+            } catch (IOException ioe) {
+                gotISE = false;
+            } catch (IllegalStateException ise) {
+                gotISE = true;
+            }
+        } finally {
+            if (stream != null) {
+                stream.close();
+            }
+
+            reader.dispose();
+
+            if (f != null) {
+                Files.delete(f.toPath());
+            }
+        }
+
+        if (!gotISE) {
+            throw new RuntimeException("Failed to get desired exception for " +
+                                       format + " reader!");
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        ImageReader gifReader = new GIFImageReader(null);
+        ImageReader jpegReader = new JPEGImageReader(null);
+        ImageReader pngReader = new PNGImageReader(null);
+
+        test(gifReader, "GIF");
+        test(jpegReader, "JPEG");
+        test(pngReader, "PNG");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/AppContextTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4421190
+ * @summary Tests that Image I/O statics may be referenced properly from
+ *          multiple AppContexts, as would be the case for multiple Applets in a
+ *          single VM. Each AppContext should get its own copy of the registry
+ *          and the caching parameters in the ImageIO class.
+ */
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.spi.IIORegistry;
+
+import sun.awt.SunToolkit;
+
+class TestThread extends Thread {
+
+    IIORegistry registry;
+    boolean useCache;
+    File cacheDirectory;
+    boolean cacheSettingsOK = false;
+    String threadName;
+
+    boolean gotCrosstalk = false;
+
+    public TestThread(ThreadGroup tg,
+                      boolean useCache, File cacheDirectory,
+                      String threadName) {
+        super(tg, threadName);
+        this.useCache = useCache;
+        this.cacheDirectory = cacheDirectory;
+        this.threadName = threadName;
+    }
+
+    public void run() {
+//          System.out.println("Thread " + threadName + " in thread group " +
+//                             getThreadGroup().getName());
+
+        // Create a new AppContext as though we were an applet
+        SunToolkit.createNewAppContext();
+
+        // Get default registry and store reference
+        this.registry = IIORegistry.getDefaultInstance();
+
+        for (int i = 0; i < 10; i++) {
+//              System.out.println(threadName +
+//                                 ": setting cache parameters to " +
+//                                 useCache + ", " + cacheDirectory);
+            ImageIO.setUseCache(useCache);
+            ImageIO.setCacheDirectory(cacheDirectory);
+
+            try {
+                sleep(1000L);
+            } catch (InterruptedException e) {
+            }
+
+//              System.out.println(threadName + ": reading cache parameters");
+            boolean newUseCache = ImageIO.getUseCache();
+            File newCacheDirectory = ImageIO.getCacheDirectory();
+            if (newUseCache != useCache ||
+                newCacheDirectory != cacheDirectory) {
+//                  System.out.println(threadName + ": got " +
+//                                     newUseCache + ", " +
+//                                     newCacheDirectory);
+//                  System.out.println(threadName + ": crosstalk encountered!");
+                gotCrosstalk = true;
+            }
+        }
+    }
+
+    public IIORegistry getRegistry() {
+        return registry;
+    }
+
+    public boolean gotCrosstalk() {
+        return gotCrosstalk;
+    }
+}
+
+public class AppContextTest {
+
+    public AppContextTest() {
+        ThreadGroup tg0 = new ThreadGroup("ThreadGroup0");
+        ThreadGroup tg1 = new ThreadGroup("ThreadGroup1");
+
+        TestThread t0 =
+            new TestThread(tg0, false, null, "TestThread 0");
+        TestThread t1 =
+            new TestThread(tg1, true, new File("."), "TestThread 1");
+
+        t0.start();
+        t1.start();
+
+        try {
+            t0.join();
+        } catch (InterruptedException ie0) {
+        }
+        try {
+            t1.join();
+        } catch (InterruptedException ie1) {
+        }
+
+        if (t0.gotCrosstalk() || t1.gotCrosstalk()) {
+            throw new RuntimeException("ImageIO methods had crosstalk!");
+        }
+
+        if (t0.getRegistry() == t1.getRegistry()) {
+            throw new RuntimeException("ThreadGroups had same IIORegistry!");
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        new AppContextTest();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/AppletResourceTest.html	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,40 @@
+<!--
+  ~ Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+  ~ 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.
+  -->
+
+<html>
+<!--
+ test
+ @bug 4481957
+ @run main AppletResourceTest
+ @run applet RestrictedBundleTest.html
+ @summary Tests that applet-supplied ImageReader, ImageWriter, and
+ IIOMetadataFormat implementations do not throw unexpected exceptions
+ when indirectly attempting to access ResourceBundles.
+  -->
+<head>
+<title> AppletResourceTest </title>
+</head>
+<body>
+<applet code=AppletResourceTest.class width=400 height=400></applet>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/AppletResourceTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,439 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4481957
+ * @key headful
+ * @summary Tests that applet-supplied ImageReader, ImageWriter, and
+ *          IIOMetadataFormat implementations do not throw unexpected exceptions
+ *          when indirectly attempting to access ResourceBundles
+ * @run main AppletResourceTest
+ * @run applet AppletResourceTest.html
+ */
+
+import java.applet.Applet;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.Vector;
+
+import javax.imageio.IIOException;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.event.IIOReadWarningListener;
+import javax.imageio.metadata.IIOInvalidTreeException;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.ImageReaderSpi;
+
+import org.w3c.dom.Node;
+
+public class AppletResourceTest extends Applet {
+
+    public static void main(String[] argv) {
+        new AppletResourceTest().init();
+    }
+
+    public void init() {
+        DummyImageReaderImpl reader;
+        MyReadWarningListener listener = new MyReadWarningListener();
+        Locale[] locales = {new Locale("ru"),
+                            new Locale("fr"),
+                            new Locale("uk")};
+
+        reader = new DummyImageReaderImpl(new DummyImageReaderSpiImpl());
+        reader.setAvailableLocales(locales);
+        reader.setLocale(new Locale("fr"));
+        reader.addIIOReadWarningListener(listener);
+
+        String baseName = "AppletResourceTest$BugStats";
+        try {
+            reader.processWarningOccurred("WarningMessage");
+            reader.processWarningOccurred(baseName, "water");
+        } catch (MissingResourceException mre) {
+            throw new RuntimeException("Test failed: couldn't load resource");
+        }
+
+
+    }
+
+    private class MyReadWarningListener implements IIOReadWarningListener {
+        public void warningOccurred(ImageReader source,
+                                    String warning)
+            {
+                System.out.println("warning occurred: " + warning);
+            }
+    }
+
+    public static class BugStats extends ListResourceBundle {
+
+        public Object[][] getContents(){
+            return contents;
+        }
+
+        private Object[][] contents = {
+            {"coffee", new String("coffee from Stats class")},
+            {"tea", new String("tea from Stats class")},
+            {"water", new String("water from Stats class")}
+        };
+    }
+
+
+    public static class DummyImageReaderImpl extends ImageReader {
+
+        public DummyImageReaderImpl(ImageReaderSpi originatingProvider) {
+            super(originatingProvider);
+        }
+
+        public int getNumImages(boolean allowSearch) throws IOException {
+            return 5;
+        }
+
+        public int getWidth(int imageIndex) throws IOException {
+            if (input == null)
+                throw new IllegalStateException();
+            if (imageIndex >= 5 || imageIndex < 0)
+                throw new IndexOutOfBoundsException();
+
+            return 10;
+        }
+
+        public int getHeight(int imageIndex) throws IOException {
+            if (input == null)
+                throw new IllegalStateException();
+            if (imageIndex >= 5 || imageIndex < 0)
+                throw new IndexOutOfBoundsException();
+
+            return 15;
+        }
+
+        public Iterator getImageTypes(int imageIndex) throws IOException {
+            if (input == null)
+                throw new IllegalStateException();
+            if (imageIndex >= 5 || imageIndex < 0)
+                throw new IndexOutOfBoundsException();
+
+            Vector imageTypes = new Vector();
+            imageTypes.add(ImageTypeSpecifier.createFromBufferedImageType
+                           (BufferedImage.TYPE_BYTE_GRAY ));
+            return imageTypes.iterator();
+        }
+
+        public IIOMetadata getStreamMetadata() throws IOException {
+            return new DummyIIOMetadataImpl(true, null, null, null, null);
+        }
+
+        public IIOMetadata getImageMetadata(int imageIndex)
+          throws IOException {
+
+            if (input == null)
+                throw new IllegalStateException();
+            if (imageIndex >= 5 || imageIndex < 0)
+                throw new IndexOutOfBoundsException();
+            if (seekForwardOnly) {
+                if (imageIndex < minIndex)
+                    throw new IndexOutOfBoundsException();
+                minIndex = imageIndex;
+            }
+            return new DummyIIOMetadataImpl(true, null, null, null, null);
+        }
+
+
+        public BufferedImage read(int imageIndex, ImageReadParam param)
+          throws IOException {
+            if (input == null)
+                throw new IllegalStateException();
+            if (imageIndex >= 5 || imageIndex < 0)
+                throw new IndexOutOfBoundsException();
+            if (seekForwardOnly) {
+                if (imageIndex < minIndex)
+                    throw new IndexOutOfBoundsException();
+                minIndex = imageIndex;
+            }
+
+            return getDestination(param, getImageTypes(imageIndex), 10, 15);
+        }
+
+// protected  methods - now public
+
+        public  boolean abortRequested() {
+            return super.abortRequested();
+        }
+
+        public  void clearAbortRequest() {
+            super.clearAbortRequest();
+        }
+
+        public  void processImageComplete() {
+            super.processImageComplete();
+        }
+
+        public  void processImageProgress(float percentageDone) {
+            super.processImageProgress(percentageDone);
+        }
+
+        public  void processImageStarted(int imageIndex) {
+            super.processImageStarted(imageIndex);
+        }
+
+        public  void processImageUpdate(BufferedImage theImage,
+                                        int minX,
+                                        int minY,
+                                        int width,
+                                        int height,
+                                        int periodX,
+                                        int periodY,
+                                        int[] bands) {
+            super.processImageUpdate(theImage,
+                                     minX,
+                                     minY,
+                                     width,
+                                     height,
+                                     periodX,
+                                     periodY,
+                                     bands);
+        }
+
+        public  void processPassComplete(BufferedImage theImage) {
+            super. processPassComplete(theImage);
+        }
+
+        public  void processPassStarted(BufferedImage theImage,
+                                        int pass, int minPass,
+                                        int maxPass,
+                                        int minX,
+                                        int minY,
+                                        int periodX,
+                                        int periodY,
+                                        int[] bands) {
+            super.processPassStarted(theImage,
+                                     pass,
+                                     minPass,
+                                     maxPass,
+                                     minX,
+                                     minY,
+                                     periodX,
+                                     periodY,
+                                     bands);
+        }
+
+        public  void processReadAborted() {
+            super.processReadAborted();
+        }
+
+        public  void processSequenceComplete() {
+            super.processSequenceComplete();
+        }
+
+        public  void processSequenceStarted(int minIndex) {
+            super.processSequenceStarted(minIndex);
+        }
+
+        public  void processThumbnailComplete() {
+            super.processThumbnailComplete();
+        }
+
+        public  void processThumbnailPassComplete(BufferedImage theThumbnail) {
+            super.processThumbnailPassComplete(theThumbnail);
+        }
+
+        public  void processThumbnailPassStarted(BufferedImage theThumbnail,
+                                                 int pass,
+                                                 int minPass,
+                                                 int maxPass,
+                                                 int minX,
+                                                 int minY,
+                                                 int periodX,
+                                                 int periodY,
+                                                 int[] bands) {
+            super.processThumbnailPassStarted(theThumbnail,
+                                              pass,
+                                              minPass,
+                                              maxPass,
+                                              minX,
+                                              minY,
+                                              periodX,
+                                              periodY,
+                                              bands);
+        }
+
+        public  void processThumbnailProgress(float percentageDone) {
+            super.processThumbnailProgress(percentageDone);
+        }
+
+        public  void processThumbnailStarted(int imageIndex, int thumbnailIndex) {
+            super.processThumbnailStarted(imageIndex, thumbnailIndex);
+        }
+
+        public  void processThumbnailUpdate(BufferedImage theThumbnail,
+                                            int minX,
+                                            int minY,
+                                            int width,
+                                            int height,
+                                            int periodX,
+                                            int periodY,
+                                            int[] bands) {
+            super.processThumbnailUpdate(theThumbnail,
+                                         minX,
+                                         minY,
+                                         width,
+                                         height,
+                                         periodX,
+                                         periodY,
+                                         bands);
+        }
+
+        public  void processWarningOccurred(String warning) {
+            super.processWarningOccurred(warning);
+        }
+
+
+
+        public static Rectangle getSourceRegion(ImageReadParam param,
+                                                int srcWidth,
+                                                int srcHeight) {
+            return ImageReader.getSourceRegion(param, srcWidth, srcHeight);
+        }
+
+        public static void computeRegions(ImageReadParam param,
+                                          int srcWidth,
+                                          int srcHeight,
+                                          BufferedImage image,
+                                          Rectangle srcRegion,
+                                          Rectangle destRegion) {
+            ImageReader.computeRegions(param,
+                                       srcWidth,
+                                       srcHeight,
+                                       image,
+                                       srcRegion,
+                                       destRegion);
+        }
+
+        public static void checkReadParamBandSettings(ImageReadParam param,
+                                                      int numSrcBands,
+                                                      int numDstBands) {
+            ImageReader.checkReadParamBandSettings( param,
+                                                    numSrcBands,
+                                                    numDstBands);
+        }
+
+        public static BufferedImage getDestination(ImageReadParam param,
+                                                   Iterator imageTypes,
+                                                   int width,
+                                                   int height) throws IIOException {
+            return ImageReader.getDestination(param,
+                                              imageTypes,
+                                              width,
+                                              height);
+        }
+
+        public  void setAvailableLocales(Locale[] locales) {
+            if (locales == null || locales.length == 0)
+                availableLocales = null;
+            else
+                availableLocales = (Locale[])locales.clone();
+        }
+
+        public  void processWarningOccurred(String baseName, String keyword) {
+            super.processWarningOccurred(baseName, keyword);
+        }
+    }
+
+    public static class DummyIIOMetadataImpl extends IIOMetadata {
+
+        public DummyIIOMetadataImpl() {
+            super();
+        }
+
+        public DummyIIOMetadataImpl(boolean standardMetadataFormatSupported,
+                                    String nativeMetadataFormatName,
+                                    String nativeMetadataFormatClassName,
+                                    String[] extraMetadataFormatNames,
+                                    String[] extraMetadataFormatClassNames) {
+            super(standardMetadataFormatSupported,
+                  nativeMetadataFormatName,
+                  nativeMetadataFormatClassName,
+                  extraMetadataFormatNames,
+                  extraMetadataFormatClassNames);
+        }
+
+        public boolean isReadOnly() {
+            return true;
+        }
+
+        public Node getAsTree(String formatName) {
+            return null;
+        }
+
+        public void mergeTree(String formatName, Node root)
+          throws IIOInvalidTreeException {
+            throw new IllegalStateException();
+        }
+
+        public void reset() {
+            throw new IllegalStateException();
+        }
+    }
+
+    public static class DummyImageReaderSpiImpl extends ImageReaderSpi {
+
+        static final String[] names ={ "myformat" };
+
+        public DummyImageReaderSpiImpl() {
+            super("vendorName",
+                  "version",
+                  names,
+                  null,
+                  null,
+                  "DummyImageReaderImpl",
+                  STANDARD_INPUT_TYPE,
+                  null,
+                  true,
+                  null,
+                  null,
+                  null,
+                  null,
+                  true,
+                  null,
+                  null,
+                  null,
+                  null);
+        }
+        public boolean canDecodeInput(Object source)
+          throws IOException {
+            return true;
+        }
+        public ImageReader createReaderInstance(Object extension)
+          throws IOException {
+            return new DummyImageReaderImpl(this);
+        }
+        public String getDescription(Locale locale) {
+            return "DummyImageReaderSpiImpl";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/GetNumImages.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4892609
+ * @summary Tests that the appropriate IllegalStateException is thrown if
+ *          ImageReader.getNumImages() is called with a null source or if
+ *          allowSearch is specified at the same time that seekForwardOnly is
+ *          true
+ */
+
+import java.io.ByteArrayInputStream;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.stream.ImageInputStream;
+
+public class GetNumImages {
+
+    public static void main(String[] args) throws Exception {
+        IIORegistry registry = IIORegistry.getDefaultInstance();
+
+        // test ImageReader.getNumImages() for all available ImageReaders,
+        // with no source set
+        Iterator readerspis = registry.getServiceProviders(ImageReaderSpi.class,
+                                                           false);
+        while (readerspis.hasNext()) {
+            boolean caughtEx = false;
+            ImageReaderSpi readerspi = (ImageReaderSpi)readerspis.next();
+            ImageReader reader = readerspi.createReaderInstance();
+            try {
+                reader.getNumImages(false);
+            } catch (IllegalStateException ise) {
+                // caught exception, everything's okay
+                caughtEx = true;
+            }
+
+            if (!caughtEx) {
+                throw new RuntimeException("Test failed: exception was not " +
+                                           "thrown for null input: " +
+                                           reader);
+            }
+        }
+
+        // test ImageReader.getNumImages() for all available ImageReaders,
+        // with source set, seekForwardOnly and allowSearch both true
+        readerspis = registry.getServiceProviders(ImageReaderSpi.class,
+                                                  false);
+        while (readerspis.hasNext()) {
+            boolean caughtEx = false;
+            ImageReaderSpi readerspi = (ImageReaderSpi)readerspis.next();
+            ImageReader reader = readerspi.createReaderInstance();
+            byte[] barr = new byte[100];
+            ByteArrayInputStream bais = new ByteArrayInputStream(barr);
+            ImageInputStream iis = ImageIO.createImageInputStream(bais);
+            try {
+                reader.setInput(iis, true);
+                reader.getNumImages(true);
+            } catch (IllegalStateException ise) {
+                // caught exception, everything's okay
+                caughtEx = true;
+            }
+
+            if (!caughtEx) {
+                throw new RuntimeException("Test failed: exception was not " +
+                                           "thrown when allowSearch and " +
+                                           "seekForwardOnly are both true: " +
+                                           reader);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/GetReaderWriterInfo.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4703112
+ * @summary Verifies that ImageIO.getReaderFileSuffixes() and similar methods
+ *          return appropriate values
+ */
+
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageWriter;
+
+public class GetReaderWriterInfo {
+
+    private static void testGetReaderFormatNames() {
+        String[] names = ImageIO.getReaderFormatNames();
+        for (String n : names) {
+            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(n);
+            if (!it.hasNext()) {
+                throw new RuntimeException("getReaderFormatNames returned " +
+                                           "an unknown name: " + n);
+            }
+        }
+    }
+
+    private static void testGetReaderMIMETypes() {
+        String[] types = ImageIO.getReaderMIMETypes();
+        for (String t : types) {
+            Iterator<ImageReader> it = ImageIO.getImageReadersByMIMEType(t);
+            if (!it.hasNext()) {
+                throw new RuntimeException("getReaderMIMETypes returned " +
+                                           "an unknown type: " + t);
+            }
+        }
+    }
+
+    private static void testGetReaderFileSuffixes() {
+        String[] suffixes = ImageIO.getReaderFileSuffixes();
+        for (String s : suffixes) {
+            Iterator<ImageReader> it = ImageIO.getImageReadersBySuffix(s);
+            if (!it.hasNext()) {
+                throw new RuntimeException("getReaderFileSuffixes returned " +
+                                           "an unknown suffix: " + s);
+            }
+        }
+    }
+
+    private static void testGetWriterFormatNames() {
+        String[] names = ImageIO.getWriterFormatNames();
+        for (String n : names) {
+            Iterator<ImageWriter> it = ImageIO.getImageWritersByFormatName(n);
+            if (!it.hasNext()) {
+                throw new RuntimeException("getWriterFormatNames returned " +
+                                           "an unknown name: " + n);
+            }
+        }
+    }
+
+    private static void testGetWriterMIMETypes() {
+        String[] types = ImageIO.getWriterMIMETypes();
+        for (String t : types) {
+            Iterator<ImageWriter> it = ImageIO.getImageWritersByMIMEType(t);
+            if (!it.hasNext()) {
+                throw new RuntimeException("getWriterMIMETypes returned " +
+                                           "an unknown type: " + t);
+            }
+        }
+    }
+
+    private static void testGetWriterFileSuffixes() {
+        String[] suffixes = ImageIO.getWriterFileSuffixes();
+        for (String s : suffixes) {
+            Iterator<ImageWriter> it = ImageIO.getImageWritersBySuffix(s);
+            if (!it.hasNext()) {
+                throw new RuntimeException("getWriterFileSuffixes returned " +
+                                           "an unknown suffix: " + s);
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        testGetReaderFormatNames();
+        testGetReaderMIMETypes();
+        testGetReaderFileSuffixes();
+        testGetWriterFormatNames();
+        testGetWriterMIMETypes();
+        testGetWriterFileSuffixes();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/IIOImageConstructor.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4392024
+ * @summary Checks for IllegalArgumentException in IIOImage constructor
+ */
+
+import java.awt.image.BufferedImage;
+
+import javax.imageio.IIOImage;
+
+public class IIOImageConstructor {
+
+    public static void main(String[] args) {
+        BufferedImage image = new BufferedImage(1, 1,
+                                                BufferedImage.TYPE_INT_RGB);
+        try {
+            IIOImage iioi = new IIOImage(image, null, null);
+        } catch (IllegalArgumentException iae) {
+            throw new RuntimeException
+                ("IIOImage constructor taking a RenderedImage fails!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/ITSDataType.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4506450
+ * @summary Tests whether ImageTypeSpecifier.createBanded() and
+ *          ImageTypeSpecifier.createInterleaved() can accept all supported
+ *          DataBuffer types
+ */
+
+import java.awt.color.ColorSpace;
+import java.awt.image.DataBuffer;
+
+import javax.imageio.ImageTypeSpecifier;
+
+public class ITSDataType {
+
+    public static final int[] dataTypes = new int[] {
+        DataBuffer.TYPE_BYTE,
+        DataBuffer.TYPE_SHORT,
+        DataBuffer.TYPE_USHORT,
+        DataBuffer.TYPE_INT,
+        DataBuffer.TYPE_FLOAT,
+        DataBuffer.TYPE_DOUBLE,
+    };
+
+    public static void main(String[] args) {
+        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
+        int[] bankIndices = new int[] { 1 };
+        int[] bandOffsets = new int[] { 0 };
+
+        // test createBanded()
+        for (int i = 0; i < dataTypes.length; i++) {
+            int dataType = dataTypes[i];
+
+            try {
+                ImageTypeSpecifier.createBanded(cs, bankIndices, bandOffsets,
+                                                dataType, false, false);
+            } catch (IllegalArgumentException e) {
+                throw new RuntimeException("createBanded() test failed for " +
+                                           "dataType = " + dataType);
+            }
+        }
+
+        // test createInterleaved()
+        for (int i = 0; i < dataTypes.length; i++) {
+            int dataType = dataTypes[i];
+
+            try {
+                ImageTypeSpecifier.createInterleaved(cs, bandOffsets,
+                                                     dataType, false, false);
+            } catch (IllegalArgumentException e) {
+                throw new RuntimeException("createInterleaved() test failed " +
+                                           "for dataType = " + dataType);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/ImageIOGetImageReaders.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4432107
+ * @summary Checks if ImageIO.getImageReaders(null) throws an IAE
+ */
+
+import javax.imageio.ImageIO;
+
+public class ImageIOGetImageReaders {
+
+    public static void main(String[] args) {
+        boolean gotIAE = false;
+        try {
+            ImageIO.getImageReaders(null);
+        } catch (IllegalArgumentException e) {
+            gotIAE = true;
+        }
+
+        if (!gotIAE) {
+            throw new RuntimeException("Failed to get IAE!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/ImageIOWriteFile.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4393174
+ * @summary Checks that ImageIO.write(..., ..., File) truncates the file
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileOutputStream;
+
+import javax.imageio.ImageIO;
+
+public class ImageIOWriteFile {
+
+    public static void main(String[] args) {
+        long length0 = -1L;
+        long length1 = -1L;
+
+        try {
+            BufferedImage bi =
+                new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
+
+            File outFile = File.createTempFile("imageiowritefile", ".tmp");
+
+            // Write image to an empty file
+            outFile.delete();
+            ImageIO.write(bi, "png", outFile);
+            length0 = outFile.length();
+
+            // Write a larger file full of junk
+            outFile.delete();
+            FileOutputStream fos = new FileOutputStream(outFile);
+            for (int i = 0; i < length0*2; i++) {
+                fos.write(1);
+            }
+            fos.close();
+
+            // Write image again
+            ImageIO.write(bi, "png", outFile);
+            length1 = outFile.length();
+
+            outFile.delete();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Unexpected exception!");
+        }
+
+        if (length0 == 0) {
+            throw new RuntimeException("File length is zero!");
+        }
+        if (length1 != length0) {
+            throw new RuntimeException("File length changed!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/ImageIOWriteNull.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4434855
+ * @summary Checks that ImageIO.write(null, null, (File)null) throws an IAE
+ */
+
+import java.io.File;
+
+import javax.imageio.ImageIO;
+
+public class ImageIOWriteNull {
+
+    public static void main(String[] args) {
+        try {
+            ImageIO.write(null, null, (File)null);
+            throw new RuntimeException("Failed to get IAE!");
+        } catch (IllegalArgumentException iae) {
+        } catch (Exception e) {
+            throw new RuntimeException("Unexpected exception: " + e);
+        }
+   }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/ImageReadParamPasses.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4429365
+ * @summary Checks that ImageReadParam.setSourceProgressivePasses handles
+ *          overflow correctly
+ */
+
+import javax.imageio.ImageReadParam;
+
+public class ImageReadParamPasses {
+
+    private static final int maxint = Integer.MAX_VALUE;
+
+    private static void expect(int i, int j) {
+        if (i != j) {
+            throw new RuntimeException("Expected " + i + ", got " + j);
+        }
+    }
+
+    private static void checkForIAE(int minPass, int numPasses) {
+        ImageReadParam param = new ImageReadParam();
+
+        boolean gotIAE = false;
+        try {
+            param.setSourceProgressivePasses(minPass, numPasses);
+        } catch (IllegalArgumentException iae) {
+            gotIAE = true;
+        }
+        if (!gotIAE) {
+            throw new RuntimeException("Failed to get IAE for wraparound!");
+        }
+    }
+
+    private static void test(int minPass, int numPasses) {
+        ImageReadParam param = new ImageReadParam();
+
+        param.setSourceProgressivePasses(minPass, numPasses);
+        expect(param.getSourceMinProgressivePass(), minPass);
+        expect(param.getSourceNumProgressivePasses(), numPasses);
+
+        int maxPass = numPasses == maxint ? maxint : minPass + numPasses - 1;
+        expect(param.getSourceMaxProgressivePass(), maxPass);
+    }
+
+    public static void main(String[] args) {
+        // Typical case
+        test(17, 30);
+
+        // Read all passes
+        test(0, maxint);
+
+        // Start at pass 17, continue indefinitely
+        test(17, maxint);
+
+        // Start at pass maxint - 10, continue indefinitely
+        test(maxint - 10, maxint);
+
+        // Start at pass maxint - 10, go up to maxint - 1
+        test(maxint - 10, 10);
+
+        // Start at pass maxint - 10, go up to maxint
+        test(maxint - 10, 11);
+
+        // Start at maxint, continue indefinitely :-)
+        test(maxint, maxint);
+
+        // Start at maxint, go up to maxint
+        test(maxint, 1);
+
+        // Check that an IllegalArgumentException is thrown if
+        // wraparound occurs
+        checkForIAE(maxint, 2);
+        checkForIAE(maxint - 5, 10);
+        checkForIAE(10, maxint - 5);
+        checkForIAE(maxint - 1000, maxint - 1000);
+        checkForIAE(maxint - 1, maxint - 1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/ImageReaderGetDestination.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4449211
+ * @summary Checks that ImageReader.getDestination throws correct exceptions
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.imageio.IIOException;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.ImageReaderSpi;
+
+public class ImageReaderGetDestination {
+
+    public static void main(String argv[]) {
+        Vector imageTypes = new Vector();
+        boolean gotIAE1 = false;
+        boolean gotIAE2 = false;
+        boolean gotIAE3 = false;
+        boolean gotIAE4 = false;
+
+        try {
+            DummyImageReaderImpl.getDestination(null, null, 5, 10);
+        } catch (IllegalArgumentException iae) {
+            gotIAE1 = true;
+        } catch (Throwable ee) {
+            System.out.println("Unexpected exception 1:");
+            ee.printStackTrace();
+        }
+        if (!gotIAE1) {
+            throw new RuntimeException("Failed to get IAE #1!");
+        }
+
+        try {
+            DummyImageReaderImpl.getDestination(null, imageTypes.iterator(),
+                                                5, 10);
+        } catch (IllegalArgumentException iae) {
+            gotIAE2 = true;
+        } catch (Throwable ee) {
+            System.out.println("Unexpected exception 2:");
+            ee.printStackTrace();
+        }
+        if (!gotIAE2) {
+            throw new RuntimeException("Failed to get IAE #2!");
+        }
+
+        imageTypes.add("abc");
+        try {
+            DummyImageReaderImpl.getDestination(null, imageTypes.iterator(),
+                                                5, 10);
+        } catch (IllegalArgumentException iae) {
+            gotIAE3 = true;
+        } catch (Throwable ee) {
+            System.out.println("Unexpected exception 3:");
+            ee.printStackTrace();
+        }
+        if (!gotIAE3) {
+            throw new RuntimeException("Failed to get IAE #3!");
+        }
+
+        imageTypes.clear();
+        ImageTypeSpecifier its = ImageTypeSpecifier.createFromBufferedImageType
+            (BufferedImage.TYPE_INT_RGB);
+        imageTypes.add(its);
+        try {
+            DummyImageReaderImpl.getDestination(null,
+                                                imageTypes.iterator(),
+                                                Integer.MAX_VALUE,
+                                                Integer.MAX_VALUE);
+        } catch (IllegalArgumentException iae) {
+            gotIAE4 = true;
+        } catch (Throwable ee) {
+            System.out.println("Unexpected exception 4: ");
+            ee.printStackTrace();
+        }
+        if (!gotIAE4) {
+            throw new RuntimeException("Failed to get IAE #4!");
+        }
+    }
+
+    public static class DummyImageReaderImpl extends ImageReader {
+        public DummyImageReaderImpl(ImageReaderSpi originatingProvider) {
+            super(originatingProvider);
+        }
+        public static BufferedImage getDestination(ImageReadParam param,
+                                                   Iterator imageTypes,
+                                                   int width,
+                                                   int height)
+          throws IIOException {
+            return ImageReader.getDestination(param, imageTypes, width, height);
+        }
+        public int getNumImages(boolean allowSearch) throws IOException {return 1;}
+        public int getWidth(int imageIndex) throws IOException {return 1;}
+        public int getHeight(int imageIndex) throws IOException {return 1;}
+        public Iterator getImageTypes(int imageIndex)
+          throws IOException {return null;}
+        public IIOMetadata getStreamMetadata() throws IOException {return null;}
+        public IIOMetadata getImageMetadata(int imageIndex)
+          throws IOException {return null;}
+        public BufferedImage read(int imageIndex, ImageReadParam param)
+          throws IOException {return null;}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/ImageReaderReadAll.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4450319
+ * @summary Checks that ImageReader.readAll(int, ImageReadParam) makes use of
+ *          the ImageReadParam object
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.stream.MemoryCacheImageInputStream;
+
+public class ImageReaderReadAll {
+
+    private final static byte[] ba = {};
+
+    public static void main(String argv[]) {
+        ImageReader ireader;
+        ImageReadParam irp;
+        IIOImage image;
+        BufferedImage bi;
+        BufferedImage bi_1;
+        BufferedImage bi_2;
+
+        ireader = new DummyImageReaderImpl(null);
+        MemoryCacheImageInputStream mciis = new MemoryCacheImageInputStream
+            (new ByteArrayInputStream(ba));
+        ireader.setInput(mciis);
+
+        irp = new ImageReadParam();
+        irp.setDestination(new BufferedImage(10, 10,
+                                             BufferedImage.TYPE_3BYTE_BGR));
+        try {
+            image = ireader.readAll(0, irp);
+            bi_1 = ireader.read(0, irp);
+            bi_2 = ireader.read(0);
+        } catch (java.io.IOException ee) {
+            throw new RuntimeException("Unexpected exception: " + ee);
+        }
+
+        bi = (BufferedImage)image.getRenderedImage();
+        if (bi.getType() != bi_1.getType()) {
+            throw new RuntimeException("Images have different type!");
+        }
+    }
+
+
+    public static class DummyImageReaderImpl extends ImageReader {
+
+        public DummyImageReaderImpl(ImageReaderSpi originatingProvider) {
+            super(originatingProvider);
+        }
+
+        public BufferedImage read(int imageIndex, ImageReadParam param)
+          throws IOException {
+            if (input == null)
+                throw new IllegalStateException();
+            if (imageIndex >= 1 || imageIndex < 0)
+                throw new IndexOutOfBoundsException();
+            if (seekForwardOnly) {
+                if (imageIndex < minIndex)
+                    throw new IndexOutOfBoundsException();
+                minIndex = imageIndex;
+            }
+
+            return getDestination(param, getImageTypes(imageIndex), 10, 15);
+        }
+
+        public Iterator getImageTypes(int imageIndex) throws IOException {
+            if (input == null)
+                throw new IllegalStateException();
+            if (imageIndex >= 1 || imageIndex < 0)
+                throw new IndexOutOfBoundsException();
+
+            Vector imageTypes = new Vector();
+            imageTypes.add(ImageTypeSpecifier.createFromBufferedImageType
+                           (BufferedImage.TYPE_BYTE_GRAY ));
+            return imageTypes.iterator();
+        }
+
+        public int getNumImages(boolean allowSearch) throws IOException {return 1;}
+        public int getWidth(int imageIndex) throws IOException {return 1;}
+        public int getHeight(int imageIndex) throws IOException {return 1;}
+        public IIOMetadata getStreamMetadata() throws IOException {return null;}
+        public IIOMetadata getImageMetadata(int imageIndex)
+          throws IOException {return null;}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/ImageStreamFromRAF.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4395378
+ * @summary Checks that ImageIO.createImageInputStream and
+ *          createImageOutputStream produce correct output when given a
+ *          RandomAccessFile
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import javax.imageio.ImageIO;
+import javax.imageio.stream.FileImageInputStream;
+import javax.imageio.stream.FileImageOutputStream;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+
+public class ImageStreamFromRAF {
+
+    public static void main(String[] args) {
+        try {
+            File f = new File("ImageInputStreamFromRAF.tmp");
+            RandomAccessFile raf = new RandomAccessFile(f, "rw");
+            ImageInputStream istream = ImageIO.createImageInputStream(raf);
+            ImageOutputStream ostream = ImageIO.createImageOutputStream(raf);
+            f.delete();
+            if (istream == null) {
+                throw new RuntimeException("ImageIO.createImageInputStream(RandomAccessFile) returned null!");
+            }
+            if (ostream == null) {
+                throw new RuntimeException("ImageIO.createImageOutputStream(RandomAccessFile) returned null!");
+            }
+            if (!(istream instanceof FileImageInputStream)) {
+                throw new RuntimeException("ImageIO.createImageInputStream(RandomAccessFile) did not return a FileImageInputStream!");
+            }
+            if (!(ostream instanceof FileImageOutputStream)) {
+                throw new RuntimeException("ImageIO.createImageOutputStream(RandomAccessFile) did not return a FileImageOutputStream!");
+            }
+        } catch (IOException ioe) {
+            throw new RuntimeException("Unexpected IOException: " + ioe);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/ImageTypeSpecifierBitsPerBand.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4392669
+ * @summary Checks contract of ImageTypeSpecifier.getBitsPerBand
+ */
+
+import java.awt.image.BufferedImage;
+
+import javax.imageio.ImageTypeSpecifier;
+
+public class ImageTypeSpecifierBitsPerBand {
+
+    public static void main(String[] args) {
+        int biType = BufferedImage.TYPE_USHORT_565_RGB;
+        ImageTypeSpecifier type =
+            ImageTypeSpecifier.createFromBufferedImageType(biType);
+
+        int b0 = type.getBitsPerBand(0);
+        int b1 = type.getBitsPerBand(1);
+        int b2 = type.getBitsPerBand(2);
+
+        if (b0 != 5 || b1 != 6 || b2 != 5) {
+            throw new RuntimeException("Got incorrect bits per band value!");
+        }
+
+        boolean gotIAE = false;
+        try {
+            int b3 = type.getBitsPerBand(3);
+        } catch (IllegalArgumentException e) {
+            gotIAE = true;
+        }
+        if (!gotIAE) {
+            throw new RuntimeException
+                ("Failed to get IllegalArgumentException for band == 3!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/ImageTypeSpecifierTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4429934 4429950 4430991 4430993
+ * @summary Checks various aspects of ImageTypeSpecifier functionality
+ */
+
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.SampleModel;
+
+import javax.imageio.ImageTypeSpecifier;
+
+public class ImageTypeSpecifierTest {
+
+    private static void fail(String message) {
+        throw new RuntimeException(message);
+    }
+
+    private static void test4429934() {
+        try {
+            ImageTypeSpecifier itspecifier =
+                new ImageTypeSpecifier(null, null);
+            fail("Failed to get IAE!");
+        } catch( IllegalArgumentException e ) {
+        }
+
+        try {
+            ImageTypeSpecifier itspecifier = new ImageTypeSpecifier(null);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e ) {
+        }
+    }
+
+    private static void test4429950() {
+        createPackedTest();
+        createInterleavedTest();
+        createBandedTest();
+        createIndexedTest();
+    }
+
+    public static void createPackedTest() {
+        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        int rmask = 0x00ff0000;
+        int gmask = 0x0000ff00;
+        int bmask = 0x000000ff;
+        int amask = 0xff000000;
+        try {
+            ImageTypeSpecifier.createPacked(null, rmask, gmask, bmask, amask, 0,
+false);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        ColorSpace cs1 = ColorSpace.getInstance(ColorSpace.CS_GRAY);
+        try {
+            ImageTypeSpecifier.createPacked
+                (cs1, rmask, gmask, bmask, amask, 0, false);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            ImageTypeSpecifier.createPacked(cs, 0, 0, 0, 0, 0, false);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            ImageTypeSpecifier.createPacked(cs, rmask, gmask, bmask, amask, -1,
+false);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public static void createInterleavedTest() {
+        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        int[] bandOffsets = {0,0,0,0};
+        int dataType = 0;
+        boolean hasAlpha = true;
+        boolean isAlphaPremultiplied = true;
+
+        try {
+            ImageTypeSpecifier.createInterleaved
+                (null, bandOffsets, dataType, hasAlpha, isAlphaPremultiplied);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            ImageTypeSpecifier.createInterleaved
+                (cs, null, dataType, hasAlpha, isAlphaPremultiplied);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        int[] bad_bandOffsets = {0,100,1000};
+        try {
+            ImageTypeSpecifier.createInterleaved
+                (cs, bad_bandOffsets, dataType, hasAlpha, isAlphaPremultiplied);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        int[] bad_bandOffsets_1 = {};
+        try {
+            ImageTypeSpecifier.createInterleaved
+                (cs, bad_bandOffsets_1, dataType, hasAlpha, isAlphaPremultiplied);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public static void createBandedTest() {
+        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        int[] bankIndices = {0, 100, 1000, 10000};
+        int[] bandOffsets = {0, 100, 1000, 10000};
+        int dataType = 0;
+        boolean hasAlpha = true;
+        boolean isAlphaPremultiplied = true;
+
+        try {
+            ImageTypeSpecifier.createBanded(null, bankIndices, bandOffsets,
+                dataType, hasAlpha, isAlphaPremultiplied);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        int[] bad_bankIndices = {};
+        int[] bad_bandOffsets = {};
+        try {
+            ImageTypeSpecifier.createBanded(cs, bad_bankIndices, bad_bandOffsets,
+                dataType, hasAlpha, isAlphaPremultiplied);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            ImageTypeSpecifier.createBanded(cs, bankIndices, bandOffsets,
+                99999, hasAlpha, isAlphaPremultiplied);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public static void createGrayscaleTest() {
+        int bits = 8;
+        int dataType = DataBuffer.TYPE_BYTE;
+        boolean isSigned = true;
+        // testcase 1
+        try {
+            ImageTypeSpecifier.createGrayscale(100, dataType, isSigned);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            ImageTypeSpecifier.createGrayscale(10, dataType, isSigned);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            ImageTypeSpecifier.createGrayscale(bits, 100, isSigned);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+   }
+
+   public static void createIndexedTest() {
+        byte[] redLUT = {0};
+        byte[] greenLUT = {0};
+        byte[] blueLUT = {0};
+        byte[] alphaLUT = {0};
+        int bits = 8;
+        int dataType = DataBuffer.TYPE_BYTE;
+
+        try {
+            ImageTypeSpecifier.createIndexed(redLUT, greenLUT,
+                blueLUT, alphaLUT, 0, dataType);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            ImageTypeSpecifier.createIndexed(redLUT, greenLUT,
+                blueLUT, alphaLUT, 17, dataType);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            ImageTypeSpecifier.createIndexed(redLUT, greenLUT,
+                blueLUT, alphaLUT, 10, dataType);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        byte[] greenLUT_4 = {};
+        try {
+            ImageTypeSpecifier.createIndexed(redLUT, greenLUT_4,
+                blueLUT, alphaLUT, bits, dataType);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        byte[] redLUT_5 = {};
+        try {
+            ImageTypeSpecifier.createIndexed(redLUT_5, greenLUT,
+                blueLUT, alphaLUT, bits, dataType);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        byte[] alphaLUT_6 = {};
+        try {
+            ImageTypeSpecifier.createIndexed(redLUT, greenLUT,
+                blueLUT, alphaLUT_6 , bits, dataType);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            ImageTypeSpecifier.createIndexed(redLUT, greenLUT,
+                blueLUT, alphaLUT , bits, 100);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    private static void test4430991() {
+        ImageTypeSpecifier itspecifier;
+
+        itspecifier = ImageTypeSpecifier.createFromBufferedImageType
+            (BufferedImage.TYPE_INT_RGB);
+
+        try {
+            itspecifier.createBufferedImage(Integer.MAX_VALUE,
+                                            Integer.MAX_VALUE);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            itspecifier.getSampleModel(Integer.MAX_VALUE, Integer.MAX_VALUE);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    private static void test4430993() {
+        ImageTypeSpecifier itspecifier;
+
+        int bits = 32;
+        int rmask = 0x00ff0000;
+        int gmask = 0x0000ff00;
+        int bmask = 0x000000ff;
+        ColorModel dcm = new java.awt.image.DirectColorModel
+            (bits, rmask, gmask, bmask);
+        int[] bandOffsets = new int[2];
+        bandOffsets[1] = 1;
+        SampleModel sm = new java.awt.image.ComponentSampleModel
+            (DataBuffer.TYPE_SHORT, 1, 1, 2, 2, bandOffsets);
+
+        try {
+            itspecifier = new ImageTypeSpecifier(dcm, sm);
+            fail("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public static void main(String[] args) {
+        try {
+            test4429934();
+            test4429950();
+            test4430991();
+            test4430993();
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("Unexpected exception: " + e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/ImageWriteParamMisc.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4434870 4434886 4441315 4446842
+ * @summary Checks that miscellaneous ImageWriteParam methods work properly
+ */
+
+import java.awt.Dimension;
+
+import javax.imageio.ImageWriteParam;
+
+public class ImageWriteParamMisc {
+
+    public static void main(String[] args) {
+        test4434870();
+        test4434886();
+        test4441315();
+        test4446842();
+    }
+
+    public static class ImageWriteParam4434870 extends ImageWriteParam {
+        public ImageWriteParam4434870() {
+            super(null);
+            super.canWriteTiles = true;
+            super.preferredTileSizes =
+                new Dimension[] {new Dimension(1, 2), new Dimension(5, 6)};
+        }
+    }
+
+    private static void test4434870() {
+        ImageWriteParam iwp = new ImageWriteParam4434870();
+        try {
+            Dimension[] dimensions = iwp.getPreferredTileSizes();
+            iwp.setTilingMode(ImageWriteParam.MODE_EXPLICIT);
+            iwp.setTiling(100, 100, 0,0);
+            throw new RuntimeException("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public static class ImageWriteParam4434886 extends ImageWriteParam {
+        public ImageWriteParam4434886() {
+            super(null);
+            super.canWriteTiles = true;
+            super.canOffsetTiles = true;
+        }
+    }
+
+    private static void test4434886() {
+        ImageWriteParam iwp = new ImageWriteParam4434886();
+        iwp.setTilingMode(ImageWriteParam.MODE_EXPLICIT);
+        try {
+            iwp.setTiling(-1,-2,-3,-4);
+            throw new RuntimeException("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public static class ImageWriteParam4441315 extends ImageWriteParam {
+        public ImageWriteParam4441315() {
+            super(null);
+            super.canWriteProgressive = true;
+        }
+    }
+
+    private static void test4441315() {
+        ImageWriteParam iwp = new ImageWriteParam4441315();
+        try {
+            iwp.setProgressiveMode(ImageWriteParam.MODE_EXPLICIT);
+            throw new RuntimeException("Failed to get IAE!");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    private static void test4446842() {
+        ImageWriteParam iwp = new ImageWriteParam(null);
+        try {
+            iwp.getCompressionTypes();
+            throw new RuntimeException("Failed to get UOE!");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/NullInputOutput.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4892682 4892698
+ * @summary Tests that the appropriate IllegalStateException is thrown if
+ *          ImageReader.read() or ImageWriter.write() is called without having
+ *          first set the input/output stream
+ */
+
+import java.awt.image.BufferedImage;
+import java.util.Iterator;
+
+import javax.imageio.ImageReader;
+import javax.imageio.ImageWriter;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.ImageWriterSpi;
+
+public class NullInputOutput {
+
+    public static void main(String[] args) throws Exception {
+        IIORegistry registry = IIORegistry.getDefaultInstance();
+
+        // test ImageReader.read() for all available ImageReaders
+        Iterator readerspis = registry.getServiceProviders(ImageReaderSpi.class,
+                                                           false);
+        while (readerspis.hasNext()) {
+            ImageReaderSpi readerspi = (ImageReaderSpi)readerspis.next();
+            ImageReader reader = readerspi.createReaderInstance();
+            try {
+                reader.read(0);
+            } catch (IllegalStateException ise) {
+                // caught exception, everything's okay
+            }
+        }
+
+        // test ImageWriter.write() for all available ImageWriters
+        BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
+        Iterator writerspis = registry.getServiceProviders(ImageWriterSpi.class,
+                                                           false);
+        while (writerspis.hasNext()) {
+            ImageWriterSpi writerspi = (ImageWriterSpi)writerspis.next();
+            ImageWriter writer = writerspi.createWriterInstance();
+            try {
+                writer.write(bi);
+            } catch (IllegalStateException ise) {
+                // caught exception, everything's okay
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/PNGSpiStreamMetadata.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4403355
+ * @summary Checks that PNGImage{Reader,Writer}Spi.getStreamMetadataFormatNames
+ *          and getNativeStreamMetadataFormatName return null
+ */
+
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.ImageWriterSpi;
+
+import com.sun.imageio.plugins.png.PNGImageReaderSpi;
+import com.sun.imageio.plugins.png.PNGImageWriterSpi;
+
+public class PNGSpiStreamMetadata {
+
+    private static void fatal() {
+        throw new RuntimeException("Got a non-null stream metadata format!");
+    }
+
+    public static void main(String[] args) {
+        ImageReaderSpi rspi = new PNGImageReaderSpi();
+        if (rspi.getNativeStreamMetadataFormatName() != null) {
+            fatal();
+        }
+        if (rspi.isStandardStreamMetadataFormatSupported() != false) {
+            fatal();
+        }
+        if (rspi.getExtraStreamMetadataFormatNames() != null) {
+            fatal();
+        }
+
+        ImageWriterSpi wspi = new PNGImageWriterSpi();
+        if (wspi.getNativeStreamMetadataFormatName() != null) {
+            fatal();
+        }
+        if (wspi.isStandardStreamMetadataFormatSupported() != false) {
+            fatal();
+        }
+        if (wspi.getExtraStreamMetadataFormatNames() != null) {
+            fatal();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/PNGSuffixes.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4394924
+ * @summary Checks for spurious leading "." in PNG file suffixes
+ */
+
+import com.sun.imageio.plugins.png.PNGImageWriterSpi;
+
+public class PNGSuffixes {
+
+    public static void main(String[] args) {
+        String[] suffixes = new PNGImageWriterSpi().getFileSuffixes();
+        for (int i = 0; i < suffixes.length; i++) {
+            if (suffixes[i].startsWith(".")) {
+                throw new RuntimeException("Found a \".\" in a suffix!");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/ReadBitsTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4416800
+ * @summary Checks that ImageInputStreamImpl.readBit and readBits handle the bit
+ *          offset correctly
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.imageio.stream.FileCacheImageInputStream;
+import javax.imageio.stream.ImageInputStream;
+
+public class ReadBitsTest {
+    public static void main(String[] args) throws IOException {
+        byte[] buffer = new byte[] {(byte)169, (byte)85}; // 10101001 01010101
+        InputStream ins = new ByteArrayInputStream(buffer);
+        ImageInputStream in = new FileCacheImageInputStream(ins,null);
+
+        if (in.getBitOffset() != 0) {
+            throw new RuntimeException("Initial bit offset != 0!");
+        }
+
+        int bit0 = in.readBit(); // 1
+        if (bit0 != 1) {
+            throw new RuntimeException("First bit != 1");
+        }
+        if (in.getBitOffset() != 1) {
+            throw new RuntimeException("Second bit offset != 1");
+        }
+
+        long bits1 = in.readBits(5); // 01010 = 10
+        if (bits1 != 10) {
+            throw new RuntimeException("Bits 1-5 != 10 (= " + bits1 + ")");
+        }
+        if (in.getBitOffset() != 6) {
+            throw new RuntimeException("Third bit offset != 6");
+        }
+
+        int bit1 = in.readBit(); // 0
+        if (bit1 != 0) {
+            throw new RuntimeException("Bit 6 != 0");
+        }
+        if (in.getBitOffset() != 7) {
+            throw new RuntimeException("Third bit offset != 7");
+        }
+
+        long bits2 = in.readBits(8); // 10101010 = 170
+        if (bits2 != 170) {
+            throw new RuntimeException("Bits 7-14 != 170 (= " + bits2 + ")");
+        }
+        if (in.getBitOffset() != 7) {
+            throw new RuntimeException("Fourth bit offset != 7");
+        }
+
+        int bit2 = in.readBit(); // 1
+        if (bit2 != 1) {
+            throw new RuntimeException("Bit 15 != 1");
+        }
+        if (in.getBitOffset() != 0) {
+            throw new RuntimeException("Fifth bit offset != 0");
+        }
+
+        in.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/SetOutput.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4414455
+ * @summary Checks for NPE from ImageWriter.setOutput when the writer has no
+ *          originating service provider
+ */
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
+
+import com.sun.imageio.plugins.png.PNGImageWriter;
+
+public class SetOutput {
+
+    public static void main(String[] args) throws IOException {
+        ImageWriter iw = new PNGImageWriter(null);
+        File f = File.createTempFile("imageio", "tmp");
+        ImageOutputStream ios = ImageIO.createImageOutputStream(f);
+        try {
+            iw.setOutput(ios);
+        } catch (NullPointerException npe) {
+            f.delete();
+            throw new RuntimeException("Got NullPointerException!");
+        }
+        f.delete();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/WriteNullImageTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4954545
+ * @summary This test verifies whether the ImageWriter implementations throw
+ *          IllegalArgumentException when a null image is passed to the write
+ *          method. This is tested for all the image writers available with the
+ *          IIORegistry.
+ */
+
+import java.io.FileOutputStream;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.stream.ImageOutputStream;
+
+public class WriteNullImageTest {
+
+    public WriteNullImageTest() {
+        boolean testFailed = false;
+        String failMsg = "FAIL: IllegalArgumentException is not thrown by the " +
+            "ImageWriter when the image passed to the write() method is " +
+            "null, for the image formats: ";
+
+        try {
+            IIORegistry reg = IIORegistry.getDefaultInstance();
+            ImageWriter writer = null;
+            Iterator writerSpiIter = reg.getServiceProviders(ImageWriterSpi.class, true);
+
+            while (writerSpiIter.hasNext()) {
+                ImageWriterSpi writerSpi = (ImageWriterSpi) writerSpiIter.next();
+                writer = writerSpi.createWriterInstance();
+                String names[] = writerSpi.getFormatNames();
+
+                FileOutputStream fos = new FileOutputStream("temp");
+                ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
+                writer.setOutput(ios);
+
+                try {
+                    writer.write(null, null, null);
+                } catch (IllegalArgumentException iae) {
+                    System.out.println("PASS: Expected exception is thrown when null img is passed " +
+                                       "to the write method, for the image format: " + names[0]);
+                    System.out.println("\n");
+                } catch (Exception e) {
+                    testFailed = true;
+                    failMsg = failMsg + names[0] + ", ";
+                }
+            }
+
+        } catch (Exception e) {
+            testFailed = true;
+            throw new RuntimeException("Test Failed. Exception thrown: " + e.toString());
+        }
+        if (testFailed) {
+            failMsg = failMsg.substring(0, failMsg.lastIndexOf(","));
+            throw new RuntimeException(failMsg);
+        }
+    }
+
+    public static void main(String args[]) {
+        WriteNullImageTest test = new WriteNullImageTest();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/event/WriteProgressListenerTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4420342 4421831
+ * @summary Checks that IIOWriteProgressListener methods are called in proper
+ *          sequence for the JPEG and PNG writers
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.event.IIOWriteProgressListener;
+import javax.imageio.stream.ImageOutputStream;
+
+public class WriteProgressListenerTest implements IIOWriteProgressListener {
+
+    final static int UNINITIALIZED = 0;
+    final static int IMAGE_STARTED = 1;
+    final static int IMAGE_COMPLETE = 2;
+
+    int state = UNINITIALIZED;
+    float prevPercentageDone = 0.0F;
+    File tempFile = null;
+
+    public WriteProgressListenerTest(String format) throws IOException {
+        ImageWriter writer = null;
+        Iterator witer = ImageIO.getImageWritersByFormatName(format);
+        if (!witer.hasNext()) {
+            error("No writer for format " + format + "!");
+        }
+        writer = (ImageWriter)witer.next();
+
+        System.out.println("Got writer " + writer);
+        writer.addIIOWriteProgressListener(this);
+
+        this.tempFile = File.createTempFile("imageio", ".tmp");
+        tempFile.deleteOnExit();
+        ImageOutputStream stream = ImageIO.createImageOutputStream(tempFile);
+        writer.setOutput(stream);
+
+        BufferedImage im =
+            new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR);
+
+        this.state = UNINITIALIZED;
+
+        writer.write(im);
+
+        if (this.state == UNINITIALIZED) {
+            error("imageStarted never called!");
+        }
+        if (this.state != IMAGE_COMPLETE) {
+            error("imageComplete not called!");
+        }
+
+        print("Passed!");
+    }
+
+    private void error(String s) {
+        if (tempFile != null) {
+            tempFile.delete();
+        }
+        throw new RuntimeException(s);
+    }
+
+    private void print(String s) {
+        System.out.println(s);
+    }
+
+    public void sequenceStarted(ImageWriter source) {
+        error("Obsolete method sequenceStarted was called!");
+    }
+
+    public void sequenceComplete(ImageWriter source) {
+        error("Obsolete method sequenceComplete was called!");
+    }
+
+    public void imageStarted(ImageWriter source, int imageIndex) {
+        print("imageStarted: imageIndex = " + imageIndex);
+
+        if (state != UNINITIALIZED) {
+            error("imageStarted not called first!");
+        }
+        state = IMAGE_STARTED;
+        prevPercentageDone = 0.0F;
+    }
+
+    public void imageProgress(ImageWriter source,
+                              float percentageDone) {
+        print("imageProgress: percentageDone = " + percentageDone);
+
+        if (state != IMAGE_STARTED) {
+            error("imageProgress called without prior imageStarted!");
+        }
+        if (percentageDone < prevPercentageDone) {
+            error("percentageDone did not increase!");
+        }
+        prevPercentageDone = percentageDone;
+    }
+
+    public void imageComplete(ImageWriter source) {
+        print("imageComplete");
+
+        if (state != IMAGE_STARTED) {
+            error("imageComplete called without imageStarted!");
+        }
+        if (prevPercentageDone == 0.0F) {
+            error("percentageDone was never updated!");
+        }
+        state = IMAGE_COMPLETE;
+    }
+
+    public void thumbnailStarted(ImageWriter source,
+                                 int imageIndex, int thumbnailIndex) {
+    }
+
+    public void thumbnailProgress(ImageWriter source, float percentageDone) {
+    }
+
+    public void thumbnailComplete(ImageWriter source) {
+    }
+
+    public void writeAborted(ImageWriter source) {
+    }
+
+    public static void main(String[] args) throws IOException {
+        new WriteProgressListenerTest("jpeg");
+        new WriteProgressListenerTest("png");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/BMPCompressionTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4641872
+ * @summary Tests writing compression modes of BMP plugin
+ */
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DirectColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.PixelInterleavedSampleModel;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.WritableRaster;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.plugins.bmp.BMPImageWriteParam;
+import javax.imageio.stream.ImageOutputStream;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+
+import com.sun.imageio.plugins.bmp.BMPMetadata;
+
+public class BMPCompressionTest {
+
+    static final String format = "BMP";
+
+    public static void main(String[] args) {
+
+        ImageWriter iw = null;
+        Iterator writers = ImageIO.getImageWritersByFormatName(format);
+        if (!writers.hasNext()) {
+            throw new RuntimeException("No available Image writer for "+format);
+        }
+        iw = (ImageWriter)writers.next();
+
+
+        Iterator tests = Test.createTestSet(iw);
+
+        while(tests.hasNext()) {
+
+            Test t = (Test)tests.next();
+            System.out.println(t.getDescription());
+            t.doTest();
+        }
+
+    }
+
+
+    static class Test {
+        static ImageWriter iw;
+        private BufferedImage img;
+        private String description;
+        private BMPImageWriteParam param;
+        private IIOMetadata meta;
+
+
+        public static Iterator createTestSet(ImageWriter w) {
+            List l = new LinkedList();
+
+            Test.iw = w;
+
+            // variate compression types
+            BMPImageWriteParam param = (BMPImageWriteParam)iw.getDefaultWriteParam();
+            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+            param.setCompressionType("BI_RGB");
+            if (param.canWriteCompressed()) {
+                String[] cTypes = param.getCompressionTypes();
+                String[] cDescr = param.getCompressionQualityDescriptions();
+                float[] cValues = param.getCompressionQualityValues();
+
+                if (cDescr == null) {
+                    System.out.println("There are no compression quality description!");
+                } else {
+                    for(int i=0; i<cDescr.length; i++) {
+                        System.out.println("Quality[" + i + "]=\""+cDescr[i]+"\"");
+                    }
+                }
+                if (cValues == null) {
+                    System.out.println("There are no compression quality values!");
+                } else {
+                    for(int i=0; i<cValues.length; i++) {
+                        System.out.println("Value["+i+"]=\""+cValues[i]+"\"");
+                    }
+                }
+
+                for(int i=0; i<cTypes.length; i++) {
+                    String compressionType = cTypes[i];
+                    BufferedImage img = null;
+
+                    int type = BufferedImage.TYPE_INT_BGR;
+                    try {
+                        img = createTestImage(type);
+                        if (compressionType.equals("BI_RLE8")) {
+                            img = createTestImage2(8, DataBuffer.TYPE_BYTE);
+                        } else if (compressionType.equals("BI_RLE4")) {
+                            img = createTestImage3(4, DataBuffer.TYPE_BYTE);
+                        } else if (compressionType.equals("BI_BITFIELDS")) {
+                            img = createTestImage4(32);
+                        }
+
+                    } catch (IOException ex) {
+                        throw new RuntimeException("Unable to create test image");
+                    }
+                    BMPImageWriteParam p = (BMPImageWriteParam)iw.getDefaultWriteParam();
+                    System.out.println("Current compression type is \""+cTypes[i]+"\"");
+                    p.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+                    p.setCompressionType(compressionType);
+
+                    IIOMetadata md = iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), p);
+
+                    l.add( new Test(p, md, img));
+                }
+            }
+            //     }
+            return l.iterator();
+
+        }
+
+        private Test(BMPImageWriteParam p, IIOMetadata md, BufferedImage i) {
+            param = p;
+            meta = md;
+            img = i;
+
+
+            description = "Compression type is " + p.getCompressionType();
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public void doTest() {
+            try {
+                System.out.println(this.getDescription());
+                if (param.getCompressionMode() != ImageWriteParam.MODE_EXPLICIT) {
+                    System.out.println("Warning: compression mode is not MODE_EXPLICIT");
+                }
+                // change metadata according to ImageWriteParam
+                IIOMetadata new_meta = iw.convertImageMetadata(meta, new ImageTypeSpecifier(img), param);
+
+                IIOImage iio_img = new IIOImage(img, null, new_meta);
+
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+                iw.setOutput(ios);
+                System.out.print("write image...");
+                System.out.println("Current compression Type is \""+param.getCompressionType()+"\"");
+                iw.write(new_meta, iio_img, param);
+                //iw.write(iio_img);
+                System.out.println("OK");
+                System.out.print("read image ... ");
+                ios.flush();
+
+                byte[] ba_image = baos.toByteArray();
+
+                System.out.println("Array length=" + ba_image.length);
+                FileOutputStream fos = new FileOutputStream(new File(param.getCompressionType()+".bmp"));
+                fos.write(ba_image);
+                fos.flush();
+                fos = null;
+                ByteArrayInputStream bais = new ByteArrayInputStream(ba_image);
+
+                ImageReader ir = ImageIO.getImageReader(iw);
+                ir.setInput(ImageIO.createImageInputStream(bais));
+
+                BufferedImage res = ir.read(0);
+                System.out.println("OK");
+
+                if (!param.getCompressionType().equals("BI_JPEG")) {
+                    System.out.print("compare images ... ");
+                    boolean r = compare(img,res);
+                    System.out.println(r?"OK":"FAILED");
+                    if (!r) {
+                        throw new RuntimeException("Compared images are not equals. Test failed.");
+                    }
+                }
+
+
+                BMPMetadata mdata = (BMPMetadata)ir.getImageMetadata(0);
+
+                if (!param.getCompressionType().equals(param.getCompressionTypes()[mdata.compression])) {
+                    throw new RuntimeException("Different compression value");
+                }
+
+            } catch (Exception ex) {
+                ex.printStackTrace();
+                throw new RuntimeException("Unexpected exception: " + ex);
+            }
+
+        }
+
+        private boolean compare(final BufferedImage in, final BufferedImage out) {
+
+            final int width = in.getWidth();
+            int height = in.getHeight();
+            if (out.getWidth() != width || out.getHeight() != height) {
+                throw new RuntimeException("Dimensions changed!");
+            }
+
+            Raster oldras = in.getRaster();
+            ColorModel oldcm = in.getColorModel();
+            Raster newras = out.getRaster();
+            ColorModel newcm = out.getColorModel();
+
+            for (int j = 0; j < height; j++) {
+                for (int i = 0; i < width; i++) {
+                    Object oldpixel = oldras.getDataElements(i, j, null);
+                    int oldrgb = oldcm.getRGB(oldpixel);
+                    int oldalpha = oldcm.getAlpha(oldpixel);
+
+                    Object newpixel = newras.getDataElements(i, j, null);
+                    int newrgb = newcm.getRGB(newpixel);
+                    int newalpha = newcm.getAlpha(newpixel);
+
+                    if (newrgb != oldrgb ||
+                        newalpha != oldalpha) {
+                        // showDiff(in, out);
+                        throw new RuntimeException("Pixels differ at " + i +
+                                                   ", " + j + " new = " + Integer.toHexString(newrgb) + " old = " + Integer.toHexString(oldrgb));
+                    }
+                }
+            }
+            return true;
+        }
+
+        private static BufferedImage createTestImage2(int nbits, int transfertype) {
+            final int colorShift = 2;
+            int SIZE = 256;
+            BufferedImage image = null;
+
+            ColorSpace colorSpace =
+                ColorSpace.getInstance(ColorSpace.CS_GRAY);
+            ColorModel colorModel =
+                new ComponentColorModel(colorSpace,
+                                        new int[] {nbits},
+                                        false,
+                                        false,
+                                        Transparency.OPAQUE,
+                                        transfertype);
+
+            SampleModel sampleModel =
+                new PixelInterleavedSampleModel(transfertype,
+                                                SIZE,
+                                                SIZE,
+                                                1,
+                                                SIZE,
+                                                new int[] {0});
+
+            image =
+                new BufferedImage(colorModel,
+                                  Raster.createWritableRaster(sampleModel, null),
+                                  false, null);
+            WritableRaster raster = image.getWritableTile(0, 0);
+            int[] samples = raster.getSamples(0, 0, SIZE, SIZE, 0, (int[])null);
+            int off = 0;
+            int[] row = new int[SIZE];
+            for(int i = 0; i < SIZE; i++) {
+                Arrays.fill(row, i << colorShift);
+                System.arraycopy(row, 0, samples, off, SIZE);
+                off += SIZE;
+            }
+            raster.setSamples(0, 0, SIZE, SIZE, 0, samples);
+
+            return image;
+        }
+
+
+        private static BufferedImage createTestImage3(int nbits, int transfertype) {
+            final int colorShift = 2;
+            int SIZE = 256;
+            BufferedImage image = null;
+
+            ColorSpace colorSpace =
+                ColorSpace.getInstance(ColorSpace.CS_sRGB);
+            ColorModel colorModel =
+                new IndexColorModel(nbits,
+                                    4,
+                                    new byte[] { (byte)255,   0,   0, (byte)255},
+                                    new byte[] {   0, (byte)255,   0, (byte)255},
+                                    new byte[] {   0,   0, (byte)255, (byte)255});
+
+            SampleModel sampleModel =
+                new PixelInterleavedSampleModel(transfertype,
+                                                SIZE,
+                                                SIZE,
+                                                1,
+                                                SIZE,
+                                                new int[] {0});
+
+            image =
+                new BufferedImage(colorModel,
+                                  Raster.createWritableRaster(sampleModel, null),
+
+                                  false, null);
+
+            Graphics2D g = image.createGraphics();
+            g.setColor(Color.white);
+            g.fillRect(0,0, SIZE, SIZE);
+            g.setColor(Color.red);
+            g.fillOval(10, 10, SIZE -20, SIZE-20);
+
+            return image;
+        }
+
+        private static BufferedImage createTestImage4(int nbits) {
+            int SIZE = 10;
+
+
+            BufferedImage image = null;
+
+            ColorSpace colorSpace =
+                ColorSpace.getInstance(ColorSpace.CS_sRGB);
+            ColorModel colorModel =
+                new DirectColorModel(colorSpace,
+                                     nbits, 0xff0000, 0x00ff00, 0x0000ff, 0x000000, false, DataBuffer.TYPE_INT);
+
+            SampleModel sampleModel =
+                new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT,
+                                                SIZE,
+                                                SIZE,
+                                      new int[] { 0xff0000, 0x00ff00, 0x0000ff} );
+
+
+            image =
+                new BufferedImage(colorModel,
+                                  Raster.createWritableRaster(sampleModel, null),
+
+                                  false, null);
+
+            Graphics2D g = image.createGraphics();
+            g.setColor(Color.red);
+            g.fillRect(0,0, SIZE, SIZE);
+            g.setColor(Color.green);
+            //g.fillOval(10, 10, SIZE -20, SIZE-20);
+            g.drawLine(7, 0, 7, SIZE);
+            g.setColor(Color.blue);
+            g.drawLine(1, 0, 1, SIZE);
+            g.setColor(Color.white);
+            g.drawLine(3, 0, 3, SIZE);
+            g.setColor(Color.yellow);
+            g.drawLine(5, 0, 5, SIZE);
+            return image;
+        }
+
+        private static BufferedImage createTestImage(int type)
+          throws IOException {
+
+            int w = 200;
+            int h = 200;
+            BufferedImage b = new BufferedImage(w, h, type);
+            Graphics2D g = b.createGraphics();
+            g.setColor(Color.white);
+            g.fillRect(0,0, w, h);
+            g.setColor(Color.black);
+            g.fillOval(10, 10, w -20, h-20);
+
+            return b;
+        }
+
+
+    }
+
+    private static void showDiff(final BufferedImage in,
+                                 final BufferedImage out) {
+        final int width = in.getWidth();
+        final int height = in.getHeight();
+
+        JFrame f = new JFrame("");
+        f.getContentPane().add( new JComponent() {
+                public Dimension getPreferredSize() {
+                    return new Dimension(2*width+2, height);
+                }
+                public void paintComponent(Graphics g) {
+                    g.setColor(Color.black);
+                    g.drawImage(in, 0,0, null);
+
+                    g.drawImage(out, width+2, 0, null);
+                }
+            });
+        f.pack();
+        f.setVisible(true);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/BMPPluginTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4641872 4892194
+ * @summary Tests writing and reading abilities of BMP plugin
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+
+import javax.imageio.IIOException;
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.ImageWriterSpi;
+
+public class BMPPluginTest {
+
+    private static final int[] types = {
+        BufferedImage.TYPE_INT_RGB, // = 1;
+        BufferedImage.TYPE_INT_ARGB, // = 2;
+        BufferedImage.TYPE_INT_ARGB_PRE, // = 3;
+        BufferedImage.TYPE_INT_BGR, // = 4;
+        BufferedImage.TYPE_3BYTE_BGR, // = 5;
+        BufferedImage.TYPE_4BYTE_ABGR, // = 6;
+        BufferedImage.TYPE_4BYTE_ABGR_PRE, // 7
+        BufferedImage.TYPE_USHORT_565_RGB, // 8
+        BufferedImage.TYPE_USHORT_555_RGB, // 9
+        BufferedImage.TYPE_BYTE_GRAY, // 10
+        BufferedImage.TYPE_USHORT_GRAY, //11
+        BufferedImage.TYPE_BYTE_BINARY, //12
+        BufferedImage.TYPE_BYTE_INDEXED //13
+    };
+
+    private static String format = "BMP";
+
+    private static ImageReader ir = null;
+    private static ImageWriter iw = null;
+    private BufferedImage img;
+    private ImageWriteParam param;
+    private ByteArrayOutputStream baos;
+
+    private static void init() {
+
+        Iterator i = ImageIO.getImageWritersByFormatName(format);
+        if (!i.hasNext()) {
+            throw new RuntimeException("No available ImageWrites for "+format+" format!");
+        }
+        iw = (ImageWriter)i.next();
+
+        i = ImageIO.getImageReadersByFormatName(format);
+        if (!i.hasNext()) {
+            throw new RuntimeException("No available ImageReaders for " +format+" format!");
+        }
+
+        ir = (ImageReader)i.next();
+    }
+
+    public static void main(String[] args) {
+        if (args.length > 0) {
+            format = args[0];
+            System.out.println("Test format " + format);
+        }
+
+        init();
+        System.out.println("IR="+ir);
+        System.out.println("IW="+iw);
+        ImageIO.setUseCache(false);
+
+        for (int i=0; i<types.length; i++) {
+            boolean bPassed = true;
+            Object reason = null;
+
+            try {
+
+                BufferedImage image = createTestImage(types[i]);
+
+                ImageWriteParam param = iw.getDefaultWriteParam();
+
+                BMPPluginTest t = new BMPPluginTest(image, param);
+                boolean res = false;
+                res = t.test();
+                if (!res) {
+                    bPassed = false;
+                    reason = new String("Null result");
+                }
+            } catch (IllegalArgumentException ex) {
+                System.out.println("Expected exception type was caught: " + ex);
+
+            } catch (Throwable ex ) {
+                System.out.println("FAILED");
+                ex.printStackTrace();
+                bPassed = false;
+                reason = ex;
+                throw new RuntimeException("Test for type " + types[i] + " FAILED due to exception");
+            }
+/*
+            System.out.println("Type " + types[i] + " result: " +
+                               (bPassed ? "PASSED" : "FAILED") +
+                               ((reason != null) ? (" Reason: " + reason) : ""));
+*/
+            System.out.println("Test for type " + types[i] + " PASSED");
+        }
+
+        System.out.println("END OF TEST");
+    }
+
+    public BMPPluginTest(BufferedImage img, ImageWriteParam param) {
+
+        this.img = img;
+        this.param = param;
+        baos = new ByteArrayOutputStream();
+    }
+
+    public boolean test() throws IIOException, IOException {
+
+        ir.reset();
+        iw.reset();
+
+        String[] suffixes = iw.getOriginatingProvider().getFileSuffixes();
+
+        IIOMetadata md = iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), param);
+
+        System.out.println("Image type " + img.getType());
+
+        ImageWriterSpi spi = iw.getOriginatingProvider();
+        boolean bCanEncode = spi.canEncodeImage(img);
+
+        System.out.println("Can encode image? " + (bCanEncode ? "YES" : "NO"));
+        if (!bCanEncode) {
+            return true;
+        }
+        IIOImage iio_img = new IIOImage(img, null, md);
+
+        String fname = "test"+img.getType()+"."+suffixes[0];
+
+        iw.setOutput(ImageIO.createImageOutputStream(new FileOutputStream(new File(fname))));
+        System.out.print("write image ... ");
+        iw.write(iio_img);
+        System.out.println("OK");
+        System.out.print("read image ... ");
+
+        byte[] ba_image = baos.toByteArray();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(ba_image);
+
+        ir.setInput(ImageIO.createImageInputStream(new FileInputStream(new File(fname))));
+
+        BufferedImage res = ir.read(0);
+        System.out.println("OK");
+
+        System.out.print("compare images ... ");
+        boolean r = compare(img,res);
+        System.out.println(r?"OK":"FAILED");
+        return r;
+    }
+
+    private boolean compare(BufferedImage in, BufferedImage out) {
+        int width = in.getWidth();
+        int height = in.getHeight();
+        if (out.getWidth() != width || out.getHeight() != height) {
+            throw new RuntimeException("Dimensions changed!");
+        }
+
+        Raster oldras = in.getRaster();
+        ColorModel oldcm = in.getColorModel();
+        Raster newras = out.getRaster();
+        ColorModel newcm = out.getColorModel();
+
+        for (int j = 0; j < height; j++) {
+            for (int i = 0; i < width; i++) {
+                Object oldpixel = oldras.getDataElements(i, j, null);
+                int oldrgb = oldcm.getRGB(oldpixel);
+                int oldalpha = oldcm.getAlpha(oldpixel);
+
+                Object newpixel = newras.getDataElements(i, j, null);
+                int newrgb = newcm.getRGB(newpixel);
+                int newalpha = newcm.getAlpha(newpixel);
+
+                if (newrgb != oldrgb ||
+                    newalpha != oldalpha) {
+                    throw new RuntimeException("Pixels differ at " + i +
+                                               ", " + j);
+                }
+            }
+        }
+        return true;
+    }
+
+
+    private static BufferedImage createTestImage(int type) throws IOException {
+
+        int w = 200;
+        int h = 200;
+        BufferedImage b = new BufferedImage(w, h, type);
+        Graphics2D g = b.createGraphics();
+        g.setColor(Color.white);
+        g.fillRect(0,0, w, h);
+        g.setColor(Color.black);
+        g.fillOval(10, 10, w -20, h-20);
+
+        return b;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/BMPWriteParamTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4641872
+ * @summary Tests writing compression modes of BMP plugin
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageOutputStream;
+
+public class BMPWriteParamTest {
+
+    static final String format = "BMP";
+
+    public static void main(String[] args) {
+
+        ImageWriter iw = null;
+        Iterator writers = ImageIO.getImageWritersByFormatName(format);
+        if (!writers.hasNext()) {
+            throw new RuntimeException("No available Image writer for "+format);
+        }
+        iw = (ImageWriter)writers.next();
+
+        try {
+            BufferedImage img = createTestImage();
+
+            BufferedImage bmp_res = getWriteResult(img, "BMP");
+            BufferedImage png_res = getWriteResult(img, "PNG");
+
+            compare(bmp_res, png_res);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            throw new RuntimeException("Unexpected exception: " + ex);
+        }
+    }
+
+    private static BufferedImage getWriteResult(BufferedImage img,
+                                                String format
+                                                ) throws IOException {
+        ImageWriter iw = null;
+        Iterator writers = ImageIO.getImageWritersByFormatName(format);
+        while (writers.hasNext()) {
+            iw = (ImageWriter)writers.next();
+            System.out.println(format + " -> " + iw.toString());
+        }
+        if (iw==null) {
+            throw new RuntimeException("No available Image writer for "+format);
+        }
+        ImageWriteParam param = iw.getDefaultWriteParam();
+
+        param.setSourceRegion(new Rectangle(10, 10, 31, 31));
+        param.setSourceSubsampling(3, 3, 0, 0);
+
+        IIOMetadata meta = iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), param);
+
+        IIOImage iio_img = new IIOImage(img, null, meta);
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+        iw.setOutput(ios);
+        iw.write(meta, iio_img, param);
+        ios.flush();
+
+        byte[] ba_image = baos.toByteArray();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(ba_image);
+
+        ImageReader ir = null;
+
+        Iterator readers = ImageIO.getImageReadersByFormatName(format);
+        while (readers.hasNext()) {
+            ir = (ImageReader)readers.next();
+            System.out.println(format + " -> " + ir.toString());
+        }
+        if (ir==null) {
+            throw new RuntimeException("No available Image reader for "+format);
+        }
+
+        ir.setInput(ImageIO.createImageInputStream(bais));
+
+        BufferedImage res = ir.read(0);
+        return res;
+    }
+
+    private static BufferedImage createTestImage()
+      throws IOException {
+
+        int w = 50;
+        int h = 50;
+        BufferedImage b = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
+        Graphics2D g = b.createGraphics();
+        g.setColor(Color.red);
+        g.fillRect(0,0, w, h);
+        g.setColor(Color.white);
+        for (int i=10; i<=10+30; i+= 3) {
+            g.drawLine(i, 10, i, 40);
+            g.drawLine(10, i, 40, i);
+        }
+        return b;
+    }
+
+    private static boolean compare(final BufferedImage in,
+                                   final BufferedImage out)
+    {
+        final int width = in.getWidth();
+        int height = in.getHeight();
+        if (out.getWidth() != width || out.getHeight() != height) {
+            throw new RuntimeException("Dimensions changed!");
+        }
+
+        Raster oldras = in.getRaster();
+        ColorModel oldcm = in.getColorModel();
+        Raster newras = out.getRaster();
+        ColorModel newcm = out.getColorModel();
+
+        for (int j = 0; j < height; j++) {
+            for (int i = 0; i < width; i++) {
+                Object oldpixel = oldras.getDataElements(i, j, null);
+                int oldrgb = oldcm.getRGB(oldpixel);
+                int oldalpha = oldcm.getAlpha(oldpixel);
+
+                Object newpixel = newras.getDataElements(i, j, null);
+                int newrgb = newcm.getRGB(newpixel);
+                int newalpha = newcm.getAlpha(newpixel);
+
+                if (newrgb != oldrgb ||
+                    newalpha != oldalpha) {
+                    // showDiff(in, out);
+                    throw new RuntimeException("Pixels differ at " + i +
+                                               ", " + j + " new = " + Integer.toHexString(newrgb) + " old = " + Integer.toHexString(oldrgb));
+                }
+            }
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/BmpBigDestinationTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4929367
+ * @summary tests what BMP image was decoded correctly if destination buffered
+ *          image is bigger than source image
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriter;
+
+public class BmpBigDestinationTest {
+    static String format = "BMP";
+    public static void main(String[] args) {
+        try {
+            BufferedImage src = new BufferedImage(100, 100,
+                                                  BufferedImage.TYPE_INT_RGB);
+            Graphics2D g = src.createGraphics();
+            g.setColor(Color.red);
+            g.fillRect(0,0,100, 100);
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+            ImageWriter iw =
+                (ImageWriter)ImageIO.getImageWritersByFormatName(format).next();
+            if (iw == null) {
+                throw new RuntimeException("No writer available. Test failed.");
+            }
+
+            iw.setOutput(ImageIO.createImageOutputStream(baos));
+            iw.write(src);
+
+            byte[] data = baos.toByteArray();
+
+            ImageReader ir =
+                (ImageReader)ImageIO.getImageReadersByFormatName(format).next();
+            ir.setInput(
+                ImageIO.createImageInputStream(
+                    new ByteArrayInputStream(data)));
+
+            Iterator specifiers = ir.getImageTypes(0);
+            ImageTypeSpecifier typeSpecifier = null;
+
+            if (specifiers.hasNext()) {
+                typeSpecifier = (ImageTypeSpecifier) specifiers.next();
+            }
+            ImageReadParam param = new ImageReadParam();
+            BufferedImage dst = typeSpecifier.createBufferedImage(200, 200);
+            param.setDestination(dst);
+
+            ir.read(0, param);
+
+            checkResults(src,dst);
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Unexpected exception. Test failed.");
+        }
+    }
+
+    private static void checkResults(BufferedImage src, BufferedImage dst) {
+        for(int x=0; x<src.getWidth(); x++) {
+            for(int y=0; y<src.getHeight(); y++) {
+                int srcRgb = src.getRGB(x,y);
+                int dstRgb = dst.getRGB(x,y);
+                if (srcRgb != dstRgb) {
+                    throw new RuntimeException("Images are different at point ["
+                                               + x + "," + y + "]");
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/BmpDefaultImageMetadataTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4895512
+ * @summary Test that default image metadata for BMP image writer is not null
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+public class BmpDefaultImageMetadataTest {
+    ImageWriter writer = null;
+    IIOMetadata imageData = null;
+    ImageWriteParam writeParam = null;
+    BufferedImage bimg = null;
+
+    public BmpDefaultImageMetadataTest(String format) {
+        try {
+            bimg = new BufferedImage(200, 200, bimg.TYPE_INT_RGB);
+            Graphics gg = bimg.getGraphics();
+            gg.setColor(Color.red);
+            gg.fillRect(50, 50, 100, 100);
+
+            Iterator it = ImageIO.getImageWritersByFormatName(format);
+            if (it.hasNext()) {
+                writer = (ImageWriter) it.next();
+            }
+            if (writer == null) {
+                throw new RuntimeException("No writer available for the given format."
+                                           + " Test failed.");
+            }
+            writeParam = writer.getDefaultWriteParam();
+
+            System.out.println("Testing Image Metadata for "+format+"\n");
+            imageData = writer.getDefaultImageMetadata(new ImageTypeSpecifier(bimg), writeParam);
+            if (imageData == null) {
+                System.out.println("return value is null. No default image metadata is associated with "+format+" writer");
+                throw new RuntimeException("Default image metadata is null."
+                                           + " Test failed.");
+            }
+            int j = 0;
+            String imageDataNames[] = null;
+            if(imageData != null) {
+                System.out.println("Is standard metadata format supported (Image) ? "+
+                                   imageData.isStandardMetadataFormatSupported() );
+                imageDataNames = imageData.getMetadataFormatNames();
+                System.out.println("\nAll supported Metadata Format Names\n");
+                if(imageDataNames!=null){
+                    for(j=0; j<imageDataNames.length; j++)  {
+                        System.out.println("FORMAT NAME: "+imageDataNames[j]);
+                        if (imageDataNames[j].equals(imageData.getNativeMetadataFormatName())) {
+                            System.out.println("This is a Native Metadata format\n");
+                        } else {
+                            System.out.println("\n");
+                        }
+                        System.out.println("");
+                        System.out.println("IIOImageMetadata DOM tree for "+imageDataNames[j]);
+                        System.out.println("");
+                        Node imageNode = imageData.getAsTree(imageDataNames[j]);
+                        displayMetadata(imageNode);
+                        System.out.println("\n\n");
+                    }
+                }
+            }
+        }catch(Exception e){
+            e.printStackTrace();
+            throw new RuntimeException("Exception was thrown."
+                                       + " Test failed.");
+        }
+    }
+
+    public void displayMetadata(Node root) {
+        displayMetadata(root, 0);
+    }
+
+    void indent(int level) {
+        for (int i = 0; i < level; i++) {
+            System.out.print(" ");
+        }
+    }
+
+    void displayMetadata(Node node, int level) {
+        indent(level); // emit open tag
+        System.out.print("<" + node.getNodeName());
+        NamedNodeMap map = node.getAttributes();
+        if (map != null) { // print attribute values
+            int length = map.getLength();
+            for (int i = 0; i < length; i++) {
+                Node attr = map.item(i);
+                System.out.print(" " + attr.getNodeName() +
+                                 "=\"" + attr.getNodeValue() + "\"");
+            }
+        }
+        Node child = node.getFirstChild();
+
+        if (node.getNodeValue() != null && !node.getNodeValue().equals("") ) {
+            System.out.println(">");
+            indent(level);
+            System.out.println(node.getNodeValue());
+            indent(level); // emit close tag
+            System.out.println("</" + node.getNodeName() + ">");
+        } else  if (child != null) {
+            System.out.println(">"); // close current tag
+            while (child != null) { // emit child tags recursively
+                displayMetadata(child, level + 1);
+                child = child.getNextSibling();
+            }
+            indent(level); // emit close tag
+            System.out.println("</" + node.getNodeName() + ">");
+        } else {
+            System.out.println("/>");
+        }
+    }
+
+    public static void main(String args[]) {
+        BmpDefaultImageMetadataTest test = new BmpDefaultImageMetadataTest("bmp");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/CompressionModeTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4893464
+ * @summary Tests bmp writer behavior with different compression modes
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.File;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageOutputStream;
+
+public class CompressionModeTest {
+
+    public static void main(String args[]) {
+        int[] iModes = { ImageWriteParam.MODE_DISABLED,
+                         ImageWriteParam.MODE_EXPLICIT,
+                         ImageWriteParam.MODE_COPY_FROM_METADATA,
+                         ImageWriteParam.MODE_DEFAULT };
+
+        String[] strModes = { "ImageWriteParam.MODE_DISABLED",
+                              "ImageWriteParam.MODE_EXPLICIT",
+                              "ImageWriteParam.MODE_COPY_FROM_METADATA",
+                              "ImageWriteParam.MODE_DEFAULT" };
+
+        for(int i=0; i<iModes.length; i++) {
+            System.out.println("Test compression mode "+strModes[i]);
+            doTest(iModes[i]);
+        }
+    }
+
+    private static void doTest(int mode) {
+        String fileFormat = "bmp";
+        try {
+            ImageWriter iw = (ImageWriter)ImageIO.getImageWritersBySuffix(fileFormat).next();
+            if(iw == null) {
+                throw new RuntimeException("No available image writer for "
+                                           + fileFormat
+                                           + " Test failed.");
+            }
+
+            File file = new File("image." + fileFormat);
+            ImageOutputStream ios = ImageIO.createImageOutputStream(file);
+            iw.setOutput(ios);
+
+            BufferedImage bimg = new BufferedImage(100,
+                                                   100, BufferedImage.TYPE_INT_RGB);
+            Graphics g = bimg.getGraphics();
+            g.setColor(Color.green);
+            g.fillRect(0,0,100,100);
+
+            ImageWriteParam param = iw.getDefaultWriteParam();
+
+            param.setCompressionMode(mode);
+
+            IIOMetadata meta = iw.getDefaultImageMetadata(new ImageTypeSpecifier(bimg),
+                                                          param);
+
+            IIOImage iioImg = new IIOImage(bimg, null, meta);
+            iw.write(null, iioImg, param);
+        } catch(Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Test failed.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/EmbeddedFormatTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6294920 6294926
+ * @summary Test verifies that BMP images with compression types BI_JPEG and
+ *          BI_PNG are read correctly in case of 1, 8, 16, 24 and 32 bpp
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+
+public class EmbeddedFormatTest {
+    ImageWriter writer;
+    ImageReader reader;
+
+    static int[] bi_types = {
+        BufferedImage.TYPE_INT_RGB,
+        BufferedImage.TYPE_3BYTE_BGR,
+        BufferedImage.TYPE_USHORT_555_RGB,
+        BufferedImage.TYPE_BYTE_GRAY,
+        BufferedImage.TYPE_BYTE_BINARY
+    };
+
+    public EmbeddedFormatTest() {
+        writer = ImageIO.getImageWritersByFormatName("BMP").next();
+        reader = ImageIO.getImageReadersByFormatName("BMP").next();
+    }
+
+    public void doTest(String compression, int bi_type) throws IOException {
+        System.out.println("Test " + compression + " on " + getImageTypeName(bi_type));
+        BufferedImage src = createTestImage(bi_type);
+        writer.reset();
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageOutputStream ios =
+                ImageIO.createImageOutputStream(baos);
+        writer.setOutput(ios);
+
+        ImageWriteParam wparam = prepareWriteParam(compression);
+        writer.write(null, new IIOImage(src, null, null), wparam);
+        ios.flush();
+        ios.close();
+
+        // read result
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ImageInputStream iis = ImageIO.createImageInputStream(bais);
+        reader.reset();
+        reader.setInput(iis);
+
+        BufferedImage dst = reader.read(0);
+
+        checkResult(dst);
+    }
+
+    protected BufferedImage createTestImage(int type) {
+        BufferedImage img = new BufferedImage(200, 200, type);
+        Graphics g = img.createGraphics();
+        g.setColor(Color.black);
+        g.fillRect(0, 0, 200, 200);
+        g.setColor(Color.white);
+        g.fillRect(50, 50, 100, 100);
+
+        return img;
+    }
+
+    protected void  checkResult(BufferedImage img) {
+        int imgBlack = img.getRGB(25, 25);
+        if (imgBlack != 0xff000000) {
+            throw new RuntimeException("Wrong black color: " +
+                    Integer.toHexString(imgBlack));
+        }
+
+        int imgWhite = img.getRGB(100, 100);
+        if (imgWhite != 0xffffffff) {
+            throw new RuntimeException("Wrong white color: " +
+                    Integer.toHexString(imgWhite));
+        }
+    }
+
+    protected ImageWriteParam prepareWriteParam(String compression) {
+        ImageWriteParam imageWriteParam = writer.getDefaultWriteParam();
+        imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+        imageWriteParam.setCompressionType(compression);
+        return imageWriteParam;
+    }
+
+
+    public static void main(String[] args) throws IOException {
+        EmbeddedFormatTest t = new EmbeddedFormatTest();
+
+        for (int i = 0; i < bi_types.length; i++) {
+            t.doTest("BI_JPEG", bi_types[i]);
+            t.doTest("BI_PNG",  bi_types[i]);
+        }
+    }
+
+    static String getImageTypeName(int type) {
+        switch(type) {
+            case BufferedImage.TYPE_INT_RGB:
+                return "TYPE_INT_RGB";
+            case BufferedImage.TYPE_3BYTE_BGR:
+                return "TYPE_3BYTE_BGR";
+            case BufferedImage.TYPE_USHORT_555_RGB:
+                return "TYPE_USHORT_555_RGB";
+            case BufferedImage.TYPE_BYTE_GRAY:
+                return "TYPE_BYTE_GRAY";
+            case BufferedImage.TYPE_BYTE_BINARY:
+                return "TYPE_BYTE_BINARY";
+            default:
+                return "TBD";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/EmptyInputBmpMetadataTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4895483
+ * @summary Test checks that the IllegalStateException was thrown if input was
+ *          not set to the BMPImageReader
+ */
+
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.metadata.IIOMetadata;
+
+public class EmptyInputBmpMetadataTest {
+    private static String fmt = "BMP";
+
+    public static void main(String[] args) {
+        boolean isPassed = false;
+        ImageReader ir = (ImageReader)ImageIO.getImageReadersByFormatName(fmt).next();
+
+        if (ir == null) {
+            throw new RuntimeException("No available reader for " + fmt);
+        }
+        IIOMetadata meta = null;
+        try {
+            meta = ir.getImageMetadata(0);
+        } catch (IllegalStateException e) {
+            System.out.println("Correct exception was thrown. Test passed.");
+            isPassed = true;
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        if (!isPassed) {
+            throw new RuntimeException("The IllegalStateException was not thrown."
+                                       +"Test failed.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/NoExtraBytesTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 5076878
+ * @summary Test verifies that ImageIO creates BMP images with correct bpp
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DirectColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Hashtable;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageInputStream;
+
+import org.w3c.dom.Node;
+
+public class NoExtraBytesTest {
+
+    private static Hashtable<Integer, Integer> tests = null;
+    private static Color[] usedColors = new Color[] { Color.red, Color.green,     Color.blue, Color.yellow, Color.white, Color.black };
+
+    private static final int TYPE_INT_GRB = 0x100;
+    private static final int TYPE_INT_GBR = 0x101;
+    private static final int TYPE_INT_RBG = 0x102;
+    private static final int TYPE_INT_BRG = 0x103;
+    private static final int TYPE_INT_555_GRB = 0x104;
+    private static final int TYPE_3BYTE_RGB = 0x105;
+    private static final int TYPE_3BYTE_GRB = 0x106;
+
+    private static final int w = 300;
+    private static final int h = 200;
+    private static final int dx = w / usedColors.length;
+
+    public static void main(String[] args) throws IOException {
+        initTests();
+
+        for (Integer type : tests.keySet()) {
+            new NoExtraBytesTest(type.intValue(), tests.get(type).intValue()).doTest();
+        }
+        System.out.println("Test passed.");
+    }
+
+    private static void initTests() {
+        tests = new Hashtable<Integer, Integer>();
+
+        tests.put(new Integer(BufferedImage.TYPE_INT_RGB), new Integer(24));
+        tests.put(new Integer(BufferedImage.TYPE_INT_BGR), new Integer(24));
+        tests.put(new Integer(BufferedImage.TYPE_3BYTE_BGR), new Integer(24));
+        tests.put(new Integer(TYPE_INT_GRB), new Integer(24));
+        tests.put(new Integer(TYPE_INT_GBR), new Integer(24));
+        tests.put(new Integer(TYPE_INT_RBG), new Integer(24));
+        tests.put(new Integer(TYPE_INT_BRG), new Integer(24));
+        tests.put(new Integer(BufferedImage.TYPE_USHORT_555_RGB), new Integer(16));
+        tests.put(new Integer(BufferedImage.TYPE_USHORT_565_RGB), new Integer(16));
+        tests.put(new Integer(TYPE_INT_555_GRB), new Integer(16));
+        tests.put(new Integer(TYPE_3BYTE_RGB), new Integer(24));
+        tests.put(new Integer(TYPE_3BYTE_GRB), new Integer(24));
+    }
+
+    private static String getImageTypeName(int t) {
+        switch(t) {
+            case BufferedImage.TYPE_INT_RGB:
+                return "TYPE_INT_RGB";
+            case BufferedImage.TYPE_INT_BGR:
+                return "TYPE_INT_BGR";
+            case BufferedImage.TYPE_3BYTE_BGR:
+                return "TYPE_3BYTE_BGR";
+            case BufferedImage.TYPE_USHORT_555_RGB:
+                return "TYPE_USHORT_555_RGB";
+            case BufferedImage.TYPE_USHORT_565_RGB:
+                return "TYPE_USHORT_565_RGB";
+            case TYPE_INT_GRB:
+                return "TYPE_INT_GRB";
+            case TYPE_INT_GBR:
+                return "TYPE_INT_GBR";
+            case TYPE_INT_RBG:
+                return "TYPE_INT_RBG";
+            case TYPE_INT_BRG:
+                return "TYPE_INT_BRG";
+            case TYPE_INT_555_GRB:
+                return "TYPE_INT_555_GRB";
+            case TYPE_3BYTE_RGB:
+                return "TYPE_3BYTE_RGB";
+            case TYPE_3BYTE_GRB:
+                return "TYPE_3BYTE_GRB";
+            default:
+                throw new IllegalArgumentException("Unknown image type: " + t);
+        }
+    }
+    private static BufferedImage createTestImage(int type) {
+        BufferedImage dst = null;
+        ColorModel colorModel = null;
+        WritableRaster raster = null;
+        ColorSpace cs = null;
+        System.out.println("Create image for " + getImageTypeName(type));
+        switch(type) {
+            case TYPE_INT_GRB:
+                colorModel = new DirectColorModel(24,
+                    0x0000ff00,
+                    0x00ff0000,
+                    0x000000ff);
+                break;
+            case TYPE_INT_GBR:
+                colorModel = new DirectColorModel(24,
+                    0x000000ff,
+                    0x00ff0000,
+                    0x0000ff00);
+                break;
+            case TYPE_INT_RBG:
+                colorModel = new DirectColorModel(24,
+                    0x00ff0000,
+                    0x000000ff,
+                    0x0000ff00);
+                break;
+            case TYPE_INT_BRG:
+                colorModel = new DirectColorModel(24,
+                    0x0000ff00,
+                    0x000000ff,
+                    0x00ff0000);
+                break;
+            case TYPE_INT_555_GRB:
+                colorModel = new DirectColorModel(24,
+                        0x0000001F,
+                        0x000003e0,
+                        0x00007c00);
+                break;
+            case TYPE_3BYTE_RGB:
+                cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+                int[] nBits = {8, 8, 8};
+                int[] bOffs = {0, 1, 2};
+                colorModel = new ComponentColorModel(cs, nBits, false, false,
+                                                     Transparency.OPAQUE,
+                                                     DataBuffer.TYPE_BYTE);
+                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                                                        w, h,
+                                                        w*3, 3,
+                                                        bOffs, null);
+                break;
+            case TYPE_3BYTE_GRB:
+                cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+                //nBits = {8, 8, 8};
+                //bOffs = {0, 1, 2};
+                colorModel = new ComponentColorModel(cs, new int[] { 8, 8, 8 }, false, false,
+                                                     Transparency.OPAQUE,
+                                                     DataBuffer.TYPE_BYTE);
+                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                        w, h,
+                        w*3, 3,
+                        new int[] { 1, 0, 2}, null);
+                break;
+            default:
+                dst = new BufferedImage(w, h, type);
+                //colorModel = ImageTypeSpecifier.createFromBufferedImageType(type).getColorModel();
+        }
+
+        if (dst == null) {
+            if (raster == null) {
+                raster = colorModel.createCompatibleWritableRaster(w, h);
+            }
+
+            dst = new BufferedImage(colorModel, raster, false, null);
+        }
+        Graphics g = dst.createGraphics();
+        for (int i = 0; i < usedColors.length; i ++) {
+            g.setColor(usedColors[i]);
+            g.fillRect(i * dx, 0, dx, h);
+        }
+        g.dispose();
+
+        return dst;
+    }
+
+    private BufferedImage src;
+    private int expectedColorDepth;
+    private int type;
+
+    private IIOImage iio_dst;
+
+    public NoExtraBytesTest(int type, int expectedColorDepth) {
+        this.type = type;
+        this.src = createTestImage(type);
+        this.expectedColorDepth = expectedColorDepth;
+    }
+
+    public void doTest() throws IOException {
+        // write src as BMP
+        System.out.println("Test for image: " + getImageTypeName(type));
+        System.out.println("image is " + src);
+
+        File f = File.createTempFile("sizeTest_", ".bmp", new File("."));
+        System.out.println("Use file " + f.getCanonicalPath());
+        ImageIO.write(src, "BMP", f);
+
+        //read it again
+        read(f);
+
+        checkColorDepth();
+
+        checkImageContent();
+    }
+
+    private void read(File f) throws IOException {
+        ImageReader reader = ImageIO.getImageReadersByFormatName("BMP").next();
+
+        ImageInputStream iis =
+                ImageIO.createImageInputStream(new FileInputStream(f));
+
+        reader.setInput(iis);
+
+        iio_dst = reader.readAll(0, reader.getDefaultReadParam());
+    }
+
+    private void checkColorDepth() {
+        IIOMetadata dst = iio_dst.getMetadata();
+
+        Node data = dst.getAsTree("javax_imageio_bmp_1.0");
+
+        Node n = data.getFirstChild();
+
+        while (n != null && !("BitsPerPixel".equals(n.getNodeName()))) {
+            System.out.println("Node " + n.getNodeName());
+            n = n.getNextSibling();
+        }
+        if (n == null) {
+            throw new RuntimeException("No BitsPerSample node!");
+        }
+
+        int bpp = 0;
+        String value = n.getNodeValue();
+        System.out.println("value = " + value);
+        try {
+            bpp = Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            throw new RuntimeException("Wrong bpp value: " + value, e);
+        }
+
+        if (bpp != this.expectedColorDepth) {
+            throw new RuntimeException("Wrong color depth: " + bpp +
+                    " (should be " + this.expectedColorDepth + ")");
+        }
+    }
+
+    private void checkImageContent() {
+        BufferedImage dst =
+                (BufferedImage)iio_dst.getRenderedImage();
+        int y = h / 2;
+        int x = dx / 2;
+
+        for (int i = 0; i < usedColors.length; i++, x += dx) {
+            int srcRgb = src.getRGB(x, y);
+            int dstRgb = dst.getRGB(x, y);
+            int rgb = usedColors[i].getRGB();
+
+            if (dstRgb != srcRgb || dstRgb != rgb) {
+                throw new RuntimeException("Wrong color at [" + x + ", " + y +
+                        "] " + Integer.toHexString(dstRgb) +
+                        " (srcRgb=" + Integer.toHexString(srcRgb) +
+                        ", original color is " + Integer.toHexString(rgb) + ")");
+            }
+
+        }
+        System.out.println("Image colors are OK.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/RLECompressionTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6332480
+ * @summary Test verifies that images encoded as BMP with RLE4 or RLE8
+ *          compression type are read correctly
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
+
+public class RLECompressionTest {
+    public static final int TEST_RLE8 = 0x01;
+    public static final int TEST_RLE4 = 0x02;
+
+    private static Color[] usedColors = new Color[] {
+        Color.black, Color.white, Color.red,
+        Color.green, Color.blue, Color.yellow };
+
+    int w = 100;
+    // NB: problem occurs when image height > width
+    // The problem manifestation is that only first w
+    // lines of image are filled by decoded data,
+    // rest of image (all lines below (w-1)-th line)
+    // is leaved uninitialized (black).
+    // In order to verify that this problem is solved,
+    // we use image with height > width.
+    int h = 2 * w;
+
+    private IndexColorModel getTestColorModel(int type) {
+        IndexColorModel icm = null;
+        int bpp = 8;
+        int size = 256;
+
+        switch(type) {
+            case TEST_RLE8:
+                bpp = 8;
+                size = 256;
+                break;
+            case TEST_RLE4:
+                bpp = 4;
+                size = 16;
+                break;
+            default:
+                throw new IllegalArgumentException("Wrong test type: " + type);
+        }
+
+        byte[] palette = new byte[size * 3];
+        for (int i = 0; i < usedColors.length; i++) {
+            palette[3 * i] = (byte)(0xff & usedColors[i].getRed());
+            palette[3 * i + 1] = (byte)(0xff & usedColors[i].getGreen());
+            palette[3 * i + 2] = (byte)(0xff & usedColors[i].getBlue());
+        }
+        // rest of palette is black
+
+        icm = new IndexColorModel(bpp, size, palette, 0, false);
+        return icm;
+    }
+
+    private BufferedImage getTestImage(int type) {
+        BufferedImage src = null;
+        IndexColorModel icm = getTestColorModel(type);
+        src = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_INDEXED, icm);
+        Graphics2D g = src.createGraphics();
+        g.setColor(Color.white);
+        g.fillRect(0, 0, w, h);
+        g.dispose();
+
+        return src;
+    }
+
+    public void doTest(int type) throws IOException {
+        BufferedImage src = getTestImage(type);
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+
+        ImageWriter writer = ImageIO.getImageWritersByFormatName("BMP").next();
+        writer.setOutput(ios);
+
+        ImageWriteParam wparam = writer.getDefaultWriteParam();
+        wparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+        switch(type) {
+            case TEST_RLE8:
+                wparam.setCompressionType("BI_RLE8");
+                break;
+            case TEST_RLE4:
+                wparam.setCompressionType("BI_RLE4");
+                break;
+            default:
+                throw new IllegalArgumentException("Wrong test type: " + type);
+        }
+
+        writer.write(null, new IIOImage(src, null, null), wparam);
+
+        ios.close();
+        baos.close();
+
+        // read result
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+
+        BufferedImage dst = ImageIO.read(bais);
+
+        checkResult(src, dst);
+    }
+
+    private void checkResult(BufferedImage src, BufferedImage dst) {
+        int x = w / 2;
+        for (int y = 0; y < h; y++) {
+            int srcRgb = src.getRGB(x, y);
+            int dstRgb = dst.getRGB(x, y);
+
+            if (srcRgb != dstRgb) {
+                throw new RuntimeException("Test failed due to color difference: " +
+                        Integer.toHexString(dstRgb) + " instead of " + Integer.toHexString(srcRgb) +
+                        " at [" + x + ", " + y + "]");
+            }
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        RLECompressionTest test = new RLECompressionTest();
+        test.doTest(TEST_RLE8);
+        test.doTest(TEST_RLE4);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/ReaderListenersTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4924507
+ * @summary Test that listeners of bmp reader receive correct events in case of
+ *          BI_JPEG and BI_PNG compression types
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.event.IIOReadProgressListener;
+import javax.imageio.event.IIOReadUpdateListener;
+
+public class ReaderListenersTest {
+    public static final String[] compTypes = { "BI_JPEG", "BI_PNG" };
+
+    public static void main(String[] args) {
+        for (int i=0; i< compTypes.length; i++) {
+            doTest(compTypes[i]);
+        }
+    }
+
+    private static void doTest(String compression) {
+        try {
+            BufferedImage img = createTestImage();
+
+            ImageWriter iw = (ImageWriter)
+                ImageIO.getImageWritersByFormatName("bmp").next();
+            if (iw == null) {
+                throw new RuntimeException("No writers for bmp format."
+                                           + " Test failed.");
+            }
+
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            iw.setOutput(ImageIO.createImageOutputStream(baos));
+            ImageWriteParam param = iw.getDefaultWriteParam();
+            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+            param.setCompressionType(compression);
+
+            iw.write(null, new IIOImage(img, null, null), param);
+            baos.close();
+
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+
+            ImageReader ir = (ImageReader)
+                ImageIO.getImageReadersByFormatName("bmp").next();
+            if (ir == null) {
+                throw new RuntimeException("No readers for bmp format."
+                                           + " Test failed.");
+            }
+
+            IIOReadUpdateAdapter updateAdapter = new IIOReadUpdateAdapter();
+            IIOReadProgressAdapter progressAdapter = new IIOReadProgressAdapter();
+            ir.addIIOReadProgressListener(progressAdapter);
+            ir.addIIOReadUpdateListener(updateAdapter);
+            ir.setInput(ImageIO.createImageInputStream(bais));
+            BufferedImage dst = ir.read(0);
+
+            progressAdapter.checkResults();
+
+            if (!updateAdapter.isImageUpdateUsed) {
+                throw new RuntimeException("imageUpdate was not used."
+                                           + " Test failed.");
+            }
+        } catch(IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Test failed");
+        }
+    }
+
+    protected static BufferedImage createTestImage() {
+        BufferedImage res = new BufferedImage(100, 100,
+                                              BufferedImage.TYPE_INT_RGB);
+        Graphics2D g = res.createGraphics();
+        g.setColor(Color.red);
+        g.fillRect(0,0, 100,100);
+        return res;
+    }
+
+    static class IIOReadProgressAdapter implements IIOReadProgressListener {
+        List progress = new ArrayList();
+        public boolean isTestPassed = false;
+        private boolean isImageStarted = false;
+        private boolean isImageComplete = false;
+        private boolean isSequenceComplete = false;
+        private boolean isSequenceStarted = false;
+
+        public void imageComplete(ImageReader source) {
+            System.out.println("Image completed");
+            if (!isImageComplete) {
+                isImageComplete = true;
+            } else {
+                throw new RuntimeException("The imageComplete() is called twice."
+                                           + " Test failed.");
+            }
+            checkProgress();
+        }
+
+        public void imageProgress(ImageReader source, float percentageDone) {
+            System.out.println("Image Progress "+percentageDone);
+            progress.add(new Float(percentageDone));
+        }
+
+        public void imageStarted(ImageReader source, int imageIndex) {
+            System.out.println("Image Started "+imageIndex);
+            if (!isImageStarted) {
+                isImageStarted = true;
+            } else {
+                throw new RuntimeException("The imageStarted() was called twice. "
+                                           + " Test failed.");
+            }
+            progress.clear();
+        }
+
+        public void thumbnailComplete(ImageReader source)  {
+            System.out.println("Thubnail completed");
+        }
+
+        public void thumbnailProgress(ImageReader source,
+                                      float percentageDone)
+        {
+            System.out.println("Thubnail Progress " + percentageDone);
+        }
+
+        public void thumbnailStarted(ImageReader source,
+                                     int imageIndex, int thumbnailIndex)
+        {
+            System.out.println("Thubnail started " + imageIndex);
+        }
+
+        public void sequenceComplete(ImageReader source) {
+            if (!isSequenceComplete) {
+                isSequenceComplete = true;
+            } else {
+                throw new RuntimeException("The imageComplete() is called twice."
+                                           + " Test failed.");
+            }
+        }
+
+        public void sequenceStarted(ImageReader source, int minIndex) {
+            if (!isSequenceStarted) {
+                isSequenceStarted = true;
+            } else {
+                throw new RuntimeException("The imageComplete() is called twice."
+                                           + " Test failed.");
+            }
+        }
+
+        public void readAborted(ImageReader source) {
+            System.out.println("read Aborted");
+            checkProgress();
+        }
+
+        private void checkProgress() {
+            Iterator i = progress.iterator();
+            if (!i.hasNext()) {
+                throw new RuntimeException("progress values list is empty!");
+            }
+            float val = ((Float)i.next()).floatValue();
+            while(i.hasNext()) {
+                float next = ((Float)i.next()).floatValue();
+                if (val >= next) {
+                    throw new RuntimeException("progress values do not increase!");
+                }
+                val = next;
+            }
+            isTestPassed = true;
+            System.out.println("Test passed.");
+        }
+
+        public void checkResults() {
+            if (isImageStarted && !isImageComplete) {
+                throw new RuntimeException("The imageCompleted was not called."
+                                           + " Test failed.");
+            }
+        }
+    }
+
+    static class IIOReadUpdateAdapter implements IIOReadUpdateListener {
+        boolean isImageUpdateUsed = false;
+        public void imageUpdate(ImageReader source, BufferedImage theImage,
+                                int minX, int minY, int width, int height,
+                                int periodX, int periodY, int[] bands)
+        {
+            System.out.println("imageUpdate");
+            isImageUpdateUsed = true;
+        }
+        public void passComplete(ImageReader source, BufferedImage theImage) {
+            System.out.println("passComplete");
+        }
+        public void passStarted(ImageReader source, BufferedImage theImage,
+                                int pass, int minPass, int maxPass,
+                                int minX, int minY, int periodX, int periodY,
+                                int[] bands)
+        {
+            System.out.println("passStarted");
+        }
+        public void thumbnailPassComplete(ImageReader source,
+                                          BufferedImage theThumbnail)
+        {
+            System.out.println("thumbnailPassComplete");
+        }
+        public void thumbnailPassStarted(ImageReader source,
+                                         BufferedImage theThumbnail,
+                                         int pass, int minPass, int maxPass,
+                                         int minX, int minY,
+                                         int periodX, int periodY,
+                                         int[] bands)
+        {
+            System.out.println("thumbnailPassStarted");
+        }
+        public void thumbnailUpdate(ImageReader source,
+                                    BufferedImage theThumbnail,
+                                    int minX, int minY,
+                                    int width, int height,
+                                    int periodX, int periodY, int[] bands)
+        {
+            System.out.println("thumbnailUpdate");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/RleEncodingTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4893446
+ * @summary Tests that we get IOException if we try to encode the incompatible
+ *          image with RLE compression
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+
+public class RleEncodingTest {
+
+    private static int testIdx = 1;
+
+    public static void main(String args[]) throws Exception {
+        try {
+            int mode = ImageWriteParam.MODE_EXPLICIT;
+            String type = "BI_RLE4";
+            doTest(type, mode);
+
+            type = "BI_RLE8";
+            doTest(type, mode);
+
+            mode = ImageWriteParam.MODE_DEFAULT;
+            type = "BI_RLE4";
+            doTest(type, mode);
+
+            type = "BI_RLE8";
+            doTest(type, mode);
+
+            System.out.println("Test 4bpp image.");
+            encodeRLE4Test();
+
+            System.out.println("Test 8bpp image.");
+            encodeRLE8Test();
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Unexpected exception. Test failed");
+        }
+    }
+
+    private static void doTest(String compressionType,
+                               int compressionMode) throws IOException
+    {
+        BufferedImage bimg = new BufferedImage(100, 100,
+                                               BufferedImage.TYPE_INT_RGB);
+        Graphics g = bimg.getGraphics();
+        g.setColor(Color.green);
+        g.fillRect(0, 0, 100, 100);
+
+        doTest(bimg, compressionType, compressionMode);
+    }
+
+    private static void encodeRLE4Test() throws IOException {
+        // create 4bpp image
+        byte[] r = new byte[16];
+        r[0] = (byte)0xff;
+        byte[] g = new byte[16];
+        g[1] = (byte)0xff;
+        byte[] b = new byte[16];
+        b[2] = (byte)0xff;
+        IndexColorModel icm = new IndexColorModel(4, 16, r, g, b);
+
+        BufferedImage bimg = new BufferedImage(100, 100,
+                                               BufferedImage.TYPE_BYTE_BINARY,
+                                               icm);
+
+        Graphics gr = bimg.getGraphics();
+        gr.setColor(Color.green);
+        gr.fillRect(0, 0, 100, 100);
+
+        doTest(bimg, "BI_RLE4", ImageWriteParam.MODE_EXPLICIT);
+    }
+
+    private static void encodeRLE8Test() throws IOException {
+        // create 8bpp image
+        byte[] r = new byte[256];
+        r[0] = (byte)0xff;
+        byte[] g = new byte[256];
+        g[1] = (byte)0xff;
+        byte[] b = new byte[256];
+        b[2] = (byte)0xff;
+        IndexColorModel icm = new IndexColorModel(8, 256, r, g, b);
+
+        BufferedImage bimg = new BufferedImage(100, 100,
+                                               BufferedImage.TYPE_BYTE_INDEXED,
+                                               icm);
+        Graphics gr = bimg.getGraphics();
+        gr.setColor(Color.green);
+        gr.fillRect(0, 0, 100, 100);
+
+        doTest(bimg, "BI_RLE8", ImageWriteParam.MODE_EXPLICIT);
+    }
+
+    private static void doTest(BufferedImage src,
+                               String compressionType,
+                               int compressionMode) throws IOException
+    {
+
+        ImageWriter iw =  (ImageWriter)ImageIO.getImageWritersBySuffix("bmp").next();
+        if (iw == null) {
+            throw new RuntimeException("No available writer. Test failed.");
+        }
+
+        IIOImage iioImg = new IIOImage(src, null, null);
+        ImageWriteParam param = iw.getDefaultWriteParam();
+
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+        iw.setOutput(ios);
+
+        System.out.println("Compression Type is " + compressionType);
+        System.out.println("Compression Mode is " + compressionMode);
+
+        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+        param.setCompressionType(compressionType);
+        if (compressionMode != ImageWriteParam.MODE_EXPLICIT) {
+            param.setCompressionMode(compressionMode);
+        }
+        try {
+            iw.write(null, iioImg, param);
+        } catch (IOException e) {
+            int bpp = src.getColorModel().getPixelSize();
+            if (compressionMode == ImageWriteParam.MODE_EXPLICIT) {
+                if ((compressionType.equals("BI_RLE4") && bpp != 4)
+                    || (compressionType.equals("BI_RLE8") && bpp != 8))
+                {
+                    System.out.println("Can not encode "+ bpp+ "bpp image as"
+                                      + compressionType);
+                    return;
+                } else {
+                    throw new RuntimeException("Unable to encode "
+                                               + bpp + "bpp image as "
+                                               + compressionType
+                                               + ". Test failed");
+                }
+            }
+        }
+        baos.close();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ImageInputStream iis = ImageIO.createImageInputStream(bais);
+
+        BufferedImage dst = ImageIO.read(iis);
+
+        int w = src.getWidth();
+        int h = src.getHeight();
+
+        Object dstPixel = dst.getRaster().getDataElements(w/2, h/2, null);
+        Object srcPixel = src.getRaster().getDataElements(w/2, h/2, null);
+
+        if ( (src.getColorModel().getRed(srcPixel)
+              != dst.getColorModel().getRed(dstPixel))
+             || (src.getColorModel().getGreen(srcPixel)
+                 != dst.getColorModel().getGreen(dstPixel))
+             || (src.getColorModel().getBlue(srcPixel)
+                 != dst.getColorModel().getBlue(dstPixel))
+             || (src.getColorModel().getAlpha(srcPixel)
+                 != dst.getColorModel().getAlpha(dstPixel)) ) {
+
+            showPixel(src, w/2, h/2);
+            showPixel(dst, w/2, h/2);
+
+            throw new RuntimeException(
+                "Colors are different: " +
+                Integer.toHexString(src.getColorModel().getRGB(srcPixel))
+                + " and " +
+                Integer.toHexString(dst.getColorModel().getRGB(dstPixel)));
+        }
+
+    }
+
+    private static void showPixel(BufferedImage src, int x, int y) {
+        System.out.println("Img is " + src);
+        Object p = src.getRaster().getDataElements(x, y, null);
+        System.out.println("RGB:   " +
+                           Integer.toHexString(src.getColorModel().getRGB(p)));
+        System.out.println("Red:   " +
+                           Integer.toHexString(src.getColorModel().getRed(p)));
+        System.out.println("Green: " +
+                           Integer.toHexString(src.getColorModel().getGreen(p)));
+        System.out.println("Blue:  " +
+                           Integer.toHexString(src.getColorModel().getBlue(p)));
+        System.out.println("Alpha: " +
+                           Integer.toHexString(src.getColorModel().getAlpha(p)));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/TestCompressionBI_BITFIELDS.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6297016 6294960 6294965 6294984
+ * @summary Test verifies that buffered images are written correctly if
+ *          compression BI_BITFIELDS is used
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+
+public class TestCompressionBI_BITFIELDS {
+
+    protected String format = "BMP";
+
+    protected ImageReader reader;
+
+    protected ImageWriter writer;
+
+    protected boolean doSave = true;
+
+    Color[] colors = {
+        Color.red, Color.green, Color.blue,
+        Color.yellow, Color.white, Color.black};
+
+    int dx = 50;
+    int h = 200;
+
+    public TestCompressionBI_BITFIELDS() {
+        this("BMP");
+    }
+
+    public TestCompressionBI_BITFIELDS(String format) {
+        this.format = format;
+        reader = ImageIO.getImageReadersByFormatName(format).next();
+        writer = ImageIO.getImageWritersByFormatName(format).next();
+    }
+
+    protected ImageWriteParam prepareWriteParam(BufferedImage src) {
+        ImageWriteParam wparam = writer.getDefaultWriteParam();
+        wparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+        wparam.setCompressionType("BI_BITFIELDS");
+
+        return wparam;
+    }
+
+    public BufferedImage writeAndRead(BufferedImage src) throws IOException {
+        writer.reset();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        writer.setOutput(ImageIO.createImageOutputStream(baos));
+
+        ImageWriteParam wparam = prepareWriteParam(src);
+
+        IIOImage img = new IIOImage(src, null, null);
+
+        writer.write(null, img, wparam);
+
+        if (doSave) {
+            // save images to file in order to be able to check
+            // that image is well-formed using standard windows tools.
+            File f = File.createTempFile("wr_test_", "." + format, new File("."));
+            System.out.println("Save to file: " + f.getCanonicalPath());
+            FileOutputStream fos = new FileOutputStream(f);
+            fos.write(baos.toByteArray());
+            fos.flush();
+            fos.close();
+        }
+
+        // read result
+        reader.reset();
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        reader.setInput(ImageIO.createImageInputStream(bais));
+
+        return reader.read(0);
+    }
+
+    public static void main(String[] args) throws IOException {
+        // buffered image types listed below can be saved as BI_BITFIELDS BMP
+        int[] types = {BufferedImage.TYPE_3BYTE_BGR,
+                       BufferedImage.TYPE_USHORT_555_RGB,
+                       BufferedImage.TYPE_USHORT_565_RGB,
+                       BufferedImage.TYPE_BYTE_GRAY,
+                       BufferedImage.TYPE_BYTE_BINARY,
+                       BufferedImage.TYPE_BYTE_INDEXED,
+                       BufferedImage.TYPE_INT_BGR,
+                       BufferedImage.TYPE_INT_RGB};
+
+        for (int i = 0; i < types.length; i++) {
+            System.out.println("Test image " + types[i]);
+            TestCompressionBI_BITFIELDS t = new TestCompressionBI_BITFIELDS();
+
+            BufferedImage src =
+                t.createTestImage(types[i]);
+            System.out.println("Image for test: " + src);
+            System.out.println("SampleModel: " + src.getSampleModel());
+
+            BufferedImage dst = null;
+            try {
+                dst = t.writeAndRead(src);
+            } catch (IOException e) {
+                e.printStackTrace(System.out);
+            }
+
+
+            t.compareImages(src, dst);
+        }
+    }
+
+    protected BufferedImage createTestImage(int type) {
+        BufferedImage bimg = new BufferedImage(dx * colors.length, h, type);
+        Graphics2D g = bimg.createGraphics();
+
+        for (int i = 0; i < colors.length; i++) {
+            g.setColor(colors[i]);
+            g.fillRect(dx * i, 0, dx, h);
+        }
+        return bimg;
+    }
+
+    protected void compareImages(BufferedImage src, BufferedImage dst) {
+        ColorSpace srcCS = src.getColorModel().getColorSpace();
+        ColorSpace dstCS = dst.getColorModel().getColorSpace();
+        if (!srcCS.equals(dstCS) && srcCS.getType() == ColorSpace.TYPE_GRAY) {
+            System.out.println("Workaround color difference with GRAY.");
+            BufferedImage tmp  =
+                new BufferedImage(src.getWidth(), src.getHeight(),
+                                  BufferedImage.TYPE_INT_RGB);
+            Graphics g = tmp.createGraphics();
+            g.drawImage(src, 0, 0, null);
+            src = tmp;
+        }
+        int y = h / 2;
+        for (int i = 0; i < colors.length; i++) {
+            int x = dx * i + dx / 2;
+            int srcRgb = src.getRGB(x, y);
+            int dstRgb = dst.getRGB(x, y);
+
+            if (srcRgb != dstRgb) {
+                throw new RuntimeException("Test failed due to color difference: " +
+                                           "src_pixel=" + Integer.toHexString(srcRgb) +
+                                           "dst_pixel=" + Integer.toHexString(dstRgb));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/Write3ByteBgrTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4892194 8014427
+ * @summary Test checks that we able to encode TYPE_3BYTE_BGR images to bmp
+ *          format. Test failed if ArrayIndexOutOfBoundsException will be thrown
+ *          or pixel colors will be changed by the writing/reading.
+ */
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+
+public class Write3ByteBgrTest {
+    private static int width = 100;
+    private static int height = 100;
+    private static Color color = new Color(0x10, 0x20, 0x30);
+
+    static int bufferedImageType[] = {
+        BufferedImage.TYPE_CUSTOM,
+        BufferedImage.TYPE_BYTE_BINARY,
+        BufferedImage.TYPE_3BYTE_BGR
+    };
+
+    static String bufferedImageStringType[] = {
+        "BufferedImage.TYPE_CUSTOM: test for BandedSampleModel",
+        "BufferedImage.TYPE_BYTE_BINARY",
+        "BufferedImage.TYPE_3BYTE_BGR"
+    };
+
+    private static String writingFormat = "BMP";
+    private static ImageWriter writer = (ImageWriter)ImageIO.getImageWritersByFormatName(writingFormat).next();
+    private int type;
+
+    public static void main(String[] args) {
+
+        //int i = 0;
+        for(int i=0; i<bufferedImageType.length; i++) {
+            Write3ByteBgrTest t1 = new Write3ByteBgrTest(bufferedImageType[i]);
+
+            System.out.println("\n\nImage test for type " + bufferedImageStringType[i]);
+            t1.doImageTest();
+        }
+    }
+
+    private Write3ByteBgrTest(int type) {
+        this.type = type;
+    }
+
+    private void doImageTest() {
+        try {
+            BufferedImage src = createTestImage(type);
+            BufferedImage dst = writeImage(src);
+
+            compareImages(src, dst);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new RuntimeException("Test failed: index out of array bounds!");
+        }
+    }
+
+
+    private void compareImages(BufferedImage src, BufferedImage dst) {
+        Object dstPixel = dst.getRaster().getDataElements(width/2, height/2, null);
+        Object srcPixel = src.getRaster().getDataElements(width/2, height/2, null);
+
+        if ( (src.getColorModel().getRed(srcPixel) != dst.getColorModel().getRed(dstPixel)) ||
+             (src.getColorModel().getGreen(srcPixel) != dst.getColorModel().getGreen(dstPixel)) ||
+             (src.getColorModel().getBlue(srcPixel) != dst.getColorModel().getBlue(dstPixel)) ||
+             (src.getColorModel().getAlpha(srcPixel) != dst.getColorModel().getAlpha(dstPixel)) ) {
+
+            showPixel(src, width/2, height/2);
+            showPixel(dst, width/2, height/2);
+
+            showRes(dst, src);
+            throw new RuntimeException(
+                "Colors are different: " +
+                Integer.toHexString(src.getColorModel().getRGB(srcPixel)) + " and " +
+                Integer.toHexString(dst.getColorModel().getRGB(dstPixel)));
+        }
+    }
+
+    private BufferedImage writeImage(BufferedImage src) {
+        try {
+            BufferedImage dst = null;
+            if (!writer.getOriginatingProvider().canEncodeImage(src)) {
+                throw new RuntimeException(writingFormat+" writer does not support the image type "+type);
+            }
+            System.out.println(writingFormat+" writer claims it can encode the image "+type);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+            writer.setOutput(ios);
+            IIOImage img = new IIOImage(src.getRaster(), null, null);
+            writer.write(img);
+            ios.close();
+            baos.close();
+
+            // save to file
+            File f = new File("test"+src.getType()+".bmp");
+            FileOutputStream fos = new FileOutputStream(f);
+            fos.write(baos.toByteArray());
+            fos.close();
+
+
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            dst = ImageIO.read(bais);
+            return dst;
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static void showPixel(BufferedImage src, int x, int y) {
+        System.out.println("Img is " + src);
+        Object p = src.getRaster().getDataElements(x, y, null);
+        System.out.println("RGB:   " +
+                           Integer.toHexString(src.getColorModel().getRGB(p)));
+        System.out.println("Red:   " +
+                           Integer.toHexString(src.getColorModel().getRed(p)));
+        System.out.println("Green: " +
+                           Integer.toHexString(src.getColorModel().getGreen(p)));
+        System.out.println("Blue:  " +
+                           Integer.toHexString(src.getColorModel().getBlue(p)));
+        System.out.println("Alpha: " +
+                           Integer.toHexString(src.getColorModel().getAlpha(p)));
+    }
+
+    private static BufferedImage createTestImage(int type) {
+        return createTestImage(type, color);
+    }
+
+    private static BufferedImage createTestImage(int type, Color c) {
+        BufferedImage i = null;
+        if (type == BufferedImage.TYPE_CUSTOM) {
+            WritableRaster wr = Raster.createBandedRaster(
+                DataBuffer.TYPE_BYTE,
+                width, height,
+                width,               // scanlineStride
+                new int[] { 0, 1, 2},// bankIndices[],
+                new int[] { 1, 2, 0},// bankOffsets[],
+                null);
+
+            ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+
+            ColorModel cm = new ComponentColorModel(cs,
+                                                    new int[] { 8, 8, 8},
+                                                    false,
+                                                    false,
+                                                    ColorModel.OPAQUE,
+                                                    DataBuffer.TYPE_BYTE);
+            i = new BufferedImage(cm, wr, false, null);
+        } else {
+            i = new BufferedImage(width, height, type);
+        }
+
+        Graphics2D g = i.createGraphics();
+
+        g.setColor(c);
+        g.fillRect(0, 0, width, height);
+        g.setColor(Color.white);
+        g.drawRect(10,10, width-20, height-20);
+
+        return i;
+    }
+
+    private static void showRes(final BufferedImage src,
+                                final BufferedImage dst)
+        {
+        final int w = src.getWidth()+  dst.getWidth();
+        final int h = Math.max(src.getHeight(), dst.getHeight());
+
+        JFrame f = new JFrame("Test results");
+        f.getContentPane().add( new JComponent() {
+                public Dimension getPreferredSize() {
+                    return new Dimension(w,h);
+                }
+
+                public void paintComponent(Graphics g) {
+                    g.drawImage(src,0,0, null);
+                    g.drawImage(dst, src.getWidth(),0, null);
+                }
+            });
+        f.pack();
+        f.setVisible(true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/WriteProgressListenerTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4897067 4920152
+ * @summary Tests that IIOWriteProgressListener receives correct progress
+ *          percentage. Also it tests problem described in 4920152: test fails
+ *          if imageComplete() or imageStarted() was called twice.
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.event.IIOWriteProgressListener;
+import javax.imageio.stream.ImageOutputStream;
+
+public class WriteProgressListenerTest {
+
+
+    protected static String format = "BMP";
+
+        protected String compression_type;
+        protected WriteProgressListener listener;
+
+        public WriteProgressListenerTest(String compression_type) {
+        this.compression_type = compression_type;
+        listener = new WriteProgressListener();
+    }
+
+    public void doTest() {
+        try {
+            System.out.println("Progress test for " + compression_type);
+            BufferedImage bi = new BufferedImage(20, 300, BufferedImage.TYPE_INT_RGB);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+
+            Iterator iter = ImageIO.getImageWritersByFormatName(format);
+            if (!iter.hasNext()) {
+                throw new RuntimeException("No available writer for " + format);
+            }
+            ImageWriter writer = (ImageWriter)iter.next();
+
+            writer.setOutput(ios);
+            writer.addIIOWriteProgressListener(listener);
+
+            IIOImage iio_img = new IIOImage(bi, null, null);
+
+            ImageWriteParam param = writer.getDefaultWriteParam();
+
+            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+            param.setCompressionType(compression_type);
+
+
+            writer.write(null, iio_img, param);
+
+            if (!listener.isTestPassed) {
+                throw new RuntimeException("Test for " + compression_type + " does not finish correctly!");
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+        public static void main(String args[]) {
+        String[] compression_types = new String[] { "BI_RGB",
+                                                    "BI_JPEG",
+                                                    "BI_PNG"};
+
+        for(int i=0; i<compression_types.length; i++) {
+            WriteProgressListenerTest test = new
+                WriteProgressListenerTest(compression_types[i]);
+            test.doTest();
+        }
+        }
+
+    static class WriteProgressListener implements IIOWriteProgressListener {
+        List progress;
+        public boolean isTestPassed = false;
+        private boolean isImageStarted = false;
+        private boolean isImageComplete = false;
+
+        public WriteProgressListener() {
+            progress = new ArrayList();
+        }
+
+        public void imageComplete(ImageWriter source) {
+            System.out.println("Image Completed");
+            if (!isImageComplete) {
+                isImageComplete = true;
+            } else {
+                throw new RuntimeException("The imageComplete() was called twice."
+                                           + " Test failed.");
+            }
+
+            checkProgress();
+        }
+        public void imageProgress(ImageWriter source, float percentageDone) {
+            System.out.println("Image Progress "+percentageDone);
+            progress.add(new Float(percentageDone));
+        }
+
+        public void imageStarted(ImageWriter source, int imageIndex) {
+            System.out.println("Image Started "+imageIndex);
+            if (!isImageStarted) {
+                isImageStarted = true;
+            } else {
+                throw new RuntimeException("The imageStarted() was called twice. "
+                                           + " Test failed.");
+            }
+            progress.clear();
+        }
+
+        public void thumbnailComplete(ImageWriter source)  {
+            System.out.println("Thubnail completed");
+        }
+
+        public void thumbnailProgress(ImageWriter source, float percentageDone) {
+            System.out.println("Thubnail Progress " + percentageDone);
+        }
+
+        public void thumbnailStarted(ImageWriter source, int imageIndex, int thumbnailIndex) {
+            System.out.println("Thubnail started " + imageIndex);
+        }
+
+        public void writeAborted(ImageWriter source) {
+            System.out.println("Writing Aborted");
+            checkProgress();
+        }
+
+        private void checkProgress() {
+            Iterator i = progress.iterator();
+            if (!i.hasNext()) {
+                throw new RuntimeException("progress values list is empty!");
+            }
+            float val = ((Float)i.next()).floatValue();
+            while(i.hasNext()) {
+                float next = ((Float)i.next()).floatValue();
+                if (val >= next) {
+                    throw new RuntimeException("progress values do not increase!");
+                }
+                val = next;
+            }
+            isTestPassed = true;
+            System.out.println("Test passed.");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/bmp/WritingColorChangeTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4892214
+ * @summary Test checks that colors are not changed by the writing/reading in
+ *          the BMP format for TYPE_INT_BGR and TYPE_USHORT_555_RGB buffered
+ *          images
+ */
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+
+public class WritingColorChangeTest {
+    private static int width = 100;
+    private static int height = 100;
+    private static Color color = new Color(0x10, 0x20, 0x30);
+
+    static int bufferedImageType[] = {
+        BufferedImage.TYPE_USHORT_565_RGB,
+        BufferedImage.TYPE_INT_BGR,
+        BufferedImage.TYPE_INT_RGB,
+        BufferedImage.TYPE_USHORT_555_RGB,
+    };
+
+    static String bufferedImageStringType[] = {
+        "BufferedImage.TYPE_USHORT_565_RGB",
+        "BufferedImage.TYPE_INT_BGR",
+        "BufferedImage.TYPE_INT_RGB",
+        "BufferedImage.TYPE_USHORT_555_RGB",
+    };
+    private static String writingFormat = "BMP";
+    private static ImageWriter writer = (ImageWriter)ImageIO.getImageWritersByFormatName(writingFormat).next();
+    private int type;
+
+    public static void main(String[] args) {
+
+        //int i = 7; //3; //7;
+        for(int i=0; i<bufferedImageType.length; i++) {
+            System.out.println("\n\nTest for type " + bufferedImageStringType[i]);
+
+            WritingColorChangeTest t1 = new WritingColorChangeTest(bufferedImageType[i]);
+            t1.doTest();
+
+        }
+    }
+
+    private WritingColorChangeTest(int type) {
+        this.type = type;
+    }
+
+    private void doTest() {
+        BufferedImage src = createTestImage(type);
+        System.out.println("Sample model is " + src.getSampleModel());
+
+        BufferedImage dst = doModification(src);
+
+        Object dstPixel = dst.getRaster().getDataElements(width/2, height/2, null);
+        Object srcPixel = src.getRaster().getDataElements(width/2, height/2, null);
+
+        if (src.getType() == BufferedImage.TYPE_USHORT_555_RGB ||
+            src.getType() == BufferedImage.TYPE_USHORT_565_RGB ) {
+
+            Color cmpColor = new Color(dst.getColorModel().getRed(dstPixel),
+                                       dst.getColorModel().getGreen(dstPixel),
+                                       dst.getColorModel().getBlue(dstPixel));
+            BufferedImage cmp = createTestImage(src.getType(), cmpColor);
+
+            Object cmpPixel = cmp.getRaster().getDataElements(width/2, height/2, null);
+
+            dst = cmp;
+            dstPixel = cmpPixel;
+        }
+
+        if ( (src.getColorModel().getRed(srcPixel) != dst.getColorModel().getRed(dstPixel)) ||
+             (src.getColorModel().getGreen(srcPixel) != dst.getColorModel().getGreen(dstPixel)) ||
+             (src.getColorModel().getBlue(srcPixel) != dst.getColorModel().getBlue(dstPixel)) ||
+             (src.getColorModel().getAlpha(srcPixel) != dst.getColorModel().getAlpha(dstPixel)) ) {
+
+            showPixel(src, width/2, height/2);
+            showPixel(dst, width/2, height/2);
+
+            showRes(dst, src);
+            throw new RuntimeException(
+                "Colors are different: " +
+                Integer.toHexString(src.getColorModel().getRGB(srcPixel)) + " and " +
+                Integer.toHexString(dst.getColorModel().getRGB(dstPixel)));
+        }
+    }
+
+    private BufferedImage doModification(BufferedImage src) {
+        try {
+            BufferedImage dst = null;
+            if (!writer.getOriginatingProvider().canEncodeImage(src)) {
+                throw new RuntimeException(writingFormat+" writer does not support the image type "+type);
+            }
+            System.out.println(writingFormat+" writer claims it can encode the image "+type);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+            writer.setOutput(ios);
+            writer.write(src);
+            ios.close();
+            baos.close();
+
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            dst = ImageIO.read(bais);
+            return dst;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static void showPixel(BufferedImage src, int x, int y) {
+        System.out.println("Img is " + src);
+        Object p = src.getRaster().getDataElements(x, y, null);
+        System.out.println("RGB:   " +
+                           Integer.toHexString(src.getColorModel().getRGB(p)));
+        System.out.println("Red:   " +
+                           Integer.toHexString(src.getColorModel().getRed(p)));
+        System.out.println("Green: " +
+                           Integer.toHexString(src.getColorModel().getGreen(p)));
+        System.out.println("Blue:  " +
+                           Integer.toHexString(src.getColorModel().getBlue(p)));
+        System.out.println("Alpha: " +
+                           Integer.toHexString(src.getColorModel().getAlpha(p)));
+    }
+
+    private static BufferedImage createTestImage(int type) {
+        return createTestImage(type, color);
+    }
+
+    private static BufferedImage createTestImage(int type, Color c) {
+        BufferedImage i = new BufferedImage(width, height,
+                                            type);
+        Graphics2D g = i.createGraphics();
+
+        g.setColor(c);
+        g.fillRect(0, 0, width, height);
+
+        return i;
+    }
+
+    private static void showRes(final BufferedImage src, final BufferedImage dst) {
+        final int w = src.getWidth()+  dst.getWidth();
+        final int h = Math.max(src.getHeight(), dst.getHeight());
+
+        JFrame f = new JFrame("Test results");
+        f.getContentPane().add( new JComponent() {
+                public Dimension getPreferredSize() {
+                    return new Dimension(w,h);
+                }
+
+                public void paintComponent(Graphics g) {
+                    g.drawImage(src,0,0, null);
+                    g.drawImage(dst, src.getWidth(),0, null);
+                }
+            });
+        f.pack();
+        f.setVisible(true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/AnimationTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4339415
+ * @summary Tests that GIF writer plugin writes image sequences correctly
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageOutputStream;
+
+public class AnimationTest {
+
+    BufferedImage img = null;
+    int x, y;
+    int w, h;
+
+    protected static String fname = "animtest.gif";
+
+    public AnimationTest() {
+        w = h = 100;
+    }
+
+    private void initFrame() {
+        if (img != null) {
+            return;
+        }
+        byte r[] = new byte[256];
+        byte g[] = new byte[256];
+        byte b[] = new byte[256];
+
+        for (int i = 0; i < 256; i++) {
+            r[i] = g[i] = b[i] = (byte)0x00;
+        }
+        r[0] = (byte)0x00; g[0] = (byte)0x00; b[0] = (byte)0x00;
+        r[1] = (byte)0xFF; g[1] = (byte)0xFF; b[1] = (byte)0xFF;
+        r[2] = (byte)0xFF; g[3] = (byte)0xFF; b[4] = (byte)0xFF;
+
+        IndexColorModel icm = new IndexColorModel(8, 256,
+                                                  r, g, b);
+
+        img = new BufferedImage(w, h,
+                                BufferedImage.TYPE_BYTE_INDEXED,
+                                icm);
+    }
+
+    private BufferedImage createNextFrame() {
+        Graphics g = img.createGraphics();
+        g.setColor(Color.white);
+        g.fillRect(0, 0, w, h);
+
+        g.setColor(Color.red);
+        g.drawLine(x, 0, x, h);
+
+        g.setColor(Color.blue);
+        g.drawLine(0, y, w, y);
+
+        x += 2;
+        y += 2;
+
+        x %= w;
+        y %= h;
+
+        return img;
+    }
+
+    ImageWriter writer = null;
+
+    private ImageWriter initWriter() throws IOException {
+        ImageOutputStream ios =
+            ImageIO.createImageOutputStream(new File(fname));
+        writer = ImageIO.getImageWritersByFormatName("GIF").next();
+
+        writer.setOutput(ios);
+
+        return writer;
+    }
+
+    public static void main(String[] args) {
+        try {
+            AnimationTest t = new AnimationTest();
+            t.initFrame();
+
+            ImageWriter w = t.initWriter();
+
+            ImageWriteParam p = w.getDefaultWriteParam();
+
+            IIOMetadata streamMetadata = w.getDefaultStreamMetadata(p);
+
+            w.prepareWriteSequence(streamMetadata);
+
+            for (int i = 0; i < 50; i++) {
+                BufferedImage f = t.createNextFrame();
+
+                ImageTypeSpecifier type = new ImageTypeSpecifier(f);
+
+                IIOMetadata m = w.getDefaultImageMetadata(type, p);
+
+                w.writeToSequence(new IIOImage(f, null, m), p);
+            }
+            w.endWriteSequence();
+
+            t.checkAnimation();
+        } catch (Exception e) {
+            throw new RuntimeException("Test failed.", e);
+        }
+    }
+
+    protected void checkAnimation() throws IOException {
+        ImageReader r = ImageIO.getImageReadersByFormatName("GIF").next();
+        r.setInput(ImageIO.createImageInputStream(new File(fname)));
+
+        int n = r.getNumImages(true);
+        for (int i = 0; i < n; i++) {
+            BufferedImage f = r.read(i);
+            checkFrame(i, f);
+        }
+        System.out.println("Test passed.");
+    }
+
+    protected void checkFrame(int i, BufferedImage f) {
+        int x = 2 * i + 1;
+        for (int y = 0; y < h; y++) {
+            int argb = f.getRGB(x, y);
+            if (argb != 0xffffffff && !(argb == 0xff0000ff && y == 2 * i)) {
+                throw new RuntimeException("Test failed - bad frame");
+            }
+            argb = f.getRGB(y, x);
+            if (argb != 0xffffffff && !(argb == 0xffff0000 && y == 2 * i)) {
+                throw new RuntimeException("Test failed - bad frame");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/DisableCompressionTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6294683
+ * @summary Test verifies that GIF ImageWriteParam behaves according to spec
+ */
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+
+public class DisableCompressionTest {
+
+    public static void main(String[] args) {
+        testFormat("GIF");
+    }
+
+    protected static void testFormat(String format) {
+        ImageWriter writer = ImageIO.getImageWritersByFormatName(format).next();
+        if (writer == null) {
+            throw new RuntimeException("No writer for " + format);
+        }
+
+        ImageWriteParam param = writer.getDefaultWriteParam();
+        int[] supported_modes = new int[] {
+            ImageWriteParam.MODE_COPY_FROM_METADATA,
+                    ImageWriteParam.MODE_DEFAULT,
+                    ImageWriteParam.MODE_EXPLICIT };
+
+        for (int mode : supported_modes) {
+            String mode_name = getModeName(mode);
+            System.out.println("Test mode " + mode_name + "...");
+            // we know that GIF image writer supports compression
+            // and supports any compression mode form supportd_modes
+            // If exception would be thrown here then test failed.
+            param.setCompressionMode(mode);
+
+            // now we are trying to disable compression.
+            // This operation is not supported because GIF image writer
+            // does not provide uncompressed output.
+            // The expected behaviour is that UnsupportedOperationException
+            // will be thrown here and current compression mode will not be
+            // changed.
+            boolean gotException = false;
+            try {
+                param.setCompressionMode(ImageWriteParam.MODE_DISABLED);
+            } catch (UnsupportedOperationException e) {
+                gotException = true;
+            } catch (Throwable e) {
+                throw new RuntimeException("Test failed due to unexpected exception", e);
+            }
+
+            if (!gotException) {
+                throw new RuntimeException("Test failed.");
+            }
+
+            if (param.getCompressionMode() != mode) {
+                throw new RuntimeException("Param state was changed.");
+            }
+            System.out.println("Test passed.");
+        }
+    }
+
+    private static String getModeName(int mode) {
+        switch(mode) {
+            case ImageWriteParam.MODE_COPY_FROM_METADATA:
+                return "MODE_COPY_FROM_METADATA";
+            case ImageWriteParam.MODE_DEFAULT:
+                return "MODE_DEFAULT";
+            case ImageWriteParam.MODE_DISABLED:
+                return "MODE_DISABLED";
+            case ImageWriteParam.MODE_EXPLICIT:
+                return "MODE_EXPLICIT";
+            default:
+                throw new IllegalArgumentException("Unknown mode: " + mode);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/EndWriteSequenceTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6275366 6275369
+ * @summary Verifies that behaviour of GIFImageWriter.endWriteSequence() is
+ *          consistent with specification
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
+
+public class EndWriteSequenceTest {
+    public static void main(String[] args) throws IOException {
+        ImageWriter w =
+            ImageIO.getImageWritersByFormatName("GIF").next();
+
+        boolean gotCorrectException = false;
+
+        /**
+         * check statement: "Throws: IllegalStateException -
+         * if the output has not been set ...."
+         */
+        try {
+            w.reset(); // to be shure that output is null
+            w.endWriteSequence();
+        } catch (IllegalStateException e) {
+            gotCorrectException = true;
+        } catch (Throwable e) {
+            throw new RuntimeException("Test failed.", e);
+        }
+        if (!gotCorrectException) {
+            throw new RuntimeException("Test failed.");
+        }
+
+        /**
+         * set up output stream
+         */
+        ByteArrayOutputStream baos =
+            new ByteArrayOutputStream();
+
+        ImageOutputStream ios =
+            ImageIO.createImageOutputStream(baos);
+
+        w.setOutput(ios);
+
+        /**
+         * check statement: "Throws: IllegalStateException -
+         * if .... prepareWriteSequence has not been called.
+         */
+        gotCorrectException = false;
+        try {
+            w.endWriteSequence();
+        } catch  (IllegalStateException e) {
+            gotCorrectException = true;
+        } catch (Throwable e) {
+            throw new RuntimeException("Test failed.", e);
+        }
+        if (!gotCorrectException) {
+            throw new RuntimeException("Test failed.");
+        }
+
+        System.out.println("Test passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/IndexingTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4339415
+ * @summary Tests that GIF writer plugin is able to write non-index images
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.util.Random;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+
+public class IndexingTest {
+
+    protected static final String fname = "itest.gif";
+
+    int w;
+    int h;
+
+    Random rnd;
+
+    public IndexingTest() {
+        w = h  = 200;
+        rnd = new Random();
+    }
+
+    public void doTest() {
+        ComponentColorModel ccm = createBitmaskColorModel();
+        BufferedImage img = createComponentImage(w, h, ccm);
+
+        try {
+            ImageWriter w = ImageIO.getImageWritersByFormatName("GIF").next();
+            w.setOutput(ImageIO.createImageOutputStream(new File(fname)));
+            w.write(img);
+        } catch (Exception e) {
+            throw new RuntimeException("Test failed.", e);
+        }
+
+        BufferedImage dst = null;
+        try {
+            dst = ImageIO.read(new File(fname));
+        } catch (Exception e) {
+            throw new RuntimeException("Test failed.", e);
+        }
+
+        compareImages(img, dst);
+
+        System.out.println("Test passed.");
+    }
+
+    protected static ComponentColorModel createBitmaskColorModel() {
+        ComponentColorModel cm =
+            new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                                    true, false, Transparency.BITMASK,
+                                    DataBuffer.TYPE_BYTE);
+        return cm;
+    }
+
+    protected static BufferedImage createComponentImage(int w, int h,
+                                                        ComponentColorModel cm)
+    {
+        WritableRaster wr = cm.createCompatibleWritableRaster(w, h);
+
+        BufferedImage img = new BufferedImage(cm, wr, false, null);
+        Graphics2D g = img.createGraphics();
+        int width = w / 8;
+        Color[] colors = new Color[8];
+        colors[0] = Color.red;
+        colors[1] = Color.green;
+        colors[2] = Color.blue;
+        colors[3] = Color.white;
+        colors[4] = Color.black;
+        colors[5] = new Color(0x80, 0x80, 0x80, 0x00);
+        colors[6] = Color.yellow;
+        colors[7] = Color.cyan;
+
+        for (int i = 0; i < 8; i++) {
+            g.setColor(colors[i]);
+            g.fillRect(i * width, 0, width, h);
+        }
+        return img;
+    }
+
+    protected void compareImages(BufferedImage src, BufferedImage dst) {
+        int n = 10;
+        while (n-- > 0) {
+            int x = rnd.nextInt(w);
+            int y = rnd.nextInt(h);
+
+            int pSrc = src.getRGB(x, y);
+            int pDst = src.getRGB(x, y);
+
+            if (pSrc != pDst) {
+                throw new RuntimeException("Images are different");
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        IndexingTest t = new IndexingTest();
+        t.doTest();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/LogicalScreenDimensionTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6307618
+ * @summary Test verifies that GIF image writer updates the dimension of the
+ *          logical screen according to image dimension
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+
+import com.sun.imageio.plugins.gif.GIFStreamMetadata;
+
+public class LogicalScreenDimensionTest {
+    public static void main(String[] args) throws IOException {
+        String format = "GIF";
+        ImageWriter writer =
+                ImageIO.getImageWritersByFormatName(format).next();
+        if (writer == null) {
+            throw new RuntimeException("No available writers for " + format);
+        }
+
+        BufferedImage img = createTestImage(100, 100, BufferedImage.TYPE_BYTE_GRAY);
+
+        ImageWriteParam p = writer.getDefaultWriteParam();
+        ImageTypeSpecifier type =
+            ImageTypeSpecifier.createFromRenderedImage(img);
+        IIOMetadata inImageMetadata =
+            writer.getDefaultImageMetadata(type, p);
+
+        IIOMetadata inStreamMetadata = writer.getDefaultStreamMetadata(p);
+
+        // write and read image
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+        ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+        writer.setOutput(ios);
+
+        writer.write(inStreamMetadata, new IIOImage(img, null, inImageMetadata), p);
+
+        ios.flush();
+        ios.close();
+
+        // read result
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ImageInputStream iis = ImageIO.createImageInputStream(bais);
+        ImageReader reader = ImageIO.getImageReader(writer);
+        reader.setInput(iis);
+
+        IIOMetadata outStreamMetadata = reader.getStreamMetadata();
+
+        GIFStreamMetadata gifStreamMetadata = (GIFStreamMetadata)outStreamMetadata;
+
+        if (gifStreamMetadata.logicalScreenWidth != img.getWidth() ||
+                gifStreamMetadata.logicalScreenHeight != img.getHeight()) {
+            throw new RuntimeException("Test failed due to wrong logical screen dimension.");
+        }
+    }
+
+    private static BufferedImage createTestImage(int w, int h, int type) {
+        BufferedImage res = new BufferedImage(w, h, type);
+        Graphics2D g = res.createGraphics();
+        g.setColor(Color.white);
+        g.fillRect(0, 0, w, h);
+        g.setColor(Color.black);
+        g.fillRect(w/4, h/4, w/2, h/2);
+
+
+        return res;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/OddPaletteTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6275211 6276621
+ * @summary Tests that GIF writer plugin is able to write indexed images if
+ *          palette size is not a power of two
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
+
+public class OddPaletteTest {
+
+    private static int w = 100;
+    private static int h = 100;
+
+    public static void main(String[] args) {
+        BufferedImage[] srcs = new BufferedImage[2];
+        srcs[0] = createTestImage(7); // bug 6275211
+        srcs[1] = createTestImage(1); // bug 6276621
+
+        for (int i = 0; i < srcs.length; i++) {
+            doTest(srcs[i]);
+        }
+    }
+
+    private static void doTest(BufferedImage src) {
+        ImageWriter w = ImageIO.getImageWritersByFormatName("GIF").next();
+        if (w == null) {
+            throw new RuntimeException("No writer available!");
+        }
+
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+            w.setOutput(ios);
+            w.write(src);
+        } catch (IOException e) {
+            throw new RuntimeException("Test failed.", e);
+        } catch (IllegalArgumentException e) {
+            throw new RuntimeException("Test failed.", e);
+        }
+    }
+
+    private static BufferedImage createTestImage(int paletteSize) {
+        byte[] r = new byte[paletteSize];
+        byte[] g = new byte[paletteSize];
+        byte[] b = new byte[paletteSize];
+
+        int shift = 256 / paletteSize;
+        for (int i = 0; i < paletteSize; i++) {
+            r[i] = g[i] = b[i] = (byte)(shift * i);
+        }
+
+        int numBits = getNumBits(paletteSize);
+
+        System.out.println("num of bits " + numBits);
+
+        IndexColorModel icm =
+            new IndexColorModel(numBits, paletteSize,  r, g, b);
+
+        BufferedImage img = new BufferedImage(w, h,
+                                              BufferedImage.TYPE_BYTE_INDEXED,
+                                              icm);
+        Graphics2D  g2d = img.createGraphics();
+        g2d.setColor(Color.white);
+        g2d.fillRect(0, 0, w, h);
+        g2d.setColor(Color.black);
+        g2d.drawLine(0, 0, w, h);
+        g2d.drawLine(0, h, w, 0);
+
+        return img;
+    }
+
+    private static int getNumBits(int paletteSize) {
+        if (paletteSize < 0) {
+            throw new IllegalArgumentException("negative palette size: " +
+                                               paletteSize);
+        }
+        if (paletteSize < 2) {
+            return 1;
+        }
+        int numBits = 0;
+
+        paletteSize--;
+
+        while (paletteSize > 0) {
+            numBits++;
+            paletteSize = paletteSize >> 1;
+        }
+        return numBits;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/PrepareWriteSequenceTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6284538
+ * @summary Test verifies whether IllegalStateException is thrown if the output
+ *          stream have not set to the GIF image writer instance
+ */
+
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+
+public class PrepareWriteSequenceTest {
+    public static void main(String[] args) throws IOException {
+        String format = "GIF";
+        ImageWriter writer = ImageIO.getImageWritersByFormatName(format).next();
+
+        ImageWriteParam param = writer.getDefaultWriteParam();
+
+        IIOMetadata streamMetadata = writer.getDefaultStreamMetadata(param);
+
+        boolean gotException = false;
+        try {
+            writer.prepareWriteSequence(streamMetadata);
+        } catch (IllegalStateException e) {
+            gotException = true;
+            System.out.println("Test passed.");
+            e.printStackTrace(System.out);
+        }
+
+        if (!gotException) {
+            throw new RuntimeException("Test failed.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/RGBAnimationTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6324581
+ * @summary Test verifies that RGB images are written to animated GIF image use
+ *          local color table if image palette is not equals to the global color
+ *          table
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageOutputStream;
+
+import com.sun.imageio.plugins.gif.GIFImageMetadata;
+
+public class RGBAnimationTest {
+    protected static String format = "GIF";
+    protected static boolean doSave = true;
+
+    Frame[] frames;
+    ImageWriter writer;
+    ImageReader reader;
+
+    public static void main(String[] args) throws IOException  {
+        RGBAnimationTest test = new RGBAnimationTest();
+        test.doTest();
+    }
+    /** Creates a new instance of RGBAnimationTest */
+    public RGBAnimationTest() {
+        frames = new Frame[4];
+
+
+        frames[0] = new Frame(new Color[] {Color.red, Color.green});
+        frames[1] = new Frame(new Color[] {Color.green, Color.cyan});
+        frames[2] = new Frame(new Color[] {Color.cyan, Color.yellow});
+        frames[3] = new Frame(new Color[] {Color.yellow, Color.red});
+
+        writer = ImageIO.getImageWritersByFormatName(format).next();
+        reader = ImageIO.getImageReadersByFormatName(format).next();
+    }
+
+    public void doTest() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        writer.reset();
+        ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+        writer.setOutput(ios);
+
+        ImageWriteParam wparam = prepareWriteParam();
+
+        IIOMetadata streamMetadata = prepareStreamMetadata(wparam);
+
+        writer.prepareWriteSequence(streamMetadata);
+
+        for (int i = 0; i < frames.length; i++) {
+            BufferedImage src = frames[i].getImage();
+            IIOMetadata imageMetadata = prepareImageMetadata(i, src, wparam);
+            IIOImage img = new IIOImage(src,  null, imageMetadata);
+
+            writer.writeToSequence(img, wparam);
+        }
+        writer.endWriteSequence();
+        ios.flush();
+        ios.close();
+
+        if (doSave) {
+            File f = File.createTempFile("wr_test_", "." + format, new File("."));
+            System.out.println("Save to file: " + f.getCanonicalPath());
+            FileOutputStream fos = new FileOutputStream(f);
+            fos.write(baos.toByteArray());
+            fos.flush();
+            fos.close();
+        }
+        // read result
+        reader.reset();
+        ByteArrayInputStream bais =
+                new ByteArrayInputStream(baos.toByteArray());
+        reader.setInput(ImageIO.createImageInputStream(bais));
+
+        int minIndex = reader.getMinIndex();
+        int numImages = reader.getNumImages(true);
+
+        for (int i = 0; i < numImages; i++) {
+            BufferedImage dst = reader.read(i + minIndex);
+            frames[i].checkResult(dst);
+        }
+    }
+
+    protected IIOMetadata prepareImageMetadata(int i, BufferedImage img, ImageWriteParam wparam) {
+        GIFImageMetadata idata = (GIFImageMetadata)
+        writer.getDefaultImageMetadata(ImageTypeSpecifier.createFromRenderedImage(img), wparam);
+
+        idata.delayTime = 100;
+        idata.disposalMethod = 0;
+        idata.transparentColorFlag = false;
+
+        if (i == 0) {
+            ArrayList<byte[]> appIDs = new ArrayList<byte[]>();
+            appIDs.add(new String("NETSCAPE").getBytes());
+            ArrayList<byte[]> authCodes = new ArrayList<byte[]>();
+            authCodes.add(new String("2.0").getBytes());
+            ArrayList<byte[]> appData = new ArrayList<byte[]>();
+            byte[] authData = {1, 0, 0};
+            appData.add(authData);
+
+            idata.applicationIDs = appIDs;
+            idata.authenticationCodes = authCodes;
+            idata.applicationData = appData;
+        }
+        return idata;
+    }
+
+    protected ImageWriteParam prepareWriteParam() {
+        return writer.getDefaultWriteParam();
+    }
+
+    protected IIOMetadata prepareStreamMetadata(ImageWriteParam wparam) {
+        return writer.getDefaultStreamMetadata(wparam);
+    }
+
+}
+
+class Frame {
+    protected static int type = BufferedImage.TYPE_INT_RGB;
+    protected static int dx = 100;
+    protected static int h = 100;
+
+    protected Color[] colors;
+    protected BufferedImage img;
+
+    public Frame(Color[] colors) {
+        this.colors = colors;
+        img = null;
+    }
+
+    public BufferedImage getImage() {
+        if (img == null) {
+            img = new BufferedImage(dx * colors.length, h, type);
+            Graphics2D g = img.createGraphics();
+            for (int i = 0; i < colors.length; i++) {
+                g.setColor(colors[i]);
+                g.fillRect(dx * i, 0, dx, h);
+            }
+        }
+        return img;
+    }
+
+    public void checkResult(BufferedImage dst) {
+        int y = h / 2;
+        int x = dx / 2;
+        for (int i = 0; i < colors.length; i++) {
+
+            int srcRgb = img.getRGB(i * dx + x, y);
+            int dstRgb = dst.getRGB(i * dx + x, y);
+
+            if (srcRgb != dstRgb) {
+                throw new RuntimeException("Test failed due to color difference: " +
+                        Integer.toHexString(dstRgb) + " instead of " +
+                        Integer.toHexString(srcRgb));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/RGBImageTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6286578
+ * @summary Test verifies that RGB images does not convert to gray-scaled if
+ *          default image metadata is used
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+
+public class RGBImageTest {
+
+    Color[] usedColors = {
+        Color.red, Color.green, Color.blue, Color.yellow,
+        Color.cyan, Color.magenta, Color.white, Color.black };
+
+    BufferedImage src = null;
+    int dx= 20;
+    int height = 100;
+
+    protected BufferedImage getSrc() {
+        if (src == null) {
+            src = new BufferedImage(dx * usedColors.length, height,
+                                    BufferedImage.TYPE_INT_RGB);
+            Graphics g = src.createGraphics();
+            for (int i = 0; i < usedColors.length; i++) {
+                g.setColor(usedColors[i]);
+                g.fillRect(dx * i,  0, dx, height);
+            }
+        }
+        return src;
+    }
+
+    protected void doTest() throws IOException {
+        BufferedImage biSrc = getSrc();
+
+        ImageWriter writer = ImageIO.getImageWritersByFormatName("GIF").next();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+        writer.setOutput(ios);
+
+        ImageWriteParam writeParam = writer.getDefaultWriteParam();
+        IIOMetadata imageMetadata =
+            writer.getDefaultImageMetadata(new ImageTypeSpecifier(biSrc), writeParam);
+
+        IIOMetadata streamMetadata = writer.getDefaultStreamMetadata(writeParam);
+
+        IIOImage iioImg = new IIOImage(biSrc, null, imageMetadata);
+        writer.write(streamMetadata, iioImg, writeParam);
+        ios.close();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ImageInputStream iis = ImageIO.createImageInputStream(bais);
+        ImageReader reader = ImageIO.getImageReader(writer);
+        reader.setInput(iis);
+        BufferedImage dst = reader.read(0);
+
+        // do test
+        int x = dx / 2;
+        int y = height / 2;
+
+        for (int i = 0; i < usedColors.length; i++) {
+            int dstRgb = dst.getRGB(x, y);
+            System.out.println("dstColor: " + Integer.toHexString(dstRgb));
+            int srcRgb = usedColors[i].getRGB();
+            System.out.println("srcColor: " + Integer.toHexString(srcRgb));
+            if (dstRgb != srcRgb) {
+                throw new RuntimeException("wrong color " + i + ": " + Integer.toHexString(dstRgb));
+            }
+            x += dx;
+        }
+
+    }
+
+    public static void main(String[] args) throws IOException {
+        RGBImageTest t = new RGBImageTest();
+        t.doTest();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/StreamMetadataTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6319418
+ * @summary Test verifies that GIF stream metadata could be merged with tree
+ *          representation for all supported formats
+ */
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOInvalidTreeException;
+import javax.imageio.metadata.IIOMetadata;
+
+import org.w3c.dom.Node;
+
+public class StreamMetadataTest {
+    protected static final String format = "GIF";
+
+    ImageWriter writer = null;
+    IIOMetadata streamData = null;
+    ImageWriteParam wparam = null;
+    boolean doMerge = true;
+
+    public StreamMetadataTest() {
+        writer = ImageIO.getImageWritersByFormatName(format).next();
+        wparam = writer.getDefaultWriteParam();
+        streamData = writer.getDefaultStreamMetadata(wparam);
+    }
+
+    public void doTest() throws IIOInvalidTreeException {
+        if (streamData == null) {
+            throw new RuntimeException("No stream metadata available");
+        }
+
+        String[] formatNames = streamData.getMetadataFormatNames();
+        for(String fname : formatNames) {
+            System.out.println("Format name: " + fname);
+            Node root = streamData.getAsTree(fname);
+            if (streamData.isReadOnly()) {
+                throw new RuntimeException("Stream metadata is readonly!");
+            }
+            streamData.reset();
+            streamData.mergeTree(fname, root);
+        }
+    }
+
+    public static void main(String args[]) {
+        StreamMetadataTest test = new StreamMetadataTest();
+        try {
+            test.doTest();
+        } catch (Exception e) {
+            throw new RuntimeException("Test failed.", e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/TransparencyTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4339415
+ * @summary Tests that GIF writer plugin is able to write images with BITMASK
+ *          transparency
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+
+public class TransparencyTest {
+
+    protected static final String fname = "ttest.gif";
+    protected BufferedImage src;
+    protected BufferedImage dst;
+
+    public static void main(String[] args) {
+        System.out.println("Test indexed image...");
+        IndexColorModel icm = createIndexedBitmaskColorModel();
+        BufferedImage img = createIndexedImage(200, 200, icm);
+        TransparencyTest t = new TransparencyTest(img);
+
+        try {
+            t.doTest();
+        } catch (Exception e) {
+            throw new RuntimeException("Test failed!", e);
+        }
+        System.out.println("Test passed.");
+    }
+
+    protected TransparencyTest(BufferedImage src) {
+        this.src = src;
+    }
+
+    protected void doTest() throws IOException {
+        int w = src.getWidth();
+        int h = src.getHeight();
+
+        System.out.println("Write image...");
+        try {
+            ImageWriter writer =
+                ImageIO.getImageWritersByFormatName("GIF").next();
+            writer.setOutput(ImageIO.createImageOutputStream(new File(fname)));
+            writer.write(src);
+        } catch (Exception e) {
+            throw new RuntimeException("Test failed.", e);
+        }
+        System.out.println("Read image....");
+        dst = ImageIO.read(new File(fname));
+
+        BufferedImage tmp = new BufferedImage(w, 2 * h,
+                                              BufferedImage.TYPE_INT_ARGB);
+        Graphics2D g = tmp.createGraphics();
+        g.setColor(Color.pink);
+        g.fillRect(0, 0, tmp.getWidth(), tmp.getHeight());
+
+        g.drawImage(src, 0, 0, null);
+        g.drawImage(dst, 0, h, null);
+
+        int width = w / 8;
+        int x = 5 * width + width / 2;
+        for (int y = 0; y < h; y++) {
+            int argb = tmp.getRGB(x, y);
+            if (Color.pink.getRGB() != argb) {
+                throw new RuntimeException("Bad color at " + x + "," + y +
+                                           " - " + Integer.toHexString(argb));
+            }
+        }
+    }
+
+    protected static BufferedImage createIndexedImage(int w, int h,
+                                                      IndexColorModel icm)
+    {
+        BufferedImage img = new BufferedImage(w, h,
+                                              BufferedImage.TYPE_BYTE_INDEXED,
+                                              icm);
+
+        int mapSize = icm.getMapSize();
+        int width = w / mapSize;
+
+        WritableRaster wr = img.getRaster();
+        for (int i = 0; i < mapSize; i++) {
+            for (int y = 0; y < h; y++) {
+                for (int x = 0; x < width; x++) {
+                    wr.setSample(i * width + x, y, 0, i);
+                }
+            }
+        }
+        return img;
+    }
+
+    protected  static IndexColorModel createIndexedBitmaskColorModel() {
+        int paletteSize = 8;
+        byte[] red = new byte[paletteSize];
+        byte[] green = new byte[paletteSize];
+        byte[] blue = new byte[paletteSize];
+
+        red[0] = (byte)0xff; green[0] = (byte)0x00; blue[0] = (byte)0x00;
+        red[1] = (byte)0x00; green[1] = (byte)0xff; blue[1] = (byte)0x00;
+        red[2] = (byte)0x00; green[2] = (byte)0x00; blue[2] = (byte)0xff;
+        red[3] = (byte)0xff; green[3] = (byte)0xff; blue[3] = (byte)0xff;
+        red[4] = (byte)0x00; green[4] = (byte)0x00; blue[4] = (byte)0x00;
+        red[5] = (byte)0x80; green[5] = (byte)0x80; blue[5] = (byte)0x80;
+        red[6] = (byte)0xff; green[6] = (byte)0xff; blue[6] = (byte)0x00;
+        red[7] = (byte)0x00; green[7] = (byte)0xff; blue[7] = (byte)0xff;
+
+        int numBits = 3;
+
+        IndexColorModel icm = new IndexColorModel(numBits, paletteSize,
+                                                  red, green, blue, 5);
+
+        return icm;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/UshortOutOfMemoryTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6294363
+ * @summary Test verifies that creation of tree representation of the native
+ *          image metadata for USHORT_GRAY images does not cause the
+ *          OutOfMemoryError
+ * @run main/othervm -Xms32M -Xmx32M UshortOutOfMemoryTest
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+
+public class UshortOutOfMemoryTest {
+    private int type;
+    private ImageWriter w;
+
+    public UshortOutOfMemoryTest(int type) {
+        this.type = type;
+        w = ImageIO.getImageWritersByFormatName("GIF").next();
+    }
+
+    public void testGetAsTree() {
+        ImageWriteParam p = w.getDefaultWriteParam();
+        IIOMetadata m =
+            w.getDefaultImageMetadata(ImageTypeSpecifier.createFromBufferedImageType(type), p);
+
+        String format = m.getNativeMetadataFormatName();
+        System.out.println("native format: " + format);
+
+        int count = 0;
+        try {
+            while (count < 100) {
+                System.out.println(" test " + count++);
+                m.getAsTree(format);
+            }
+        } catch (OutOfMemoryError e) {
+            System.gc();
+            throw new RuntimeException("Test failed. Number of performed operations: " + count, e);
+        }
+    }
+
+
+    public static void main(String[] args) throws IOException {
+        UshortOutOfMemoryTest t = new UshortOutOfMemoryTest(
+                BufferedImage.TYPE_USHORT_GRAY);
+        t.testGetAsTree();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/WriteMetadataTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6287880
+ * @summary Test verifies that default metadata for stream and image returned by
+ *          GIFImageWriter can be modified by the tree representation
+ */
+
+import java.awt.image.BufferedImage;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOInvalidTreeException;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataNode;
+
+public class WriteMetadataTest {
+    private static String format = "GIF";
+
+    public static void main(String[] args) {
+        ImageWriter w = ImageIO.getImageWritersByFormatName(format).next();
+        if (w == null) {
+            throw new RuntimeException("No available writers for format " + format);
+        }
+        ImageWriteParam p = w.getDefaultWriteParam();
+
+        ImageTypeSpecifier t =
+                ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
+
+        IIOMetadata m = w.getDefaultImageMetadata(t, p);
+        System.out.println("Default image metadata is " + m);
+        testWritableMetadata(m);
+
+        IIOMetadata sm = w.getDefaultStreamMetadata(p);
+        System.out.println("Default stream metadata is " + sm);
+        testWritableMetadata(sm);
+    }
+
+    public static void testWritableMetadata(IIOMetadata m) {
+        String nativeFormatName =
+                m.getNativeMetadataFormatName();
+        System.out.println("Format: " + nativeFormatName);
+        IIOMetadataNode root = (IIOMetadataNode)m.getAsTree(nativeFormatName);
+        if (m.isReadOnly()) {
+            throw new RuntimeException("Metadata is read only!");
+        }
+        try {
+            m.setFromTree(nativeFormatName, root);
+        } catch (IIOInvalidTreeException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Test failed!", e);
+        } catch (IllegalStateException e) {
+            throw new RuntimeException("Test failed!", e);
+        }
+        System.out.println("Test passed.\n\n");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/WriterResetTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6275251
+ * @summary Verifies that GIF image writer throws IllegalStateException if
+ *          assigned output stream was cleared by reset() method
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
+
+public class WriterResetTest {
+    public static void main(String[] args) throws IOException {
+        ImageWriter w = ImageIO.getImageWritersByFormatName("GIF").next();
+        if (w == null) {
+            throw new RuntimeException("No writers available!");
+        }
+
+        ByteArrayOutputStream baos =
+            new ByteArrayOutputStream();
+
+        ImageOutputStream ios =
+            ImageIO.createImageOutputStream(baos);
+
+        w.setOutput(ios);
+
+        BufferedImage img = createTestImage();
+
+        try {
+            w.reset();
+            w.write(img);
+        } catch (IllegalStateException e) {
+            System.out.println("Test passed");
+        } catch (Throwable e) {
+            throw new RuntimeException("Test failed", e);
+        }
+    }
+
+    private static BufferedImage createTestImage() {
+        BufferedImage img = new BufferedImage(100, 100,
+                                              BufferedImage.TYPE_INT_RGB);
+        Graphics2D g = img.createGraphics();
+        g.setColor(Color.white);
+        g.fillRect(0, 0, 100, 100);
+        g.setColor(Color.black);
+        g.fillRect(20, 20, 60, 60);
+
+        return img;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/gif/WriterReuseTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6283089
+ * @summary Test verifies that abort flag is cleared by the next write() call
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.event.IIOWriteProgressListener;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageOutputStream;
+
+public class WriterReuseTest implements IIOWriteProgressListener {
+
+    boolean isFirst = true;
+    boolean isWritingCompleted = false;
+    boolean isWritingAborted = false;
+
+    public static void main(String[] args) throws IOException {
+        doTest(false);
+        doTest(true);
+    }
+
+    public static void doTest(boolean writeSequence) throws IOException {
+        String format = "GIF";
+        ImageWriter writer =
+                ImageIO.getImageWritersByFormatName(format).next();
+        if (writer == null) {
+            throw new RuntimeException("No writer available for " + format);
+        }
+
+        BufferedImage img = createTestImage();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+        writer.setOutput(ios);
+
+        WriterReuseTest t = new WriterReuseTest();
+        writer.addIIOWriteProgressListener(t);
+
+        ImageWriteParam param = writer.getDefaultWriteParam();
+        IIOMetadata streamMetadata = writer.getDefaultStreamMetadata(param);
+        IIOImage iioImg = new IIOImage(img, null, null);
+        if (writeSequence) {
+            writer.prepareWriteSequence(streamMetadata);
+            writer.writeToSequence(iioImg, param);
+        } else {
+            writer.write(img);
+        }
+
+        if (!t.isWritingAborted || t.isWritingCompleted) {
+            throw new RuntimeException("Test failed.");
+        }
+        t.reset();
+
+        // next attempt after abort
+        ImageOutputStream ios2 =
+             ImageIO.createImageOutputStream(new ByteArrayOutputStream());
+        writer.setOutput(ios2);
+        if (writeSequence) {
+            writer.writeToSequence(iioImg, param);
+        } else {
+            writer.write(img);
+        }
+
+        if (t.isWritingAborted || !t.isWritingCompleted) {
+            throw new RuntimeException("Test failed.");
+        }
+        System.out.println("Test passed.");
+    }
+
+    public static BufferedImage createTestImage() {
+        BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_BYTE_INDEXED);
+        Graphics g = img.createGraphics();
+        g.setColor(Color.black);
+        g.fillRect(0, 0, 100, 100);
+
+        g.setColor(Color.white);
+        g.fillRect(10, 10, 80, 80);
+
+        return img;
+    }
+
+    public WriterReuseTest() {
+        isFirst = true;
+        reset();
+    }
+
+    public void reset() {
+        isWritingAborted = false;
+        isWritingCompleted = false;
+    }
+
+    public void imageComplete(ImageWriter source) {
+        System.out.println("Image Completed");
+        this.isWritingCompleted = true;
+    }
+
+    public void imageProgress(ImageWriter source, float percentageDone) {
+        System.out.println("Image Progress "+percentageDone);
+        if (percentageDone > 50 && isFirst) {
+            isFirst = false;
+            source.abort();
+        }
+    }
+
+    public void imageStarted(ImageWriter source, int imageIndex) {
+        System.out.println("Image Started "+imageIndex);
+    }
+
+    public void thumbnailComplete(ImageWriter source)  {
+        System.out.println("Thubnail completed");
+    }
+
+    public void thumbnailProgress(ImageWriter source, float percentageDone) {
+        System.out.println("Thubnail Progress " + percentageDone);
+    }
+
+    public void thumbnailStarted(ImageWriter source, int imageIndex, int thumbnailIndex) {
+        System.out.println("Thubnail started " + imageIndex);
+    }
+
+    public void writeAborted(ImageWriter source) {
+        System.out.println("Writing Aborted");
+        this.isWritingAborted = true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/jpeg/ByteBinaryTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4450894
+ * @summary Tests if the JPEG writer properly encodes IndexColorModel images
+ *          that contain less than 8-bit indices (such as TYPE_BYTE_BINARY)
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+public class ByteBinaryTest {
+
+    private static final int[] expectedVals =
+        { 0xffffffff, 0xff000000, 0xffffffff };
+
+    public static void main(String[] args) {
+        BufferedImage bi = new BufferedImage(100, 100,
+                                             BufferedImage.TYPE_BYTE_BINARY);
+
+        Graphics g = bi.createGraphics();
+        g.setColor(Color.white);
+        g.fillRect(0, 0, 100, 100);
+        g.setColor(Color.black);
+        g.fillRect(20, 20, 40, 40);
+        g.setColor(Color.white);
+        g.fillRect(25, 25, 25, 25);
+        g.dispose();
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        boolean success;
+
+        try {
+            success = ImageIO.write(bi, "jpeg", baos);
+        } catch (IOException ioe) {
+            throw new RuntimeException("Could not write JPEG to stream");
+        }
+
+        if (!success) {
+            throw new RuntimeException("Could not find valid JPEG writer...");
+        }
+
+        byte[] bytearr = baos.toByteArray();
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytearr);
+        BufferedImage bi2 = null;
+
+        try {
+            bi2 = ImageIO.read(bais);
+        } catch (IOException ioe) {
+            throw new RuntimeException("Could not read JPEG stream");
+        }
+
+        int[] actualVals = new int[3];
+
+        actualVals[0] = bi2.getRGB(27, 5);
+        actualVals[1] = bi2.getRGB(27, 22);
+        actualVals[2] = bi2.getRGB(35, 35);
+
+        for (int i = 0; i < actualVals.length; i++) {
+            if (actualVals[i] != expectedVals[i]) {
+                throw new RuntimeException("Pixel mismatch at index: " + i);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/jpeg/CanEncodeIndexed.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4528585
+ * @summary Tests whether the JPEGImageWriterSpi advertises that it is capable
+ *          of writing images using an IndexColorModel. The test fails if an
+ *          exception is thrown.
+ */
+
+import java.awt.image.BufferedImage;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+
+public class CanEncodeIndexed {
+
+    public static void main(String[] args) {
+        BufferedImage img = new BufferedImage(32, 32,
+                                              BufferedImage.TYPE_BYTE_INDEXED);
+
+        ImageTypeSpecifier spec =
+            ImageTypeSpecifier.createFromRenderedImage(img);
+
+        Iterator writers = ImageIO.getImageWriters(spec, "jpeg");
+
+        if (!writers.hasNext()) {
+            throw new RuntimeException("Test failed: " +
+                                       "no JPEG writer found for " +
+                                       "image with IndexColorModel");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/jpeg/CompressionBug.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4415068 4622201
+ * @summary Tests if the JPEG writer responds to the compression quality setting
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Random;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
+
+public class CompressionBug {
+
+    public CompressionBug() throws IOException {
+        File fileHighComp = File.createTempFile("CompressionHigh", ".jpg");
+        File fileLowComp = File.createTempFile("CompressionLow", ".jpg");
+
+        fileHighComp.deleteOnExit();
+        fileLowComp.deleteOnExit();
+
+        ImageOutputStream iosHighComp =
+            ImageIO.createImageOutputStream(fileHighComp);
+        ImageOutputStream iosLowComp =
+            ImageIO.createImageOutputStream(fileLowComp);
+
+        int width = 100;
+        int height = 100;
+        BufferedImage bi =
+            new BufferedImage(width, height,
+                              BufferedImage.TYPE_INT_RGB);
+        Graphics g = bi.createGraphics();
+        Random r = new Random();
+        for (int i = 0; i < 100; i++) {
+            Color c = new Color(r.nextInt(256),
+                                r.nextInt(256),
+                                r.nextInt(256));
+            int x = r.nextInt(width);
+            int y = r.nextInt(height);
+            int w = r.nextInt(width - x);
+            int h = r.nextInt(height - y);
+            g.setColor(c);
+            g.fillRect(x, y, w, h);
+        }
+
+        ImageTypeSpecifier typeSpecifier =
+            new ImageTypeSpecifier(bi.getColorModel(),
+                                   bi.getSampleModel());
+
+        ImageWriter writer = null;
+        Iterator iter = ImageIO.getImageWriters(typeSpecifier,"jpeg");
+        while (iter.hasNext()) {
+            writer = (ImageWriter)iter.next();
+            break;
+        }
+
+        IIOImage iioImg = new IIOImage(bi, null, null);
+        ImageWriteParam wParam = writer.getDefaultWriteParam();
+        wParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+
+        // write the highly compressed image (a compression quality setting of
+        // 0.1f means low visual quality and small file size)
+        wParam.setCompressionQuality(0.1f);
+        writer.setOutput(iosHighComp);
+        writer.write(null, iioImg, wParam);
+
+        // write the somewhat compressed image (a compression quality setting
+        // of 0.9f means high visual quality and large file size)
+        wParam.setCompressionQuality(0.9f);
+        writer.setOutput(iosLowComp);
+        writer.write(null, iioImg, wParam);
+
+        long sizeOfFileLowComp = fileLowComp.length();
+        long sizeOfFileHighComp = fileHighComp.length();
+
+        // the highly compressed image file should have a smaller file size
+        // than the image file with low compression; throw an exception if
+        // this isn't the case
+        if (sizeOfFileLowComp < sizeOfFileHighComp) {
+            throw new RuntimeException("Lower compression quality did not " +
+                                       "reduce file size!");
+        }
+    }
+
+    public static void main(String args[]) throws IOException {
+        new CompressionBug();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/jpeg/CompressionVals.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4972087
+ * @summary Verifies that JPEGImageWriteParam.getCompressionQualityValues()
+ *          returns an array that is one longer than the one returned by
+ *          getCompressionQualityDescriptions()
+ */
+
+import javax.imageio.ImageWriteParam;
+import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
+
+public class CompressionVals {
+
+    public static void main(String[] args) {
+        ImageWriteParam iwp = new JPEGImageWriteParam(null);
+        iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+        float[] vals = iwp.getCompressionQualityValues();
+        String[] descs = iwp.getCompressionQualityDescriptions();
+        if (vals.length != (descs.length + 1)) {
+            throw new RuntimeException("Test failed: Values array is not " +
+                                       "one larger than descriptions array");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/jpeg/CrashAfterDispose.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4660047
+ * @summary Tests if the JPEG reader/writer crashes the VM if certain methods
+ *          are called after a call to dispose()
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+
+public class CrashAfterDispose {
+
+    public static void main(String[] args) throws IOException {
+        InputStream bais = new ByteArrayInputStream(new byte[100]);
+        ImageInputStream iis = ImageIO.createImageInputStream(bais);
+
+        // find the JPEG reader
+        ImageReader reader = null;
+        Iterator readers = ImageIO.getImageReadersByFormatName("jpeg");
+        if (readers.hasNext()) {
+            reader = (ImageReader)readers.next();
+        } else {
+            throw new RuntimeException("Unable to find a reader!");
+        }
+
+        // dispose the reader, then poke and prod it... the reader should
+        // throw exceptions (which will be caught by this test), but it
+        // should not crash the VM
+        reader.dispose();
+
+        try {
+            reader.setInput(iis);
+        } catch (IllegalStateException e) {
+        }
+
+        try {
+            reader.read(0);
+        } catch (IllegalStateException e) {
+        }
+
+        try {
+            reader.abort();
+        } catch (IllegalStateException e) {
+        }
+
+        try {
+            reader.reset();
+        } catch (IllegalStateException e) {
+        }
+
+        try {
+            reader.dispose();
+        } catch (IllegalStateException e) {
+        }
+
+        // find the JPEG writer
+        ImageWriter writer = null;
+        Iterator writers = ImageIO.getImageWritersByFormatName("jpeg");
+        if (writers.hasNext()) {
+            writer = (ImageWriter)writers.next();
+        } else {
+            throw new RuntimeException("Unable to find a writer!");
+        }
+
+        // set up output stream
+        OutputStream baos = new ByteArrayOutputStream();
+        ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
+        BufferedImage bi = new BufferedImage(10, 10,
+                                             BufferedImage.TYPE_INT_RGB);
+
+        // dispose the writer, then poke and prod it... the writer should
+        // throw exceptions (which will be caught by this test), but it
+        // should not crash the VM
+        writer.dispose();
+
+        try {
+            writer.setOutput(ios);
+        } catch (IllegalStateException e) {
+        }
+
+        try {
+            writer.write(bi);
+        } catch (IllegalStateException e) {
+        }
+
+        try {
+            writer.abort();
+        } catch (IllegalStateException e) {
+        }
+
+        try {
+            writer.reset();
+        } catch (IllegalStateException e) {
+        }
+
+        try {
+            writer.dispose();
+        } catch (IllegalStateException e) {
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/jpeg/DestTypeTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 5028259
+ * @summary Verifies that usage of the destination type does not cause the
+ *          increase of size of the result jpeg file
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.event.IIOReadWarningListener;
+import javax.imageio.event.IIOWriteWarningListener;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageOutputStream;
+
+public class DestTypeTest implements IIOWriteWarningListener, IIOReadWarningListener {
+
+    ImageWriter w;
+    ImageReader r;
+
+    public static void main(String[] args) throws IOException {
+        BufferedImage bi_rgb = createTestImage(BufferedImage.TYPE_INT_RGB);
+
+        DestTypeTest bug = new DestTypeTest();
+        byte[] rgb_data = bug.writeTest(bi_rgb);
+
+        System.out.println("rgb jpeg data length is " + rgb_data.length);
+
+        BufferedImage bi_argb = createTestImage(BufferedImage.TYPE_INT_ARGB);
+
+        ImageWriteParam p = bug.getWriteParam();
+        IIOMetadata m = bug.getMetadata(p);
+
+        byte[] submeta_data = bug.writeTest(bi_argb, p, m);
+        System.out.println("desttype and metadata jpeg data length is " + submeta_data.length);
+
+        p = bug.getWriteParam();
+        byte[] subbanded_data = bug.writeTest(bi_argb, p);
+        System.out.println("desttype jpeg data length is " + subbanded_data.length);
+
+        if (submeta_data.length > rgb_data.length) {
+            throw new  RuntimeException("Too big result jpeg: " + submeta_data.length +
+                                        "(rgb image size is " + rgb_data.length + ")");
+        }
+        if (subbanded_data.length > rgb_data.length) {
+            throw new  RuntimeException("Too big result jpeg: " + subbanded_data.length +
+                                        "(rgb image size is " + rgb_data.length + ")");
+        }
+    }
+
+    public DestTypeTest() {
+        w = (ImageWriter)
+            ImageIO.getImageWritersByFormatName("jpeg").next();
+        w.addIIOWriteWarningListener(this);
+
+        r = (ImageReader)
+            ImageIO.getImageReadersByFormatName("jpeg").next();
+        r.addIIOReadWarningListener(this);
+    }
+
+    public ImageWriteParam getWriteParam() {
+        ImageWriteParam p =  w.getDefaultWriteParam();
+        p.setSourceBands(new int[] {0, 1, 2});
+        ImageTypeSpecifier type =
+            ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
+        p.setDestinationType(type);
+
+        return p;
+    }
+
+    public IIOMetadata getMetadata(ImageWriteParam p) {
+        return w.getDefaultImageMetadata(p.getDestinationType(), null);
+    }
+
+    public byte[] writeTest(BufferedImage bi) throws IOException {
+        return writeTest(bi, null);
+    }
+
+    public byte[] writeTest(BufferedImage bi,
+                          ImageWriteParam p) throws IOException {
+        return writeTest(bi, p, null);
+    }
+    public byte[] writeTest(BufferedImage bi,
+                            ImageWriteParam p,
+                            IIOMetadata m) throws IOException {
+        ByteArrayOutputStream baos =
+            new ByteArrayOutputStream();
+
+        // write test image as jpeg
+        ImageOutputStream ios =
+            ImageIO.createImageOutputStream(baos);
+        w.setOutput(ios);
+        w.write(null,
+                new IIOImage(bi, null, m),
+                p);
+        ios.close();
+        return baos.toByteArray();
+    }
+
+    public static BufferedImage createTestImage(int type) {
+        int w = 100;
+        int h = 500;
+        BufferedImage bi = new BufferedImage(3*w, h, type);
+        Graphics g = bi.createGraphics();
+        g.setColor(Color.red);
+        g.fillRect(0,0,w,h);
+        g.setColor(Color.green);
+        g.fillRect(w, 0,w,h);
+        g.setColor(Color.blue);
+        g.fillRect(2*w,0,w,h);
+
+        return bi;
+    }
+
+    public void warningOccurred(ImageWriter source,
+                                int imageIndex,
+                                String warning) {
+        System.out.println("WRITING WARNING: " + warning);
+    }
+
+    public void warningOccurred(ImageReader source,
+                                String warning) {
+        System.out.println("READING WARNING: " + warning);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/jpeg/JPEGsNotAcceleratedTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4994702
+ * @key headful
+ * @summary verifies that no regression were introduced with the fix for this
+ *          bug
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.ImageCapabilities;
+import java.awt.Rectangle;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.FileImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+
+public class JPEGsNotAcceleratedTest {
+
+    public static final int testRGB = Color.red.getRGB();
+    public static final int TEST_W = 100;
+    public static final int TEST_H = 100;
+    public static final Rectangle roi =
+        new Rectangle(TEST_W/4, TEST_H/4, TEST_W/2, TEST_H/2);
+
+    static Frame f;
+    static boolean showRes = false;
+    static int testsFinished = 0;
+    static int testsStarted = 0;
+    static boolean lowCompression = false;
+
+    static boolean failed = false;
+
+    public JPEGsNotAcceleratedTest(String name) {
+        BufferedImage bi = readTestImage(name, null, null);
+        runTestOnImage("no dest image, no region of interest", bi, null);
+
+        BufferedImage destBI = getDestImage();
+        bi = readTestImage(name, destBI, null);
+        runTestOnImage("w/ dest image, no region of interest", bi, null);
+
+        // steal the raster, see if the destination image
+        // gets accelerated
+        destBI = getDestImage();
+        DataBuffer db =
+            ((WritableRaster)destBI.getRaster()).getDataBuffer();
+        bi = readTestImage(name, destBI, null);
+        runTestOnImage("w/ dest image (with stolen raster),"+
+                       " no region of interest", bi, null);
+
+        bi = readTestImage(name, null, roi);
+        runTestOnImage("no dest image, region of interest", bi, roi);
+
+        destBI = getDestImage();
+        bi = readTestImage(name, destBI, roi);
+        runTestOnImage("w/ dest image, region of interest", bi, roi);
+
+        // accelerate the destination image first, then load
+        // an image into it. Check that the accelerated copy gets
+        // updated
+        destBI = getDestImage();
+        accelerateImage(destBI);
+        bi = readTestImage(name, destBI, roi);
+        runTestOnImage("w/ accelerated dest image,"+
+                       " region of interest", bi, roi);
+
+        synchronized (JPEGsNotAcceleratedTest.class) {
+            testsFinished++;
+            JPEGsNotAcceleratedTest.class.notify();
+        }
+
+    }
+
+    public static BufferedImage readTestImage(String fileName,
+                                   BufferedImage dest,
+                                   Rectangle srcROI)
+    {
+        BufferedImage bi = null;
+
+        try {
+            FileImageInputStream is =
+                new FileImageInputStream(new File(fileName));
+            ImageReader reader =
+                (ImageReader)ImageIO.getImageReaders(is).next();
+            ImageReadParam param = reader.getDefaultReadParam();
+            if (dest != null) {
+                param.setDestination(dest);
+            }
+            if (srcROI != null) {
+                param.setSourceRegion(srcROI);
+            }
+            reader.setInput(is);
+            bi = reader.read(0, param);
+        } catch (IOException e) {
+            System.err.println("Error " + e +
+                               " when reading file: " + fileName);
+            throw new RuntimeException(e);
+        }
+
+        return bi;
+    }
+
+    public static void writeTestImage(String fileName) {
+        BufferedImage bi =
+            new BufferedImage(TEST_W, TEST_H, BufferedImage.TYPE_INT_RGB);
+        Graphics g = bi.getGraphics();
+        g.setColor(new Color(testRGB));
+        g.fillRect(0, 0, TEST_W, TEST_H);
+        try {
+            System.err.printf("Writing %s\n", fileName);
+            if (lowCompression) {
+                ImageWriter iw = (ImageWriter)ImageIO.getImageWritersBySuffix("jpeg").next();
+                if(iw == null) {
+                    throw new RuntimeException("No available image writer for "
+                                               + "jpeg "
+                                               + " Test failed.");
+                }
+
+                File file = new File(fileName);
+                ImageOutputStream ios = ImageIO.createImageOutputStream(file);
+                iw.setOutput(ios);
+
+                ImageWriteParam param = iw.getDefaultWriteParam();
+                param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+                param.setCompressionQuality(1);
+
+                IIOImage iioImg = new IIOImage(bi, null, null);
+                iw.write(null, iioImg, param);
+
+            } else {
+                ImageIO.write(bi, "jpeg", new File(fileName));
+            }
+        } catch (IOException e) {
+            System.err.println("Error " + e +
+                               " when writing file: " + fileName);
+            throw new RuntimeException(e);
+        }
+    }
+
+    public VolatileImage accelerateImage(BufferedImage bi) {
+        VolatileImage testVI = f.createVolatileImage(TEST_W, TEST_H);
+        do {
+            if (testVI.validate(f.getGraphicsConfiguration()) ==
+                VolatileImage.IMAGE_INCOMPATIBLE)
+            {
+                testVI = f.createVolatileImage(TEST_W, TEST_H);
+            }
+            Graphics2D g = testVI.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.setColor(Color.green);
+            g.fillRect(0, 0, TEST_W, TEST_H);
+
+            g.drawImage(bi, 0, 0, null);
+            g.drawImage(bi, 0, 0, null);
+            g.drawImage(bi, 0, 0, null);
+            g.dispose();
+        } while (testVI.contentsLost());
+
+        return testVI;
+    }
+
+    public BufferedImage getDestImage() {
+        BufferedImage destBI =
+            new BufferedImage(TEST_W, TEST_H, BufferedImage.TYPE_INT_RGB);
+        Graphics2D g = (Graphics2D)destBI.getGraphics();
+        g.setComposite(AlphaComposite.Src);
+        g.setColor(Color.blue);
+        g.fillRect(0, 0, TEST_W, TEST_H);
+        return destBI;
+    }
+
+    public void runTestOnImage(String desc, BufferedImage bi,
+                               Rectangle srcROI)
+    {
+
+        if (srcROI == null) {
+            srcROI = new Rectangle(0, 0, TEST_W, TEST_H);
+        }
+
+        VolatileImage testVI = accelerateImage(bi);
+
+        ImageCapabilities ic =
+            bi.getCapabilities(f.getGraphicsConfiguration());
+        boolean accelerated = ic.isAccelerated();
+
+        System.err.println("Testing: " + desc +
+                           " -- bi.isAccelerated(): " + accelerated );
+
+        BufferedImage snapshot = testVI.getSnapshot();
+        if (showRes) {
+            showRes(desc, snapshot);
+        }
+
+        for (int y = 0; y < srcROI.height; y++) {
+            for (int x = 0; x < srcROI.width; x++) {
+                int destRGB = snapshot.getRGB(x, y);
+                if (destRGB != testRGB && destRGB != 0xfffe0000) {
+                    failed = true;
+                    System.err.printf("Test failed at %dx%d pixel=%x\n",
+                                      x, y, snapshot.getRGB(x, y));
+                    if (!showRes) {
+                        showRes(desc, snapshot);
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
+    static int startX = 64, startY = 0;
+    static int frameX = startX, frameY = startY;
+    private static void showRes(String desc, final BufferedImage src) {
+        final int w = src.getWidth();
+        final int h = src.getHeight();
+
+        Frame f = new Frame(desc+": dbl-click to exit");
+        Component c;
+        f.add(c = new Component() {
+            public Dimension getPreferredSize() {
+                return new Dimension(w,h);
+            }
+
+            public void paint(Graphics g) {
+                g.clearRect(0, 0, getWidth(), getHeight());
+                g.drawImage(src, 0,0, null);
+            }
+        });
+        c.addMouseListener(new MouseAdapter() {
+            public void mouseClicked(MouseEvent e) {
+                if (e.getClickCount() > 1) {
+                    System.exit(0);
+                }
+            }
+        });
+        f.pack();
+        synchronized (JPEGsNotAcceleratedTest.class) {
+            f.setLocation(frameX, frameY);
+            frameX += f.getWidth();
+            if ((frameX + f.getWidth()) >
+                f.getGraphicsConfiguration().getBounds().width)
+            {
+                frameY += TEST_H;
+                if ((frameY + f.getHeight()) >
+                    f.getGraphicsConfiguration().getBounds().height)
+                {
+                    startY += 30;
+                    startX += 30;
+                    frameY = startY;
+                }
+                frameX = startX;
+            }
+        };
+        f.setVisible(true);
+    }
+
+    public static void usage() {
+        System.err.println("Usage: java Test [file name] [-write][-show][-low]");
+        System.exit(0);
+    }
+
+    public static void main(String[] args) {
+        System.setProperty("sun.java2d.pmoffscreen", "true");
+        System.setProperty("sun.java2d.ddforcevram", "true");
+        String name = "red.jpg";
+
+        f = new Frame();
+        f.pack();
+
+        if (f.getGraphicsConfiguration().getColorModel().getPixelSize() < 16) {
+            System.err.println("8-bit display mode detected, dithering issues possible, "+
+                               "considering test passed.");
+            f.dispose();
+            return;
+        }
+
+
+        for (String arg : args) {
+            if (arg.equals("-write")) {
+                writeTestImage(name);
+                System.exit(0);
+            } else if (arg.equals("-show")) {
+                showRes = true;
+            } else if (arg.equals("-low")) {
+                lowCompression = true;
+                name ="red_low.jpg";
+                System.err.println("Using low jpeg compression");
+            } else if (arg.equals("-help")) {
+                usage();
+            } else {
+                final String filename = arg;
+                testsStarted++;
+                new Thread(new Runnable() {
+                    public void run() {
+                        new JPEGsNotAcceleratedTest(filename);
+                    }
+                }).start();
+            }
+        }
+
+        if (testsStarted == 0) {
+            writeTestImage(name);
+            testsStarted++;
+            new JPEGsNotAcceleratedTest(name);
+        }
+
+
+        synchronized (JPEGsNotAcceleratedTest.class) {
+            while (testsFinished < testsStarted) {
+                try {
+                    JPEGsNotAcceleratedTest.class.wait(100);
+                } catch (InterruptedException e) {
+                    failed = true; break;
+                }
+            }
+        }
+
+        f.dispose();
+        if (failed) {
+            throw new RuntimeException("Test failed");
+        }
+
+        System.err.println("Passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/jpeg/MergeTreeTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4895547
+ * @summary Test verifies that mergeTree() of JPEGMetadata does not throw the
+ *          NPE
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageOutputStream;
+
+import org.w3c.dom.Node;
+
+public class MergeTreeTest {
+    public static void main(String[] args) throws IOException {
+        ImageWriter iw =
+            (ImageWriter)ImageIO.getImageWritersByFormatName("jpeg").next();
+
+        ImageTypeSpecifier type =
+            ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
+
+        ImageOutputStream ios =
+            ImageIO.createImageOutputStream(new File("MergeTreeTest.jpeg"));
+        iw.setOutput(ios);
+
+        IIOMetadata meta = iw.getDefaultImageMetadata(type, null);
+
+        boolean isFailed = false;
+
+        String[] fmts = meta.getMetadataFormatNames();
+        for (int i=0; i<fmts.length; i++) {
+            System.out.print("Format: " + fmts[i] + " ... ");
+            Node root = meta.getAsTree(fmts[i]);
+            try {
+                meta.mergeTree(fmts[i], root);
+            } catch (NullPointerException e) {
+                throw new RuntimeException("Test failed for format " + fmts[i], e);
+            }
+            System.out.println("PASSED");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/jpeg/RasterWithMinXTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4843895
+ * @summary Tests that we handle raster with non-zero minX and minY correctly
+ */
+
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.awt.image.RasterFormatException;
+import java.awt.image.WritableRaster;
+import java.io.ByteArrayOutputStream;
+import java.util.Arrays;
+import java.util.Iterator;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.stream.MemoryCacheImageOutputStream;
+
+public class RasterWithMinXTest {
+
+    public static void main(String[] args) {
+        String format = "jpeg";
+
+        // Set output file.
+        ImageOutputStream output = new MemoryCacheImageOutputStream(new ByteArrayOutputStream());
+
+        // Create image.
+        BufferedImage bi = new BufferedImage(256, 256,
+                                             BufferedImage.TYPE_3BYTE_BGR);
+
+        // Populate image.
+        int[] rgbArray = new int[256];
+        for(int i = 0; i < 256; i++) {
+            Arrays.fill(rgbArray, i);
+            bi.setRGB(0, i, 256, 1, rgbArray, 0, 256);
+        }
+
+        // create translated raster in order to get non-zero minX and minY
+        WritableRaster r = (WritableRaster)bi.getRaster().createTranslatedChild(64,64);
+
+        Iterator i =  ImageIO.getImageWritersByFormatName(format);
+        ImageWriter iw = null;
+        while(i.hasNext() && iw == null) {
+            Object o = i.next();
+            if (o instanceof com.sun.imageio.plugins.jpeg.JPEGImageWriter) {
+                iw = (ImageWriter)o;
+            }
+        }
+        if (iw == null) {
+            throw new RuntimeException("No available image writer");
+        }
+
+         ImageWriteParam iwp = iw.getDefaultWriteParam();
+         IIOMetadata metadata = iw.getDefaultImageMetadata(new ImageTypeSpecifier(bi.getColorModel(), r.getSampleModel()), iwp);
+
+         IIOImage img = new IIOImage(r, null, metadata);
+
+         iw.setOutput(output);
+         try {
+             iw.write(img);
+         } catch (RasterFormatException e) {
+             e.printStackTrace();
+             throw new RuntimeException("RasterException occurs. Test Failed!");
+         } catch (Exception ex) {
+             ex.printStackTrace();
+             throw new RuntimeException("Unexpected Exception");
+         }
+
+         // test case of theImageWriteParam with non-null sourceRegion
+         iwp.setSourceRegion(new Rectangle(32,32,192,192));
+         metadata = iw.getDefaultImageMetadata(new ImageTypeSpecifier(bi.getColorModel(), r.getSampleModel()), iwp);
+         try {
+             iw.write(metadata, img, iwp);
+         } catch (RasterFormatException e) {
+             e.printStackTrace();
+             throw new RuntimeException("SetSourceRegion causes the RasterException. Test Failed!");
+         } catch (Exception ex) {
+             ex.printStackTrace();
+             throw new RuntimeException("Unexpected Exception");
+         }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/jpeg/ResetOutOfMemory.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4411955
+ * @summary Checks that the JPEG writer does not throw an OutOfMemoryError from
+ *          its reset() method
+ */
+
+import javax.imageio.ImageWriter;
+
+import com.sun.imageio.plugins.jpeg.JPEGImageWriter;
+
+public class ResetOutOfMemory {
+
+    public static void main(String args[]) {
+        ImageWriter writer = new JPEGImageWriter(null);
+        try {
+            writer.reset();
+        } catch (OutOfMemoryError e) {
+            throw new RuntimeException("Got OutOfMemoryError!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/jpeg/UshortGrayTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4450894
+ * @summary Tests if the JPEGImageWriter allows images with > 8-bit samples to
+ *          be written. Also tests the JPEGImageWriterSpi.canEncodeImage()
+ *          mechanism for this same behavior.
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
+
+public class UshortGrayTest {
+
+    public static void main(String[] args) {
+        Iterator iter;
+        BufferedImage bi = new BufferedImage(10, 10,
+                                             BufferedImage.TYPE_USHORT_GRAY);
+
+        // Part 1: ensure that JPEGImageWriter throws an exception if it
+        // encounters an image with 16-bit samples
+        ImageWriter writer = null;
+        iter = ImageIO.getImageWritersByFormatName("jpeg");
+        if (iter.hasNext()) {
+            writer = (ImageWriter)iter.next();
+        } else {
+            throw new RuntimeException("No JPEG reader found");
+        }
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageOutputStream ios = null;
+        boolean exceptionThrown = false;
+
+        try {
+            ios = ImageIO.createImageOutputStream(baos);
+        } catch (IOException ioe) {
+            throw new RuntimeException("Could not create ImageOutputStream");
+        }
+
+        try {
+            writer.setOutput(ios);
+            writer.write(bi);
+        } catch (IOException ioe) {
+            exceptionThrown = true;
+        }
+
+        if (!exceptionThrown) {
+            throw new RuntimeException("JPEG writer should not be able to " +
+                                       "write USHORT_GRAY images");
+        }
+
+        // Part 2: ensure that JPEGImageWriterSpi.canEncodeImage() returns
+        // false for images with 16-bit samples
+        ImageTypeSpecifier its =
+            ImageTypeSpecifier.createFromRenderedImage(bi);
+
+        iter = ImageIO.getImageWriters(its, "jpeg");
+        if (iter.hasNext()) {
+            throw new RuntimeException("JPEG writer should not be available" +
+                                       " for USHORT_GRAY images");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/png/CanEncodeShort.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4474819
+ * @summary Tests whether the PNGImageWriterSpi advertises that it is capable of
+ *          writing images of TYPE_USHORT_565_RGB and TYPE_USHORT_555_RGB. The
+ *          test fails if an exception is thrown.
+ */
+
+import java.awt.image.BufferedImage;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+
+public class CanEncodeShort {
+
+    private static final int[] types = new int[] {
+        BufferedImage.TYPE_USHORT_565_RGB,
+        BufferedImage.TYPE_USHORT_555_RGB,
+    };
+
+    private static final String[] typeNames = new String[] {
+        "TYPE_USHORT_565_RGB",
+        "TYPE_USHORT_555_RGB",
+    };
+
+    public static void main(String[] args) {
+        for (int i = 0; i < types.length; i++) {
+            BufferedImage img = new BufferedImage(32, 32, types[i]);
+
+            ImageTypeSpecifier spec =
+                ImageTypeSpecifier.createFromRenderedImage(img);
+
+            Iterator writers = ImageIO.getImageWriters(spec, "png");
+
+            if (!writers.hasNext()) {
+                throw new RuntimeException("Test failed: " +
+                                           "no PNG writer found for type " +
+                                           typeNames[i]);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/png/ImageCompare.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+
+// Utility to compare two BufferedImages for RGB equality
+public class ImageCompare {
+
+    public static void compare(BufferedImage oldimg,
+                               BufferedImage newimg) {
+        int width = oldimg.getWidth();
+        int height = oldimg.getHeight();
+        if (newimg.getWidth() != width || newimg.getHeight() != height) {
+            throw new RuntimeException("Dimensions changed!");
+        }
+
+        Raster oldras = oldimg.getRaster();
+        ColorModel oldcm = oldimg.getColorModel();
+        Raster newras = newimg.getRaster();
+        ColorModel newcm = newimg.getColorModel();
+
+        for (int j = 0; j < height; j++) {
+            for (int i = 0; i < width; i++) {
+                Object oldpixel = oldras.getDataElements(i, j, null);
+                int oldrgb = oldcm.getRGB(oldpixel);
+                int oldalpha = oldcm.getAlpha(oldpixel);
+
+                Object newpixel = newras.getDataElements(i, j, null);
+                int newrgb = newcm.getRGB(newpixel);
+                int newalpha = newcm.getAlpha(newpixel);
+
+                if (newrgb != oldrgb ||
+                    newalpha != oldalpha) {
+                    throw new RuntimeException("Pixels differ at " + i +
+                                               ", " + j);
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/png/PngPremultAlphaTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4888478
+ * @summary Test that colors do not distort when buffered image with
+ *          premultiplied alpha is encoded to png format
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import javax.imageio.ImageIO;
+
+public class PngPremultAlphaTest {
+    protected static int width = 100;
+    protected static int height = 100;
+
+    protected static String format = "png";
+
+    protected static int[] iBufferedImageTypes = {
+        BufferedImage.TYPE_INT_RGB,
+        BufferedImage.TYPE_INT_ARGB,
+        BufferedImage.TYPE_4BYTE_ABGR_PRE,
+        BufferedImage.TYPE_INT_ARGB_PRE
+    };
+
+    protected static String[] strBufferedImageTypes = {
+        "TYPE_INT_RGB",
+        "TYPE_INT_ARGB",
+        "BufferedImage.TYPE_4BYTE_ABGR_PRE",
+        "BufferedImage.TYPE_INT_ARGB_PRE"
+    };
+
+    public static void main(String[] arg) {
+        for(int i=0; i<iBufferedImageTypes.length; i++) {
+            System.out.println("Test for " + strBufferedImageTypes[i]);
+            doTest(iBufferedImageTypes[i]);
+        }
+    }
+
+    public static void doTest(int type) {
+        try {
+            BufferedImage src = new BufferedImage(100, 100,
+                                                  type);
+            Graphics2D g = src.createGraphics();
+            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.5f));
+            g.setColor(new Color(0x20, 0x40, 0x60));
+            g.fillRect(0,0,100,100);
+
+            int[] samples = new int[src.getData().getNumBands()];
+            src.getData().getPixels(0,0,1,1,samples);
+            for(int i=0; i<samples.length; i++) {
+                System.out.println("sample["+i+"]="+Integer.toHexString(samples[i]));
+            }
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ImageIO.write(src, format, baos);
+            baos.close();
+
+
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            BufferedImage dst = ImageIO.read(bais);
+
+            isSameColors(src, dst);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Test failed.");
+        }
+    }
+
+    private static boolean isSameColors(BufferedImage src, BufferedImage dst) {
+        Object dstPixel = dst.getRaster().getDataElements(width/2, height/2, null);
+        Object srcPixel = src.getRaster().getDataElements(width/2, height/2, null);
+
+        // take into account the rounding error
+        if ( Math.abs(src.getColorModel().getRed(srcPixel) -  dst.getColorModel().getRed(dstPixel)) > 1
+             || Math.abs(src.getColorModel().getGreen(srcPixel) - dst.getColorModel().getGreen(dstPixel)) > 1
+             || Math.abs(src.getColorModel().getBlue(srcPixel) - dst.getColorModel().getBlue(dstPixel)) > 1) {
+            showPixel(src, width/2, height/2);
+            showPixel(dst, width/2, height/2);
+
+            throw new RuntimeException( "Colors are different: "
+                                        + Integer.toHexString(src.getColorModel().getRGB(srcPixel))
+                                        + " and "
+                                        + Integer.toHexString(dst.getColorModel().getRGB(dstPixel)));
+        }
+        return true;
+    }
+
+    private static void showPixel(BufferedImage src, int x, int y) {
+        System.out.println("Img is " + src);
+        System.out.println("CM is " + src.getColorModel().getClass().getName());
+        Object p = src.getRaster().getDataElements(x, y, null);
+        System.out.println("RGB:   " +
+                           Integer.toHexString(src.getColorModel().getRGB(p)));
+        System.out.println("Red:   " +
+                           Integer.toHexString(src.getColorModel().getRed(p)));
+        System.out.println("Green: " +
+                           Integer.toHexString(src.getColorModel().getGreen(p)));
+        System.out.println("Blue:  " +
+                           Integer.toHexString(src.getColorModel().getBlue(p)));
+        System.out.println("Alpha: " +
+                           Integer.toHexString(src.getColorModel().getAlpha(p)));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/png/ShortPaletteTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4826548
+ * @summary Tests for reading PNG images with 5,6,7 and 8 colors in palette
+ */
+
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+public class ShortPaletteTest {
+
+    public static void main(String[] args) {
+
+        for (int numberColors = 2; numberColors <= 16; numberColors++) {
+            try {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                BufferedImage image = createImage(numberColors);
+                ImageIO.write(image, "png", baos);
+                baos.close();
+                System.out.println("Number of colors: " + numberColors);
+                byte[] buffer = baos.toByteArray();
+                ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
+                ImageIO.read(bais);
+                System.out.println("OK");
+            } catch (ArrayIndexOutOfBoundsException e) {
+                e.printStackTrace();
+                throw new RuntimeException("Test failed.");
+            } catch (IOException e) {
+                e.printStackTrace();
+                throw new RuntimeException("Unexpected exception was thrown."
+                                           + " Test failed.");
+            }
+        }
+    }
+
+    private static IndexColorModel createColorModel(int numberColors) {
+
+        byte[] colors = new byte[numberColors*3];
+        int depth = 4;
+        int startIndex = 0;
+
+        return new IndexColorModel(depth,
+                                   numberColors,
+                                   colors,
+                                   startIndex,
+                                   false);
+    }
+
+    private static BufferedImage createImage(int numberColors) {
+        return new BufferedImage(32,
+                                 32,
+                                 BufferedImage.TYPE_BYTE_BINARY,
+                                 createColorModel(numberColors));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/png/WriteProgressive.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4432615
+ * @summary Tests progressive writing in the PNG encoder
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Random;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
+
+public class WriteProgressive {
+
+    public static void main(String[] args) throws IOException {
+        Iterator witer = ImageIO.getImageWritersByFormatName("png");
+        ImageWriter w = (ImageWriter)witer.next();
+
+        File f = File.createTempFile("WriteProgressive", ".png");
+        ImageOutputStream ios = ImageIO.createImageOutputStream(f);
+        w.setOutput(ios);
+
+        BufferedImage bi = new BufferedImage(100, 100,
+                                             BufferedImage.TYPE_3BYTE_BGR);
+        Graphics2D g = bi.createGraphics();
+        Random r = new Random(10);
+        for (int i = 0; i < 10000; i++) {
+            Color c =
+                new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
+            g.setColor(c);
+            g.fillRect(r.nextInt(100), r.nextInt(100), 1, 1);
+        }
+
+        IIOImage iioimage = new IIOImage(bi, null, null);
+
+        ImageWriteParam param = w.getDefaultWriteParam();
+        param.setProgressiveMode(ImageWriteParam.MODE_DEFAULT);
+
+        try {
+            w.write(null, iioimage, param);
+        } catch (NullPointerException npe) {
+            throw new RuntimeException("Got NPE during write!");
+        }
+
+        ios.close();
+
+        BufferedImage bi2 = ImageIO.read(f);
+        f.delete();
+
+        ImageCompare.compare(bi, bi2);
+    }
+}
--- a/test/javax/imageio/plugins/shared/CanWriteSequence.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/javax/imageio/plugins/shared/CanWriteSequence.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -23,6 +23,7 @@
 
 import java.io.File;
 import java.io.FileOutputStream;
+import java.nio.file.Files;
 import java.util.Iterator;
 
 import javax.imageio.ImageIO;
@@ -34,11 +35,19 @@
 
 /**
  * @test
- * @bug 4958064
- * @author Sergey Bylokhov
+ * @bug     4958064 8183349
+ * @summary Test verifies that when we try to forcefully run
+ *          prepareWriteSequence() where it is not supported
+ *          will ImageIO throws an UnsupportedOperationException
+ *          or not.
+ * @run     main CanWriteSequence
  */
 public final class CanWriteSequence {
 
+    private static File file;
+    private static FileOutputStream fos;
+    private static ImageOutputStream ios;
+
     public static void main(final String[] args) throws Exception {
         final IIORegistry registry = IIORegistry.getDefaultInstance();
         final Iterator<ImageWriterSpi> iter =
@@ -54,25 +63,35 @@
     }
 
     private static void test(final ImageWriter writer) throws Exception {
-        final File file = File.createTempFile("temp", ".img");
-        file.deleteOnExit();
-        final FileOutputStream fos = new FileOutputStream(file);
-        final ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
-        writer.setOutput(ios);
-        final IIOMetadata data = writer.getDefaultStreamMetadata(null);
+        try {
+            file = File.createTempFile("temp", ".img");
+            fos = new FileOutputStream(file);
+            ios = ImageIO.createImageOutputStream(fos);
+            writer.setOutput(ios);
+            final IIOMetadata data = writer.getDefaultStreamMetadata(null);
 
-        if (writer.canWriteSequence()) {
-            writer.prepareWriteSequence(data);
-        } else {
-            try {
+            if (writer.canWriteSequence()) {
                 writer.prepareWriteSequence(data);
-                throw new RuntimeException(
-                        "UnsupportedOperationException was not thrown");
-            } catch (final UnsupportedOperationException ignored) {
+            } else {
+                try {
+                    writer.prepareWriteSequence(data);
+                    throw new RuntimeException(
+                            "UnsupportedOperationException was not thrown");
+                } catch (final UnsupportedOperationException ignored) {
                 // expected
+                }
+            }
+        } finally {
+            writer.dispose();
+            if (file != null) {
+                if (ios != null) {
+                    ios.close();
+                }
+                if (fos != null) {
+                    fos.close();
+                }
+                Files.delete(file.toPath());
             }
         }
-        writer.dispose();
-        ios.close();
     }
 }
\ No newline at end of file
--- a/test/javax/imageio/plugins/shared/WriteAfterAbort.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/javax/imageio/plugins/shared/WriteAfterAbort.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
  * 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 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.Iterator;
+import java.nio.file.Files;
 
 import javax.imageio.ImageIO;
 import javax.imageio.ImageWriter;
@@ -41,9 +42,9 @@
 
 /**
  * @test
- * @bug 4952954
+ * @bug     4952954 8183349
  * @summary abortFlag must be cleared for every ImageWriter.write operation
- * @author Sergey Bylokhov
+ * @run     main WriteAfterAbort
  */
 public final class WriteAfterAbort implements IIOWriteProgressListener {
 
@@ -54,73 +55,85 @@
     private volatile boolean isStartedCalled;
     private static final int WIDTH = 100;
     private static final int HEIGHT = 100;
+    private static FileOutputStream fos;
+    private static File file;
 
     private void test(final ImageWriter writer) throws IOException {
-        // Image initialization
-        final BufferedImage imageWrite = new BufferedImage(WIDTH, HEIGHT,
-                                                           TYPE_BYTE_BINARY);
-        final Graphics2D g = imageWrite.createGraphics();
-        g.setColor(Color.WHITE);
-        g.fillRect(0, 0, WIDTH, HEIGHT);
-        g.dispose();
+        try {
+            // Image initialization
+            final BufferedImage imageWrite =
+                    new BufferedImage(WIDTH, HEIGHT, TYPE_BYTE_BINARY);
+            final Graphics2D g = imageWrite.createGraphics();
+            g.setColor(Color.WHITE);
+            g.fillRect(0, 0, WIDTH, HEIGHT);
+            g.dispose();
+
+            // File initialization
+            file = File.createTempFile("temp", ".img");
+            fos = new SkipWriteOnAbortOutputStream(file);
+            final ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
+            writer.setOutput(ios);
+            writer.addIIOWriteProgressListener(this);
 
-        // File initialization
-        final File file = File.createTempFile("temp", ".img");
-        file.deleteOnExit();
-        final FileOutputStream fos = new SkipWriteOnAbortOutputStream(file);
-        final ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
-        writer.setOutput(ios);
-        writer.addIIOWriteProgressListener(this);
+            // This write will be aborted, and file will not be touched
+            writer.write(imageWrite);
+            if (!isStartedCalled) {
+                throw new RuntimeException("Started should be called");
+            }
+            if (!isProgressCalled) {
+                throw new RuntimeException("Progress should be called");
+            }
+            if (!isAbortCalled) {
+                throw new RuntimeException("Abort should be called");
+            }
+            if (isCompleteCalled) {
+                throw new RuntimeException("Complete should not be called");
+            }
+            // Flush aborted data
+            ios.flush();
 
-        // This write will be aborted, and file will not be touched
-        writer.write(imageWrite);
-        if (!isStartedCalled) {
-            throw new RuntimeException("Started should be called");
-        }
-        if (!isProgressCalled) {
-            throw new RuntimeException("Progress should be called");
-        }
-        if (!isAbortCalled) {
-            throw new RuntimeException("Abort should be called");
-        }
-        if (isCompleteCalled) {
-            throw new RuntimeException("Complete should not be called");
-        }
-        // Flush aborted data
-        ios.flush();
+            /*
+             * This write should be completed successfully and the file should
+             * contain correct image data.
+             */
+            abortFlag = false;
+            isAbortCalled = false;
+            isCompleteCalled = false;
+            isProgressCalled = false;
+            isStartedCalled = false;
+            writer.write(imageWrite);
 
-        // This write should be completed successfully and the file should
-        // contain correct image data.
-        abortFlag = false;
-        isAbortCalled = false;
-        isCompleteCalled = false;
-        isProgressCalled = false;
-        isStartedCalled = false;
-        writer.write(imageWrite);
+            if (!isStartedCalled) {
+                throw new RuntimeException("Started should be called");
+            }
+            if (!isProgressCalled) {
+                throw new RuntimeException("Progress should be called");
+            }
+            if (isAbortCalled) {
+                throw new RuntimeException("Abort should not be called");
+            }
+            if (!isCompleteCalled) {
+                throw new RuntimeException("Complete should be called");
+            }
+            ios.close();
 
-        if (!isStartedCalled) {
-            throw new RuntimeException("Started should be called");
-        }
-        if (!isProgressCalled) {
-            throw new RuntimeException("Progress should be called");
-        }
-        if (isAbortCalled) {
-            throw new RuntimeException("Abort should not be called");
-        }
-        if (!isCompleteCalled) {
-            throw new RuntimeException("Complete should be called");
-        }
-        writer.dispose();
-        ios.close();
-
-        // Validates content of the file.
-        final BufferedImage imageRead = ImageIO.read(file);
-        for (int x = 0; x < WIDTH; ++x) {
-            for (int y = 0; y < HEIGHT; ++y) {
-                if (imageRead.getRGB(x, y) != imageWrite.getRGB(x, y)) {
-                    throw new RuntimeException("Test failed.");
+            // Validates content of the file.
+            final BufferedImage imageRead = ImageIO.read(file);
+            for (int x = 0; x < WIDTH; ++x) {
+                for (int y = 0; y < HEIGHT; ++y) {
+                    if (imageRead.getRGB(x, y) != imageWrite.getRGB(x, y)) {
+                        throw new RuntimeException("Test failed.");
+                    }
                 }
             }
+        } finally {
+            writer.dispose();
+            if (file != null) {
+                if (fos != null) {
+                    fos.close();
+                }
+                Files.delete(file.toPath());
+            }
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/wbmp/EmptyInputWbmpMetadataTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4895483
+ * @summary Test checks that the IllegalStateException was thrown if input was
+ *          not set to the WBMPImageReader
+ */
+
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.metadata.IIOMetadata;
+
+public class EmptyInputWbmpMetadataTest {
+    private static String fmt = "BMP";
+
+    public static void main(String[] args) {
+        boolean isPassed = false;
+        ImageReader ir = (ImageReader)ImageIO.getImageReadersByFormatName(fmt).next();
+
+        if (ir == null) {
+            throw new RuntimeException("No available reader for " + fmt);
+        }
+        IIOMetadata meta = null;
+        try {
+            meta = ir.getImageMetadata(0);
+        } catch (IllegalStateException e) {
+            System.out.println("Correct exception was thrown. Test passed.");
+            isPassed = true;
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        if (!isPassed) {
+            throw new RuntimeException("The IllegalStateException was not thrown."
+                                       +"Test failed.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/wbmp/GetImageTypesTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4928273
+ * @summary Verifies what IllegalStateException is thrown if image input was not
+ *          set
+ */
+
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+
+public class GetImageTypesTest {
+
+    private static final String format = "wbmp";
+
+    public static void main(String[] args) {
+
+        boolean passed = false;
+        ImageReader ir = (ImageReader)ImageIO.getImageReadersByFormatName(format).next();
+
+        if (ir == null) {
+            throw new RuntimeException("No matching reader found. Test Failed");
+        }
+
+        try {
+            Iterator types = ir.getImageTypes(0);
+        } catch (IllegalStateException e) {
+            System.out.println("Test passed.");
+            passed = true;
+        } catch (Exception e) {
+            throw new RuntimeException("Unexpected exception was thrown. "
+                                       + "Test failed.");
+        }
+
+        if (!passed) {
+            throw new RuntimeException("IllegalStateException is not thrown when "
+                                       + "calling getImageTypes() without setting "
+                                       + "the input source for the image format: "
+                                       + format
+                                       + ". Test failed");
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/wbmp/ValidWbmpTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4924512
+ * @summary Test that wbmp image reader detects incorrect image format
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import javax.imageio.IIOException;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+
+public class ValidWbmpTest {
+
+    public static void main(String[] args) {
+        try {
+            String[] formats = { "JPEG", "PNG", "BMP" };
+
+            BufferedImage img = new BufferedImage(100, 100,
+                                                  BufferedImage.TYPE_BYTE_GRAY);
+            Graphics g = img.createGraphics();
+            g.setColor(Color.white);
+            g.fillRect(0,0,100,100);
+            g.setColor(Color.black);
+            g.fillRect(10,10,80,80);
+
+            ImageReader ir = (ImageReader)ImageIO.getImageReadersByFormatName("WBMP").next();
+            if (ir==null) {
+                throw new RuntimeException("No readers for WBMP format!");
+            }
+            for(int i=0; i<formats.length; i++) {
+                System.out.println("Test " + formats[i] + " stream...");
+                boolean passed = false;
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ImageIO.write(img, formats[i], baos);
+                baos.close();
+                ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+
+                ImageInputStream iis = null;
+                iis = ImageIO.createImageInputStream(bais);
+                ir.setInput(iis);
+                try {
+                    BufferedImage res = ir.read(0);
+                } catch (IIOException e) {
+                    StackTraceElement[] stack = e.getStackTrace();
+                    if (ir.getClass().getName().equals(stack[0].getClassName())
+                        && "readHeader".equals(stack[0].getMethodName()))
+                    {
+                        passed = true;
+                    }
+                } catch (Throwable t) {
+                    t.printStackTrace();
+                }
+
+                if (!passed) {
+                    throw new RuntimeException("Test failed!");
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Unexpected exception. Test failed.");
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/wbmp/WBMPPluginTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4641872
+ * @summary Tests writing and reading abilities of WBMP plugin
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+
+import javax.imageio.IIOException;
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+
+public class WBMPPluginTest {
+
+    private static final int[] types = {
+        BufferedImage.TYPE_INT_RGB, // = 1;
+        BufferedImage.TYPE_INT_ARGB, // = 2;
+        BufferedImage.TYPE_INT_ARGB_PRE, // = 3;
+        BufferedImage.TYPE_INT_BGR, // = 4;
+        BufferedImage.TYPE_3BYTE_BGR, // = 5;
+        BufferedImage.TYPE_4BYTE_ABGR, // = 6;
+        BufferedImage.TYPE_4BYTE_ABGR_PRE, // 7
+        BufferedImage.TYPE_USHORT_565_RGB, // 8
+        BufferedImage.TYPE_USHORT_555_RGB, // 9
+        BufferedImage.TYPE_BYTE_GRAY, // 10
+        BufferedImage.TYPE_USHORT_GRAY, //11
+        BufferedImage.TYPE_BYTE_BINARY, //12
+        BufferedImage.TYPE_BYTE_INDEXED //13
+    };
+
+    private static String format = "WBMP";
+
+    private static ImageReader ir = null;
+    private static ImageWriter iw = null;
+    private BufferedImage img;
+    private ImageWriteParam param;
+    private ByteArrayOutputStream baos;
+
+    private static void init() {
+
+        Iterator i = ImageIO.getImageWritersByFormatName(format);
+        if (!i.hasNext()) {
+            throw new RuntimeException("No available ImageWrites for "+format+" format!");
+        }
+        iw = (ImageWriter)i.next();
+
+        i = ImageIO.getImageReadersByFormatName(format);
+        if (!i.hasNext()) {
+            throw new RuntimeException("No available ImageReaders for " +format+" format!");
+        }
+
+        ir = (ImageReader)i.next();
+    }
+
+    public static void main(String[] args) {
+        if (args.length > 0) {
+            format = args[0];
+            System.out.println("Test format " + format);
+        }
+
+        init();
+        ImageIO.setUseCache(false);
+
+        for (int i=0; i<types.length; i++) {
+            boolean bPassed = true;
+            Object reason = null;
+
+            try {
+
+                BufferedImage image = createTestImage(types[i]);
+
+                ImageWriteParam param = iw.getDefaultWriteParam();
+
+                WBMPPluginTest t = new WBMPPluginTest(image, param);
+                boolean res = false;
+                res = t.test();
+                if (!res) {
+                    bPassed = false;
+                    reason = new String("Null result");
+                }
+            } catch (IllegalArgumentException ex) {
+                System.out.println("Expected exception type was caught: " + ex);
+
+            } catch (Throwable ex ) {
+                System.out.println("FAILED");
+                ex.printStackTrace();
+                bPassed = false;
+                reason = ex;
+                throw new RuntimeException("Test for type " + types[i] + " FAILED due to exception");
+            }
+/*
+            System.out.println("Type " + types[i] + " result: " +
+                               (bPassed ? "PASSED" : "FAILED") +
+                               ((reason != null) ? (" Reason: " + reason) : ""));
+*/
+            System.out.println("Test for type " + types[i] + " PASSED");
+        }
+
+        System.out.println("END OF TEST");
+    }
+
+    public WBMPPluginTest(BufferedImage img, ImageWriteParam param) {
+
+        this.img = img;
+        this.param = param;
+        baos = new ByteArrayOutputStream();
+    }
+
+    public boolean test() throws IIOException, IOException {
+
+        ir.reset();
+        iw.reset();
+
+        String[] suffixes = iw.getOriginatingProvider().getFileSuffixes();
+
+        IIOMetadata md = iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), param);
+        IIOImage iio_img = new IIOImage(img, null, md);
+
+        System.out.println("Image type " + img.getType());
+
+        String fname = "test"+img.getType()+"."+suffixes[0];
+
+        iw.setOutput(ImageIO.createImageOutputStream(new FileOutputStream(new File(fname))));
+        System.out.print("write image ... ");
+        iw.write(iio_img);
+        System.out.println("OK");
+        System.out.print("read image ... ");
+
+        byte[] ba_image = baos.toByteArray();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(ba_image);
+
+        ir.setInput(ImageIO.createImageInputStream(new FileInputStream(new File(fname))));
+
+        BufferedImage res = ir.read(0);
+        System.out.println("OK");
+
+        System.out.print("compare images ... ");
+        boolean r = compare(img,res);
+        System.out.println(r?"OK":"FAILED");
+        return r;
+    }
+
+    private boolean compare(BufferedImage in, BufferedImage out) {
+        int width = in.getWidth();
+        int height = in.getHeight();
+        if (out.getWidth() != width || out.getHeight() != height) {
+            throw new RuntimeException("Dimensions changed!");
+        }
+
+        Raster oldras = in.getRaster();
+        ColorModel oldcm = in.getColorModel();
+        Raster newras = out.getRaster();
+        ColorModel newcm = out.getColorModel();
+
+        for (int j = 0; j < height; j++) {
+            for (int i = 0; i < width; i++) {
+                Object oldpixel = oldras.getDataElements(i, j, null);
+                int oldrgb = oldcm.getRGB(oldpixel);
+                int oldalpha = oldcm.getAlpha(oldpixel);
+
+                Object newpixel = newras.getDataElements(i, j, null);
+                int newrgb = newcm.getRGB(newpixel);
+                int newalpha = newcm.getAlpha(newpixel);
+
+                if (newrgb != oldrgb ||
+                    newalpha != oldalpha) {
+                    throw new RuntimeException("Pixels differ at " + i +
+                                               ", " + j);
+                }
+            }
+        }
+        return true;
+    }
+
+
+    private static BufferedImage createTestImage(int type) throws IOException {
+
+        int w = 200;
+        int h = 200;
+        BufferedImage b = new BufferedImage(w, h, type);
+        Graphics2D g = b.createGraphics();
+        g.setColor(Color.white);
+        g.fillRect(0,0, w, h);
+        g.setColor(Color.black);
+        g.fillOval(10, 10, w -20, h-20);
+
+        return b;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/wbmp/WbmpBigDestinationTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4929367
+ * @summary tests what BMP image was decoded correctly if destination buffered
+ *          image is bigger than source image
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriter;
+
+public class WbmpBigDestinationTest {
+    static String format = "WBMP";
+    public static void main(String[] args) {
+        try {
+            BufferedImage src = new BufferedImage(100, 100,
+                                                  BufferedImage.TYPE_BYTE_BINARY);
+            Graphics2D g = src.createGraphics();
+            g.setColor(Color.white);
+            g.fillRect(0,0,100, 100);
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+            ImageWriter iw =
+                (ImageWriter)ImageIO.getImageWritersByFormatName(format).next();
+            if (iw == null) {
+                throw new RuntimeException("No writer available. Test failed.");
+            }
+
+            iw.setOutput(ImageIO.createImageOutputStream(baos));
+            iw.write(src);
+
+            byte[] data = baos.toByteArray();
+
+            ImageReader ir =
+                (ImageReader)ImageIO.getImageReadersByFormatName(format).next();
+            ir.setInput(
+                ImageIO.createImageInputStream(
+                    new ByteArrayInputStream(data)));
+
+            Iterator specifiers = ir.getImageTypes(0);
+            ImageTypeSpecifier typeSpecifier = null;
+
+            if (specifiers.hasNext()) {
+                typeSpecifier = (ImageTypeSpecifier) specifiers.next();
+            }
+            ImageReadParam param = new ImageReadParam();
+            BufferedImage dst = typeSpecifier.createBufferedImage(200, 200);
+            param.setDestination(dst);
+
+            ir.read(0, param);
+
+            checkResults(src,dst);
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Unexpected exception. Test failed.");
+        }
+    }
+
+    private static void checkResults(BufferedImage src, BufferedImage dst) {
+        for(int x=0; x<src.getWidth(); x++) {
+            for(int y=0; y<src.getHeight(); y++) {
+                int srcRgb = src.getRGB(x,y);
+                int dstRgb = dst.getRGB(x,y);
+                if (srcRgb != dstRgb) {
+                    throw new RuntimeException("Images are different at point ["
+                                               + x + "," + y + "]");
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/plugins/wbmp/WbmpDefaultImageMetadataTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4895512
+ * @summary Test that WBMPImageWriter return non-null default image metadata
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+public class WbmpDefaultImageMetadataTest {
+    ImageWriter writer = null;
+    IIOMetadata imageData = null;
+    ImageWriteParam writeParam = null;
+    BufferedImage bimg = null;
+
+    public WbmpDefaultImageMetadataTest(String format) {
+        try {
+            bimg = new BufferedImage(200, 200, bimg.TYPE_INT_RGB);
+            Graphics gg = bimg.getGraphics();
+            gg.setColor(Color.red);
+            gg.fillRect(50, 50, 100, 100);
+
+            Iterator it = ImageIO.getImageWritersByFormatName(format);
+            if (it.hasNext()) {
+                writer = (ImageWriter) it.next();
+            }
+            if (writer == null) {
+                throw new RuntimeException("No writer available for the given format."
+                                           + " Test failed.");
+            }
+            writeParam = writer.getDefaultWriteParam();
+
+            System.out.println("Testing Image Metadata for "+format+"\n");
+            imageData = writer.getDefaultImageMetadata(new ImageTypeSpecifier(bimg), writeParam);
+            if (imageData == null) {
+                System.out.println("return value is null. No default image metadata is associated with "+format+" writer");
+                throw new RuntimeException("Default image metadata is null."
+                                           + " Test failed.");
+            }
+            int j = 0;
+            String imageDataNames[] = null;
+            if(imageData != null) {
+                System.out.println("Is standard metadata format supported (Image) ? "+
+                                   imageData.isStandardMetadataFormatSupported() );
+                imageDataNames = imageData.getMetadataFormatNames();
+                System.out.println("\nAll supported Metadata Format Names\n");
+                if(imageDataNames!=null){
+                    for(j=0; j<imageDataNames.length; j++)  {
+                        System.out.println("FORMAT NAME: "+imageDataNames[j]);
+                        if (imageDataNames[j].equals(imageData.getNativeMetadataFormatName())) {
+                            System.out.println("This is a Native Metadata format\n");
+                        } else {
+                            System.out.println("\n");
+                        }
+                        System.out.println("");
+                        System.out.println("IIOImageMetadata DOM tree for "+imageDataNames[j]);
+                        System.out.println("");
+                        Node imageNode = imageData.getAsTree(imageDataNames[j]);
+                        displayMetadata(imageNode);
+                        System.out.println("\n\n");
+                    }
+                }
+            }
+        }catch(Exception e){
+            e.printStackTrace();
+            throw new RuntimeException("Exception was thrown."
+                                       + " Test failed.");
+        }
+    }
+
+    public void displayMetadata(Node root) {
+        displayMetadata(root, 0);
+    }
+
+    void indent(int level) {
+        for (int i = 0; i < level; i++) {
+            System.out.print(" ");
+        }
+    }
+
+    void displayMetadata(Node node, int level) {
+        indent(level); // emit open tag
+        System.out.print("<" + node.getNodeName());
+        NamedNodeMap map = node.getAttributes();
+        if (map != null) { // print attribute values
+            int length = map.getLength();
+            for (int i = 0; i < length; i++) {
+                Node attr = map.item(i);
+                System.out.print(" " + attr.getNodeName() +
+                                 "=\"" + attr.getNodeValue() + "\"");
+            }
+        }
+        Node child = node.getFirstChild();
+
+        if (node.getNodeValue() != null && !node.getNodeValue().equals("") ) {
+            System.out.println(">");
+            indent(level);
+            System.out.println(node.getNodeValue());
+            indent(level); // emit close tag
+            System.out.println("</" + node.getNodeName() + ">");
+        } else  if (child != null) {
+            System.out.println(">"); // close current tag
+            while (child != null) { // emit child tags recursively
+                displayMetadata(child, level + 1);
+                child = child.getNextSibling();
+            }
+            indent(level); // emit close tag
+            System.out.println("</" + node.getNodeName() + ">");
+        } else {
+            System.out.println("/>");
+        }
+    }
+
+    public static void main(String args[]) {
+        WbmpDefaultImageMetadataTest test =
+            new WbmpDefaultImageMetadataTest("wbmp");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/spi/AppletContextTest/BadPluginConfigurationTest.sh	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,280 @@
+#!/bin/ksh -p
+# Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+# 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        6342404 7078379 8167503 8183351
+#
+#   @summary    Test verifies that incorrectly configured ImageIO plugin spi
+#               does not affect registration of other ImageIO plugin in the
+#               applet context.
+#
+#
+#   @compile    IIOPluginTest.java
+#   @compile    DummyReaderPluginSpi.java
+#   @run shell  BadPluginConfigurationTest.sh
+
+# There are several resources which need to be present before many
+#  shell scripts can run.  Following are examples of how to check for
+#  many common ones.
+#
+# Note that the shell used is the Korn Shell, KSH
+#
+# Also note, it is recommended that make files NOT be used.  Rather,
+#  put the individual commands directly into this file.  That way,
+#  it is possible to use command line arguments and other shell tech-
+#  niques to find the compiler, etc on different systems.  For example,
+#  a different path could be used depending on whether this were a
+#  Solaris or Win32 machine, which is more difficult (if even possible)
+#  in a make file.
+
+
+# Beginning of subroutines:
+status=1
+
+#Call this from anywhere to fail the test with an error message
+# usage: fail "reason why the test failed"
+fail()
+ { echo "The test failed :-("
+   echo "$*" 1>&2
+   echo "exit status was $status"
+   clean
+   exit $status
+ } #end of fail()
+
+#Call this from anywhere to pass the test with a message
+# usage: pass "reason why the test passed if applicable"
+pass()
+ { echo "The test passed!!!"
+   echo "$*" 1>&2
+   clean
+   exit 0
+ } #end of pass()
+
+#Clean up the test_ext directory (PLUGINDST_DIR) before leaving
+clean()
+ {
+ echo "Removing PLUGINDST_DIR ${PLUGINDST_DIR}"
+ if [ -n "${PLUGINDST_DIR}" -a -d "${PLUGINDST_DIR}" ] ; then
+ rm -rf "${PLUGINDST_DIR}"
+ fi
+ }
+
+# end of subroutines
+
+
+# The beginning of the script proper
+
+# Checking for proper OS
+OS=`uname -s`
+case "$OS" in
+   SunOS | Linux | Darwin )
+      FILESEP="/"
+      PATHSEP=":"
+      TMP=`cd /tmp; pwd -P`
+      ;;
+
+   Windows* )
+      FILESEP="\\"
+      PATHSEP=";"
+      TMP=`cd "${SystemRoot}/Temp"; echo ${PWD}`
+      ;;
+
+   CYGWIN* )
+      FILESEP="/"
+      PATHSEP=";"
+      TMP="/tmp"
+      ;;
+
+   # catch all other OSs
+   * )
+      echo "Unrecognized system!  $OS"
+      fail "Unrecognized system!  $OS"
+      ;;
+esac
+
+# Want this test to run standalone as well as in the harness, so do the
+#  following to copy the test's directory into the harness's scratch directory
+#  and set all appropriate variables:
+
+if [ -z "${TESTJAVA}" ] ; then
+   # TESTJAVA is not set, so the test is running stand-alone.
+   # TESTJAVA holds the path to the root directory of the build of the JDK
+   # to be tested.  That is, any java files run explicitly in this shell
+   # should use TESTJAVA in the path to the java interpreter.
+   # So, we'll set this to the JDK spec'd on the command line.  If none
+   # is given on the command line, tell the user that and use a cheesy
+   # default.
+   # THIS IS THE JDK BEING TESTED.
+   if [ -n "$1" ] ;
+      then TESTJAVA=$1
+      else fail "no JDK specified on command line!"
+   fi
+   TESTSRC=.
+   TESTCLASSES=.
+   STANDALONE=1;
+fi
+echo "JDK under test is: $TESTJAVA"
+
+#Deal with .class files:
+if [ -n "${STANDALONE}" ] ;
+   then
+   #if standalone, remind user to cd to dir. containing test before running it
+   echo "Just a reminder: cd to the dir containing this test when running it"
+   # then compile all .java files (if there are any) into .class files
+   if [ -a *.java ] ;
+      then echo "Reminder, this test should be in its own directory with all"
+      echo "supporting files it needs in the directory with it."
+      ${COMPILEJAVA}/bin/javac ./*.java ;
+   fi
+   # else in harness so copy all the class files from where jtreg put them
+   # over to the scratch directory this test is running in.
+   else cp ${TESTCLASSES}/*.class . ;
+fi
+
+#if in test harness, then copy the entire directory that the test is in over
+# to the scratch directory.  This catches any support files needed by the test.
+if [ -z "${STANDALONE}" ] ;
+   then cp ${TESTSRC}/*.java .
+fi
+
+#Just before executing anything, make sure it has executable permission!
+chmod 777 ./*
+
+###############  YOUR TEST CODE HERE!!!!!!!  #############
+
+#All files required for the test should be in the same directory with
+# this file.  If converting a standalone test to run with the harness,
+# as long as all files are in the same directory and it returns 0 for
+# pass, you should be able to cut and paste it into here and it will
+# run with the test harness.
+
+# This is an example of running something -- test
+# The stuff below catches the exit status of test then passes or fails
+# this shell test as appropriate ( 0 status is considered a pass here )
+
+echo
+echo ------ PREPARE TEST PLUGIN ---------
+
+# note that we can not use some subdirectory of the
+# scratch dir as the plugin dst dir because the test
+# app have file read permission for all subdirs of the
+# scratch dir
+
+PLUGINDST_DIR=$(mktemp -d ${TMP}/iio_test.XXXXXXXX)
+echo "Created PLUGINDST_DIR as ${PLUGINDST_DIR}"
+
+TEST_PLUGIN=dummy.jar
+
+# remove old service declaration
+if [ -d META-INF ] ; then
+    rm -rf META-INF
+fi
+
+# generate the service declaration
+if [ ! -d META_INF ] ; then
+     mkdir META-INF
+     mkdir META-INF/services
+fi
+
+# add wrong record to the service configuration
+echo "BadReaderPluginSpi" >  META-INF/services/javax.imageio.spi.ImageReaderSpi
+
+echo "DummyReaderPluginSpi" >> META-INF/services/javax.imageio.spi.ImageReaderSpi
+
+
+${TESTJAVA}/bin/jar -cvf ${TEST_PLUGIN} DummyReaderPluginSpi*.class META-INF/services/javax.imageio.spi.ImageReaderSpi
+
+echo ----- TEST PLUGIN IS READY --------
+echo
+echo ----- INSTALL PLUGIN --------
+echo "Install test plugin to ${PLUGINDST_DIR}"
+if [ -f ${PLUGINDST_DIR}/${TEST_PLUGIN} ] ; then
+    echo "Remove old plugin..."
+    rm -f ${PLUGINDST_DIR}/${TEST_PLUGIN}
+fi
+mv -f ${TEST_PLUGIN} ${PLUGINDST_DIR}
+if [ -f ${PLUGINDST_DIR}/${TEST_PLUGIN} ] ; then
+    echo Test plugin is installed.
+else
+    fail "Unable to install test plugin to $PLUGINDST_DIR"
+fi
+echo ----- PLUGIN IS INSTALLED ------
+echo
+echo ----- CLEAN PLUGIN TEMPORARY FILES -----
+rm -rf DummyReaderPluginSpi*.class META-INF
+echo ----- CLEANING IS COMPLETE -------
+echo
+
+
+case "$OS" in
+   CYGWIN* )
+      TEST_CODEBASE=$(cygpath -m ${PWD})
+      TEST_PLUGIN_JAR=$(cygpath -m ${PLUGINDST_DIR}${FILESEP}${TEST_PLUGIN})
+      ;;
+
+   # catch all other OSs
+   * )
+      TEST_CODEBASE=${PWD}
+      TEST_PLUGIN_JAR=${PLUGINDST_DIR}${FILESEP}${TEST_PLUGIN}
+      ;;
+esac
+
+
+# Update policy file to grant read permission
+echo "grant codeBase \"file:${TEST_CODEBASE}\" {" > classpath.policy
+echo " permission java.io.FilePermission \"${TEST_PLUGIN_JAR}\", \"read\";" >> classpath.policy
+echo " permission java.util.PropertyPermission \"test.5076692.property\", \"read\";" >> classpath.policy
+echo "};" >> classpath.policy
+echo "grant codeBase \"file:${TEST_PLUGIN_JAR}\" {" >> classpath.policy
+echo " permission java.util.PropertyPermission \"test.5076692.property\", \"read\";" >> classpath.policy
+echo "};" >> classpath.policy
+
+echo ---------------------
+echo --- Applet policy ---
+echo ---------------------
+cat classpath.policy
+echo ---------------------
+echo
+
+echo -------------------------------
+echo ---  Applet Classpath Test  ---
+echo -------------------------------
+#
+# please note that we need to use "==" in setup of the java.security.policy
+# property in order to overwrite policies defined in the user policy file
+# For more details see:
+#  http://java.sun.com/j2se/1.5.0/docs/guide/security/PolicyFiles.html)
+#
+
+${TESTJAVA}/bin/java ${TESTVMOPTS} -cp ".${PATHSEP}${TEST_PLUGIN_JAR}" \
+    -Djava.security.policy==classpath.policy \
+    -Djava.security.manager IIOPluginTest
+
+status=$?
+
+if [ $status -eq "0" ] ; then
+    pass ""
+else
+    fail "Test failed due to test plugin was not found."
+fi
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/spi/AppletContextTest/DummyReaderPluginSpi.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.util.Locale;
+
+import javax.imageio.IIOException;
+import javax.imageio.ImageReader;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.ServiceRegistry;
+
+public class DummyReaderPluginSpi extends ImageReaderSpi {
+
+    private static String [] writerSpiNames =
+        {"DummyWriterPluginSpi"};
+    public static String[] formatNames = {"test_5076692", "TEST_5076692"};
+    public static String[] entensions = {"test_5076692"};
+    public static String[] mimeType = {"image/test_5076692"};
+
+    private boolean registered = false;
+
+    public DummyReaderPluginSpi() {
+        super("Sun Microsystems, Inc.",
+              "1.0",
+              formatNames,
+              entensions,
+              mimeType,
+              "DummyPluginReader",
+              STANDARD_INPUT_TYPE,
+              writerSpiNames,
+              false,
+              null, null, null, null,
+              false,
+              "",
+              "",
+              null, null);
+    }
+
+    public void onRegistration(ServiceRegistry registry,
+                               Class<?> category) {
+        if (registered) {
+            return;
+        }
+
+        System.getProperty("test.5076692.property", "not found");
+
+        registered = true;
+    }
+
+    public String getDescription(Locale locale) {
+        return "Standard Dummy Image Reader";
+    }
+
+    public boolean canDecodeInput(Object source) throws IOException {
+        return false;
+    }
+
+    public ImageReader createReaderInstance(Object extension)
+        throws IIOException {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/spi/AppletContextTest/IIOPluginTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 javax.imageio.ImageIO;
+
+public class IIOPluginTest {
+
+    public static String[] dummyformatNames = {"test_5076692", "TEST_5076692"};
+    public static String[] dummymimeType = {"image/test_5076692"};
+
+    public static void main(String[] args) {
+        SecurityManager sm = System.getSecurityManager();
+        System.out.println("Sm is " + sm);
+
+        String formatNames[] = ImageIO.getReaderFormatNames();
+        String readerMimeTypes[] = ImageIO.getReaderMIMETypes();
+
+        if (!isPresent(dummyformatNames, formatNames) ||
+            !isPresent(dummymimeType, readerMimeTypes)) {
+            throw new RuntimeException("No test plugin available!");
+        }
+    }
+
+    public static boolean isPresent(String[] t, String[] r) {
+        for (int i=0; i<t.length; i++) {
+            if (!isPresent(t[i], r)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static boolean isPresent(String s, String[] a) {
+        for (int i=0; i<a.length; i++) {
+            System.out.println(a[i] + " ");
+            if (s.equals(a[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/spi/CreateMemoryCacheOutputStream.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4415456
+ * @summary Tests the ability to create a MemoryCacheImageOutputStream using the
+ *          normal service provider interface mechanisms
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+import javax.imageio.ImageIO;
+import javax.imageio.stream.ImageOutputStream;
+
+public class CreateMemoryCacheOutputStream {
+
+    public static void main(String[] args) {
+        ImageIO.setUseCache(false);
+        OutputStream os = new ByteArrayOutputStream();
+        ImageOutputStream stream = null;
+        try {
+            stream = ImageIO.createImageOutputStream(os);
+        } catch (Exception e) {
+            throw new RuntimeException("Got exception " + e);
+        }
+        if (stream == null) {
+            throw new RuntimeException("Got null stream!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/spi/DeregisterAllSpiTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4835841
+ * @summary This test verifies that we will able to register new SPI after
+ *          deregistration all previously registered SPIs by using
+ *          deregisterAll() method
+ */
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.ServiceRegistry;
+import javax.imageio.stream.ImageInputStream;
+
+public class DeregisterAllSpiTest {
+
+    public DeregisterAllSpiTest() throws Exception {
+        ImageReaderSpi BMPSpi = new BMPImageReaderSPI();
+        IIORegistry.getDefaultInstance().registerServiceProvider(BMPSpi);
+
+        System.out.println("Reader Format Names available in the registry");
+        String formatNames[] = ImageIO.getReaderFormatNames();
+        if( formatNames == null || formatNames.length <= 0) {
+            throw new RuntimeException("No registered ImageReaders!");
+        }
+        for (int x=0; x < formatNames.length; x++) {
+            System.out.println("format "+formatNames[x]);
+        }
+
+        IIORegistry.getDefaultInstance().deregisterAll();
+
+        System.out.println("\nReader Format Names after deregistering all SPIs");
+        formatNames = ImageIO.getReaderFormatNames();
+        if(formatNames.length == 0) {
+            System.out.println("No readers available\n");
+        } else {
+            throw new RuntimeException("Some providers was not deregistered!");
+        }
+
+        IIORegistry.getDefaultInstance().registerServiceProvider(BMPSpi);
+        System.out.println("Reader Format Names after re-register of BMP Plugin");
+        formatNames = ImageIO.getReaderFormatNames();
+        if(formatNames.length == 0) {
+            throw new RuntimeException("Unable to register new SPI after deregisterAll()!");
+        }
+    }
+
+
+    public static void main(String args[]) throws Exception{
+        DeregisterAllSpiTest regis = new DeregisterAllSpiTest();
+    }
+
+
+    public static class BMPImageReaderSPI extends javax.imageio.spi.ImageReaderSpi{
+
+        private static final String vendorName = "Javasoft";
+
+        private static final String version = "2.0";
+
+        private static final String[] names = { "bmp" };
+
+        private static final String[] suffixes = { "bmp" };
+
+        private static final String[] MIMETypes = { "image/x-bmp"};
+
+        private static final String readerClassName =
+        "com.sun.imageio.plugins.png.PNGImageReader";
+
+        private static final String[] writerSpiNames = {
+            "com.sun.imageio.plugins.png.PNGImageWriterSpi"
+        };
+
+        public BMPImageReaderSPI() {
+            super(vendorName,
+                  version,
+                  names,
+                  suffixes,
+                  MIMETypes,
+                  readerClassName,
+                  STANDARD_INPUT_TYPE,
+                  writerSpiNames,
+                  false,
+                  null, null,
+                  null, null,
+                  true,
+                  "BMP Native Metadata",
+                  "com.sun.imageio.plugins.png.PNGMetadataFormat",
+                  null, null
+                  );
+        }
+
+        public String getDescription(Locale locale) {
+            return "Standard BMP image reader";
+        }
+
+        public boolean canDecodeInput(Object input) throws IOException {
+            if (!(input instanceof ImageInputStream)) {
+                return false;
+            }
+
+            ImageInputStream stream = (ImageInputStream)input;
+            byte[] b = new byte[8];
+            stream.mark();
+            stream.readFully(b);
+            stream.reset();
+
+            return (b[0] == (byte)137 &&
+                    b[1] == (byte)80 &&
+                    b[2] == (byte)78 &&
+                    b[3] == (byte)71 &&
+                    b[4] == (byte)13 &&
+                    b[5] == (byte)10 &&
+                    b[6] == (byte)26 &&
+                    b[7] == (byte)10);
+        }
+
+        public ImageReader createReaderInstance(Object extension) {
+            //return new PNGImageReader(this);
+            return null;
+        }
+        public void onRegistration(ServiceRegistry sr, Class<?> category) {
+            System.out.println("\nfrom OnRegistration: BMP plugin Registered\n");
+            super.onRegistration(sr, category);
+        }
+
+        public void onDeregistration(ServiceRegistry sr, Class<?> category) {
+            System.out.println("\nfrom OnDeregistration: BMP plugin De-Registered\n");
+            //super.onRegistration(sr, category);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/spi/DeregisterOrderedSpiTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4936495 8037743
+ * @summary This test verifies whether deregistering an ordered spi object does
+ *          not throw any exception
+ */
+
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.ServiceRegistry;
+
+public class DeregisterOrderedSpiTest {
+
+     public DeregisterOrderedSpiTest() {
+
+         try {
+
+             ServiceRegistry reg = IIORegistry.getDefaultInstance();
+             ImageReaderSpi gifSpi = (ImageReaderSpi) reg.getServiceProviderByClass(com.sun.imageio.plugins.gif.GIFImageReaderSpi.class);
+             ImageReaderSpi pngSpi = (ImageReaderSpi) reg.getServiceProviderByClass(com.sun.imageio.plugins.png.PNGImageReaderSpi.class);
+             ImageReaderSpi jpgSpi = (ImageReaderSpi) reg.getServiceProviderByClass(com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi.class);
+             ImageReaderSpi bmpSpi = (ImageReaderSpi) reg.getServiceProviderByClass(com.sun.imageio.plugins.bmp.BMPImageReaderSpi.class);
+
+             boolean ordered = reg.setOrdering(ImageReaderSpi.class, pngSpi,
+                                               gifSpi);
+
+             ordered = reg.setOrdering(ImageReaderSpi.class, gifSpi, jpgSpi);
+             ordered = reg.setOrdering(ImageReaderSpi.class, bmpSpi, gifSpi);
+             reg.deregisterServiceProvider(gifSpi);
+             System.out.println("PASS");
+
+         } catch (Exception e) {
+             System.out.println("FAIL");
+             throw new RuntimeException("Deregistering a spi object involved in some "
+                                        + "ordering throws the following exception: " + e.toString());
+         }
+     }
+
+     public static void main(String args[]) {
+         DeregisterOrderedSpiTest test = new DeregisterOrderedSpiTest();
+     }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/spi/OrderingTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4936445
+ * @summary This test verifies whether setting the order reversely between 2 spi
+ *          objects removes the previous ordering that was set between the
+ *          same set of spi objects. This is verified by invoking
+ *          unsetOrdering() method twice consecutively with respect to the same
+ *          spi objects and unsetOrdering() is supposed to return false when
+ *          called for the second time.
+ */
+
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.ServiceRegistry;
+
+public class OrderingTest {
+
+    public OrderingTest() {
+
+         ServiceRegistry reg = IIORegistry.getDefaultInstance();
+         ImageReaderSpi gifSpi = (ImageReaderSpi) reg.getServiceProviderByClass(com.sun.imageio.plugins.gif.GIFImageReaderSpi.class);
+         ImageReaderSpi pngSpi = (ImageReaderSpi) reg.getServiceProviderByClass(com.sun.imageio.plugins.png.PNGImageReaderSpi.class);
+
+         boolean ordered = reg.setOrdering(ImageReaderSpi.class, gifSpi, pngSpi);
+
+         ordered = reg.setOrdering(ImageReaderSpi.class, pngSpi, gifSpi);
+
+         boolean unordered = reg.unsetOrdering(ImageReaderSpi.class, gifSpi,
+                                               pngSpi);
+         boolean unordered1 = reg.unsetOrdering(ImageReaderSpi.class, gifSpi,
+                                                pngSpi);
+
+         if (unordered1) {
+             throw new RuntimeException("FAIL: Ordering 2 spi objects in the  "
+                                        + "reverse direction does not remove the previous ordering "
+                                        + "set between the spi objects and hence unsetOrdering() "
+                                        + "returns true for the same spi objects when called consecutively");
+         } else {
+             System.out.println("PASS");
+         }
+
+     }
+
+     public static void main(String args[]) {
+         OrderingTest test = new OrderingTest();
+     }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/spi/PluginSpiTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 6275112
+ * @summary Test verifies that imageReaders for base image formats return
+ *          meaningful name of service provider interface (SPI) for base image
+ *          formats
+ */
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageWriter;
+import javax.imageio.spi.ImageReaderSpi;
+
+public class PluginSpiTest {
+
+    public static void main(String[] args) {
+        String format[] = { "GIF", "PNG", "JPEG", "BMP", "WBMP" };
+        for (int i = 0; i < format.length; i++) {
+            System.out.println("\nFormat " + format[i]);
+            testFormat(format[i]);
+        }
+    }
+
+    public static void testFormat(String format) {
+        ImageReader reader =
+            ImageIO.getImageReadersByFormatName(format).next();
+        if (reader == null) {
+            throw new RuntimeException("Failed to get reader for " + format);
+        }
+
+        ImageReaderSpi readerSpi = reader.getOriginatingProvider();
+        System.out.println(format + " Reader SPI: " + readerSpi);
+
+        String writerSpiNames[] = readerSpi.getImageWriterSpiNames();
+        if (writerSpiNames == null || writerSpiNames.length == 0) {
+            throw new RuntimeException("Failed to get writer spi names for " +
+                                       format);
+        }
+
+        System.out.println("Available writer spi names:");
+        for (int i = 0; i < writerSpiNames.length; i++) {
+            System.out.println(writerSpiNames[i]);
+            try {
+                Class spiClass = Class.forName(writerSpiNames[i]);
+                if (spiClass == null) {
+                    throw new RuntimeException("Failed to get spi class " +
+                                               writerSpiNames[i]);
+                }
+                System.out.println("Got class " + spiClass.getName());
+
+                Object spiObject = spiClass.newInstance();
+                if (spiObject == null) {
+                    throw new RuntimeException("Failed to instantiate spi " +
+                                               writerSpiNames[i]);
+                }
+                System.out.println("Got instance " + spiObject);
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed to test spi " +
+                                           writerSpiNames[i]);
+            }
+        }
+
+        ImageWriter writer = ImageIO.getImageWriter(reader);
+        if (writer == null) {
+            throw new RuntimeException("Failed to get writer for " + format);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/spi/RegisterPluginTwiceTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4836432 8037743
+ * @summary This test attempts to register two instances of one ImageReaderSPI.
+ *          Expected behavior is that only one instance of ImageReaderSPI will
+ *          be registered.
+ */
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Locale;
+
+import javax.imageio.ImageReader;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ServiceRegistry;
+import javax.imageio.stream.ImageInputStream;
+
+public class RegisterPluginTwiceTest {
+
+    public RegisterPluginTwiceTest() throws Exception {
+        BMPImageReaderSPI BMPSpi = new BMPImageReaderSPI();
+        BMPImageReaderSPI BMPSpi1 = new BMPImageReaderSPI();
+
+        IIORegistry regis = IIORegistry.getDefaultInstance();
+        boolean res1
+            = regis.registerServiceProvider(BMPSpi,
+                                            javax.imageio.spi.ImageReaderSpi.class);
+        boolean res2
+            = regis.registerServiceProvider(BMPSpi1,
+                                            javax.imageio.spi.ImageReaderSpi.class);
+
+        if(!res1 || res2) {
+            throw new RuntimeException("Bad returned values for registerServiceProvider");
+        }
+        Iterator it = regis.getServiceProviders(Class.forName("javax.imageio.spi.ImageReaderSpi"), true);
+        int count = 0;
+        while (it.hasNext()) {
+            Object o = it.next();
+            if(o instanceof BMPImageReaderSPI) {
+                count++;
+                System.out.println("Found next BMPImageReaderSPI, count = " +count);
+            }
+        }
+        if(count > 1) {
+            throw new RuntimeException("Too many instances of the BMPImageReaderSPI was registered!");
+        }
+    }
+
+    public static void main(String args[]) throws Exception{
+        RegisterPluginTwiceTest fnio = new RegisterPluginTwiceTest();
+    }
+
+
+ /**
+  Not a perfect implementation of SPI. This is just a dummy implementation
+  which denotes some arbitrary reader class. The intention is to check how this
+  is getting registered in the registry. Hence some of the values in this class
+  may be inappropriate..
+ */
+    public static class BMPImageReaderSPI extends javax.imageio.spi.ImageReaderSpi{
+
+        private static final String vendorName = "Javasoft";
+
+        private static final String version = "2.0";
+
+        private static final String[] names = { "bmp" };
+
+        private static final String[] suffixes = { "bmp" };
+
+        private static final String[] MIMETypes = { "image/x-bmp"};
+
+        private static final String readerClassName =
+        "com.sun.imageio.plugins.png.PNGImageReader";
+
+        private static final String[] writerSpiNames = {
+            "com.sun.imageio.plugins.png.PNGImageWriterSpi"
+        };
+
+        public BMPImageReaderSPI() {
+            super(vendorName,
+                  version,
+                  names,
+                  suffixes,
+                  MIMETypes,
+                  readerClassName,
+                  STANDARD_INPUT_TYPE,
+                  writerSpiNames,
+                  false,
+                  null, null,
+                  null, null,
+                  true,
+                  "BMP Native Metadata",
+                  "com.sun.imageio.plugins.png.PNGMetadataFormat",
+                  null, null
+                  );
+        }
+
+        public String getDescription(Locale locale) {
+            return "Standard BMP image reader";
+        }
+
+        public boolean canDecodeInput(Object input) throws IOException {
+            if (!(input instanceof ImageInputStream)) {
+                return false;
+            }
+
+            ImageInputStream stream = (ImageInputStream)input;
+            byte[] b = new byte[8];
+            stream.mark();
+            stream.readFully(b);
+            stream.reset();
+
+            return (b[0] == (byte)137 &&
+                    b[1] == (byte)80 &&
+                    b[2] == (byte)78 &&
+                    b[3] == (byte)71 &&
+                    b[4] == (byte)13 &&
+                    b[5] == (byte)10 &&
+                    b[6] == (byte)26 &&
+                    b[7] == (byte)10);
+        }
+
+        public ImageReader createReaderInstance(Object extension) {
+            //return new PNGImageReader(this);
+            return null;
+        }
+        public void onRegistration(ServiceRegistry sr, Class<?> category) {
+            //System.out.println("Registered "+category);
+            super.onRegistration(sr, category);
+        }
+
+        public void onDeregistration(ServiceRegistry sr, Class<?> category) {
+            //System.out.println("De-Registered "+category);
+            //super.onRegistration(sr, category);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/spi/SpiTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4395376
+ * @summary Performs various sanity checks on Spi class constructors and get
+ *          methods
+ */
+
+import java.util.Iterator;
+import java.util.Locale;
+
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriter;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.IIOServiceProvider;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.ImageReaderWriterSpi;
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.spi.ServiceRegistry;
+
+public class SpiTest {
+
+    String vendorName = null;
+    String version = null;
+    String[] names = null;
+    String[] suffixes = null;
+    String[] MIMETypes = null;
+    String readerClassName = null;
+    String writerClassName = null;
+    Class[] inputTypes = null;
+    Class[] outputTypes = null;
+    String[] writerSpiNames = null;
+    String[] readerSpiNames = null;
+    String nativeStreamMetadataFormatName = null;
+    String nativeStreamMetadataFormatClassName = null;
+    String[] extraStreamMetadataFormatNames = null;
+    String[] extraStreamMetadataFormatClassNames = null;
+    String nativeImageMetadataFormatName = null;
+    String nativeImageMetadataFormatClassName = null;
+    String[] extraImageMetadataFormatNames = null;
+    String[] extraImageMetadataFormatClassNames = null;
+
+    private void error(String message) {
+        // System.out.println("Error: " + message);
+        throw new RuntimeException(message);
+    }
+
+    private void testSpi(IIOServiceProvider spi) {
+        if (spi.getVendorName() == null) {
+            error(spi + " getVendorName == null!");
+        }
+        if (spi.getVersion() == null) {
+            error(spi + " getVersion == null!");
+        }
+    }
+
+    private void testSpi(ImageReaderWriterSpi spi) {
+        testSpi((IIOServiceProvider)spi);
+        if (spi.getFormatNames() == null) {
+            error("spi.getFormatNames == null!");
+        }
+        String[] suffixes = spi.getFileSuffixes();
+        if (suffixes != null && suffixes.length == 0) {
+            error("suffixes.length == 0!");
+        }
+        String[] MIMETypes = spi.getMIMETypes();
+        if (MIMETypes != null && MIMETypes.length == 0) {
+            error("MIMETypes.length == 0!");
+        }
+        if (spi.getPluginClassName() == null) {
+            error("spi.getPluginClassName == null!");
+        }
+        String[] extraStreamMetadataFormatNames =
+            spi.getExtraStreamMetadataFormatNames();
+        if (extraStreamMetadataFormatNames != null &&
+            extraStreamMetadataFormatNames.length == 0) {
+            error("extraStreamMetadataFormatNames.length == 0!");
+        }
+        String[] extraImageMetadataFormatNames =
+            spi.getExtraImageMetadataFormatNames();
+        if (extraImageMetadataFormatNames != null &&
+            extraImageMetadataFormatNames.length == 0) {
+            error("extraImageMetadataFormatNames.length == 0!");
+        }
+    }
+
+    public void testSpi(ImageReaderSpi spi) {
+        testSpi((ImageReaderWriterSpi)spi);
+        Class[] inputTypes = spi.getInputTypes();
+        if (inputTypes == null) {
+            error("inputTypes == null!");
+        }
+        if (inputTypes.length == 0) {
+            error("inputTypes.length == 0!");
+        }
+        String[] writerSpiNames = spi.getImageWriterSpiNames();
+        if (writerSpiNames != null && writerSpiNames.length == 0) {
+            error("writerSpiNames.length == 0!");
+        }
+    }
+
+    public void testSpi(ImageWriterSpi spi) {
+        testSpi((ImageReaderWriterSpi)spi);
+        Class[] outputTypes = spi.getOutputTypes();
+        if (outputTypes == null) {
+            error("outputTypes == null!");
+        }
+        if (outputTypes.length == 0) {
+            error("outputTypes.length == 0!");
+        }
+        String[] readerSpiNames = spi.getImageReaderSpiNames();
+        if (readerSpiNames != null && readerSpiNames.length == 0) {
+            error("readerSpiNames.length == 0!");
+        }
+    }
+
+    private void resetConstructorArguments() {
+        vendorName = null;
+        version = null;
+        names = null;
+        suffixes = null;
+        MIMETypes = null;
+        readerClassName = null;
+        inputTypes = null;
+        outputTypes = null;
+        writerSpiNames = null;
+        readerSpiNames = null;
+        nativeStreamMetadataFormatName = null;
+        nativeStreamMetadataFormatClassName = null;
+        extraStreamMetadataFormatNames = null;
+        extraStreamMetadataFormatClassNames = null;
+        nativeImageMetadataFormatName = null;
+        nativeImageMetadataFormatClassName = null;
+        extraImageMetadataFormatNames = null;
+        extraImageMetadataFormatClassNames = null;
+    }
+
+    private ImageReaderSpi constructImageReaderSpi() {
+        return new ImageReaderSpi(vendorName,
+                                  version,
+                                  names,
+                                  suffixes,
+                                  MIMETypes,
+                                  readerClassName,
+                                  inputTypes,
+                                  writerSpiNames,
+                                  false,
+                                  nativeStreamMetadataFormatName,
+                                  nativeStreamMetadataFormatClassName,
+                                  extraStreamMetadataFormatNames,
+                                  extraStreamMetadataFormatClassNames,
+                                  false,
+                                  nativeImageMetadataFormatName,
+                                  nativeImageMetadataFormatClassName,
+                                  extraImageMetadataFormatNames,
+                                  extraImageMetadataFormatClassNames) {
+
+                public String getDescription(Locale locale) {
+                    return null;
+                }
+
+                public boolean canDecodeInput(Object source) {
+                    return false;
+                }
+
+                public ImageReader createReaderInstance(Object extension) {
+                    return null;
+                }
+         };
+    }
+
+    private ImageWriterSpi constructImageWriterSpi() {
+        return new ImageWriterSpi(vendorName,
+                                  version,
+                                  names,
+                                  suffixes,
+                                  MIMETypes,
+                                  writerClassName,
+                                  outputTypes,
+                                  readerSpiNames,
+                                  false,
+                                  nativeStreamMetadataFormatName,
+                                  nativeStreamMetadataFormatClassName,
+                                  extraStreamMetadataFormatNames,
+                                  extraStreamMetadataFormatClassNames,
+                                  false,
+                                  nativeImageMetadataFormatName,
+                                  nativeImageMetadataFormatClassName,
+                                  extraImageMetadataFormatNames,
+                                  extraImageMetadataFormatClassNames) {
+
+                public String getDescription(Locale locale) {
+                    return null;
+                }
+
+                public boolean canEncodeImage(ImageTypeSpecifier type) {
+                    return false;
+                }
+
+                public ImageWriter createWriterInstance(Object extension) {
+                    return null;
+                }
+         };
+    }
+
+    private void checkImageReaderSpiConstructor(boolean shouldFail) {
+        boolean gotIAE = false;
+        try {
+            constructImageReaderSpi();
+        } catch (Exception e) {
+            if (!(e instanceof IllegalArgumentException)) {
+                error("Got exception " + e);
+            } else {
+                gotIAE = true;
+            }
+        }
+        if (gotIAE != shouldFail) {
+            if (gotIAE) {
+                error("ImageReaderSpi constructor threw an IAE!");
+            } else {
+                error("ImageReaderSpi constructor didn't throw an IAE!");
+            }
+        }
+    }
+
+    private void checkImageWriterSpiConstructor(boolean shouldFail) {
+        boolean gotIAE = false;
+        try {
+            constructImageWriterSpi();
+        } catch (Exception e) {
+            if (!(e instanceof IllegalArgumentException)) {
+                error("Got exception " + e);
+            } else {
+                gotIAE = true;
+            }
+        }
+        if (gotIAE != shouldFail) {
+            if (gotIAE) {
+                error("ImageWriterSpi constructor threw an IAE!");
+            } else {
+                error("ImageWriterSpi constructor didn't throw an IAE!");
+            }
+        }
+    }
+
+    public void testImageReaderSpiConstructor() {
+        resetConstructorArguments();
+
+        checkImageReaderSpiConstructor(true);
+        vendorName = "My Vendor";
+        checkImageReaderSpiConstructor(true);
+        version = "My Version";
+        checkImageReaderSpiConstructor(true);
+        names = new String[0];
+        checkImageReaderSpiConstructor(true);
+        names = new String[1];
+        names[0] = "My Format Name";
+        checkImageReaderSpiConstructor(true);
+        readerClassName = "com.mycompany.Reader";
+        checkImageReaderSpiConstructor(true);
+        inputTypes = new Class[0];
+        checkImageReaderSpiConstructor(true);
+        inputTypes = new Class[1];
+        inputTypes[0] = Object.class;
+        // Now it should work
+        checkImageReaderSpiConstructor(false);
+
+        // Test normalization of zero-length arrays
+        suffixes = new String[0];
+        MIMETypes = new String[0];
+        writerSpiNames = new String[0];
+        extraStreamMetadataFormatNames = new String[0];
+        extraImageMetadataFormatNames = new String[0];
+
+        ImageReaderSpi spi = constructImageReaderSpi();
+        if (spi.getFileSuffixes() != null) {
+            error("Failed to normalize suffixes!");
+        }
+        if (spi.getMIMETypes() != null) {
+            error("Failed to normalize MIMETypes!");
+        }
+        if (spi.getImageWriterSpiNames() != null) {
+            error("Failed to normalize writerSpiNames!");
+        }
+        if (spi.getExtraStreamMetadataFormatNames() != null) {
+            error("Failed to normalize extraStreamMetadataFormatNames!");
+        }
+        if (spi.getExtraImageMetadataFormatNames() != null) {
+            error("Failed to normalize extraImageMetadataFormatNames!");
+        }
+    }
+
+    public void testImageWriterSpiConstructor() {
+        resetConstructorArguments();
+
+        checkImageWriterSpiConstructor(true);
+        vendorName = "My Vendor";
+        checkImageWriterSpiConstructor(true);
+        version = "My Version";
+        checkImageWriterSpiConstructor(true);
+        names = new String[0];
+        checkImageWriterSpiConstructor(true);
+        names = new String[1];
+        names[0] = "My Format Name";
+        checkImageWriterSpiConstructor(true);
+        writerClassName = "com.mycompany.Writer";
+        checkImageWriterSpiConstructor(true);
+        outputTypes = new Class[0];
+        checkImageWriterSpiConstructor(true);
+        outputTypes = new Class[1];
+        outputTypes[0] = Object.class;
+        // Now it should work
+        checkImageWriterSpiConstructor(false);
+
+        // Test normalization of zero-length arrays
+        suffixes = new String[0];
+        MIMETypes = new String[0];
+        readerSpiNames = new String[0];
+        extraStreamMetadataFormatNames = new String[0];
+        extraStreamMetadataFormatClassNames = new String[0];
+        extraImageMetadataFormatNames = new String[0];
+        extraImageMetadataFormatClassNames = new String[0];
+
+        ImageWriterSpi spi = constructImageWriterSpi();
+        if (spi.getFileSuffixes() != null) {
+            error("Failed to normalize suffixes!");
+        }
+        if (spi.getMIMETypes() != null) {
+            error("Failed to normalize MIMETypes!");
+        }
+        if (spi.getImageReaderSpiNames() != null) {
+            error("Failed to normalize readerSpiNames!");
+        }
+        if (spi.getExtraStreamMetadataFormatNames() != null) {
+            error("Failed to normalize extraStreamMetadataFormatNames!");
+        }
+        if (spi.getExtraImageMetadataFormatNames() != null) {
+            error("Failed to normalize extraImageMetadataFormatNames!");
+        }
+    }
+
+    public SpiTest() {
+        testImageReaderSpiConstructor();
+        testImageWriterSpiConstructor();
+
+        ServiceRegistry registry = IIORegistry.getDefaultInstance();
+        Iterator readers = registry.getServiceProviders(ImageReaderSpi.class,
+                                                        false);
+        while (readers.hasNext()) {
+            ImageReaderSpi rspi = (ImageReaderSpi)readers.next();
+            System.out.println("*** Testing " + rspi.getClass().getName());
+            testSpi(rspi);
+        }
+
+        Iterator writers = registry.getServiceProviders(ImageWriterSpi.class,
+                                                        false);
+        while (writers.hasNext()) {
+            ImageWriterSpi wspi = (ImageWriterSpi)writers.next();
+            System.out.println("*** Testing " + wspi.getClass().getName());
+            testSpi(wspi);
+        }
+    }
+
+    public static void main(String[] args) {
+        new SpiTest();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/spi/SpiVersionNumbers.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4415450
+ * @summary Checks the version number for the standard stream Spis
+ */
+
+import javax.imageio.spi.IIOServiceProvider;
+
+import com.sun.imageio.spi.FileImageInputStreamSpi;
+import com.sun.imageio.spi.FileImageOutputStreamSpi;
+import com.sun.imageio.spi.InputStreamImageInputStreamSpi;
+import com.sun.imageio.spi.OutputStreamImageOutputStreamSpi;
+import com.sun.imageio.spi.RAFImageInputStreamSpi;
+import com.sun.imageio.spi.RAFImageOutputStreamSpi;
+
+public class SpiVersionNumbers {
+
+    private static void check(IIOServiceProvider spi) {
+        String version = spi.getVersion();
+        if (!version.equals("1.0")) {
+            throw new RuntimeException("Provider " +
+                                       spi.getClass().getName() +
+                                       " has version " + version + "!");
+        }
+    }
+
+    public static void main(String[] args) {
+        check(new FileImageInputStreamSpi());
+        check(new InputStreamImageInputStreamSpi());
+        check(new RAFImageInputStreamSpi());
+
+        check(new FileImageOutputStreamSpi());
+        check(new OutputStreamImageOutputStreamSpi());
+        check(new RAFImageOutputStreamSpi());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/stream/BitPadding.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4430395
+ * @summary Checks if write(int) properly pads unwritten bits with zeros
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.imageio.stream.FileCacheImageOutputStream;
+
+public class BitPadding {
+
+    public static void main(String[] args) throws IOException {
+        OutputStream ostream = new ByteArrayOutputStream();
+        File f = null;
+        FileCacheImageOutputStream fcios =
+            new FileCacheImageOutputStream(ostream, f);
+        fcios.writeBit(1);
+        fcios.write(96);
+
+        fcios.seek(0);
+        int r1 = fcios.read();
+        if (r1 != 128 ) {
+            throw new RuntimeException("Failed, first byte is " + r1);
+        }
+
+        int r2 = fcios.read();
+        if (r2 != 96) {
+            throw new RuntimeException("Failed, second byte is " + r2);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/stream/DeleteOnExitTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+
+public class DeleteOnExitTest {
+    public static void main(String[] args) throws IOException {
+        ByteArrayInputStream is =
+            new ByteArrayInputStream(new byte[100]);
+        ByteArrayOutputStream os =
+            new ByteArrayOutputStream();
+
+        String tmp = System.getProperty("java.io.tmpdir", ".");
+        System.out.println("tmp: " + tmp);
+
+        // count number of files before test
+        ImageIO.setUseCache(true);
+        ImageIO.setCacheDirectory(new File(tmp));
+
+        File tmpDir = ImageIO.getCacheDirectory();
+        System.out.println("tmpDir is " + tmpDir);
+        int fnum_before = tmpDir.list().length;
+        System.out.println("Files before test: " + fnum_before);
+
+        ImageInputStream iis =
+            ImageIO.createImageInputStream(is);
+        System.out.println("iis = " + iis);
+
+        ImageInputStream iis2 =
+            ImageIO.createImageInputStream(is);
+
+        ImageOutputStream ios =
+            ImageIO.createImageOutputStream(os);
+        System.out.println("ios = " + ios);
+
+        ImageOutputStream ios2 =
+            ImageIO.createImageOutputStream(os);
+
+        iis2.close();
+        ios2.close();
+        int fnum_after = tmpDir.list().length;
+        System.out.println("Files after test: " + fnum_after);
+
+        if (fnum_before == fnum_after) {
+            throw new RuntimeException("Test failed: cache was not used.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/stream/DeleteOnExitTest.sh	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,69 @@
+# Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+# 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 6291034
+# @run shell DeleteOnExitTest.sh
+# @summary Verify that temporary imageio files files are deleted on VM exit.
+
+if [ -z "${TESTSRC}" ]; then
+  echo "TESTSRC undefined: defaulting to ."
+  TESTSRC=.
+fi
+
+if [ -z "${TESTCLASSES}" ]; then
+  echo "TESTCLASSES undefined: defaulting to ."
+  TESTCLASSES=.
+fi
+
+if [ -z "${TESTJAVA}" ]; then
+  echo "TESTJAVA undefined: can't continue."
+  exit 1
+fi
+
+echo "TESTJAVA=${TESTJAVA}"
+echo "TESTSRC=${TESTSRC}"
+echo "TESTCLASSES=${TESTCLASSES}"
+cd ${TESTSRC}
+${COMPILEJAVA}/bin/javac -d ${TESTCLASSES} DeleteOnExitTest.java
+
+cd ${TESTCLASSES}
+
+numfiles0=`ls ${TESTCLASSES} | grep "imageio*.tmp" | wc -l`
+
+${TESTJAVA}/bin/java ${TESTVMOPTS} \
+    -Djava.io.tmpdir=${TESTCLASSES} DeleteOnExitTest
+
+if [ $? -ne 0 ]
+    then
+      echo "Test fails: exception thrown!"
+      exit 1
+fi
+
+numfiles1=`ls ${TESTCLASSES} | grep "imageio*.tmp" | wc -l`
+
+if [ $numfiles0 -ne $numfiles1 ]
+    then
+      echo "Test fails: tmp file exists!"
+      exit 1
+fi
+echo "Test passed."
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/stream/FileCacheImageInputStreamNullTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4428802
+ * @summary Checks for IAE from FileCacheImageInputStream constructor with a
+ *          null value for 'stream'
+ */
+
+import javax.imageio.stream.FileCacheImageInputStream;
+
+public class FileCacheImageInputStreamNullTest {
+
+    public static void main (String[] args) throws Exception {
+        boolean gotIAE = false;
+        try {
+            FileCacheImageInputStream fciis =
+                new FileCacheImageInputStream(null, null);
+        } catch (IllegalArgumentException e) {
+            gotIAE = true;
+        }
+
+        if (!gotIAE) {
+            throw new RuntimeException
+                ("Failed to get IllegalArgumentException!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/stream/FlushBefore.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4431503
+ * @summary Checks if flushBefore(pos) throws an IndexOutOfBoundsException if
+ *          pos lies in the flushed portion of the stream
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.imageio.stream.FileCacheImageOutputStream;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.stream.MemoryCacheImageOutputStream;
+
+public class FlushBefore {
+
+    public static void main(String[] args) throws IOException {
+        OutputStream ostream = new ByteArrayOutputStream();
+
+        FileCacheImageOutputStream fcios =
+            new FileCacheImageOutputStream(ostream, null);
+        test(fcios);
+
+        MemoryCacheImageOutputStream mcios =
+            new MemoryCacheImageOutputStream(ostream);
+        test(mcios);
+    }
+
+    private static void test(ImageOutputStream ios) throws IOException {
+        try {
+            ios.write(new byte[10], 0, 10);
+            ios.flushBefore(5);
+            ios.flushBefore(4);
+
+            throw new RuntimeException
+                ("Failed to get IndexOutOfBoundsException!");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/stream/MemoryCacheImageOutputStreamTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4417672 4422328
+ * @summary Checks the functionality of MemoryCacheImageOutputStream
+ *          particularly with regard to seeking and flushing
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.stream.MemoryCacheImageOutputStream;
+
+public class MemoryCacheImageOutputStreamTest {
+
+    public static void main(String[] args) throws IOException {
+        try {
+            MemoryCacheImageOutputStream stream =
+                new MemoryCacheImageOutputStream(new ByteArrayOutputStream());
+            stream.write(0);  // or write anything, for that matter
+            stream.flush();
+        } catch (Exception e) {
+            throw new RuntimeException("Error flushing stream: " + e);
+        }
+
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        ImageOutputStream ios = new MemoryCacheImageOutputStream(os);
+
+        byte[] b = new byte[30*256];
+        byte byteVal = (byte)0;
+        for (int i = 0; i < b.length; i++) {
+            b[i] = byteVal++;
+        }
+
+        // Write 261,120 bytes
+        for (int i = 0; i < 34; i++) {
+            ios.write(b);
+        }
+        // Scatter 256 values at positions 1000, 2000, ...
+        // Using both write(int) and write(byte[])
+        byte[] buf = new byte[1];
+        for (int i = 0; i < 256; i += 2) {
+            ios.seek(1000*i);
+            ios.write(i);
+
+            ios.seek(1000*(i + 1));
+            buf[0] = (byte)(i + 1);
+            ios.write(buf);
+        }
+
+        // Re-read scattered values
+        for (int i = 0; i < 256; i++) {
+            ios.seek(1000*i);
+            int val = ios.read();
+            if (val != i) {
+                System.out.println("Got bad value (1) at pos = " + (1000*i));
+            }
+        }
+
+        // Discard two buffers and re-read scattered values
+        ios.flushBefore(2*8192);
+
+        for (int i = 0; i < 256; i++) {
+            long pos = 1000*i;
+            if (pos >= 2*8192) {
+                ios.seek(pos);
+                int val = ios.read();
+                if (val != i) {
+                    System.out.println("Got bad value (2) at pos = " + (1000*i));
+                }
+            }
+        }
+        ios.close();
+
+        byte[] data = os.toByteArray();
+        for (int i = 0; i < data.length; i++) {
+            byte val = data[i];
+            if ((i < 256000) && (i % 1000) == 0) {
+                if (val != (byte)(i/1000)) {
+                    System.out.println("Got bad value (3) at pos = " + i);
+                }
+            } else {
+                byte gval = (byte)((i % (30*256)) % 256);
+                if (val != gval) {
+                    System.out.println("Got bad value (4) at pos = " + i +
+                                       "(got " + (val & 0xff) +
+                                       " wanted " + (gval & 0xff) +")");
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/stream/ReadBytesIIOByteBuffer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4446906
+ * @summary Checks if ImageInputStreamImpl.readBytes(IIOByteBuffer) tests for
+ *          len < 0
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import javax.imageio.stream.IIOByteBuffer;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
+
+public class ReadBytesIIOByteBuffer {
+
+    public static void main(String[] argv) {
+        byte[] bar = {1, 1, 1};
+        InputStream is = new ByteArrayInputStream(bar);
+
+        ImageInputStream iis = new MemoryCacheImageInputStream(is);
+        byte[] b = new byte[10];
+        IIOByteBuffer iiob = new IIOByteBuffer(b, 0, b.length);
+        try {
+            iis.readBytes(iiob, -1);
+        } catch (IndexOutOfBoundsException e) {
+            return;
+        } catch (Exception e) {
+            throw new RuntimeException("Unexpected exception: " + e);
+        }
+        throw new RuntimeException("No exception thrown for len < 0!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/stream/ReadFullyTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4422263
+ * @summary Checks that ImageInputStream.readFully(type[], int int) handles sign
+ *          extension and byte ordering correctly
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.ByteOrder;
+
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
+
+public class ReadFullyTest {
+
+    static final ByteOrder bigEndian = ByteOrder.BIG_ENDIAN;
+    static final ByteOrder littleEndian = ByteOrder.LITTLE_ENDIAN;
+
+    private static void expect(long e, long g) {
+        if (e != g) {
+            throw new RuntimeException("Expected " + e + ", got " + g);
+        }
+    }
+
+    public static void main (String args[]) {
+        try {
+            byte[] b = {
+                (byte)0x11, (byte)0x22, // low low
+                (byte)0x44, (byte)0x99, // low high
+                (byte)0xAA, (byte)0x33, // high low
+                (byte)0xBB, (byte)0xCC  // high high
+            };
+            InputStream in = new ByteArrayInputStream(b);
+            ImageInputStream iin = new MemoryCacheImageInputStream(in);
+
+            short[] s = new short[b.length/2];
+            char[] c = new char[b.length/2];
+            int[] i = new int[b.length/4];
+            long[] l = new long[b.length/8];
+            float[] f = new float[b.length/4];
+            double[] d = new double[b.length/8];
+
+            iin.seek(0L);
+            iin.setByteOrder(bigEndian);
+            iin.readFully(s, 0, s.length);
+            expect(s[0] & 0xffff, 0x1122);
+            expect(s[1] & 0xffff, 0x4499);
+            expect(s[2] & 0xffff, 0xAA33);
+            expect(s[3] & 0xffff, 0xBBCC);
+
+            iin.seek(0L);
+            iin.setByteOrder(littleEndian);
+            iin.readFully(s, 0, s.length);
+            expect(s[0] & 0xffff, 0x2211);
+            expect(s[1] & 0xffff, 0x9944);
+            expect(s[2] & 0xffff, 0x33AA);
+            expect(s[3] & 0xffff, 0xCCBB);
+
+            iin.seek(0L);
+            iin.setByteOrder(bigEndian);
+            iin.readFully(c, 0, c.length);
+            expect(c[0], 0x1122);
+            expect(c[1], 0x4499);
+            expect(c[2], 0xAA33);
+            expect(c[3], 0xBBCC);
+
+            iin.seek(0L);
+            iin.setByteOrder(littleEndian);
+            iin.readFully(c, 0, c.length);
+            expect(c[0], 0x2211);
+            expect(c[1], 0x9944);
+            expect(c[2], 0x33AA);
+            expect(c[3], 0xCCBB);
+
+            iin.seek(0L);
+            iin.setByteOrder(bigEndian);
+            iin.readFully(i, 0, i.length);
+            expect(i[0] & 0xffffffff, 0x11224499);
+            expect(i[1] & 0xffffffff, 0xAA33BBCC);
+
+            iin.seek(0L);
+            iin.setByteOrder(littleEndian);
+            iin.readFully(i, 0, i.length);
+            expect(i[0] & 0xffffffff, 0x99442211);
+            expect(i[1] & 0xffffffff, 0xCCBB33AA);
+
+            iin.seek(0L);
+            iin.setByteOrder(bigEndian);
+            iin.readFully(f, 0, f.length);
+            expect(Float.floatToIntBits(f[0]) & 0xffffffff, 0x11224499);
+            expect(Float.floatToIntBits(f[1]) & 0xffffffff, 0xAA33BBCC);
+
+            iin.seek(0L);
+            iin.setByteOrder(littleEndian);
+            iin.readFully(f, 0, f.length);
+            expect(Float.floatToIntBits(f[0]) & 0xffffffff, 0x99442211);
+            expect(Float.floatToIntBits(f[1]) & 0xffffffff, 0xCCBB33AA);
+
+            iin.seek(0L);
+            iin.setByteOrder(bigEndian);
+            iin.readFully(l, 0, l.length);
+            expect(l[0], 0x11224499AA33BBCCL);
+
+            iin.seek(0L);
+            iin.setByteOrder(littleEndian);
+            iin.readFully(l, 0, l.length);
+            expect(l[0], 0xCCBB33AA99442211L);
+
+            iin.seek(0L);
+            iin.setByteOrder(bigEndian);
+            iin.readFully(d, 0, d.length);
+            expect(Double.doubleToLongBits(d[0]), 0x11224499AA33BBCCL);
+
+            iin.seek(0L);
+            iin.setByteOrder(littleEndian);
+            iin.readFully(d, 0, d.length);
+            expect(Double.doubleToLongBits(d[0]), 0xCCBB33AA99442211L);
+        } catch (Exception ex) {
+            throw new RuntimeException("Got exception " + ex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/stream/ReadUnsignedIntTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4949609
+ * @summary Tests that the readUnsignedInt returns the positive value
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.stream.ImageInputStream;
+
+public class ReadUnsignedIntTest {
+
+    public static void main(String[] args) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream dos = new DataOutputStream(baos);
+
+        dos.writeInt(1);
+        dos.writeInt(0x7fffffff);
+        dos.writeInt(0x8fffffff);
+        dos.writeInt(0xffffffff);
+
+        dos.close();
+
+        ByteArrayInputStream bais =
+            new ByteArrayInputStream(baos.toByteArray());
+        ImageInputStream iis = ImageIO.createImageInputStream(bais);
+        for (int i=0; i<4; i++) {
+            long res = iis.readUnsignedInt();
+            if (res <= 0) {
+                throw new RuntimeException("Negative number was read: "+
+                                           Long.toString(res, 16));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/stream/StreamFlush.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4414990 4415041
+ * @summary Checks that the output is flushed properly when using various
+ *          ImageOutputStreams and writers
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.stream.ImageOutputStream;
+
+public class StreamFlush {
+
+    public static void main(String[] args) throws IOException {
+        ImageIO.setUseCache(true);
+
+        // Create a FileImageOutputStream from a FileOutputStream
+        File temp1 = File.createTempFile("imageio", ".tmp");
+        temp1.deleteOnExit();
+        ImageOutputStream fios = ImageIO.createImageOutputStream(temp1);
+
+        // Create a FileCacheImageOutputStream from a BufferedOutputStream
+        File temp2 = File.createTempFile("imageio", ".tmp");
+        temp2.deleteOnExit();
+        FileOutputStream fos2 = new FileOutputStream(temp2);
+        BufferedOutputStream bos = new BufferedOutputStream(fos2);
+        ImageOutputStream fcios1 = ImageIO.createImageOutputStream(bos);
+
+        // Create a FileCacheImageOutputStream from a ByteArrayOutputStream
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageOutputStream fcios2 = ImageIO.createImageOutputStream(baos);
+
+        BufferedImage bi =
+            new BufferedImage(10, 10, BufferedImage.TYPE_3BYTE_BGR);
+
+        ImageIO.write(bi, "jpg", fios); // No bug, check it anyway
+        ImageIO.write(bi, "png", fcios1); // Bug 4414990
+        ImageIO.write(bi, "jpg", fcios2); // Bug 4415041
+
+        // It should not be necessary to flush any of the streams
+        // If flushing does make a difference, it indicates a bug
+        // in the writer or the stream implementation
+
+        // Get length of temp1 before and after flushing
+        long file1NoFlushLength = temp1.length();
+        fios.flush();
+        long file1FlushLength = temp1.length();
+
+        // Get length of temp2 before and after flushing
+        long file2NoFlushLength = temp2.length();
+        fcios1.flush();
+        bos.flush();
+        long file2FlushLength = temp2.length();
+
+        byte[] b0 = baos.toByteArray();
+        int cacheNoFlushLength = b0.length;
+        fcios2.flush();
+        byte[] b1 = baos.toByteArray();
+        int cacheFlushLength = b1.length;
+
+        if (file1NoFlushLength != file1FlushLength) {
+            // throw new RuntimeException
+            System.out.println
+                ("FileImageOutputStream not flushed!");
+        }
+
+        if (file2NoFlushLength != file2FlushLength) {
+            // throw new RuntimeException
+            System.out.println
+             ("FileCacheImageOutputStream/BufferedOutputStream not flushed!");
+        }
+
+        if (cacheNoFlushLength != cacheFlushLength) {
+            // throw new RuntimeException
+            System.out.println
+            ("FileCacheImageOutputStream/ByteArrayOutputStream not flushed!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/imageio/stream/WriteBitsTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4507868
+ * @summary Checks that ImageOutputStreamImpl.writeBits() advances the stream
+ *          position and bit offset correctly. Also verifies that the
+ *          MemoryCacheImageOutputStream.read() variants reset the bitOffset
+ *          before the read actually occurs.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.stream.MemoryCacheImageOutputStream;
+
+public class WriteBitsTest {
+
+    private static void verify(ImageOutputStream ios,
+                               long expstreampos, int expbitoffset)
+        throws IOException, RuntimeException
+    {
+        long actstreampos = ios.getStreamPosition();
+        int actbitoffset = ios.getBitOffset();
+
+        if ((actstreampos != expstreampos) ||
+            (actbitoffset != expbitoffset))
+        {
+            System.err.println("Expected stream position: " + expstreampos +
+                               " Actual: " + actstreampos);
+            System.err.println("Expected bit offset: " + expbitoffset +
+                               " Actual: " + actbitoffset);
+            throw new RuntimeException("Test failed.");
+        }
+    }
+
+    public static void main(String argv[]) throws RuntimeException {
+        ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+        MemoryCacheImageOutputStream mcios = new
+            MemoryCacheImageOutputStream(ostream);
+
+        try {
+            // verify correct writeBits() functionality
+            long streampos = 0;
+            int bitoffset = 0;
+
+            mcios.setBitOffset(bitoffset);
+            verify(mcios, streampos, bitoffset);
+
+            bitoffset = 3;
+            mcios.setBitOffset(bitoffset);
+            verify(mcios, streampos, bitoffset);
+
+            for (int incr = 3; incr <= 15; incr += 12) {
+                for (int i = 0; i < 64; i += incr) {
+                    mcios.writeBits(10, incr);
+
+                    bitoffset += incr;
+
+                    if (bitoffset > 7) {
+                        int stroffset = bitoffset / 8;
+                        bitoffset = bitoffset % 8;
+                        streampos += stroffset;
+                    }
+
+                    verify(mcios, streampos, bitoffset);
+                }
+            }
+
+            // verify correct read(byte[], int, int) functionality
+            byte[] bytearr = new byte[2];
+            mcios.seek(2);
+            mcios.setBitOffset(3);
+            int numread = mcios.read(bytearr, 0, 2);
+            if (numread != 2) {
+                throw new RuntimeException("Error in mcios.read([BII)I");
+            }
+            verify(mcios, 4, 0);
+
+            // verify correct read() functionality
+            mcios.setBitOffset(3);
+            mcios.read();
+            verify(mcios, 5, 0);
+        } catch (IOException e) {
+            throw new RuntimeException("Unexpected IOException: " + e);
+        }
+    }
+}
--- a/test/javax/management/loading/ParserInfiniteLoopTest.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/javax/management/loading/ParserInfiniteLoopTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -31,9 +31,9 @@
  * @author Luis-Miguel Alventosa
  * @run clean ParserInfiniteLoopTest
  * @run build ParserInfiniteLoopTest
- * @run main/othervm/timeout=5 ParserInfiniteLoopTest mlet1.html
- * @run main/othervm/timeout=5 ParserInfiniteLoopTest mlet2.html
- * @run main/othervm/timeout=5 ParserInfiniteLoopTest mlet3.html
+ * @run main/othervm ParserInfiniteLoopTest mlet1.html
+ * @run main/othervm ParserInfiniteLoopTest mlet2.html
+ * @run main/othervm ParserInfiniteLoopTest mlet3.html
  */
 
 import java.io.File;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Devices/ClosedReceiver.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Synthesizer;
+
+/**
+ * @test
+ * @bug 4616517
+ * @summary Receiver.send() does not work properly
+ */
+public class ClosedReceiver {
+
+    public static void main(String[] args) throws Exception {
+        out("#4616517: Receiver.send() does not work properly");
+        if (!isMidiInstalled()) {
+            out("Soundcard does not exist or sound drivers not installed!");
+            out("This test requires sound drivers for execution.");
+            return;
+        }
+
+        boolean passed = true;
+
+        passed &= testReceiverSend();
+        passed &= testClosedReceivers();
+        if (passed) {
+            out("Test PASSED.");
+        } else {
+            throw new Exception("Test FAILED.");
+        }
+    }
+
+    /**
+     * Execute Receiver.send() and expect that there is no exception.
+     */
+    private static boolean testReceiverSend() {
+        boolean result = true;
+
+        Receiver receiver;
+        ShortMessage shMsg = new ShortMessage();
+
+        try {
+            receiver = MidiSystem.getReceiver();
+            shMsg.setMessage(ShortMessage.NOTE_ON, 0,60, 93);
+            try {
+                receiver.send( shMsg, -1 );
+            } catch(IllegalStateException ilEx) {
+                ilEx.printStackTrace(System.out);
+                out("IllegalStateException was thrown incorrectly!");
+                result = false;
+            }
+            receiver.close();
+        } catch(MidiUnavailableException e) {
+            out("Midi unavailable, cannot test.");
+        } catch(InvalidMidiDataException ine) {
+            out("InvalidMidiDataException, cannot test.");
+        }
+        return result;
+    }
+
+    private static boolean testClosedReceivers() {
+        boolean result = true;
+        Receiver receiver;
+        Synthesizer synt = null;
+
+        // test Synthesizer's Receiver
+        try {
+            synt = MidiSystem.getSynthesizer();
+            synt.open();
+        } catch(MidiUnavailableException e) {
+            out("Midi unavailable, cannot test.");
+            return result;
+        }
+        try {
+            receiver = synt.getReceiver();
+        } catch (MidiUnavailableException e) {
+            out("unable to get Receiver from synthesizer, cannot test.");
+            return result;
+        }
+        result &= testClosedReceiver(receiver);
+        synt.close();
+
+        // test all MidiDevices' Receivers
+
+        MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
+        for (int i = 0; i < devices.length; i++) {
+            try {
+                MidiDevice device = MidiSystem.getMidiDevice(devices[i]);
+                if (device.getMaxReceivers() != 0) {
+                    receiver = device.getReceiver();
+                    result &= testClosedReceiver(receiver);
+                }
+            } catch (Exception e) {
+                out(e);
+                out("cannot test.");
+                return result;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Execute send() on a closed Receivers and expect IllegalStateException.
+     */
+    private static boolean testClosedReceiver(Receiver receiver) {
+        boolean result = true;
+        out("testing Receiver: " + receiver);
+        ShortMessage shMsg = new ShortMessage();
+        try {
+            shMsg.setMessage(ShortMessage.NOTE_ON, 0,60, 93);
+        } catch(InvalidMidiDataException e) {
+            out(e);
+            out("unable to construct ShortMessage, cannot test.");
+            return result;
+        }
+
+        // begin of test
+        receiver.close();
+        try {
+            receiver.send( shMsg, -1 );
+            out("IllegalStateException was not thrown "
+                + "on Receiver.send()!");
+            result = false;
+        } catch(IllegalStateException e) {
+            out("IllegalStateException was thrown. Ok.");
+        }
+        return result;
+    }
+
+    private static void out(Throwable t) {
+        t.printStackTrace(System.out);
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+
+    /**
+     * Returns true if at least one MIDI (port) device is correctly installed on
+     * the system.
+     */
+    private static boolean isMidiInstalled() {
+        boolean result = false;
+        MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
+        for (int i = 0; i < devices.length; i++) {
+            try {
+                MidiDevice device = MidiSystem.getMidiDevice(devices[i]);
+                result = !(device instanceof Sequencer)
+                        && !(device instanceof Synthesizer);
+            } catch (Exception e1) {
+                System.err.println(e1);
+            }
+            if (result)
+                break;
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Devices/IOLoop.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.SysexMessage;
+import javax.sound.midi.Transmitter;
+
+/**
+ * @test
+ * @bug 4782924
+ * @bug 4812168
+ * @bug 4356787
+ * @summary MIDI i/o. This is an interactive test! Start it and follow the
+ *          instructions.
+ * @run main/manual IOLoop
+ */
+public class IOLoop {
+    private static final int LONG_SYSEX_LENGTH = 2000;
+
+    private static Receiver receiver;
+    private static Transmitter transmitter;
+    private static MidiMessage receivedMessage;
+    private static ByteArrayOutputStream baos;
+    private static int expectedBytes;
+    private static int receivedBytes;
+    private static Object lock = new Object();
+    private static long lastTimestamp;
+
+    public static void main(String[] args) throws Exception {
+        ShortMessage sMsg = new ShortMessage();
+        SysexMessage syMsg = new SysexMessage();
+        boolean isTestPassed = true;
+        boolean sysExTestPassed = true;
+        boolean isTestExecuted = true;
+
+        out("To run this test successfully, you need to have attached");
+        out("  your MIDI out port with the MIDI in port.");
+
+        MidiDevice inDev = null;
+        MidiDevice outDev = null;
+
+        // setup
+        try {
+            MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
+
+            int devNum = Integer.decode(args[0]).intValue();
+            out("-> opening Transmitter from "+infos[devNum]);
+            inDev = MidiSystem.getMidiDevice(infos[devNum]);
+            inDev.open();
+            transmitter = inDev.getTransmitter();
+            Receiver testReceiver = new TestReceiver();
+            transmitter.setReceiver(testReceiver);
+
+            devNum = Integer.decode(args[1]).intValue();
+            out("-> opening Receiver from "+infos[devNum]);
+            outDev = MidiSystem.getMidiDevice(infos[devNum]);
+            outDev.open();
+            receiver = outDev.getReceiver();
+
+        } catch (Exception e) {
+            System.out.println(e);
+            System.out.println("Cannot test!");
+            return;
+        }
+
+        // test
+        sMsg.setMessage(ShortMessage.NOTE_OFF | 0, 27, 100);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.NOTE_OFF | 0, 0, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.NOTE_OFF | 15, 127, 127);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.NOTE_ON | 4, 27, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.NOTE_ON | 0, 0, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.NOTE_ON | 15, 127, 127);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.POLY_PRESSURE | 11, 98, 99);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.POLY_PRESSURE | 0, 0, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.POLY_PRESSURE | 15, 127, 127);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.CONTROL_CHANGE | 13, 1, 63);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.CONTROL_CHANGE | 0, 0, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.CONTROL_CHANGE | 15, 127, 127);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.PROGRAM_CHANGE | 2, 120, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.PROGRAM_CHANGE | 0, 0, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.PROGRAM_CHANGE | 15, 127, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.CHANNEL_PRESSURE | 6, 30, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.CHANNEL_PRESSURE | 0, 0, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.CHANNEL_PRESSURE | 15, 127, 0);
+        isTestPassed &= testMessage(sMsg);
+
+        sMsg.setMessage(ShortMessage.PITCH_BEND | 6, 56, 4);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.PITCH_BEND | 0, 0, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.PITCH_BEND | 15, 127, 127);
+        isTestPassed &= testMessage(sMsg);
+
+        sMsg.setMessage(ShortMessage.MIDI_TIME_CODE, 0, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.MIDI_TIME_CODE, 127, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.SONG_POSITION_POINTER, 1, 77);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.SONG_POSITION_POINTER, 0, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.SONG_POSITION_POINTER, 127, 127);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.SONG_SELECT, 51, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.SONG_SELECT, 0, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.SONG_SELECT, 127, 0);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.TUNE_REQUEST);
+        isTestPassed &= testMessage(sMsg);
+
+        sMsg.setMessage(ShortMessage.TIMING_CLOCK);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.START);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.CONTINUE);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.STOP);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.ACTIVE_SENSING);
+        isTestPassed &= testMessage(sMsg);
+        sMsg.setMessage(ShortMessage.SYSTEM_RESET);
+        isTestPassed &= testMessage(sMsg);
+
+        syMsg.setMessage(new byte[]{(byte) 0xF0, (byte) 0xF7}, 2);
+        isTestPassed &= testMessage(syMsg);
+        syMsg.setMessage(new byte[]{(byte) 0xF0, 0x01, (byte) 0xF7}, 3);
+        isTestPassed &= testMessage(syMsg);
+        syMsg.setMessage(new byte[]{(byte) 0xF0, 0x02, 0x03, (byte) 0xF7}, 4);
+        isTestPassed &= testMessage(syMsg);
+        syMsg.setMessage(new byte[]{(byte) 0xF0, 0x04, 0x05, 0x06, (byte) 0xF7}, 5);
+        isTestPassed &= testMessage(syMsg);
+
+        if (isTestPassed) {
+            byte[] sysexArray = new byte[LONG_SYSEX_LENGTH];
+            sysexArray[0] = (byte) 0xF0;
+            for (int i = 1; i < sysexArray.length; i++) {
+                sysexArray[i] = (byte) (i % 0x80);
+            }
+//          syMsg.setMessage(new byte[]{(byte) 0xF7, (byte) ShortMessage.START}, 2);
+//          sMsg.setMessage(ShortMessage.START);
+//          isTestPassed &= testMessage(syMsg, sMsg, DEFAULT_SLEEP_INTERVALL);
+            for (int trial = sysexArray.length; trial > 4; trial -= 1234) {
+                sleep(500);
+                sysexArray[trial - 1] = (byte) 0xF7;
+                syMsg.setMessage(sysexArray, trial);
+                sysExTestPassed &= testMessage(syMsg);
+                break;
+            }
+        }
+
+        // cleanup
+        receiver.close();
+        transmitter.close();
+        inDev.close();
+        outDev.close();
+
+        if (isTestExecuted) {
+            if (isTestPassed && sysExTestPassed) {
+
+                out("Test PASSED.");
+            } else {
+                if (isTestPassed
+                    && !sysExTestPassed
+                    && (System.getProperty("os.name").startsWith("Windows"))) {
+                    out("Some Windows MIDI i/o drivers have a problem with larger ");
+                    out("sys ex messages. The failing sys ex cases are OK, therefore.");
+                    out("Test PASSED.");
+                } else {
+                    throw new Exception("Test FAILED.");
+                }
+            }
+        } else {
+            out("Test NOT FAILED");
+        }
+    }
+
+    private static boolean testMessage(MidiMessage message) {
+        receivedMessage = null;
+        baos = new ByteArrayOutputStream();
+        expectedBytes = message.getLength();
+        receivedBytes = 0;
+        System.out.print("Sending message " + getMessageString(message.getMessage())+"...");
+        receiver.send(message, -1);
+        /* sending 3 bytes can roughly be done in 1 millisecond,
+         * so this estimate waits at max 3 times longer than the message takes,
+         * plus a little offset to allow the MIDI subsystem some processing time
+         */
+        int offset = 300; // standard offset 100 millis
+        if (message instanceof SysexMessage) {
+            // add a little processing time to sysex messages
+            offset += 1000;
+        }
+        if (receivedBytes < expectedBytes) {
+            sleep(expectedBytes + offset);
+        }
+        boolean equal;
+        byte[] data = baos.toByteArray();
+        if (data.length > 0) {
+            equal = messagesEqual(message.getMessage(), data);
+        } else {
+            equal = messagesEqual(message, receivedMessage);
+            if (receivedMessage != null) {
+                data = receivedMessage.getMessage();
+            } else {
+                data = null;
+            }
+        }
+        if (!equal) {
+            if ((message.getStatus() & 0xF0) == ShortMessage.PITCH_BEND) {
+                out("NOT failed (may expose a bug in ALSA)");
+                equal = true;
+                sleep(100);
+            }
+            if ((message.getStatus() == 0xF6) && (message.getLength() == 1)) {
+                out("NOT failed (may expose an issue on Solaris)");
+                equal = true;
+                sleep(100);
+            }
+            else if ((message.getStatus()) == 0xF0 && message.getLength() < 4) {
+                out("NOT failed (not a correct sys ex message)");
+                equal = true;
+                sleep(200);
+            } else {
+                out("FAILED:");
+                out("  received as " + getMessageString(data));
+            }
+        } else {
+            System.out.println("OK");
+        }
+        return equal;
+    }
+
+    private static void sleep(int milliseconds) {
+        synchronized(lock) {
+            try {
+                lock.wait(milliseconds);
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+    private static String getMessageString(byte[] data) {
+        String s;
+        if (data == null) {
+            s = "<null>";
+        } else if (data.length == 0) {
+            s = "0-sized array";
+        } else {
+            int status = data[0] & 0xFF;
+            if (data.length <= 3) {
+                if (status < 240) {
+                    s = "command 0x" + Integer.toHexString(status & 0xF0) + " channel " + (status & 0x0F);
+                } else {
+                    s = "status 0x" + Integer.toHexString(status);
+                }
+                if (data.length > 1) {
+                    s += " data 0x" + Integer.toHexString(data[1] & 0xFF);
+                    if (data.length > 2) {
+                        s += " 0x" + Integer.toHexString(data[2] & 0xFF);
+                    }
+                }
+            } else {
+                s = "status " + Integer.toHexString(status)+" and length "+data.length+" bytes";
+            }
+        }
+        return s;
+    }
+
+    private static boolean messagesEqual(MidiMessage m1, MidiMessage m2) {
+        if (m1 == null || m2 == null) {
+            return false;
+        }
+        if (m1.getLength() != m2.getLength()) {
+            return false;
+        }
+        byte[] array1 = m1.getMessage();
+        byte[] array2 = m2.getMessage();
+        return messagesEqual(array1, array2);
+    }
+
+    private static boolean messagesEqual(byte[] a1, byte[] a2) {
+        if (a1.length != a2.length) return false;
+        for (int i = 0; i < a1.length; i++) {
+            if (a1[i] != a2[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static void out(String s) {
+        System.out.println(s);
+        System.out.flush();
+    }
+
+    private static String canIn(MidiDevice dev) {
+        if (dev.getMaxTransmitters() != 0) {
+            return "IN ";
+        }
+        return "   ";
+    }
+
+    private static String canOut(MidiDevice dev) {
+        if (dev.getMaxReceivers() != 0) {
+            return "OUT ";
+        }
+        return "   ";
+    }
+
+
+    private static void checkTimestamp(long timestamp) {
+        // out("checking timestamp...");
+        if (timestamp < 1) {
+            out("timestamp 0 or negative!");
+        }
+        if (timestamp < lastTimestamp) {
+            out("timestamp not progressive!");
+        }
+        lastTimestamp = timestamp;
+    }
+
+    private static class TestReceiver implements Receiver {
+        public void send(MidiMessage message, long timestamp) {
+            //System.out.print(""+message.getLength()+"..");
+            checkTimestamp(timestamp);
+            try {
+                receivedMessage = message;
+                if (message.getStatus() == 0xF0
+                    || (message.getLength() > 3 && message.getStatus() != 0xF7)) {
+                    // sys ex message
+                    byte[] data = message.getMessage();
+                    baos.write(data);
+                    receivedBytes += data.length;
+                }
+                else if (message.getStatus() == 0xF7) {
+                    // sys ex cont'd message
+                    byte[] data = message.getMessage();
+                    // ignore the prepended 0xF7
+                    baos.write(data, 1, data.length-1);
+                    receivedBytes += (data.length - 1);
+                } else {
+                    receivedBytes += message.getLength();
+                }
+                if (receivedBytes >= expectedBytes) {
+                    synchronized(lock) {
+                        lock.notify();
+                    }
+                }
+                System.out.print(""+receivedBytes+"..");
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        public void close() {
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Devices/MidiDeviceGetReceivers.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.util.List;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Transmitter;
+
+/**
+ * @test
+ * @bug 4931387
+ * @summary Add methods to MidiDevice to get list of Transmitters and Receivers
+ */
+public class MidiDeviceGetReceivers {
+
+    private static boolean executed = false;
+    private static boolean failed = false;
+
+    public static void main(String[] args) throws Exception {
+        out("unit test 4931387: Add methods to MidiDevice to get list of Transmitters and Receivers");
+        doAllTests();
+        if (executed) {
+            if (failed) throw new Exception("Test FAILED!");
+            out("Test PASSED.");
+        } else {
+            out("Test NOT failed.");
+        }
+    }
+
+    private static void doAllTests() {
+        MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
+        for (int i = 0; i < infos.length; i++) {
+            MidiDevice device = null;
+            try {
+                device = MidiSystem.getMidiDevice(infos[i]);
+                doTest(device);
+            } catch (MidiUnavailableException e) {
+                out("Exception occured when retrieving device "+infos[i]+": "+e);
+            }
+        }
+        if (infos.length == 0) {
+            out("No MIDI devices exist or sound drivers not installed!");
+        }
+    }
+
+    private static boolean containsReceiver(MidiDevice dev, Receiver rec) {
+        List<Receiver> recvs = dev.getReceivers();
+        return recvs.contains(rec);
+    }
+
+    private static boolean containsTransmitter(MidiDevice dev, Transmitter tra) {
+        List<Transmitter> tras = dev.getTransmitters();
+        return tras.contains(tra);
+    }
+
+    private static void doTest(MidiDevice device) {
+        boolean thisFailed = false;
+        out1("Testing: " + device+"...");
+        try {
+            device.open();
+        } catch (Exception e) {
+            out2("device.open threw exception: "+e);
+            out2("cannot test this device.");
+            return;
+        }
+        if (device.getMaxReceivers() != 0) {
+            // device offers receivers
+            try {
+                List<Receiver> origList = device.getReceivers();
+                Receiver rec = device.getReceiver();
+                if (!containsReceiver(device, rec)) {
+                    out2("Getting a receiver did not add it to device list!");
+                    thisFailed = true;
+                }
+                if (origList.contains(rec)) {
+                    out2("Original unmodifiable list was modified by adding a receiver!");
+                    thisFailed = true;
+                }
+                rec.close();
+                if (containsReceiver(device, rec)) {
+                    out2("Closing a receiver did not remove it from device list!");
+                    thisFailed = true;
+                }
+                // add a new receiver so that the device.close will really test
+                // that the receiver is removed
+                rec = device.getReceiver();
+                if (!containsReceiver(device, rec)) {
+                    out2("Getting a receiver again did not add it to device list!");
+                    thisFailed = true;
+                }
+            } catch (MidiUnavailableException e) {
+                out2("Exception on getting Receiver: " + e);
+            }
+        }
+        if (device.getMaxTransmitters() != 0) {
+            // device offers transmitters
+            try {
+                List<Transmitter> origList = device.getTransmitters();
+                Transmitter tra = device.getTransmitter();
+                if (!containsTransmitter(device, tra)) {
+                    out2("Getting a transmitter did not add it to device list!");
+                    thisFailed = true;
+                }
+                if (origList.contains(tra)) {
+                    out2("Original unmodifiable list was modified by adding a transmitter!");
+                    thisFailed = true;
+                }
+                tra.close();
+                if (containsTransmitter(device, tra)) {
+                    out2("Closing a transmitter did not remove it from device list!");
+                    thisFailed = true;
+                }
+                tra = device.getTransmitter();
+                if (!containsTransmitter(device, tra)) {
+                    out2("Getting a transmitter again did not add it to device list!");
+                    thisFailed = true;
+                }
+            } catch (MidiUnavailableException e) {
+                out("Exception on getting Transmitter: " + e);
+            }
+        }
+        try {
+            device.close();
+            if (device.getTransmitters().size() > 0) {
+                out2(" Device still has transmitters after close() was called!");
+                thisFailed = true;
+            }
+            if (device.getReceivers().size() > 0) {
+                out2(" Device still has receivers after close() was called!");
+                thisFailed = true;
+            }
+        } catch (Exception e) {
+            out2("device.close threw exception: "+e);
+        }
+        if (!thisFailed) {
+            out("OK");
+        } else {
+            failed = true;
+        }
+        executed = true;
+    }
+
+    static boolean lfMissing = false;
+
+    private static void out(String message) {
+        lfMissing = true;
+        System.out.println(message);
+    }
+
+    /* don't print LF at end */
+    private static void out1(String message) {
+        System.out.print(message);
+        lfMissing = true;
+    }
+
+    /* print at a new line, indented */
+    private static void out2(String message) {
+        if (lfMissing) {
+            System.out.println();
+            lfMissing = false;
+        }
+        System.out.println("  "+message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Devices/MidiIO.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+
+/**
+ * @test
+ * @bug 4356787
+ * @summary MIDI device I/O is not working
+ */
+public class MidiIO {
+
+    public static void main(String[] args) throws Exception {
+        out("4356787: MIDI device I/O is not working (windows)");
+
+        if (System.getProperty("os.name").startsWith("Windows")) {
+            boolean forInput=true;
+            boolean forOutput=true;
+            int outOnlyCount=0;
+            int inOnlyCount=0;
+            out("  available MIDI devices:");
+            MidiDevice.Info[] aInfos = MidiSystem.getMidiDeviceInfo();
+            for (int i = 0; i < aInfos.length; i++) {
+                try {
+                    MidiDevice      device = MidiSystem.getMidiDevice(aInfos[i]);
+                    boolean         bAllowsInput = (device.getMaxTransmitters() != 0);
+                    boolean         bAllowsOutput = (device.getMaxReceivers() != 0);
+                    if (bAllowsInput && !bAllowsOutput) {
+                        inOnlyCount++;
+                    }
+                    if (!bAllowsInput && bAllowsOutput) {
+                        outOnlyCount++;
+                    }
+                    if ((bAllowsInput && forInput) || (bAllowsOutput && forOutput)) {
+                        out(""+i+"  "
+                                +(bAllowsInput?"IN ":"   ")
+                                +(bAllowsOutput?"OUT ":"    ")
+                                +aInfos[i].getName()+", "
+                                +aInfos[i].getVendor()+", "
+                                +aInfos[i].getVersion()+", "
+                                +aInfos[i].getDescription());
+                    }
+                }
+                catch (MidiUnavailableException e) {
+                    // device is obviously not available...
+                }
+            }
+            if (aInfos.length == 0) {
+                out("No devices available. Test should be run on systems with MIDI drivers installed.");
+            } else {
+                if (outOnlyCount>1) {
+                    if (inOnlyCount==0) {
+                        //throw new Exception("No input devices! test fails.");
+                        out("System provides out devices, but no input devices. This means either");
+                        out("a bug in Java Sound, or the drivers are not set up correctly.");
+                    }
+                    out("Test passed.");
+                } else {
+                    out("no MIDI I/O installed. Test should be run on systems with MIDI drivers installed.");
+                }
+            }
+        } else {
+            out("  -- not on Windows. Test doesn't apply.");
+        }
+    }
+
+    static void out(String s) {
+        System.out.println(s); System.out.flush();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Devices/MidiOutGetMicrosecondPositionBug.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.Synthesizer;
+
+/**
+ * @test
+ * @bug 4903786
+ * @summary MIDI OUT does not implement getMicrosecondPosition() consistently
+ */
+public class MidiOutGetMicrosecondPositionBug {
+    static int successfulTests = 0;
+
+    private static void testDevice(MidiDevice device) throws Exception {
+        boolean timestampsAvailable = false;
+        boolean timestampPrecisionOk = false;
+        try {
+            // expected behaviour if not opened?
+            device.open();
+            /* First, we're testing if timestamps are provided at all.
+               Returning -1 (unsupported), while allowed by the API
+               specification, is not sufficient to pass this test. */
+            long timestamp = device.getMicrosecondPosition();
+            timestampsAvailable = (timestamp != -1);
+
+            /* Then, we're testing the precision. Note that the system time
+               is measured in milliseconds, while the device time is measured
+               in microseconds. */
+
+            long systemTime1 = System.currentTimeMillis();
+            long deviceTime1 = device.getMicrosecondPosition();
+            // rest for 5 seconds
+            Thread.sleep(5000);
+            long systemTime2 = System.currentTimeMillis();
+            long deviceTime2 = device.getMicrosecondPosition();
+
+            // now both period measurements are calculated in milliseconds.
+            long systemDuration = systemTime2 - systemTime1;
+            long deviceDuration = (deviceTime2 - deviceTime1) / 1000;
+            long delta = Math.abs(systemDuration - deviceDuration);
+            // a deviation of 0.5 seconds (= 500 ms) is allowed.
+            timestampPrecisionOk = (delta <= 500);
+        } catch (Throwable t) {
+            System.out.println("  - Caught exception. Not failed.");
+            System.out.println("  - " + t.toString());
+            return;
+        } finally {
+            device.close();
+        }
+        if (! timestampsAvailable) {
+            throw new Exception("timestamps are not supported");
+        }
+        if (! timestampPrecisionOk) {
+            throw new Exception("device timer not precise enough");
+        }
+        successfulTests++;
+    }
+
+    private static void doAll() throws Exception {
+        MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
+        for (int i=0; i < infos.length; i++) {
+            MidiDevice device = MidiSystem.getMidiDevice(infos[i]);
+            if ((! (device instanceof Sequencer)) &&
+                (! (device instanceof Synthesizer)) &&
+                (device.getMaxReceivers() > 0 || device.getMaxReceivers() == -1)) {
+
+                System.out.println("--------------");
+                System.out.println("Testing MIDI device: " + infos[i]);
+                testDevice(device);
+            }
+            if (infos.length==0) {
+                System.out.println("No MIDI devices available!");
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (!isMidiInstalled()) {
+            return;
+        }
+        doAll();
+        if (successfulTests==0) {
+            System.out.println("Could not execute any of the tests. Test NOT failed.");
+        } else {
+            System.out.println("Test PASSED.");
+        }
+    }
+
+    /**
+     * Returns true if at least one MIDI (port) device is correctly installed on
+     * the system.
+     */
+    public static boolean isMidiInstalled() {
+        boolean result = false;
+        MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
+        for (int i = 0; i < devices.length; i++) {
+            try {
+                MidiDevice device = MidiSystem.getMidiDevice(devices[i]);
+                result = ! (device instanceof Sequencer) && ! (device instanceof Synthesizer);
+            } catch (Exception e1) {
+                System.err.println(e1);
+            }
+            if (result)
+                break;
+        }
+        if (!result) {
+            System.err.println("Soundcard does not exist or sound drivers not installed!");
+            System.err.println("This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Devices/OpenClose.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,611 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.Synthesizer;
+import javax.sound.midi.Transmitter;
+
+/**
+ * @test
+ * @bug 4616517
+ * @summary Receiver.send() does not work properly. Tests open/close behaviour
+ *          of MidiDevices. For this test, it is essential that the MidiDevice
+ *          picked from the list of devices (MidiSystem.getMidiDeviceInfo()) is
+ *          the same as the one used by
+ *          MidiSystem.getReceiver()/getTransmitter(). To achieve this, default
+ *          provider properties for Receivers/Transmitters are used.
+ */
+public class OpenClose {
+
+    private static boolean isTestExecuted;
+    private static boolean isTestPassed;
+
+    public static void main(String[] args) throws Exception {
+        boolean failed = false;
+        out("#4616517: Receiver.send() does not work properly");
+        if (!isMidiInstalled()) {
+            out("Soundcard does not exist or sound drivers not installed!");
+            out("This test requires sound drivers for execution.");
+            return;
+        }
+        MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
+        MidiDevice outDevice = null;
+        MidiDevice inDevice = null;
+        for (int i = 0; i < infos.length; i++) {
+            MidiDevice device = MidiSystem.getMidiDevice(infos[i]);
+            if (! (device instanceof Synthesizer) &&
+                ! (device instanceof Sequencer)) {
+                if (device.getMaxReceivers() != 0) {
+                    outDevice = device;
+                }
+                if (device.getMaxTransmitters() != 0) {
+                    inDevice = device;
+                }
+            }
+        }
+        if (outDevice != null) {
+            // set the default provider properties
+            System.setProperty(Receiver.class.getName(),
+                               "#" + outDevice.getDeviceInfo().getName());
+        }
+        if (inDevice != null) {
+            System.setProperty(Transmitter.class.getName(),
+                               "#" + inDevice.getDeviceInfo().getName());
+        }
+        out("Using MIDI OUT Device: " + outDevice);
+        out("Using MIDI IN Device: " + inDevice);
+
+        isTestExecuted = false;
+        if (outDevice != null) {
+            isTestExecuted = true;
+            TestHelper testHelper = new ReceiverTestHelper(outDevice);
+            try {
+                doTest("Receiver", testHelper);
+                failed |= testHelper.hasFailed();
+            } catch (Exception e) {
+                out("Exception occured, cannot test!");
+                isTestExecuted = false;
+            }
+        }
+
+        if (inDevice != null) {
+            isTestExecuted = true;
+            TestHelper testHelper = new TransmitterTestHelper(inDevice);
+            try {
+                doTest("Transmitter", testHelper);
+                failed |= testHelper.hasFailed();
+            } catch (Exception e) {
+                out("Exception occured, cannot test!");
+                isTestExecuted = false;
+            }
+        }
+
+        isTestPassed = ! failed;
+
+        if (isTestExecuted) {
+            if (isTestPassed) {
+                out("Test PASSED.");
+            } else {
+                throw new Exception("Test FAILED.");
+            }
+        } else {
+            out("Test NOT FAILED");
+        }
+    }
+
+    private static void doTest(String type,
+                               TestHelper testHelper) throws Exception {
+        /* Case 1:
+           - MidiDevice.open()
+           - MidiDevice.close()
+        */
+        out("checking " + type + " case 1...");
+        testHelper.checkClosed();
+
+        testHelper.openDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeDevice();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 2a:
+           - MidiSystem.get[Receiver|Transmitter]()
+           - [Receiver|Transmitter].close()
+        */
+        out("checking " + type + " case 2a...");
+        testHelper.checkClosed();
+
+        testHelper.fetchObjectMidiSystem();
+        testHelper.checkOpen();
+
+        testHelper.closeObjectMidiSystem();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 2b:
+           - MidiDevice.get[Receiver|Transmitter]()
+           - [Receiver|Transmitter].close()
+        */
+        out("checking " + type + " case 2b...");
+        testHelper.checkClosed();
+
+        testHelper.fetchObjectDevice();
+        testHelper.checkClosed();
+
+        testHelper.closeObjectDevice();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 3a:
+           - MidiSystem.get[Receiver|Transmitter]()
+           - MidiDevice.open()
+           - MidiDevice.close()
+           - [Receiver|Transmitter].close()
+        */
+        out("checking " + type + " case 3a...");
+        testHelper.checkClosed();
+
+        testHelper.fetchObjectMidiSystem();
+        testHelper.checkOpen();
+
+        testHelper.openDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeDevice();
+        testHelper.checkClosed();
+
+        testHelper.closeObjectMidiSystem();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 3b:
+           - MidiDevice.get[Receiver|Transmitter]()
+           - MidiDevice.open()
+           - MidiDevice.close()
+           - [Receiver|Transmitter].close()
+        */
+        out("checking " + type + " case 3b...");
+        testHelper.checkClosed();
+
+        testHelper.fetchObjectDevice();
+        testHelper.checkClosed();
+
+        testHelper.openDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeDevice();
+        testHelper.checkClosed();
+
+        testHelper.closeObjectDevice();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 4a:
+           - MidiSystem.get[Receiver|Transmitter]()
+           - MidiDevice.open()
+           - [Receiver|Transmitter].close()
+           - MidiDevice.close()
+        */
+        out("checking " + type + " case 4a...");
+        testHelper.checkClosed();
+
+        testHelper.fetchObjectMidiSystem();
+        testHelper.checkOpen();
+
+        testHelper.openDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeObjectMidiSystem();
+        testHelper.checkOpen();
+
+        testHelper.closeDevice();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 4b:
+           - MidiDevice.get[Receiver|Transmitter]()
+           - MidiDevice.open()
+           - [Receiver|Transmitter].close()
+           - MidiDevice.close()
+        */
+        out("checking " + type + " case 4b...");
+        testHelper.checkClosed();
+
+        testHelper.fetchObjectDevice();
+        testHelper.checkClosed();
+
+        testHelper.openDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeObjectDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeDevice();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 5a:
+           - MidiDevice.open()
+           - MidiSystem.get[Receiver|Transmitter]()
+           - MidiDevice.close()
+           - [Receiver|Transmitter].close()
+        */
+        out("checking " + type + " case 5a...");
+        testHelper.checkClosed();
+
+        testHelper.openDevice();
+        testHelper.checkOpen();
+
+        testHelper.fetchObjectMidiSystem();
+        testHelper.checkOpen();
+
+        testHelper.closeDevice();
+        testHelper.checkClosed();
+
+        testHelper.closeObjectMidiSystem();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 5b:
+           - MidiDevice.open()
+           - MidiDevice.get[Receiver|Transmitter]()
+           - MidiDevice.close()
+           - [Receiver|Transmitter].close()
+        */
+        out("checking " + type + " case 5b...");
+        testHelper.checkClosed();
+
+        testHelper.openDevice();
+        testHelper.checkOpen();
+
+        testHelper.fetchObjectDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeDevice();
+        testHelper.checkClosed();
+
+        testHelper.closeObjectDevice();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 6a:
+           - MidiDevice.open()
+           - MidiSystem.get[Receiver|Transmitter]()
+           - [Receiver|Transmitter].close()
+           - MidiDevice.close()
+        */
+        out("checking " + type + " case 6a...");
+        testHelper.checkClosed();
+
+        testHelper.openDevice();
+        testHelper.checkOpen();
+
+        testHelper.fetchObjectMidiSystem();
+        testHelper.checkOpen();
+
+        testHelper.closeObjectMidiSystem();
+        testHelper.checkOpen();
+
+        testHelper.closeDevice();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 6b:
+           - MidiDevice.open()
+           - MidiDevice.get[Receiver|Transmitter]()
+           - [Receiver|Transmitter].close()
+           - MidiDevice.close()
+        */
+        out("checking " + type + " case 6b...");
+        testHelper.checkClosed();
+
+        testHelper.openDevice();
+        testHelper.checkOpen();
+
+        testHelper.fetchObjectDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeObjectDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeDevice();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 7:
+           - MidiSystem.get[Receiver|Transmitter]() // 1
+           - MidiDevice.get[Receiver|Transmitter]() // 2
+           - [Receiver|Transmitter].close() // 2
+           - [Receiver|Transmitter].close() // 1
+        */
+        out("checking " + type + " case 7...");
+        testHelper.checkClosed();
+
+        testHelper.fetchObjectMidiSystem();
+        testHelper.checkOpen();
+
+        testHelper.fetchObjectDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeObjectDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeObjectMidiSystem();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 8:
+           - MidiSystem.get[Receiver|Transmitter]() // 1
+           - MidiDevice.get[Receiver|Transmitter]() // 2
+           - [Receiver|Transmitter].close() // 1
+           - [Receiver|Transmitter].close() // 2
+        */
+        out("checking " + type + " case 8...");
+        testHelper.checkClosed();
+
+        testHelper.fetchObjectMidiSystem();
+        testHelper.checkOpen();
+
+        testHelper.fetchObjectDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeObjectMidiSystem();
+        testHelper.checkClosed();
+
+        testHelper.closeObjectDevice();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 9:
+           - MidiDevice.get[Receiver|Transmitter]() // 2
+           - MidiSystem.get[Receiver|Transmitter]() // 1
+           - [Receiver|Transmitter].close() // 2
+           - [Receiver|Transmitter].close() // 1
+        */
+        out("checking " + type + " case 9...");
+        testHelper.checkClosed();
+
+        testHelper.fetchObjectDevice();
+        testHelper.checkClosed();
+
+        testHelper.fetchObjectMidiSystem();
+        testHelper.checkOpen();
+
+        testHelper.closeObjectDevice();
+        testHelper.checkOpen();
+
+        testHelper.closeObjectMidiSystem();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case 10:
+           - MidiDevice.get[Receiver|Transmitter]() // 2
+           - MidiSystem.get[Receiver|Transmitter]() // 1
+           - [Receiver|Transmitter].close() // 1
+           - [Receiver|Transmitter].close() // 2
+        */
+        out("checking " + type + " case 10...");
+        testHelper.checkClosed();
+
+        testHelper.fetchObjectDevice();
+        testHelper.checkClosed();
+
+        testHelper.fetchObjectMidiSystem();
+        testHelper.checkOpen();
+
+        testHelper.closeObjectMidiSystem();
+        testHelper.checkClosed();
+
+        testHelper.closeObjectDevice();
+        testHelper.checkClosed();
+
+        out("...OK");
+
+        /* Case N - 1:
+           - 10 x MidiSystem.get[Receiver|Transmitter]()
+           - 10 x [Receiver|Transmitter].close()
+        */
+        out("checking " + type + " case N - 1...");
+        TestHelper[] testHelpers = new TestHelper[10];
+        for (int i = 0; i < 10; i++) {
+            testHelpers[i] = (TestHelper) testHelper.clone();
+        }
+        testHelper.checkClosed();
+
+        for (int i = 0; i < 10; i++) {
+            testHelpers[i].fetchObjectMidiSystem();
+            testHelper.checkOpen();
+        }
+
+
+        for (int i = 0; i < 9; i++) {
+            testHelpers[i].closeObjectMidiSystem();
+            testHelper.checkOpen();
+        }
+
+        testHelpers[9].closeObjectMidiSystem();
+        testHelper.checkClosed();
+
+        out("...OK");
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+
+    private static abstract class TestHelper implements Cloneable {
+        private MidiDevice device;
+        private boolean failed;
+
+        protected TestHelper(MidiDevice device) {
+            this.device = device;
+            failed = false;
+        }
+
+        protected MidiDevice getDevice() {
+            return device;
+        }
+
+        public boolean hasFailed() {
+            return failed;
+        }
+
+        public void openDevice() throws MidiUnavailableException {
+            getDevice().open();
+        }
+
+        public void closeDevice() {
+            getDevice().close();
+        }
+
+        public void checkOpen(){
+            checkOpen(getDevice(), true);
+        }
+
+        public void checkClosed(){
+            checkOpen(getDevice(), false);
+        }
+
+        private void checkOpen(MidiDevice device, boolean desiredState) {
+            if (device.isOpen() != desiredState) {
+                out("device should be " +
+                                    getStateString(desiredState) + ", but isn't!");
+                failed = true;
+            }
+        }
+
+
+        private String getStateString(boolean state) {
+            return state ? "open" : "closed";
+        }
+
+
+        public abstract void fetchObjectMidiSystem() throws MidiUnavailableException;
+        public abstract void fetchObjectDevice() throws MidiUnavailableException;
+        public abstract void closeObjectMidiSystem();
+        public abstract void closeObjectDevice();
+
+        public Object clone() {
+            try {
+                return super.clone();
+            } catch (CloneNotSupportedException e) {
+                return null;
+            }
+        }
+    }
+
+    private static class ReceiverTestHelper extends TestHelper {
+        private Receiver receiverMidiSystem;
+        private Receiver receiverDevice;
+
+        public ReceiverTestHelper(MidiDevice device) {
+            super(device);
+        }
+
+        public void fetchObjectMidiSystem() throws MidiUnavailableException {
+            receiverMidiSystem = MidiSystem.getReceiver();
+        }
+
+
+        public void fetchObjectDevice() throws MidiUnavailableException {
+            receiverDevice = getDevice().getReceiver();
+        }
+
+
+        public void closeObjectMidiSystem() {
+            receiverMidiSystem.close();
+        }
+
+
+        public void closeObjectDevice() {
+            receiverDevice.close();
+        }
+    }
+
+    private static class TransmitterTestHelper extends TestHelper {
+        private Transmitter transmitterMidiSystem;
+        private Transmitter transmitterDevice;
+
+        public TransmitterTestHelper(MidiDevice device) {
+            super(device);
+        }
+
+        public void fetchObjectMidiSystem() throws MidiUnavailableException {
+            transmitterMidiSystem = MidiSystem.getTransmitter();
+        }
+
+
+        public void fetchObjectDevice() throws MidiUnavailableException {
+            transmitterDevice = getDevice().getTransmitter();
+        }
+
+
+        public void closeObjectMidiSystem() {
+            transmitterMidiSystem.close();
+        }
+
+
+        public void closeObjectDevice() {
+            transmitterDevice.close();
+        }
+    }
+
+    /**
+     * Returns true if at least one MIDI (port) device is correctly installed on
+     * the system.
+     */
+    public static boolean isMidiInstalled() {
+        boolean result = false;
+        MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
+        for (int i = 0; i < devices.length; i++) {
+            try {
+                MidiDevice device = MidiSystem.getMidiDevice(devices[i]);
+                result = ! (device instanceof Sequencer) && ! (device instanceof Synthesizer);
+            } catch (Exception e1) {
+                System.err.println(e1);
+            }
+            if (result)
+                break;
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Devices/ReceiverTransmitterAvailable.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Transmitter;
+
+/**
+ * @test
+ * @bug 4616517
+ * @summary Receiver.send() does not work properly
+ */
+public class ReceiverTransmitterAvailable {
+
+    private static boolean isTestExecuted;
+    private static boolean isTestPassed;
+
+    public static void main(String[] args) throws Exception {
+        out("#4616517: Receiver.send() does not work properly");
+        doAllTests();
+        if (isTestExecuted) {
+            if (isTestPassed) {
+                out("Test PASSED.");
+            } else {
+                throw new Exception("Test FAILED.");
+            }
+        } else {
+            out("Test NOT FAILED");
+        }
+    }
+
+    private static void doAllTests() {
+        boolean problemOccured = false;
+        boolean succeeded = true;
+        MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
+        for (int i = 0; i < infos.length; i++) {
+            MidiDevice device = null;
+            try {
+                device = MidiSystem.getMidiDevice(infos[i]);
+                succeeded &= doTest(device);
+            } catch (MidiUnavailableException e) {
+                out("exception occured; cannot test");
+                problemOccured = true;
+            }
+        }
+        if (infos.length == 0) {
+            out("Soundcard does not exist or sound drivers not installed!");
+            out("This test requires sound drivers for execution.");
+        }
+        isTestExecuted = !problemOccured;
+        isTestPassed = succeeded;
+    }
+
+    private static boolean doTest(MidiDevice device) {
+        boolean succeeded = true;
+        out("Testing: " + device);
+        boolean expectingReceivers = (device.getMaxReceivers() != 0);
+        boolean expectingTransmitters = (device.getMaxTransmitters() != 0);
+        try {
+            Receiver rec = device.getReceiver();
+            rec.close();
+            if (! expectingReceivers) {
+                out("no exception on getting Receiver");
+                succeeded = false;
+            }
+        } catch (MidiUnavailableException e) {
+            if (expectingReceivers) {
+                out("Exception on getting Receiver: " + e);
+                succeeded = false;
+            }
+        }
+        try {
+            Transmitter trans = device.getTransmitter();
+            trans.close();
+            if (! expectingTransmitters) {
+                out("no exception on getting Transmitter");
+                succeeded = false;
+            }
+        } catch (MidiUnavailableException e) {
+            if (expectingTransmitters) {
+                out("Exception on getting Transmitter: " + e);
+                succeeded = false;
+            }
+        }
+        return succeeded;
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Devices/Reopen.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.Synthesizer;
+
+/**
+ * @test
+ * @bug 4914667
+ * @summary Closing and reopening MIDI IN device on Linux throws
+ *          MidiUnavailableException
+ */
+public class Reopen {
+
+    private static boolean isTestExecuted;
+    private static boolean isTestPassed;
+
+    /*
+     * run manually:
+     * java Reopen 100 in      for 100 iterations on the MIDI IN device
+     * java Reopen 16 out      for 16 iterations on the MIDI OUT device
+     */
+    public static void main(String[] args) throws Exception {
+        if (args.length == 0) {
+            doAllTests();
+        } else if (args.length == 2) {
+            int numIterations = Integer.parseInt(args[0]);
+            if (args[1].equals("in")) {
+                doTest(numIterations, true);
+            } else {
+                doTest(numIterations, false);
+            }
+        } else {
+            out("usage: java Reopen <iterations> in|out");
+        }
+    }
+
+    private static void doAllTests() throws Exception {
+        out("#4914667: Closing and reopening MIDI IN device on Linux throws MidiUnavailableException");
+        boolean success = true;
+        try {
+            success &= doTest(20, true); // MIDI IN
+            success &= doTest(20, false); // MIDI OUT
+            isTestExecuted = true;
+        } catch (Exception e) {
+            out(e);
+            isTestExecuted = false;
+        }
+        isTestPassed = success;
+        if (isTestExecuted) {
+            if (isTestPassed) {
+                out("Test PASSED.");
+            } else {
+                throw new Exception("Test FAILED.");
+            }
+        } else {
+            out("Test NOT FAILED");
+        }
+    }
+
+    private static boolean doTest(int numIterations, boolean input) throws Exception {
+        MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
+        MidiDevice outDevice = null;
+        MidiDevice inDevice = null;
+        for (int i = 0; i < infos.length; i++) {
+            MidiDevice device = MidiSystem.getMidiDevice(infos[i]);
+            if (! (device instanceof Sequencer) &&
+                ! (device instanceof Synthesizer)) {
+                if (device.getMaxReceivers() != 0) {
+                    outDevice = device;
+                }
+                if (device.getMaxTransmitters() != 0) {
+                    inDevice = device;
+                }
+            }
+        }
+        MidiDevice testDevice = null;
+        if (input) {
+            testDevice = inDevice;
+        } else {
+            testDevice = outDevice;
+        }
+        if (testDevice == null) {
+            out("Cannot test: device not available.");
+            return true;
+        }
+        out("Using Device: " + testDevice);
+
+        for (int i = 0; i < numIterations; i++) {
+            out("@@@ ITERATION: " + i);
+            testDevice.open();
+            // This sleep ensures that the thread of MidiInDevice is started.
+            sleep(50);
+            testDevice.close();
+        }
+        return true;
+    }
+
+    private static void sleep(int milliseconds) {
+        try {
+            Thread.sleep(milliseconds);
+        } catch (InterruptedException e) {
+        }
+    }
+
+    private static void out(Throwable t) {
+        t.printStackTrace(System.out);
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/File/SMFCp037.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+
+import javax.sound.midi.MidiSystem;
+
+/**
+ * @test
+ * @bug 4303933
+ * @summary MidiSystem fails to load MIDI file on systems with EBCDIC simulation
+ */
+public class SMFCp037 {
+
+    public static void main(String args[]) throws Exception {
+        // Test to read MIDI files with Cp037 character set - close enough
+        // for EBCDIC simulation
+        System.setProperty("file.encoding", "Cp037");
+        // try to read this file with Cp037 encoding
+        MidiSystem.getSequence(new ByteArrayInputStream(SHORT_SMF));
+        System.out.println("  test passed.");
+    }
+
+public static byte[] SHORT_SMF = {
+        77, 84, 104, 100, 0, 0, 0, 6, 0, 1, 0, 2, 0, 120, 77, 84, 114, 107, 0, 0,
+        0, 27, 0, -1, 3, 19, 77, 73, 68, 73, 32, 116, 101, 115, 116, 32, 45, 32,
+        116, 114, 97, 99, 107, 32, 48, 0, -1, 47, 0, 77, 84, 114, 107, 0, 0, 0, -44,
+        0, -1, 3, 19, 77, 73, 68, 73, 32, 116, 101, 115, 116, 32, 45, 32, 116, 114,
+        97, 99, 107, 32, 49, 0, -64, 30, 0, -112, 68, 126, 0, -32, 6, 67, 0, 14,
+        71, 0, 20, 74, 0, 26, 77, 0, 32, 80, 0, 42, 85, 6, 50, 89, 6, 56, 92, 5,
+        66, 97, 6, 74, 101, 6, 80, 104, 11, 84, 106, 20, 76, 102, 6, 70, 99, 5, 60,
+        94, 6, 52, 90, 5, 44, 86, 4, 34, 81, 5, 26, 77, 5, 20, 74, 6, 10, 69, 5,
+        2, 65, 7, 0, 64, 42, -112, 66, 123, 11, 68, 0, 72, 63, 126, 4, 66, 0, 43,
+        -32, 0, 63, 6, 0, 60, 7, 0, 56, 6, 0, 53, 5, 0, 49, 5, 0, 43, 4, 0, 37, 3,
+        0, 30, 3, 0, 25, 3, 0, 19, 3, 0, 13, 4, 0, 8, 4, 0, 2, 4, 0, 0, 70, 0, 3,
+        5, 0, 9, 3, 0, 14, 7, 0, 16, 25, 0, 21, 5, 0, 25, 7, 0, 28, 5, 0, 32, 5,
+        0, 36, 5, 0, 41, 6, 0, 46, 5, 0, 50, 5, 0, 53, 4, 0, 58, 7, 0, 61, 7, 0,
+        64, 117, -112, 63, 0, 0, -1, 47, 0
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/File/SMFParserBreak.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+
+/**
+ * @test
+ * @bug 4910986
+ * @summary MIDI file parser breaks up on http connection
+ */
+public class SMFParserBreak {
+
+    public static void main(String[] args) throws Exception {
+
+        InputStream is = new ByteArrayInputStream(midifile);
+        // create a buffered input stream that seems
+        // to be on an unfortunate boundary for the
+        // 1.4.2 SMF parser implementation
+        is = new ChunkInputStream(is, 32);
+        Sequence sequence = MidiSystem.getSequence(is);
+
+        long duration = sequence.getMicrosecondLength() / 10000;
+        System.out.println("Duration: "+duration+" deciseconds ");
+
+        // the test is passed if no exception thrown
+        System.out.println("Test passed");
+    }
+
+    // A MIDI file
+    static byte[] midifile = {
+        77, 84, 104, 100, 0, 0, 0, 6, 0, 1, 0, 3, -30, 120, 77, 84, 114, 107, 0,
+        0, 0, 123, 0, -112, 30, 100, -113, 49, -128, 50, 100, -114, 69, -112, 31,
+        100, -114, 33, -128, 51, 100, -114, 55, -112, 32, 100, -114, 120, -128, 52,
+        100, -114, 40, -112, 33, 100, -114, 26, -128, 53, 100, -114, 26, -112, 34,
+        100, -114, 76, -128, 54, 100, -114, 12, -112, 35, 100, -114, 91, -128, 55,
+        100, -114, 69, -112, 36, 100, -114, 33, -128, 56, 100, -114, 55, -112, 37,
+        100, -114, 84, -128, 57, 100, -114, 40, -112, 38, 100, -114, 26, -128, 58,
+        100, -114, 26, -112, 39, 100, -113, 24, -128, 59, 100, -113, 60, -112, 40,
+        100, -113, 110, -128, 60, 100, -113, 96, -112, 41, 100, -113, 39, -128, 61,
+        100, 0, -1, 47, 0, 77, 84, 114, 107, 0, 0, 0, 4, 0, -1, 47, 0, 77, 84, 114,
+        107, 0, 0, 0, 4, 0, -1, 47, 0
+    };
+}
+
+/* an input stream that always returns data in chunks */
+class ChunkInputStream extends FilterInputStream {
+    int chunkSize;
+    int p = 0; // position
+
+    public ChunkInputStream(InputStream is, int chunkSize) {
+        super(is);
+        this.chunkSize = chunkSize;
+    }
+
+    // override to increase counter
+    public int read() throws IOException {
+        int ret = super.read();
+        if (ret >= 0) {
+            p++;
+        }
+        return ret;
+    }
+
+    // override to make sure that read(byte[], int, int) is used
+    public int read(byte[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    // override to split the data in chunks
+    public int read(byte[] b, int off, int len) throws IOException {
+        // if we would pass a chunk boundary,
+        // only return up to the chunk boundary
+        if ( (p / chunkSize) < ( (p+len) / chunkSize)) {
+            // p+len is in the next chunk
+            len -= ((p+len) % chunkSize);
+        }
+        int ret = super.read(b, off, len);
+        if (ret >= 0) {
+            p += ret;
+        }
+        return ret;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/File/WriteRealTimeMessageNPE.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 5048381
+ * @summary NPE when writing a sequence with a realtime MIDI message
+ */
+public class WriteRealTimeMessageNPE {
+
+    public static void main(String args[]) throws Exception {
+        System.out.println("5048381: NullPointerException when saving a MIDI sequence");
+        boolean npeThrown = false;
+        boolean noEx = false;
+
+        Sequence seq = new Sequence(Sequence.PPQ, 384, 1);
+        Track t = seq.getTracks()[0];
+        ShortMessage msg = new ShortMessage();
+        msg.setMessage(0xF8, 0, 0);
+        t.add(new MidiEvent(msg, 0));
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        try {
+            MidiSystem.write(seq, 0, out);
+            noEx = true;
+        } catch (NullPointerException npe) {
+            npeThrown = true;
+            System.out.println("## Failed: Threw unexpected NPE: "+npe);
+            throw new Exception("Test FAILED!");
+        } catch (Exception e) {
+            System.out.println("Threw unexpected Exception: "+e);
+            System.out.println("But at least did not throw NPE...");
+        }
+        if (noEx) {
+            InputStream is = new ByteArrayInputStream(out.toByteArray());
+            seq = MidiSystem.getSequence(is);
+            System.out.println("Sequence has "+seq.getTracks().length+" tracks.");
+            if (seq.getTracks().length > 0) {
+                System.out.println("Track 0 has "+seq.getTracks()[0].size()+" events.");
+            }
+        }
+        System.out.println("Test passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/MetaMessage/MetaMessageClone.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import  javax.sound.midi.MetaMessage;
+
+/**
+ * @test
+ * @bug 4511796
+ * @summary Check that MetaMessage.clone() works correctly
+ */
+public class MetaMessageClone {
+
+    private static void printMsg(MetaMessage msg, byte[] data) {
+        System.out.println(""+msg.getLength()+" total bytes, type="+msg.getType()+", dataLength="+data.length);
+    }
+
+    private static void checkClone(MetaMessage msg) throws Exception {
+        System.out.print("Original: ");
+        byte[] msgData=msg.getData();
+        printMsg(msg, msgData);
+        MetaMessage msg2=(MetaMessage) msg.clone();
+        byte[] msg2Data=msg2.getData();
+        System.out.print("Clone:    ");
+        printMsg(msg2, msg2Data);
+
+        if (msg2.getLength()!=msg.getLength()
+            || msg.getType()!=msg2.getType()
+            || msgData.length!=msg2Data.length) {
+                throw new Exception("cloned MetaMessage is not equal.");
+        }
+        int max=Math.min(msgData.length, 10);
+        for (int i=0; i<max; i++) {
+            if (msgData[i]!=msg2Data[i]) {
+                throw new Exception("Cloned MetaMessage data is not equal.");
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        // let's create some MetaMessages and check them
+        MetaMessage msg=new MetaMessage();
+        String text="a textmarker";
+        msg.setMessage(1, text.getBytes(), text.length());
+        checkClone(msg);
+        msg.setMessage(0x2E, new byte[0], 0);
+        checkClone(msg);
+        byte[] data=new byte[17000];
+        for (int i=0; i<30; data[i]=(byte) (i++ & 0xFF));
+        msg.setMessage(0x02, data, 80); checkClone(msg);
+        msg.setMessage(0x02, data, 160); checkClone(msg);
+        msg.setMessage(0x02, data, 400); checkClone(msg);
+        msg.setMessage(0x02, data, 1000); checkClone(msg);
+        msg.setMessage(0x02, data, 10000); checkClone(msg);
+        msg.setMessage(0x02, data, 17000); checkClone(msg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/MidiSystem/6411624/Test6411624.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 2006, 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.
+ */
+
+import java.awt.Button;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.Panel;
+import java.awt.TextArea;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * @test
+ * @bug 6411624
+ * @summary Tests that MidiSystem.getReceiver() & MidiSystem.getTransmitter
+ *          doesn't return sequencer
+ * @build bug6411624
+ * @run main/manual Test6411624
+ */
+public class Test6411624 {
+
+   private static void init() throws Exception {
+        //*** Create instructions for the user here ***
+
+        String[] instructions =
+        {
+         "This test should only be run on solaris or linux system",
+         "WITHOUT audio card installed (to test on SunRay set",
+         "incorrect $AUDIODEV value).",
+         "If you system does not meet this conditions, press PASS.",
+         "To run the test follow these instructions:",
+         "1. Open a terminal window.",
+         "2. Type \"cd " + System.getProperty("test.classes") + "\".",
+         "3. Type \"" + System.getProperty("java.home") + "/bin/java bug6411624\".",
+         "4. Follow the instructions shown in the terminal window.",
+         "If you see \"All tests sucessfully passed\", press PASS else press FAIL."
+       };
+
+      Sysout.createDialog( );
+      Sysout.printInstructions( instructions );
+
+    }
+
+ /*****************************************************
+     Standard Test Machinery Section
+      DO NOT modify anything in this section -- it's a
+      standard chunk of code which has all of the
+      synchronisation necessary for the test harness.
+      By keeping it the same in all tests, it is easier
+      to read and understand someone else's test, as
+      well as insuring that all tests behave correctly
+      with the test harness.
+     There is a section following this for test-defined
+      classes
+   ******************************************************/
+   private static boolean theTestPassed = false;
+   private static boolean testGeneratedInterrupt = false;
+   private static String failureMessage = "";
+
+   private static Thread mainThread = null;
+
+   private static int sleepTime = 300000;
+
+   public static void main( String args[] ) throws Exception
+    {
+      mainThread = Thread.currentThread();
+      try
+       {
+         init();
+       }
+      catch( TestPassedException e )
+       {
+         //The test passed, so just return from main and harness will
+         // interepret this return as a pass
+         return;
+       }
+      //At this point, neither test passed nor test failed has been
+      // called -- either would have thrown an exception and ended the
+      // test, so we know we have multiple threads.
+
+      //Test involves other threads, so sleep and wait for them to
+      // called pass() or fail()
+      try
+       {
+         Thread.sleep( sleepTime );
+         //Timed out, so fail the test
+         throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+       }
+      catch (InterruptedException e)
+       {
+         if( ! testGeneratedInterrupt ) throw e;
+
+         //reset flag in case hit this code more than once for some reason (just safety)
+         testGeneratedInterrupt = false;
+         if ( theTestPassed == false )
+          {
+            throw new RuntimeException( failureMessage );
+          }
+       }
+
+    }//main
+
+   public static synchronized void setTimeoutTo( int seconds )
+    {
+      sleepTime = seconds * 1000;
+    }
+
+   public static synchronized void pass()
+    {
+      Sysout.println( "The test passed." );
+      Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+      //first check if this is executing in main thread
+      if ( mainThread == Thread.currentThread() )
+       {
+         //Still in the main thread, so set the flag just for kicks,
+         // and throw a test passed exception which will be caught
+         // and end the test.
+         theTestPassed = true;
+         throw new TestPassedException();
+       }
+      //pass was called from a different thread, so set the flag and interrupt
+      // the main thead.
+      theTestPassed = true;
+      testGeneratedInterrupt = true;
+      mainThread.interrupt();
+    }//pass()
+
+   public static synchronized void fail()
+    {
+      //test writer didn't specify why test failed, so give generic
+      fail( "it just plain failed! :-)" );
+    }
+
+   public static synchronized void fail( String whyFailed )
+    {
+      Sysout.println( "The test failed: " + whyFailed );
+      Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+      //check if this called from main thread
+      if ( mainThread == Thread.currentThread() )
+       {
+         //If main thread, fail now 'cause not sleeping
+         throw new RuntimeException( whyFailed );
+       }
+      theTestPassed = false;
+      testGeneratedInterrupt = true;
+      failureMessage = whyFailed;
+      mainThread.interrupt();
+    }//fail()
+
+ }// class Orient
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+ {
+ }
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         Orient.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         Orient.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+ {
+   private static TestDialog dialog;
+
+   public static void createDialogWithInstructions( String[] instructions )
+    {
+      dialog = new TestDialog( new Frame(), "Instructions" );
+      dialog.printInstructions( instructions );
+      dialog.show();
+      println( "Any messages for the tester will display here." );
+    }
+
+   public static void createDialog( )
+    {
+      dialog = new TestDialog( new Frame(), "Instructions" );
+      String[] defInstr = { "Instructions will appear here. ", "" } ;
+      dialog.printInstructions( defInstr );
+      dialog.show();
+      println( "Any messages for the tester will display here." );
+    }
+
+
+   public static void printInstructions( String[] instructions )
+    {
+      dialog.printInstructions( instructions );
+    }
+
+
+   public static void println( String messageIn )
+    {
+      dialog.displayMessage( messageIn );
+    }
+
+ }// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog implements ActionListener
+ {
+
+   TextArea instructionsText;
+   TextArea messageText;
+   int maxStringLength = 80;
+   Panel  buttonP = new Panel();
+   Button passB = new Button( "pass" );
+   Button failB = new Button( "fail" );
+
+   //DO NOT call this directly, go through Sysout
+   public TestDialog( Frame frame, String name )
+    {
+      super( frame, name );
+      int scrollBoth = TextArea.SCROLLBARS_BOTH;
+      instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+      add( "North", instructionsText );
+
+      messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+      add("Center", messageText);
+
+      passB = new Button( "pass" );
+      passB.setActionCommand( "pass" );
+      passB.addActionListener( this );
+      buttonP.add( "East", passB );
+
+      failB = new Button( "fail" );
+      failB.setActionCommand( "fail" );
+      failB.addActionListener( this );
+      buttonP.add( "West", failB );
+
+      add( "South", buttonP );
+      pack();
+
+      show();
+    }// TestDialog()
+
+   //DO NOT call this directly, go through Sysout
+   public void printInstructions( String[] instructions )
+    {
+      //Clear out any current instructions
+      instructionsText.setText( "" );
+
+      //Go down array of instruction strings
+
+      String printStr, remainingStr;
+      for( int i=0; i < instructions.length; i++ )
+       {
+         //chop up each into pieces maxSringLength long
+         remainingStr = instructions[ i ];
+         while( remainingStr.length() > 0 )
+          {
+            //if longer than max then chop off first max chars to print
+            if( remainingStr.length() >= maxStringLength )
+             {
+               //Try to chop on a word boundary
+               int posOfSpace = remainingStr.
+                  lastIndexOf( ' ', maxStringLength - 1 );
+
+               if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+               printStr = remainingStr.substring( 0, posOfSpace + 1 );
+               remainingStr = remainingStr.substring( posOfSpace + 1 );
+             }
+            //else just print
+            else
+             {
+               printStr = remainingStr;
+               remainingStr = "";
+             }
+
+            instructionsText.append( printStr + "\n" );
+
+          }// while
+
+       }// for
+
+    }//printInstructions()
+
+   //DO NOT call this directly, go through Sysout
+   public void displayMessage( String messageIn )
+    {
+      messageText.append( messageIn + "\n" );
+    }
+
+   //catch presses of the passed and failed buttons.
+   //simply call the standard pass() or fail() static methods of
+   //DialogOrient
+   public void actionPerformed( ActionEvent e )
+    {
+      if( e.getActionCommand() == "pass" )
+       {
+         Test6411624.pass();
+       }
+      else
+       {
+         Test6411624.fail();
+       }
+    }
+
+ }// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/MidiSystem/6411624/bug6411624.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2006, 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.
+ */
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.Synthesizer;
+import javax.sound.midi.Transmitter;
+
+/**
+ * This test should be run on specific environment (solaris or linux w/o
+ * audio card installed).
+ */
+public class bug6411624 {
+
+    public static void main(String args[]) throws Exception {
+        log("This test should only be run on solaris or linux system");
+        log("without audio card installed (to test on SunRay set");
+        log("incorrect $AUDIODEV value).");
+        readln();
+
+        boolean testRecv = false;
+        boolean testTrans = false;
+        boolean testSeq = true;
+
+        // print add info (midi device list)
+        try {
+            MidiDevice.Info[] midis = MidiSystem.getMidiDeviceInfo();
+            log("MidiDevices (total " + midis.length + "):");
+            for (int i=0; i<midis.length; i++) {
+                log("" + i + ": " + midis[i].toString());
+//                MidiDevice dev = MidiSystem.getMidiDevice(midis[i]);
+//                log("    device: " + dev);
+            }
+        } catch (Exception ex) {
+            log("!!!EXCEPTION:");
+            ex.printStackTrace();
+        }
+
+        log("");
+        log("getting default receiver...");
+        try {
+            Receiver rec = MidiSystem.getReceiver();
+            log(" - OK: " + rec);
+            testRecv = checkDevice(rec);
+            rec.close();
+        } catch (MidiUnavailableException e) {
+            log("MidiUnavailableException has been thrown - OK");
+            testRecv = true;
+        }
+
+
+        log("");
+        log("getting default transmitter...");
+        try {
+            Transmitter trans = MidiSystem.getTransmitter();
+            log(" - OK: " + trans);
+            testTrans = checkDevice(trans);
+            trans.close();
+        } catch (MidiUnavailableException e) {
+            log("MidiUnavailableException has been thrown - OK");
+            testTrans = true;
+        }
+
+
+        // print default synthesizer
+        log("");
+        log("getting default synth...");
+        try {
+            Synthesizer synth = MidiSystem.getSynthesizer();
+            log(" - OK: " + synth);
+            synth.close();
+        } catch (MidiUnavailableException e) {
+            log("MidiUnavailableException has been thrown - OK:");
+            e.printStackTrace();
+        }
+
+
+        log("");
+        log("getting default sequencer (connected)...");
+        try {
+            Sequencer seq = MidiSystem.getSequencer();
+            log("OK: " + seq);
+
+            // check that returned sequencer doesn't connected to another sequencer
+            log("  receivers:");
+            log("    max=" + seq.getMaxReceivers());
+            List<Receiver> recvList = seq.getReceivers();
+            log("    count=" + recvList.size());
+            Iterator<Receiver> recvIter = recvList.iterator();
+            int i = 0;
+            while (recvIter.hasNext()) {
+                Receiver recv = recvIter.next();
+                log("    " + (++i) + ": " + recv);
+            }
+
+            log("  transmitters:");
+            log("    max=" + seq.getMaxTransmitters());
+            List<Transmitter> transList = seq.getTransmitters();
+            log("    count=" + transList.size());
+            Iterator<Transmitter> transIter = transList.iterator();
+            i = 0;
+            while (transIter.hasNext()) {
+                Transmitter trans = transIter.next();
+                log("    " + (++i) + ": " + trans);
+                Receiver recv = trans.getReceiver();
+                log("      recv: " + recv);
+                if (!checkDevice(recv))
+                    testSeq = false;
+            }
+
+            log("opening sequencer...");
+            seq.open();
+            log("OK.");
+
+            log("closing...");
+            seq.close();
+            log("OK.");
+        } catch (MidiUnavailableException e) {
+            log("MidiUnavailableException has been thrown - OK:");
+            e.printStackTrace();
+        }
+
+
+        // debug testing - non-connected sequencer
+        log("");
+        log("getting default sequencer (non-connected)...");
+        try {
+            Sequencer seq = MidiSystem.getSequencer(false);
+            log("OK: " + seq);
+
+            log("  receivers:");
+            log("    max=" + seq.getMaxReceivers());
+            List<Receiver> recvList = seq.getReceivers();
+            log("    count=" + recvList.size());
+            Iterator<Receiver> recvIter = recvList.iterator();
+            int i = 0;
+            while (recvIter.hasNext()) {
+                Receiver recv = recvIter.next();
+                log("    " + (++i) + ": " + recv);
+            }
+
+            log("  transmitters:");
+            log("    max=" + seq.getMaxTransmitters());
+            List<Transmitter> transList = seq.getTransmitters();
+            log("    count=" + transList.size());
+            Iterator<Transmitter> transIter = transList.iterator();
+            i = 0;
+            while (transIter.hasNext()) {
+                Transmitter trans = transIter.next();
+                log("    " + (++i) + ": " + trans);
+                Receiver recv = trans.getReceiver();
+                log("      recv: " + recv);
+            }
+            seq.close();
+        } catch (MidiUnavailableException e) {
+            log("MidiUnavailableException has been thrown (shouln't?):");
+            e.printStackTrace();
+        }
+
+        log("");
+        log("Test result:");
+        // print results
+        if (testRecv && testTrans && testSeq) {
+            log("  All tests sucessfully passed.");
+        } else {
+            log("  Some tests failed:");
+            log("    receiver test:    " + (testRecv ? "OK" : "FAILED"));
+            log("    transmitter test: " + (testTrans ? "OK" : "FAILED"));
+            log("    sequencer test:   " + (testSeq ? "OK" : "FAILED"));
+        }
+        log("\n\n\n");
+    }
+
+    // check that device is not sequencer
+    static boolean checkDevice(Object dev) {
+        String className = dev.getClass().toString().toLowerCase();
+        boolean result = (className.indexOf("sequencer") < 0);
+        if (!result)
+            log("ERROR: inapropriate device");
+        return result;
+    }
+
+    // helper routines
+    static long startTime = currentTimeMillis();
+    static long currentTimeMillis() {
+        //return System.nanoTime() / 1000000L;
+        return System.currentTimeMillis();
+    }
+    static void log(String s) {
+        long time = currentTimeMillis() - startTime;
+        long ms = time % 1000;
+        time /= 1000;
+        long sec = time % 60;
+        time /= 60;
+        long min = time % 60;
+        time /= 60;
+        System.out.println(""
+                + (time < 10 ? "0" : "") + time
+                + ":" + (min < 10 ? "0" : "") + min
+                + ":" + (sec < 10 ? "0" : "") + sec
+                + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms
+                + " (" + Thread.currentThread().getName() + ") " + s);
+    }
+    static void delay(int millis) {
+        try {
+            Thread.sleep(millis);
+        } catch (InterruptedException e) {}
+    }
+    static void readln() {
+        log("");
+        log("Press ENTER to continue...");
+        try {
+            while (System.in.read() != 10) ;
+        } catch (IOException e) { }
+        log("");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/MidiSystem/DefaultDevices.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.util.List;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.Synthesizer;
+import javax.sound.midi.Transmitter;
+import javax.sound.midi.spi.MidiDeviceProvider;
+
+import com.sun.media.sound.JDK13Services;
+
+/**
+ * @test
+ * @bug 4776511
+ * @bug 4934509
+ * @bug 4938236
+ * @modules java.desktop/com.sun.media.sound
+ * @run main/timeout=600 DefaultDevices
+ * @summary RFE: Setting the default MixerProvider
+ */
+/** Test the retrieving of MidiDevices with default device properties.
+ * This is a part of the test for 4776511.
+ * The test also functions as a unit test for 4934509: SPEC: Document
+ * explicitely MidiSystem.getReceiver's behavior
+ * and a regession test for 4938236: Crash when opening synthesizer implicitly
+ * The test has been updated to reflect a fix for 6411624: MidiSystem.getSequencer()
+ * doesn't throw MidiUnavaivableException if no audio card installed (see also
+ * 6422786: regression test javax/sound/midi/MidiSystem/DefaultDevices.java fails)
+ */
+public class DefaultDevices {
+
+    private static final String ERROR_PROVIDER_CLASS_NAME = "abc";
+    private static final String ERROR_INSTANCE_NAME = "def";
+
+    private static final Class RECEIVER_CLASS = javax.sound.midi.Receiver.class;
+    private static final Class TRANSMITTER_CLASS = javax.sound.midi.Transmitter.class;
+    private static final Class SEQUENCER_CLASS = javax.sound.midi.Sequencer.class;
+    private static final Class SYNTHESIZER_CLASS = javax.sound.midi.Synthesizer.class;
+
+    public static void main(String[] args) throws Exception {
+        boolean allOk = true;
+        MidiDevice.Info[] infos;
+
+        out("\nTesting MidiDevices retrieved via MidiSystem");
+        infos = MidiSystem.getMidiDeviceInfo();
+        allOk &= testDevices(infos, null);
+
+        out("\nTesting MidiDevices retrieved from MidiDeviceProviders");
+        List providers = JDK13Services.getProviders(MidiDeviceProvider.class);
+        for (int i = 0; i < providers.size(); i++) {
+            MidiDeviceProvider provider = (MidiDeviceProvider)providers.get(i);
+            infos = provider.getDeviceInfo();
+            allOk &= testDevices(infos, provider.getClass().getName());
+        }
+
+        if (!allOk) {
+            throw new Exception("Test failed");
+        } else {
+            out("Test passed");
+        }
+    }
+
+    private static boolean testDevices(MidiDevice.Info[] infos,
+            String providerClassName) {
+        boolean allOk = true;
+
+        for (int i = 0; i < infos.length; i++) {
+            MidiDevice device = null;
+            try {
+                device = MidiSystem.getMidiDevice(infos[i]);
+            } catch (MidiUnavailableException e) {
+                out("Exception thrown; Test NOT failed.");
+                e.printStackTrace(System.out);
+                out("");
+            }
+            out("\nTesting device: " + device);
+            if (device instanceof Sequencer) {
+                allOk &= testDevice(device, SEQUENCER_CLASS, providerClassName, true, true);
+                // incorrect cases
+                allOk &= testDevice(device, SYNTHESIZER_CLASS, providerClassName, false, false);
+                allOk &= testDevice(device, RECEIVER_CLASS, providerClassName, false, false);
+                allOk &= testDevice(device, TRANSMITTER_CLASS, providerClassName, false, false);
+            }
+            if (device instanceof Synthesizer) {
+                allOk &= testDevice(device, SYNTHESIZER_CLASS, providerClassName, true, true);
+                allOk &= testDevice(device, RECEIVER_CLASS, providerClassName, false, true);
+                // incorrect cases
+                allOk &= testDevice(device, TRANSMITTER_CLASS, providerClassName, false, false);
+                allOk &= testDevice(device, SEQUENCER_CLASS, providerClassName, false, false);
+            }
+            if (device instanceof Receiver) {
+                allOk &= testDevice(device, RECEIVER_CLASS, providerClassName, true, true);
+                // incorrect cases
+                allOk &= testDevice(device, TRANSMITTER_CLASS, providerClassName, false, false);
+                allOk &= testDevice(device, SYNTHESIZER_CLASS, providerClassName, false, false);
+                allOk &= testDevice(device, SEQUENCER_CLASS, providerClassName, false, false);
+            }
+            if (device instanceof Transmitter) {
+                allOk &= testDevice(device, TRANSMITTER_CLASS, providerClassName, true, true);
+                // incorrect cases
+                allOk &= testDevice(device, RECEIVER_CLASS, providerClassName, false, false);
+                allOk &= testDevice(device, SYNTHESIZER_CLASS, providerClassName, false, false);
+                allOk &= testDevice(device, SEQUENCER_CLASS, providerClassName, false, false);
+            }
+        }
+        return allOk;
+    }
+
+    private static boolean testDevice(MidiDevice device, Class type,
+            String providerClassName, boolean testWrong, boolean expectedResult) {
+        boolean allOk = true;
+        String instanceName = device.getDeviceInfo().getName();
+
+        // no error
+        allOk &= testDevice(device, type, providerClassName,
+                            instanceName, expectedResult);
+
+        if (testWrong) {
+            // erroneous provider class name, correct instance name
+            allOk &= testDevice(device, type, ERROR_PROVIDER_CLASS_NAME,
+                                instanceName, expectedResult);
+
+            // correct provider class name, erroneous instance name
+            // we presume that provider provides only one class of requested type
+            allOk &= testDevice(device, type, providerClassName,
+                                ERROR_INSTANCE_NAME, expectedResult);
+        }
+
+        return allOk;
+    }
+
+    private static boolean testDevice(MidiDevice device, Class type,
+            String providerClassName, String instanceName,
+            boolean expectedResult) {
+        boolean allOk = true;
+
+        try {
+            String propertyName = type.getName();
+            String propertyValue = (providerClassName != null) ? providerClassName: "" ;
+            propertyValue += "#" + instanceName;
+            out("property: " + propertyName + "="+ propertyValue);
+            System.setProperty(propertyName, propertyValue);
+            Object reference = null;
+            Object result = null;
+            if (type == SEQUENCER_CLASS) {
+                reference = device;
+                result = MidiSystem.getSequencer();
+            } else if (type == SYNTHESIZER_CLASS) {
+                reference = device;
+                result = MidiSystem.getSynthesizer();
+            } else if (type == RECEIVER_CLASS) {
+                reference = device.getReceiver();
+                result = MidiSystem.getReceiver();
+            } else if (type == TRANSMITTER_CLASS) {
+                reference = device.getTransmitter();
+                result = MidiSystem.getTransmitter();
+            }
+            out("result: " + result);
+            boolean rightDevice = (reference.getClass() == result.getClass());
+            if (rightDevice != expectedResult) {
+                out("\nERROR: type " + type + " failed:"
+                        + " class should" + (expectedResult ? "" : " NOT") + " be '"
+                        + reference.getClass()
+                        + "' but is '" + result.getClass() + "'!\n");
+                allOk = false;
+            }
+            if (expectedResult
+                    && reference instanceof MidiDevice
+                    && result instanceof MidiDevice) {
+                MidiDevice referenceDevice = (MidiDevice)reference;
+                MidiDevice resultDevice = (MidiDevice)result;
+                if (!referenceDevice.getDeviceInfo().getName().equals(
+                                    resultDevice.getDeviceInfo().getName())) {
+                    out("\nERROR: type " + type + " failed: name should be '"
+                            + referenceDevice.getDeviceInfo().getName()
+                            + "' but is '"
+                            + resultDevice.getDeviceInfo().getName() + "'!\n");
+                    allOk = false;
+                }
+            }
+            if (result instanceof Receiver) {
+                ((Receiver)result).close();
+            } else if (result instanceof Transmitter) {
+                ((Transmitter)result).close();
+            } else if (result instanceof Synthesizer) {
+                ((Synthesizer)result).close();
+            } else if (result instanceof Sequencer) {
+                ((Sequencer)result).close();
+            }
+        } catch (Exception e) {
+            out("Exception thrown; Test NOT failed.");
+            e.printStackTrace(System.out);
+            out("");
+        }
+        return allOk;
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/MidiSystem/DefaultProperties.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.File;
+
+import com.sun.media.sound.JDK13Services;
+
+/**
+ * @test
+ * @bug 4776511
+ * @summary RFE: Setting the default MixerProvider. Test the retrieving and
+ *          parsing of properties. This is a part of the test for 4776511.
+ * @run main/othervm DefaultProperties
+ * @modules java.desktop/com.sun.media.sound
+ */
+public class DefaultProperties {
+
+    private static final Class[] lineTypeClasses = {
+        javax.sound.midi.Receiver.class,
+        javax.sound.midi.Transmitter.class,
+        javax.sound.midi.Sequencer.class,
+        javax.sound.midi.Synthesizer.class,
+    };
+
+    public static void main(String[] args) throws Exception {
+        boolean allOk = true;
+        File file = new File(System.getProperty("test.src", "."), "testdata");
+        System.setProperty("java.home", file.getCanonicalPath());
+
+        for (int i = 0; i < lineTypeClasses.length; i++) {
+            Class cls = lineTypeClasses[i];
+            String propertyName = cls.getName();
+            String result;
+            String provClassName;
+            String instanceName;
+
+            // properties file, both provider class name and instance name
+            provClassName = "xyz";
+            instanceName = "123";
+            result = JDK13Services.getDefaultProviderClassName(cls);
+            if (! provClassName.equals(result)) {
+                out("type " + cls + " failed: provider class should be '" +
+                    provClassName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+            result = JDK13Services.getDefaultInstanceName(cls);
+            if (! instanceName.equals(result)) {
+                out("type " + cls + " failed: instance name should be '" +
+                    instanceName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+
+            // system property, provider class name only, no trailing hash
+            provClassName = "abc";
+            System.setProperty(propertyName, provClassName);
+            result = JDK13Services.getDefaultProviderClassName(cls);
+            if (! provClassName.equals(result)) {
+                out("type " + cls + " failed: provider class should be '" +
+                    provClassName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+            result = JDK13Services.getDefaultInstanceName(cls);
+            if (result != null) {
+                out("type " + cls + " failed: instance name should be " +
+                    "null but is '" + result + "'!");
+                allOk = false;
+            }
+
+            // system property, provider class name only, trailing hash
+            provClassName = "def";
+            System.setProperty(propertyName, provClassName + "#");
+            result = JDK13Services.getDefaultProviderClassName(cls);
+            if (! provClassName.equals(result)) {
+                out("type " + cls + " failed: provider class should be '" +
+                    provClassName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+            result = JDK13Services.getDefaultInstanceName(cls);
+            if (result != null) {
+                out("type " + cls + " failed: instance name should be " +
+                    "null but is '" + result + "'!");
+                allOk = false;
+            }
+
+            // system property, instance name only
+            instanceName = "ghi";
+            System.setProperty(propertyName, "#" + instanceName);
+            result = JDK13Services.getDefaultProviderClassName(cls);
+            if (result != null) {
+                out("type " + cls + " failed: provider class should be " +
+                    "null but is '" + result + "'!");
+                allOk = false;
+            }
+            result = JDK13Services.getDefaultInstanceName(cls);
+            if (! instanceName.equals(result)) {
+                out("type " + cls + " failed: instance name should be '" +
+                    instanceName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+
+            // system property, both provider class and instance name
+            provClassName = "jkl";
+            instanceName = "mno";
+            System.setProperty(propertyName, provClassName + "#" + instanceName);
+            result = JDK13Services.getDefaultProviderClassName(cls);
+            if (! provClassName.equals(result)) {
+                out("type " + cls + "failed: provider class should be '" +
+                    provClassName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+            result = JDK13Services.getDefaultInstanceName(cls);
+            if (! instanceName.equals(result)) {
+                out("type " + cls + "failed: instance name should be '" +
+                    instanceName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+
+            // system property, empty
+            System.setProperty(propertyName, "");
+            result = JDK13Services.getDefaultProviderClassName(cls);
+            if (result != null) {
+                out("type " + cls + " failed: provider class should be " +
+                    "null but is '" + result + "'!");
+                allOk = false;
+            }
+            result = JDK13Services.getDefaultInstanceName(cls);
+            if (result != null) {
+                out("type " + cls + "failed: instance name should be " +
+                    "null but is '" + result + "'!");
+                allOk = false;
+            }
+        }
+        if (! allOk) {
+            throw new Exception("Test failed");
+        } else {
+            out("Test passed");
+        }
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/MidiSystem/GetSequencer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.util.List;
+
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.Transmitter;
+
+/**
+ * @test
+ * @bug 4931400
+ * @summary Clarify default connections in default sequencer
+ */
+public class GetSequencer {
+
+    static boolean failed = false;
+
+    public static void main(String args[]) throws Exception {
+        doTest(1);
+        doTest(2);
+        doTest(3);
+
+        if (failed) throw new Exception("Test FAILED!");
+        out("test OK");
+    }
+
+    public static void doTest(int mode) {
+        Sequencer seq = null;
+        boolean connected = false;
+
+        try {
+            switch (mode) {
+            case 1:
+                seq = MidiSystem.getSequencer();
+                connected = true;
+                break;
+            case 2:
+                seq = MidiSystem.getSequencer(false);
+                connected = false;
+                break;
+            case 3:
+                seq = MidiSystem.getSequencer(true);
+                connected = true;
+                break;
+            }
+            out("Testing Sequencer "+seq);
+            if (connected) {
+                out("  opened in connected mode.");
+            } else {
+                out("  opened in non-connected mode.");
+            }
+            System.out.println("  opening...");
+            seq.open();
+        } catch (MidiUnavailableException mue) {
+            System.err.println("MidiUnavailableException was thrown: " + mue);
+            System.err.println("  could not test this sequencer.");
+            return;
+        }
+
+        try {
+            List<Transmitter> transmitters = seq.getTransmitters();
+            int size = transmitters.size();
+            out("  transmitters.size()="+size);
+            if (size != 1 && connected) {
+                out("  should have 1 connection! Failed.");
+                failed = true;
+            }
+            if (size != 0 && !connected) {
+                out("  should have 0 connections! Failed.");
+                failed = true;
+            }
+            out("  closing...");
+            seq.close();
+            transmitters = seq.getTransmitters();
+            size = transmitters.size();
+            out("  transmitters.size()="+size);
+            if (size != 0) {
+                out("  should have 0 connections! Failed.");
+                failed = true;
+            }
+
+            out("  opening again...");
+            seq.open();
+            transmitters = seq.getTransmitters();
+            size = transmitters.size();
+            out("  transmitters.size()="+size);
+            if (size != 1 && connected) {
+                out("  should have 1 connection! Failed.");
+                failed = true;
+            }
+            if (size != 0 && !connected) {
+                out("  should have 0 connections! Failed.");
+                failed = true;
+            }
+        } catch (Exception e) {
+            System.err.println("  unexpectedException was thrown: " + e);
+            System.err.println("  causes this test to FAIL.");
+            failed = true;
+        }
+        seq.close();
+    }
+
+    static void out(String s) {
+        System.out.println(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/MidiSystem/MidiFileTypeUniqueness.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.midi.MidiSystem;
+
+/**
+ * @test
+ * @bug 4883060
+ * @summary  AudioSystem.getAudioFileTypes returns duplicates
+ */
+public class MidiFileTypeUniqueness {
+
+    public static void main(String[] args) throws Exception {
+        boolean foundDuplicates = false;
+        int[]   aTypes = MidiSystem.getMidiFileTypes();
+        for (int i = 0; i < aTypes.length; i++)
+        {
+            for (int j = 0; j < aTypes.length; j++)
+            {
+                if (aTypes[i] == aTypes[j] && i != j) {
+                    foundDuplicates = true;
+                }
+            }
+        }
+        if (foundDuplicates) {
+            throw new Exception("Test failed");
+        } else {
+            System.out.println("Test passed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/MidiSystem/ProviderCacheing.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.util.List;
+
+import com.sun.media.sound.JDK13Services;
+
+/**
+ * @test
+ * @bug 4776511
+ * @summary RFE: Setting the default MixerProvider. Test the cacheing of
+ *          providers. This is a part of the test for 4776511.
+ * @modules java.desktop/com.sun.media.sound
+ */
+public class ProviderCacheing {
+
+    private static final Class[] providerClasses = {
+        javax.sound.midi.spi.MidiDeviceProvider.class,
+        javax.sound.midi.spi.MidiFileReader.class,
+        javax.sound.midi.spi.MidiFileWriter.class,
+        javax.sound.midi.spi.SoundbankReader.class,
+    };
+
+    public static void main(String[] args) throws Exception {
+        boolean allCached = true;
+        for (int i = 0; i < providerClasses.length; i++) {
+            List list0 = JDK13Services.getProviders(providerClasses[i]);
+            List list1 = JDK13Services.getProviders(providerClasses[i]);
+            if (list0 == list1) {
+                out("Providers should not be cached for " + providerClasses[i]);
+                allCached = false;
+            }
+        }
+
+        if (! allCached) {
+            throw new Exception("Test failed");
+        } else {
+            out("Test passed");
+        }
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/MidiSystem/testdata/lib/conf/sound.properties	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2003, 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.
+#
+
+javax.sound.midi.Receiver=xyz#123
+javax.sound.midi.Transmitter=xyz#123
+javax.sound.midi.Sequencer=xyz#123
+javax.sound.midi.Synthesizer=xyz#123
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequence/GetMicrosecondLength.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4929955
+ * @summary Sequence.getMicrosecondLength() returns wrong value
+ */
+public class GetMicrosecondLength {
+
+    public static boolean failed = false;
+    //private static Sequencer seq = null;
+
+    public static void main(String[] args) throws Exception {
+        /*
+          try {
+          seq = MidiSystem.getSequencer();
+          } catch (Exception e) {
+          e.printStackTrace();
+          }
+        */
+        for (int sec = 1; sec < 10; sec += 4) {
+            for (int tempo=0; tempo < 1000; tempo+=120) {
+                for (int resolution=1; resolution < 480; ) {
+                    testSequence(sec, tempo, resolution);
+                    if (resolution == 1) {
+                        resolution = 120;
+                    } else {
+                        resolution += 120;
+                    }
+                }
+            }
+        }
+        if (failed) throw new Exception("Test FAILED!");
+        out("Test Passed.");
+    }
+
+    /**
+     * Create a new Sequence for testing.
+     */
+    private static void testSequence(int lengthInSeconds, int tempoInBPM, int resolution) {
+        Sequence sequence = null;
+        long lengthInMicroseconds = lengthInSeconds * 1000000;
+        boolean createTempoEvent = true;
+        if (tempoInBPM == 0) {
+            tempoInBPM = 120;
+            createTempoEvent = false;
+            System.out.print("Creating sequence: "+lengthInSeconds+"sec, "
+                             +"resolution="+resolution+" ticks/beat...");
+        } else {
+            System.out.print("Creating sequence: "+lengthInSeconds+"sec, "
+                             +tempoInBPM+" beats/min, "
+                             +"resolution="+resolution+" ticks/beat...");
+        }
+        //long lengthInTicks = (lengthInMicroseconds * resolution) / tempoInBPM;
+        long lengthInTicks = (lengthInMicroseconds * tempoInBPM * resolution) / 60000000l;
+        //out("expected length in ticks: " + lengthInTicks);
+        try {
+            sequence = new Sequence(Sequence.PPQ, resolution);
+            Track track = sequence.createTrack();
+            if (createTempoEvent) {
+                int tempoInMPQ = (int) (60000000l / tempoInBPM);
+                MetaMessage tm = new MetaMessage();
+                byte[] msg = new byte[3];
+                msg[0] = (byte) (tempoInMPQ >> 16);
+                msg[1] = (byte) ((tempoInMPQ >> 8) & 0xFF);
+                msg[2] = (byte) (tempoInMPQ & 0xFF);
+
+                tm.setMessage(0x51 /* Meta Tempo */, msg, msg.length);
+                track.add(new MidiEvent(tm, 0));
+                //out("regtest: tempoInMPQ="+tempoInMPQ);
+                //out("Added tempo event: new size="+track.size());
+            }
+            ShortMessage mm = new ShortMessage();
+            mm.setMessage(0xF6, 0, 0);
+            MidiEvent me = new MidiEvent(mm, lengthInTicks);
+            track.add(me);
+            //out("Added realtime event: new size="+track.size());
+        } catch (InvalidMidiDataException e) {
+            out(e);
+        }
+        boolean thisFailed = false;
+        long actualLengthInTicks = sequence.getTickLength();
+        // allow +/- 5%
+        if (Math.abs(actualLengthInTicks - lengthInTicks) > lengthInTicks / 20) {
+            out("FAILED:");
+            out("  expected length in ticks: " + lengthInTicks);
+            out("  actual length in ticks  : " + actualLengthInTicks);
+            thisFailed = true;
+        }
+        long actualLengthInUs = sequence.getMicrosecondLength();
+        // allow +/- 5%
+        if (Math.abs(actualLengthInUs - lengthInMicroseconds) > lengthInMicroseconds / 20) {
+            if (!thisFailed) {
+                out("FAILED:");
+            }
+            out("  expected length in microsecs: " + lengthInMicroseconds);
+            out("  actual length in microsecs  : " + actualLengthInUs);
+            thisFailed = true;
+        }
+        if (!thisFailed) {
+            out("OK");
+        }
+        /*if (seq != null) {
+          try {
+          seq.setSequence(sequence);
+          out("Sequencer tempo="+seq.getTempoInBPM());
+          } catch (Exception e) {
+          e.printStackTrace();
+          }
+          }
+        */
+        failed |= thisFailed;
+    }
+
+
+    private static void out(Throwable t) {
+        t.printStackTrace(System.out);
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequence/MidiSMPTE.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+
+/**
+ * @test
+ * @bug 4291250
+ * @summary Midi files with SMPTE time do not play properly
+ */
+public class MidiSMPTE {
+
+    public static void main(String[] args) throws Exception {
+        Sequence s = null;
+        //File midiFile = new File("outsmpte.mid");
+        //InputStream is = new FileInputStream(midiFile);
+        //is = new BufferedInputStream(is);
+        InputStream is = new ByteArrayInputStream(smptemidifile);
+        s = MidiSystem.getSequence(is);
+        long duration = s.getMicrosecondLength() / 1000000;
+        System.out.println("Duration: "+duration+" seconds ");
+        if (duration > 14) {
+            throw new Exception("SMPTE time reader is broken! Test FAILED");
+        }
+        System.out.println("Test passed");
+    }
+
+    public static void printFile(String filename) throws Exception {
+        File file = new File(filename);
+        FileInputStream fis = new FileInputStream(file);
+        byte[] data = new byte[(int) file.length()];
+        fis.read(data);
+        String s = "";
+        for (int i=0; i<data.length; i++) {
+            s+=String.valueOf(data[i])+", ";
+            if (s.length()>72) {
+                System.out.println(s);
+                s="";
+            }
+        }
+        System.out.println(s);
+    }
+
+    // A MIDI file with SMPTE timing
+    static byte[] smptemidifile = {
+            77, 84, 104, 100, 0, 0, 0, 6, 0, 1, 0, 3, -30, 120, 77, 84, 114, 107, 0,
+            0, 0, 123, 0, -112, 30, 100, -113, 49, -128, 50, 100, -114, 69, -112, 31,
+            100, -114, 33, -128, 51, 100, -114, 55, -112, 32, 100, -114, 120, -128, 52,
+            100, -114, 40, -112, 33, 100, -114, 26, -128, 53, 100, -114, 26, -112, 34,
+            100, -114, 76, -128, 54, 100, -114, 12, -112, 35, 100, -114, 91, -128, 55,
+            100, -114, 69, -112, 36, 100, -114, 33, -128, 56, 100, -114, 55, -112, 37,
+            100, -114, 84, -128, 57, 100, -114, 40, -112, 38, 100, -114, 26, -128, 58,
+            100, -114, 26, -112, 39, 100, -113, 24, -128, 59, 100, -113, 60, -112, 40,
+            100, -113, 110, -128, 60, 100, -113, 96, -112, 41, 100, -113, 39, -128, 61,
+            100, 0, -1, 47, 0, 77, 84, 114, 107, 0, 0, 0, 4, 0, -1, 47, 0, 77, 84, 114,
+            107, 0, 0, 0, 4, 0, -1, 47, 0
+    };
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequence/SMPTEDuration.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4702328
+ * @summary Wrong time in sequence for SMPTE based types
+ */
+public class SMPTEDuration {
+
+    public static void main(String args[]) throws Exception {
+         int[][] dataMes =  { {ShortMessage.NOTE_ON, 10, 0x24, 0x50} ,
+                 { ShortMessage.NOTE_OFF, 10, 0x24, 0x44 },
+                 { ShortMessage.NOTE_ON, 10, 0x24, 0x50 },
+                 { ShortMessage.NOTE_ON, 10, 0x26, 0x50 },
+                 { ShortMessage.NOTE_OFF, 10, 0x26, 0x53 } };
+         long[] ticks = { 0, 68, 240, 240, 286};
+         int res = 240;
+         ShortMessage msg;
+         Sequence midiData = null;
+         Track track;
+         boolean failed = false;
+
+
+         try {
+             midiData = new Sequence(Sequence.SMPTE_24 , res);
+         } catch (InvalidMidiDataException invMidiEx) {
+             invMidiEx.printStackTrace(System.out);
+             System.out.println("Unexpected InvalidMidiDataException: "
+                     + invMidiEx.getMessage());
+             failed = true;
+         }
+         track = midiData.createTrack();
+         for (int i = 0; i < dataMes.length; i++) {
+             msg = new ShortMessage();
+             try {
+                 msg.setMessage(dataMes[i][0], dataMes[i][1], dataMes[i][2],
+                         dataMes[i][3]);
+             } catch (InvalidMidiDataException invMidiEx) {
+                 invMidiEx.printStackTrace(System.out);
+                 System.out.println("Unexpected InvalidMidiDataException: "
+                         + invMidiEx.getMessage());
+                 failed = true;
+             }
+             track.add(new MidiEvent(msg, ticks[i]));
+         }
+         //   lengthInMs = (tickLength*1000000)/(divType*Res)
+         long micros = (long) ((midiData.getTickLength() * 1000000) / (res * Sequence.SMPTE_24));
+         if (midiData.getMicrosecondLength() != micros) {
+             failed = true;
+             System.out.println("getMicrosecondLength() returns wrong length: "
+                     + midiData.getMicrosecondLength());
+             System.out.println("getMicrosecondLength() must return length: "
+                     + micros);
+         }
+         if (midiData.getTickLength() != 286) {
+             failed = true;
+             System.out.println("getTickLength() returns wrong length: "
+                     + midiData.getTickLength());
+         }
+
+         if( failed == true ) {
+             throw new Exception("test failed");
+         } else {
+             System.out.println("Passed.");
+         }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequencer/LoopIAE.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 5025549
+ * @summary Verify that setLoopEndPoint throws IAE
+ */
+public class LoopIAE {
+
+    static ShortMessage MidiMsg3(int a, int b, int c) {
+        try {
+            ShortMessage msg = new ShortMessage();
+            msg.setMessage((byte)a,(byte)b,(byte)c);
+            return msg;
+        } catch(InvalidMidiDataException ex) {
+            throw new RuntimeException();
+        }
+    }
+
+    static boolean failed = false;
+
+    public static void main(String[] argv) throws Exception {
+        if (!hasSequencer()) {
+            return;
+        }
+        Sequencer sequencer = MidiSystem.getSequencer();
+        Sequence sequence = new Sequence(Sequence.PPQ, 240);
+        Track track = sequence.createTrack();
+
+        track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+0,45,100),0));
+        track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+0,45,0),0 + 240));
+        track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+9,45,100),10*20));
+        track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+9,45,0),10*20 + 10));
+
+        try {
+            sequencer.open();
+            sequencer.setSequence(sequence);
+            sequencer.setTempoInBPM(100);
+
+            System.out.println("Setting loop end point to 1");
+            sequencer.setLoopEndPoint(1);
+            System.out.println("  -> effectively: "+sequencer.getLoopEndPoint());
+            System.out.println("Setting loop start point to 2 -- should throw IAE");
+            sequencer.setLoopStartPoint(2);
+            System.out.println("  -> effectively: "+sequencer.getLoopStartPoint());
+            System.out.println("No IllegalArgumentException was thrown!");
+            failed = true;
+        } catch (IllegalArgumentException iae) {
+            System.out.println("IAE was thrown correctly.");
+        } catch (MidiUnavailableException mue) {
+            System.out.println("MidiUnavailableException was thrown: " + mue);
+            System.out.println("Cannot execute test.");
+        } catch (InvalidMidiDataException imEx) {
+            System.out.println("InvalidMidiDataException was thrown.");
+            imEx.printStackTrace();
+            System.out.println("Cannot execute test.");
+        } finally {
+            if (sequencer != null && sequencer.isOpen()) {
+                sequencer.close();
+            }
+        }
+        if (failed) {
+            throw new Exception("Test FAILED!");
+        }
+        System.out.println("test passed.");
+    }
+
+    static boolean hasSequencer() {
+        try {
+            Sequencer seq = MidiSystem.getSequencer();
+            if (seq != null) {
+                if (seq.isOpen()) {
+                    seq.close();
+                }
+                return true;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        System.out.println("No sequencer available! Cannot execute test.");
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequencer/Looping.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MetaEventListener;
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4204105
+ * @summary RFE: add loop() method(s) to Sequencer
+ * @key intermittent
+ */
+public class Looping {
+
+    public static void main(String[] args) throws Exception {
+        out("4204105: RFE: add loop() method(s) to Sequencer");
+        boolean passed = testAll();
+        if (passed) {
+            out("Test PASSED.");
+        } else {
+            throw new Exception("Test FAILED.");
+        }
+    }
+
+    /**
+     * Execute the test on all available Sequencers.
+     *
+     * @return true if the test passed for all Sequencers, false otherwise
+     */
+    private static boolean testAll() throws Exception {
+        boolean result = true;
+        MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
+        for (int i = 0; i < devices.length; i++) {
+            MidiDevice device = MidiSystem.getMidiDevice(devices[i]);
+            if (device instanceof Sequencer) {
+                result &= testSequencer((Sequencer) device);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Execute the test on the passed Sequencer.
+     *
+     * @return true if the test is passed this Sequencer, false otherwise
+     */
+    private static boolean testSequencer(Sequencer seq) throws Exception{
+        boolean result = true;
+        out("testing: " + seq);
+
+        result &= testGetSet(seq);
+
+        seq.setSequence(createSequence());
+
+        result &= testGetSet(seq);
+
+        result &= testPlay(seq);
+
+        return result;
+    }
+
+    private static boolean testGetSet(Sequencer seq) {
+        boolean result = true;
+        Sequence sequence = seq.getSequence();
+        boolean isSequenceLoaded = (sequence != null);
+
+        out("TestGetSet");
+
+        try {
+            if (seq.getLoopStartPoint() != 0) {
+                out("start point", isSequenceLoaded,
+                    "isn't 0!");
+                result = false;
+            }
+        } catch (IllegalArgumentException iae) {
+            if (!isSequenceLoaded) {
+                out("Caught permissable IllegalArgumentException:");
+            } else {
+                out("Threw unacceptable IllegalArgumentException! FAILED");
+                result = false;
+            }
+            out(iae.toString());
+        }
+
+        if (seq.getLoopEndPoint() != -1) {
+            out("end point", isSequenceLoaded,
+                "isn't -1!");
+            result = false;
+        }
+
+        try {
+            seq.setLoopStartPoint(25);
+            if (seq.getLoopStartPoint() != 25) {
+                out("setLoopStartPoint()", isSequenceLoaded,
+                    "doesn't set the start point correctly!");
+                result = false;
+            }
+        } catch (IllegalArgumentException iae) {
+            if (!isSequenceLoaded) {
+                out("Caught permissable IllegalArgumentException:");
+            } else {
+                out("Threw unacceptable IllegalArgumentException! FAILED");
+                result = false;
+            }
+            out(iae.toString());
+        }
+
+        try {
+            seq.setLoopEndPoint(26);
+            if (seq.getLoopEndPoint() != 26) {
+                out("setLoopEndPoint()", isSequenceLoaded,
+                    "doesn't set the end point correctly!");
+                result = false;
+            }
+        } catch (IllegalArgumentException iae) {
+            if (!isSequenceLoaded) {
+                out("Caught permissable IllegalArgumentException:");
+            } else {
+                out("Threw unacceptable IllegalArgumentException! FAILED");
+                result = false;
+            }
+            out(iae.toString());
+        }
+
+        try {
+            seq.setLoopStartPoint(0);
+            if (seq.getLoopStartPoint() != 0) {
+                out("setLoopStartPoint()", isSequenceLoaded,
+                    "doesn't set the start point correctly!");
+                result = false;
+            }
+        } catch (IllegalArgumentException iae) {
+            if (!isSequenceLoaded) {
+                out("Caught permissable IllegalArgumentException:");
+            } else {
+                out("Threw unacceptable IllegalArgumentException! FAILED");
+                result = false;
+            }
+            out(iae.toString());
+        }
+
+        if (isSequenceLoaded) {
+            seq.setLoopEndPoint(sequence.getTickLength());
+            if (seq.getLoopEndPoint() != sequence.getTickLength()) {
+                out("setLoopEndPoint()", isSequenceLoaded,
+                    "doesn't set the end point correctly!");
+                result = false;
+            }
+        } else {
+            // fails
+            seq.setLoopEndPoint(-1);
+            if (seq.getLoopEndPoint() != -1) {
+                out("setLoopEndPoint()", isSequenceLoaded,
+                    "doesn't set the end point correctly!");
+                result = false;
+            }
+        }
+
+        if (seq.getLoopCount() != 0) {
+            out("loop count", isSequenceLoaded,
+                "isn't 0!");
+            result = false;
+        }
+
+        seq.setLoopCount(1001);
+        if (seq.getLoopCount() != 1001) {
+            out("setLoopCount()", isSequenceLoaded,
+                "doesn't set the loop count correctly!");
+            result = false;
+        }
+
+        seq.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
+        if (seq.getLoopCount() != Sequencer.LOOP_CONTINUOUSLY) {
+            out("setLoopCount(Sequencer.LOOP_CONTINUOUSLY)", isSequenceLoaded,
+                "doesn't set the loop count correctly!");
+            result = false;
+        }
+
+        try {
+            seq.setLoopCount(-55);
+            out("setLoopCount()", isSequenceLoaded,
+                "doesn't throw IllegalArgumentException on illegal value!");
+            result = false;
+        } catch (IllegalArgumentException e) {
+            // EXCEPTION IS EXPECTED
+            out("Caught permissable IAE");
+        }
+
+        seq.setLoopCount(0);
+        if (seq.getLoopCount() != 0) {
+            out("setLoopCount()", isSequenceLoaded,
+                "doesn't set the loop count correctly!");
+            result = false;
+        }
+
+        return result;
+    }
+
+    private static boolean testPlay(Sequencer seq) {
+        boolean result = true;
+        long stopTime;
+
+        out("TestPlay");
+
+        TestMetaEventListener listener = new TestMetaEventListener();
+        seq.addMetaEventListener(listener);
+        long startTime = System.currentTimeMillis();
+        try {
+            seq.open();
+            out("Playing sequence, length="+(seq.getMicrosecondLength()/1000)+"millis");
+            seq.start();
+            while (true) {
+                stopTime = listener.getStopTime();
+                if (stopTime != 0) {
+                    break;
+                }
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                }
+            }
+            long measuredDuration = stopTime - startTime;
+            out("play duration (us): " + measuredDuration);
+        } catch (Exception e) {
+            out("test not executed; exception:");
+            e.printStackTrace();
+        }
+        seq.close();
+        return result;
+    }
+
+    /**
+     * Create a new Sequence for testing.
+     *
+     * @return a dummy Sequence, or null, if a problem occured while creating
+     *         the Sequence
+     */
+    private static Sequence createSequence() {
+        Sequence sequence = null;
+        int lengthInSeconds = 2;
+        long lengthInMicroseconds = lengthInSeconds * 1000000;
+        int resolution = 480;
+        long lengthInTicks = (lengthInMicroseconds * 120 * resolution) / 60000000l;
+        out("length in ticks: " + lengthInTicks);
+        try {
+            sequence = new Sequence(Sequence.PPQ, resolution, 1);
+            Track track = sequence.createTrack();
+            ShortMessage mm = new ShortMessage();
+            mm.setMessage(0xF6, 0, 0);
+            MidiEvent me = new MidiEvent(mm, lengthInTicks);
+            track.add(me);
+        } catch (InvalidMidiDataException e) {
+            // DO NOTHING
+        }
+        out("sequence length (ticks): " + sequence.getTickLength());
+        out("sequence length (us): " + sequence.getMicrosecondLength());
+        return sequence;
+    }
+
+
+    private static void out(String m1, boolean isSequenceLoaded, String m2) {
+        out(m1 + (isSequenceLoaded ? " with Sequence " : " without Sequence ") + m2);
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+
+    private static class TestMetaEventListener implements MetaEventListener {
+        private long stopTime;
+
+
+        public void meta(MetaMessage m) {
+            System.out.print("  Got MetaMessage: ");
+            if (m.getType() == 47) {
+                stopTime = System.currentTimeMillis();
+                System.out.println(" End Of Track -- OK");
+            } else {
+                System.out.println(" unknown. Ignored.");
+            }
+        }
+
+        public long getStopTime() {
+            return stopTime;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequencer/MetaCallback.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MetaEventListener;
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4347135
+ * @summary MIDI MetaMessage callback inconsistent
+ * @run main/othervm MetaCallback
+ */
+public class MetaCallback implements MetaEventListener {
+
+    static ShortMessage MidiMsg3(int a, int b, int c) {
+        try {
+            ShortMessage msg = new ShortMessage();
+            msg.setMessage((byte)a,(byte)b,(byte)c);
+            return msg;
+        } catch(InvalidMidiDataException ex) {
+            throw new RuntimeException();
+        }
+    }
+
+    //Synthesizer synth;
+    Instrument[] instruments;
+    Sequencer sequencer;
+    Sequence sequence;
+    Track track;
+
+    public static int TOTAL_COUNT = 100;
+
+    int metaCount = 0;
+    boolean finished = false;
+
+    MetaCallback() throws Exception {
+
+        sequencer=MidiSystem.getSequencer();
+        sequence=new Sequence(Sequence.PPQ,240);
+        track=sequence.createTrack();
+        sequencer.addMetaEventListener(this);
+
+        byte[] data = new byte[1];
+
+        track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+0,45,100),0));
+        track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+0,45,0),0 + 240));
+        int c;
+        for(c=0; c < TOTAL_COUNT; c++) {
+            data[0]=(byte)(c+1);
+            MetaMessage meta = new MetaMessage();
+            meta.setMessage(1, data, 1); // type, data, length
+            track.add(new MidiEvent(meta,c*20));
+        }
+        track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+9,45,100),c*20));
+        track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+9,45,0),c*20 + 10));
+
+        sequencer.setSlaveSyncMode(Sequencer.SyncMode.INTERNAL_CLOCK);
+        sequencer.setMasterSyncMode(Sequencer.SyncMode.INTERNAL_CLOCK);
+        sequencer.open();
+        sequencer.setSequence(sequence);
+        sequencer.setTempoInBPM(100);
+        System.out.println("Starting playback...");
+        this.start();
+        while (!finished && sequencer.getTickPosition() < sequencer.getTickLength()) {
+            System.out.println("Tick "+sequencer.getTickPosition()+"...");
+            Thread.sleep(1000);
+        }
+        System.out.println("Stopping playback...");
+        this.stop();
+        if (metaCount != TOTAL_COUNT) {
+            throw new Exception("Expected "+TOTAL_COUNT+" callbacks, but got "+metaCount+"!");
+        }
+    }
+    void start() {sequencer.start();}
+    void stop() {sequencer.stop();}
+
+    public void meta(MetaMessage msg) {
+        System.out.println(""+metaCount+": got "+msg);
+        if (msg.getType() == 0x2F) {
+            finished = true;
+        } else if (msg.getData().length > 0 && msg.getType() == 1) {
+            metaCount++;
+        }
+    }
+
+    public static void main(String[] argv) throws Exception {
+        if (hasSequencer()) {
+            new MetaCallback();
+            System.out.println("Test passed");
+        }
+    }
+
+    static boolean hasSequencer() {
+        try {
+            Sequencer seq = MidiSystem.getSequencer();
+            if (seq != null) {
+                seq.open();
+                seq.close();
+                return true;
+            }
+        } catch (Exception e) {}
+        System.out.println("No sequencer available! Cannot execute test.");
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequencer/Recording.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4932841
+ * @key intermittent
+ * @summary Sequencer's recording feature does not work
+ */
+public class Recording {
+
+    public static boolean failed = false;
+    public static boolean passed = false;
+    private static Sequencer seq = null;
+
+    public static void main(String[] args) throws Exception {
+        try {
+            seq = MidiSystem.getSequencer();
+
+            // create an arbitrary sequence which lasts 10 seconds
+            Sequence sequence = createSequence(10, 120, 240);
+
+            seq.setSequence(sequence);
+            out("Set Sequence to Sequencer. Tempo="+seq.getTempoInBPM());
+
+            Track track = sequence.createTrack();
+            int oldSize = track.size();
+            seq.recordEnable(track, -1);
+
+            seq.open();
+
+            // if getReceiver throws Exception, failed!
+            failed = true;
+            Receiver rec = seq.getReceiver();
+
+            // start recording and add various events
+            seq.startRecording();
+
+            // is exception from here on, not failed
+            failed = false;
+
+            if (!seq.isRecording()) {
+                failed = true;
+                throw new Exception("Sequencer did not start recording!");
+            }
+            if (!seq.isRunning()) {
+                failed = true;
+                throw new Exception("Sequencer started recording, but is not running!");
+            }
+
+            // first: add an event to the middle of the sequence
+            ShortMessage msg = new ShortMessage();
+            msg.setMessage(0xC0, 80, 00);
+            rec.send(msg, 5l * 1000l * 1000l);
+
+            Thread.sleep(1000);
+
+            // then add a real-time event
+            msg = new ShortMessage();
+            msg.setMessage(0xC0, 81, 00);
+            long secondEventTick = seq.getTickPosition();
+            rec.send(msg, -1);
+
+            seq.stopRecording();
+            if (seq.isRecording()) {
+                failed = true;
+                throw new Exception("Stopped recording, but Sequencer is still recording!");
+            }
+            if (!seq.isRunning()) {
+                failed = true;
+                throw new Exception("Stopped recording, but Sequencer but is not running anymore!");
+            }
+
+            seq.stop();
+            if (seq.isRunning()) {
+                failed = true;
+                throw new Exception("Stopped Sequencer, but it is still running!");
+            }
+
+            // now examine the contents of the recorded track:
+            // 1) number of events: should be 2 more
+            int newSize = track.size();
+            int addedEventCount = newSize - oldSize;
+
+            out("Added "+addedEventCount+" events to recording track.");
+            if (addedEventCount != 2) {
+                failed = true;
+                throw new Exception("Did not add 2 events!");
+            }
+
+            // 2) the first event should be at roughly "secondEventTick"
+            MidiEvent ev = track.get(0);
+            msg = (ShortMessage) ev.getMessage();
+            out("The first recorded event is at tick position: "+ev.getTick());
+            if (Math.abs(ev.getTick() - secondEventTick) > 1000) {
+                out(" -> but expected something like: "+secondEventTick+"! FAILED.");
+                failed = true;
+            }
+
+            ev = track.get(1);
+            msg = (ShortMessage) ev.getMessage();
+            out("The 2nd recorded event is at tick position: "+ev.getTick());
+            out(" -> sequence's tick length is "+seq.getTickLength());
+            if (Math.abs(ev.getTick() - (sequence.getTickLength() / 2)) > 1000) {
+                out(" -> but expected something like: "+(seq.getTickLength()/2)+"! FAILED.");
+                failed = true;
+            }
+
+            passed = true;
+        } catch (Exception e) {
+            out(e.toString());
+            if (!failed) out("Test not failed.");
+        }
+        if (seq != null) {
+            seq.close();
+        }
+
+        if (failed) {
+            throw new Exception("Test FAILED!");
+        }
+        else if (passed) {
+            out("Test Passed.");
+        }
+    }
+
+    /**
+     * Create a new Sequence for testing.
+     */
+    private static Sequence createSequence(int lengthInSeconds, int tempoInBPM,
+                                           int resolution) {
+        Sequence sequence = null;
+        long lengthInMicroseconds = lengthInSeconds * 1000000;
+        boolean createTempoEvent = true;
+        if (tempoInBPM == 0) {
+            tempoInBPM = 120;
+            createTempoEvent = false;
+            System.out.print("Creating sequence: "+lengthInSeconds+"sec, "
+                             +"resolution="+resolution+" ticks/beat...");
+        } else {
+            System.out.print("Creating sequence: "+lengthInSeconds+"sec, "
+                             +tempoInBPM+" beats/min, "
+                             +"resolution="+resolution+" ticks/beat...");
+        }
+        //long lengthInTicks = (lengthInMicroseconds * resolution) / tempoInBPM;
+        long lengthInTicks = (lengthInMicroseconds * tempoInBPM * resolution) / 60000000l;
+        //out("expected length in ticks: " + lengthInTicks);
+        try {
+            sequence = new Sequence(Sequence.PPQ, resolution);
+            Track track = sequence.createTrack();
+            if (createTempoEvent) {
+                int tempoInMPQ = (int) (60000000l / tempoInBPM);
+                MetaMessage tm = new MetaMessage();
+                byte[] msg = new byte[3];
+                msg[0] = (byte) (tempoInMPQ >> 16);
+                msg[1] = (byte) ((tempoInMPQ >> 8) & 0xFF);
+                msg[2] = (byte) (tempoInMPQ & 0xFF);
+
+                tm.setMessage(0x51 /* Meta Tempo */, msg, msg.length);
+                track.add(new MidiEvent(tm, 0));
+                //out("regtest: tempoInMPQ="+tempoInMPQ);
+                //out("Added tempo event: new size="+track.size());
+            }
+            ShortMessage mm = new ShortMessage();
+            mm.setMessage(0xF6, 0, 0);
+            MidiEvent me = new MidiEvent(mm, lengthInTicks);
+            track.add(me);
+            //out("Added realtime event: new size="+track.size());
+        } catch (InvalidMidiDataException e) {
+            out(e);
+        }
+        out("OK");
+
+        return sequence;
+    }
+
+    private static void out(Throwable t) {
+        t.printStackTrace(System.out);
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequencer/SeqRecordDoesNotCopy.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 5048381
+ * @summary Sequencer doesn't create distinct messages when recording events.
+ * @key headful
+ */
+public class SeqRecordDoesNotCopy {
+    public static void main(String argv[]) throws Exception {
+        Sequencer s = MidiSystem.getSequencer();
+        s.open();
+        try {
+            Sequence seq = new Sequence(Sequence.PPQ, 384, 2);
+            s.setSequence(seq);
+            Track t = seq.getTracks()[0];
+            ShortMessage msg = new ShortMessage();
+            msg.setMessage(0x90, 0x40, 0x7F);
+            t.add(new MidiEvent(msg, 11000));
+            msg.setMessage(0x90, 0x40, 0x00);
+            t.add(new MidiEvent(msg, 12000));
+            t = seq.getTracks()[1];
+            s.recordEnable(t, -1);
+            System.out.println("Started recording...");
+            s.startRecording();
+            Receiver r = s.getReceiver();
+            Thread.sleep(100);
+            // send a normal message
+            System.out.println("Recording a normal NOTE ON message...");
+            msg.setMessage(0x90, 0x40, 0x6F);
+            r.send(msg, -1);
+            Thread.sleep(100);
+            // send a normal message
+            System.out.println("Recording a normal NOTE OFF message...");
+            msg.setMessage(0x90, 0x40, 0x00);
+            r.send(msg, -1);
+            Thread.sleep(100);
+            s.stop();
+            // now see if the messages were recorded
+            System.out.println("Recorded messages:");
+            int sameMessage = 0;
+            for (int i = 0; i < t.size(); i++) {
+                System.out.print(" "+(i+1)+". ");
+                printEvent(t.get(i));
+                if (t.get(i).getMessage() == msg) {
+                    System.out.println("## Failed: Same Message reference!");
+                    sameMessage++;
+                }
+            }
+            if (sameMessage > 0) {
+                System.out.println("## Failed: The same instance was recorded!");
+                throw new Exception("Test FAILED!");
+            }
+            System.out.println("Did not detect any duplicate messages.");
+            System.out.println("Test passed.");
+        } catch (Exception e) {
+            System.out.println("Unexpected Exception: "+e);
+            //e.printStackTrace();
+            throw new Exception("Test FAILED!");
+        } finally {
+            s.close();
+        }
+    }
+    public static void printEvent(MidiEvent event)
+    {
+        MidiMessage message = event.getMessage();
+        long tick = event.getTick();
+        byte[] data = message.getMessage();
+
+        StringBuffer sb = new StringBuffer((data.length * 3) - 1);
+
+        for (int i = 0; i < data.length; i++)
+        {
+                sb.append(toHexByteString(data[i]));
+                if (i < data.length - 1) sb.append(' ');
+        }
+        System.out.printf("%5d: %s%n", tick, sb);
+    }
+
+    private static String toHexByteString(int n)
+    {
+        if (n < 0) n &= 0xFF;
+        String s = Integer.toHexString(n).toUpperCase();
+        if (s.length() == 1) s = '0' + s;
+        return s;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequencer/SeqRecordsRealTimeEvents.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 5048381
+ * @summary Sequencer records real time messages into the sequence
+ * @key headful
+ */
+public class SeqRecordsRealTimeEvents {
+    public static void main(String argv[]) throws Exception {
+        Sequencer s = MidiSystem.getSequencer();
+        s.open();
+        try {
+            Sequence seq = new Sequence(Sequence.PPQ, 384, 2);
+            s.setSequence(seq);
+            Track t = seq.getTracks()[0];
+            ShortMessage msg = new ShortMessage();
+            msg.setMessage(0x90, 0x40, 0x7F);
+            t.add(new MidiEvent(msg, 11000));
+            msg = new ShortMessage();
+            msg.setMessage(0x90, 0x40, 0x00);
+            t.add(new MidiEvent(msg, 12000));
+            t = seq.getTracks()[1];
+            s.recordEnable(t, -1);
+            System.out.println("Started recording...");
+            s.startRecording();
+            Receiver r = s.getReceiver();
+            Thread.sleep(100);
+            int oldTrackSize = t.size();
+            // send a realtime message to the track
+            System.out.println("Recording real time message...");
+            msg = new ShortMessage();
+            msg.setMessage(0xF8, 0, 0);
+            r.send(msg, -1);
+            Thread.sleep(100);
+            // send a normal message
+            msg = new ShortMessage();
+            System.out.println("Recording a normal NOTE ON message...");
+            msg.setMessage(0x90, 0x40, 0x6F);
+            r.send(msg, -1);
+            Thread.sleep(100);
+            s.stop();
+            // now see if the messages were recorded
+            int newMessages = t.size() - oldTrackSize;
+            System.out.println("Recorded messages:");
+            for (int i = 0; i < t.size(); i++) {
+                System.out.print(" "+(i+1)+". ");
+                printEvent(t.get(i));
+            }
+            if (newMessages == 0) {
+                System.out.println("## Failed: No messages were recorded!");
+                throw new Exception("Test FAILED!");
+            } else if (newMessages == 1) {
+                System.out.println("Only one message was recorded. Correct!");
+            } else if (newMessages > 1) {
+                System.out.println("## Failed: 2 or more messages were recorded!");
+                throw new Exception("Test FAILED!");
+            }
+            System.out.println("Test passed.");
+        } catch (Exception e) {
+            System.out.println("Unexpected Exception: "+e);
+            //e.printStackTrace();
+            throw new Exception("Test FAILED!");
+        } finally {
+            s.close();
+        }
+    }
+    public static void printEvent(MidiEvent event)
+    {
+        MidiMessage message = event.getMessage();
+        long tick = event.getTick();
+        byte[] data = message.getMessage();
+
+        StringBuffer sb = new StringBuffer((data.length * 3) - 1);
+
+        for (int i = 0; i < data.length; i++)
+        {
+                sb.append(toHexByteString(data[i]));
+                if (i < data.length - 1) sb.append(' ');
+        }
+        System.out.printf("%5d: %s%n", tick, sb);
+    }
+
+    private static String toHexByteString(int n)
+    {
+        if (n < 0) n &= 0xFF;
+        String s = Integer.toHexString(n).toUpperCase();
+        if (s.length() == 1) s = '0' + s;
+        return s;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequencer/SeqStartRecording.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequencer;
+
+/**
+ * @test
+ * @bug 5001943
+ * @summary Sequencer.startRecording throws unexpected NPE
+ * @key headful
+ */
+public class SeqStartRecording {
+    public static void main(String argv[]) throws Exception {
+        Sequencer seq = MidiSystem.getSequencer();
+        seq.open();
+        try {
+            seq.startRecording();
+            System.out.println("Test passed.");
+        } catch (NullPointerException npe) {
+            System.out.println("Caught NPE: "+npe);
+            npe.printStackTrace();
+            throw new Exception("Test FAILED!");
+        } catch (Exception e) {
+            System.out.println("Unexpected Exception: "+e);
+            e.printStackTrace();
+            System.out.println("Test NOT failed.");
+        } finally {
+            seq.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequencer/SequencerCacheValues.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Sequencer;
+
+/**
+ * @test
+ * @bug 4716740
+ * @summary default sequencer does not set the tempo factor
+ */
+public class SequencerCacheValues {
+
+    static boolean failed = false;
+
+    public static void main(String args[]) throws Exception {
+        Sequencer seq = null;
+        int totalNumberOfSequencers = 0;
+
+        MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
+        for (int device=0; device<infos.length; device++) {
+            //seq = MidiSystem.getSequencer();
+            MidiDevice dev = MidiSystem.getMidiDevice(infos[device]);
+            if (dev instanceof Sequencer) {
+                seq = (Sequencer) dev;
+                totalNumberOfSequencers++;
+                System.out.println("Opening sequencer "+infos[device]);
+                try {
+                    seq.open();
+                    try {
+                        doTest(seq);
+                    } finally {
+                        if (seq != null) {
+                            seq.close();
+                            seq = null;
+                        }
+                    }
+                } catch (MidiUnavailableException mue) {
+                    System.err.println("MidiUnavailableException was thrown: " + mue);
+                    System.err.println("could not test this sequencer.");
+                }
+            }
+        }
+        if (totalNumberOfSequencers == 0) {
+            System.out.println("No sequencers installed!");
+            failed = true;
+        }
+        if (failed) {
+            throw new Exception("FAILED");
+        } else {
+            System.out.println("test OK");
+        }
+    }
+
+    public static boolean equalsFloat(float f1, float f2) {
+        return (f1-f2<0.0001) && (f2-f1<0.0001);
+    }
+
+    public static void doTest(Sequencer seq) throws Exception {
+        seq.setTempoInMPQ(3.0f);
+        System.out.println("Setting tempo in MPQ to "+3.0f);
+        if (!equalsFloat(seq.getTempoInMPQ(), 3.0f)) {
+            System.err.println("getTempoInMPQ() returns wrong value : "
+                + seq.getTempoInMPQ());
+            failed = true;
+        }
+
+        System.out.println("Setting tempo factor to "+2.0f);
+        seq.setTempoFactor(2.0f);
+        if (!equalsFloat(seq.getTempoFactor(), 2.0f)) {
+            System.err.println("getTempoFactor() returns: " + seq.getTempoFactor());
+            failed = true;
+        }
+
+        float bpmTempo = 120.0f;
+        System.out.println("Setting tempo to "+120.0f+"bpm");
+        seq.setTempoInBPM(bpmTempo);
+        if (!equalsFloat(seq.getTempoInMPQ(), (60000000.0f/seq.getTempoInBPM()))) {
+            System.err.println("getTempoInMPQ() returns: " + seq.getTempoInMPQ());
+            System.err.println("getTempoInBPM() returns: " + seq.getTempoInBPM());
+            failed = true;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequencer/SequencerSetMuteSolo.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+
+/**
+ * @test
+ * @bug 4713900
+ * @summary default Sequencer allows to set Mute for invalid track
+ */
+public class SequencerSetMuteSolo {
+
+    public static void main(String args[]) throws Exception {
+        if (!hasSequencer()) {
+            return;
+        }
+
+        //printMidiFile(args[0]);
+
+        boolean failed = false;
+        Sequencer seq = null;
+        Sequence midiData = getSequence();
+        int numTracks = midiData.getTracks().length;
+        int totalNumberOfSequencers = 0;
+        int totalNumberOfTestedSequencers = 0;
+
+        MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
+        for (int device=0; device<infos.length; device++) {
+            //seq = MidiSystem.getSequencer();
+            MidiDevice dev = MidiSystem.getMidiDevice(infos[device]);
+            if (dev instanceof Sequencer) {
+                seq = (Sequencer) dev;
+                totalNumberOfSequencers++;
+                System.out.println("Opening sequencer "+infos[device]);
+                try {
+                    seq.open();
+                    try {
+                        seq.setSequence(midiData);
+                        System.err.println("Number of tracks: " + numTracks);
+                        System.err.println("TrackMute["+numTracks+"] state was: " + seq.getTrackMute(numTracks));
+                        System.err.println("  setting to muted.");
+                        seq.setTrackMute(numTracks, true);
+                        System.err.println("  TrackMute["+numTracks+"] is now: " + seq.getTrackMute(numTracks));
+                        if (seq.getTrackMute(numTracks)) {
+                            failed = true;
+                        }
+                        System.err.println("TrackSolo["+numTracks+"] state was: " + seq.getTrackSolo(numTracks));
+                        System.err.println("  setting to solo.");
+                        seq.setTrackSolo(numTracks, true);
+                        System.err.println("  TrackSolo["+numTracks+"] is now: " + seq.getTrackSolo(numTracks));
+                        if (seq.getTrackSolo(numTracks)) {
+                            failed = true;
+                        }
+                        totalNumberOfTestedSequencers++;
+                    } finally {
+                        if (seq != null) {
+                            seq.close();
+                            seq = null;
+                        }
+                    }
+                } catch (MidiUnavailableException mue) {
+                    System.err.println("MidiUnavailableException was thrown: " + mue);
+                    System.err.println("could not test this sequencer.");
+                    return;
+                }
+            }
+        }
+        if (totalNumberOfSequencers == 0) {
+            System.out.println("No sequencers installed!");
+            failed = true;
+        }
+        if (totalNumberOfTestedSequencers == 0) {
+            System.out.println("Could not test any sequencers!");
+            failed = true;
+        }
+        if( failed ) {
+            throw new Exception("FAILED");
+        } else {
+            System.out.println("test OK");
+        }
+    }
+
+    public static String getString(byte b) {
+        //String res = Integer.toHexString(b & 0xFF).toUpperCase();
+        //while (res.length()<2) res="0"+res;
+        //return res;
+        return String.valueOf(b);
+    }
+
+
+    public static void printMidiFile(String filename) throws Exception {
+        File file = new File(filename);
+        FileInputStream fis = new FileInputStream(file);
+        byte[] data = new byte[(int) file.length()];
+        fis.read(data);
+        String s = "";
+        for (int i=0; i<data.length; i++) {
+                s+=getString(data[i])+", ";
+                if (s.length()>72) {
+                        System.out.println(s);
+                        s="";
+                }
+        }
+        System.out.println(s);
+    }
+
+    public static Sequence getSequence() throws Exception {
+        ByteArrayInputStream bais = new ByteArrayInputStream(pitchbend);
+        Sequence seq = MidiSystem.getSequence(bais);
+        return seq;
+    }
+
+    public static byte[] pitchbend = {
+        77, 84, 104, 100, 0, 0, 0, 6, 0, 1, 0, 2, 0, 120, 77, 84, 114, 107, 0, 0,
+        0, 27, 0, -1, 3, 19, 77, 73, 68, 73, 32, 116, 101, 115, 116, 32, 45, 32,
+        116, 114, 97, 99, 107, 32, 48, 0, -1, 47, 0, 77, 84, 114, 107, 0, 0, 0, -44,
+        0, -1, 3, 19, 77, 73, 68, 73, 32, 116, 101, 115, 116, 32, 45, 32, 116, 114,
+        97, 99, 107, 32, 49, 0, -64, 30, 0, -112, 68, 126, 0, -32, 6, 67, 0, 14,
+        71, 0, 20, 74, 0, 26, 77, 0, 32, 80, 0, 42, 85, 6, 50, 89, 6, 56, 92, 5,
+        66, 97, 6, 74, 101, 6, 80, 104, 11, 84, 106, 20, 76, 102, 6, 70, 99, 5, 60,
+        94, 6, 52, 90, 5, 44, 86, 4, 34, 81, 5, 26, 77, 5, 20, 74, 6, 10, 69, 5,
+        2, 65, 7, 0, 64, 42, -112, 66, 123, 11, 68, 0, 72, 63, 126, 4, 66, 0, 43,
+        -32, 0, 63, 6, 0, 60, 7, 0, 56, 6, 0, 53, 5, 0, 49, 5, 0, 43, 4, 0, 37, 3,
+        0, 30, 3, 0, 25, 3, 0, 19, 3, 0, 13, 4, 0, 8, 4, 0, 2, 4, 0, 0, 70, 0, 3,
+        5, 0, 9, 3, 0, 14, 7, 0, 16, 25, 0, 21, 5, 0, 25, 7, 0, 28, 5, 0, 32, 5,
+        0, 36, 5, 0, 41, 6, 0, 46, 5, 0, 50, 5, 0, 53, 4, 0, 58, 7, 0, 61, 7, 0,
+        64, 117, -112, 63, 0, 0, -1, 47, 0
+    };
+
+    static boolean hasSequencer() {
+        try {
+            Sequencer seq = MidiSystem.getSequencer();
+            if (seq != null) {
+                seq.open();
+                seq.close();
+                return true;
+            }
+        } catch (Exception e) {}
+        System.out.println("No sequencer available! Cannot execute test.");
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequencer/SequencerState.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+
+/**
+ * @test
+ * @bug 4913027
+ * @summary several Sequencer methods should specify behaviour on closed Sequencer
+ */
+public class SequencerState {
+
+    private static boolean hasSequencer() {
+        try {
+            Sequencer seq = MidiSystem.getSequencer();
+            if (seq != null) {
+                seq.open();
+                seq.close();
+                return true;
+            }
+        } catch (Exception e) {}
+        System.out.println("No sequencer available! Cannot execute test.");
+        return false;
+    }
+
+
+    public static void main(String[] args) throws Exception {
+        out("4913027: several Sequencer methods should should specify behaviour on closed Sequencer");
+        if (hasSequencer()) {
+            boolean passed = testAll();
+            if (passed) {
+                out("Test PASSED.");
+            } else {
+                throw new Exception("Test FAILED.");
+            }
+        }
+    }
+
+    /**
+     * Execute the test on all available Sequencers.
+     *
+     * @return true if the test passed for all Sequencers, false otherwise
+     */
+    private static boolean testAll() throws Exception {
+        boolean result = true;
+        MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
+        for (int i = 0; i < devices.length; i++) {
+            MidiDevice device = MidiSystem.getMidiDevice(devices[i]);
+            if (device instanceof Sequencer) {
+                result &= testSequencer((Sequencer) device);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Execute the test on the passed Sequencer.
+     *
+     * @return true if the test is passed this Sequencer, false otherwise
+     */
+    private static boolean testSequencer(Sequencer seq) throws Exception {
+        boolean result = true;
+
+        out("testing: " + seq);
+        /* test calls in closed state.
+         */
+        if (seq.isOpen()) {
+            out("Sequencer is already open, cannot test!");
+            return result;
+        }
+
+        try {
+            seq.start();
+            out("closed state: start() does not throw IllegalStateException!");
+            result = false;
+        } catch (IllegalStateException e) {
+        }
+
+        try {
+            seq.stop();
+            out("closed state: stop() does not throw IllegalStateException!");
+            result = false;
+        } catch (IllegalStateException e) {
+        }
+
+        try {
+            seq.startRecording();
+            out("closed state: startRecording() does not throw IllegalStateException!");
+            result = false;
+        } catch (IllegalStateException e) {
+        }
+
+        try {
+            seq.stopRecording();
+            out("closed state: stopRecording() does not throw IllegalStateException!");
+            result = false;
+        } catch (IllegalStateException e) {
+        }
+
+        Sequence sequence = createSequence();
+        if (sequence == null) {
+            out("created Sequence is null, cannot test!");
+            return result;
+        }
+        try {
+            seq.setSequence(sequence);
+        } catch (IllegalStateException e) {
+            out("closed state: setSequence(Sequence) throws IllegalStateException!");
+            result = false;
+        }
+
+        InputStream inputStream = createSequenceInputStream();
+        if (inputStream == null) {
+            out("created InputStream is null, cannot test!");
+            return result;
+        }
+        try {
+            seq.setSequence(inputStream);
+        } catch (IllegalStateException e) {
+            out("closed state: setSequence(InputStream) throws IllegalStateException!");
+            result = false;
+        }
+
+        try {
+            seq.getSequence();
+        } catch (IllegalStateException e) {
+            out("closed state: getSequence() throws IllegalStateException!");
+            result = false;
+        }
+
+        /* test calls in open state.
+         */
+        seq.open();
+        if (! seq.isOpen()) {
+            out("Sequencer is not open, cannot test!");
+            return result;
+        }
+
+        try {
+            seq.start();
+        } catch (IllegalStateException e) {
+            out("open state: start() throws IllegalStateException!");
+            result = false;
+        }
+
+        try {
+            seq.stop();
+        } catch (IllegalStateException e) {
+            out("open state: stop() throws IllegalStateException!");
+            result = false;
+        }
+
+        try {
+            seq.startRecording();
+        } catch (IllegalStateException e) {
+            out("open state: startRecording() throws IllegalStateException!");
+            result = false;
+        }
+
+        try {
+            seq.stopRecording();
+        } catch (IllegalStateException e) {
+            out("open state: stopRecording() throws IllegalStateException!");
+            result = false;
+        }
+
+        sequence = createSequence();
+        if (sequence == null) {
+            out("created Sequence is null, cannot test!");
+            return result;
+        }
+        try {
+            seq.setSequence(sequence);
+        } catch (IllegalStateException e) {
+            out("open state: setSequence(Sequence) throws IllegalStateException!");
+            result = false;
+        }
+
+        inputStream = createSequenceInputStream();
+        if (inputStream == null) {
+            out("created InputStream is null, cannot test!");
+            return result;
+        }
+        try {
+            seq.setSequence(inputStream);
+        } catch (IllegalStateException e) {
+            out("open state: setSequence(InputStream) throws IllegalStateException!");
+            result = false;
+        }
+
+        try {
+            seq.getSequence();
+        } catch (IllegalStateException e) {
+            out("open state: getSequence() throws IllegalStateException!");
+            result = false;
+        }
+
+        seq.close();
+        return result;
+    }
+
+    /**
+     * Create a new Sequence for testing.
+     *
+     * @return a dummy Sequence, or null, if a problem occured while creating
+     *         the Sequence
+     */
+    private static Sequence createSequence() {
+        Sequence sequence = null;
+        try {
+            sequence = new Sequence(Sequence.PPQ, 480, 1);
+        } catch (InvalidMidiDataException e) {
+            // DO NOTHING
+        }
+        return sequence;
+    }
+
+    /**
+     * Create a new InputStream containing a Sequence for testing.
+     *
+     * @return an InputStream containing a dummy Sequence, or null, if a problem
+     *         occured while creating the InputStream
+     */
+    private static InputStream createSequenceInputStream() {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Sequence sequence = createSequence();
+        if (sequence == null) {
+            return null;
+        }
+        try {
+            MidiSystem.write(sequence, 0, baos);
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            return bais;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequencer/SetTickPosition.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4493775
+ * @summary Sequncer method, setTickPosition(long) doesnot set the Tick position
+ */
+public class SetTickPosition {
+        private static boolean testPassed = true;
+
+        public void runTest()
+        {
+            Sequencer theSequencer = null;
+            try
+            {
+                System.out.print("Getting Sequencer...");
+                theSequencer = MidiSystem.getSequencer();
+                System.out.println("got "+theSequencer);
+
+                if(!(theSequencer.isOpen()))
+                {
+                    System.out.println("Opening Sequencer...");
+                    theSequencer.open();
+
+                    if(!(theSequencer.isOpen()))
+                    {
+                        System.out.println("Unable to open the Sequencer. Test NOT FAILED.");
+                        return;
+                    }
+                }
+
+                System.out.println("theSequencer is open!\n");
+
+                System.out.println("Creating New Sequence...");
+                Sequence theSequence = new Sequence(Sequence.PPQ, 120);
+
+                System.out.println("Adding Track To Sequence...");
+                Track theTrack = theSequence.createTrack();
+
+                int theChannel = 0;
+
+                int theNote = 60;
+                int theVelocity = 100;
+                ShortMessage theShortMessage = new ShortMessage();
+
+                for (int tick=0; tick<2000; tick+=120) {
+                    //System.out.println("Adding NOTE_ON To Track At Tick: " + tick + "...\n");
+                    theShortMessage.setMessage(ShortMessage.NOTE_ON, theChannel, theNote, theVelocity);
+                    MidiEvent theMidiEvent = new MidiEvent(theShortMessage, tick);
+                    theTrack.add(theMidiEvent);
+
+                    //System.out.println("Adding NOTE_OFF To Track At Tick: " + (tick+60) + "...\n");
+                    theShortMessage.setMessage(ShortMessage.NOTE_OFF, theChannel, theNote, theVelocity);
+                    theMidiEvent = new MidiEvent(theShortMessage, tick+60);
+                    theTrack.add(theMidiEvent);
+                }
+                theSequencer.setSequence(theSequence);
+
+                float theTempoInBPM = 120;
+                theSequencer.setTempoInBPM(theTempoInBPM);
+                long theTickLengthOfSequence = theSequencer.getTickLength();
+                System.out.println("Length Of Sequence In Ticks: " + theTickLengthOfSequence);
+                System.out.println("Sequence resolution: " + theSequencer.getSequence().getResolution());
+
+                theSequencer.start();
+                for(long theTickPosition = 0; theTickPosition < theTickLengthOfSequence; theTickPosition += (theTickLengthOfSequence / 10))
+                {
+                    System.out.println("Now Setting Tick Position To: " + theTickPosition);
+                    theSequencer.setTickPosition(theTickPosition);
+
+                    long theCurrentTickPosition = theSequencer.getTickPosition();
+                    long theCurrentMsPosition = (long) (theSequencer.getMicrosecondPosition()/1000);
+                    System.out.println("IsRunning()=" + theSequencer.isRunning());
+                    System.out.println("Now Current Tick Position Is: " + theCurrentTickPosition);
+                    //System.out.println("Now Current micro Position Is: " + theCurrentMsPosition);
+                    System.out.println("");
+
+                    try {
+                        Thread.sleep(800);
+                    } catch (InterruptedException ie) {}
+
+                    // last time, set tick pos to 0
+                    if (theTickPosition>0 && theTickPosition<(theTickLengthOfSequence / 10)) {
+                        theTickPosition=(theTickLengthOfSequence / 10);
+                    }
+
+                    // 30 = 1/4 * 120, the resolution of the sequence
+                    if(Math.abs(theCurrentTickPosition - theTickPosition) > 30) {
+                        System.out.println("theCurrentTickPosition != theTickPosition!");
+                        testPassed = false;
+                    }
+                }
+
+            }
+            catch (Exception ex) { ex.printStackTrace(); }
+            if (theSequencer != null) {
+                theSequencer.close();
+            }
+            if (testPassed) {
+                System.out.println("Test Passed.");
+            }
+        }
+
+    public static void main(String[] args) throws Exception {
+        SetTickPosition thisTest = new SetTickPosition();
+        thisTest.runTest();
+        if (!testPassed) {
+            throw new Exception("Test FAILED");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Sequencer/TickLength.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MetaEventListener;
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4427890
+ * @run main/othervm TickLength
+ * @summary Sequencer.getTickLength() and Sequence.getTickLength() report the
+ *          wrong length
+ */
+public class TickLength implements MetaEventListener {
+    private Sequence          theSequence;
+    private Sequencer         theSequencer;
+
+    public TickLength() {
+     this.initMidiCompoments();
+     System.out.println("Got Sequencer "+theSequencer);
+     theSequence = this.generateSequence();
+     try {
+       theSequencer.setSequence(theSequence);
+     }
+     catch(Exception e) {
+       System.out.println(this.getClass()+"\tCannot set sequence to sequencer ("+e+")");
+       return;
+     }
+    }
+
+    public  void start() {
+     theSequencer.start();
+    }
+
+    /*
+     instantiate the necessary midi components
+    */
+    private boolean initMidiCompoments() {
+
+
+     try {
+       theSequencer = MidiSystem.getSequencer();
+     }
+     catch(Exception e) {
+       System.out.println(this.getClass()+"\tSequencer Device not supported"+e+")");
+       return false;
+     }
+
+     try {
+       theSequencer.open();
+     }
+     catch(Exception e) {
+       System.out.println(this.getClass()+"Cannot open Sequencer Device");
+       return false;
+     }
+     if(!theSequencer.addMetaEventListener(this)) {
+       System.out.println(this.getClass()+"\tCould not register MetaEventListener - there will be problems with scrolling! ");
+       return false;
+     }
+     return true;
+    }
+
+    static int lastTick = 0;
+
+    private Sequence generateSequence() {
+     MidiEvent dummyMidiEvent;
+     ShortMessage dummyShortMessage;
+     Sequence dummySequence        = null;
+     Track[] allTracks ;
+     Track theTrack;
+
+     try {
+       dummySequence = new Sequence(Sequence.PPQ,1500);
+     }
+     catch(InvalidMidiDataException e) {
+       System.out.println("O o "+e);
+     }
+
+     dummySequence.createTrack();
+     allTracks = dummySequence.getTracks();
+     theTrack = allTracks[0];
+    lastTick = 0;
+     for(int i=0;i<20; i++) {
+       theTrack.add(this.createShortMidiEvent(ShortMessage.NOTE_ON, 2, 30+i, 100,100+1000*i));
+       theTrack.add(this.createMetaMidiEvent(1,"start",100+1000*i));
+       lastTick = (1000*i)+600;
+       theTrack.add(this.createShortMidiEvent(ShortMessage.NOTE_OFF, 2, 30+i, 100, lastTick));
+       theTrack.add(this.createMetaMidiEvent(1,"end",lastTick));
+     }
+
+     return dummySequence;
+    }
+
+    /*
+     A method to create a short midi event (sound)
+    */
+
+    public MidiEvent createShortMidiEvent(int theCommand, int theChannel, int theData1, int theData2, long theTime) {
+     ShortMessage dummyShortMessage;
+     MidiEvent    dummyMidiEvent;
+
+     try {
+       dummyShortMessage = new ShortMessage();
+       dummyShortMessage.setMessage(theCommand, theChannel, theData1, theData2);
+       dummyMidiEvent    = new MidiEvent(dummyShortMessage,theTime);
+     }
+     catch (Exception e) {
+       System.out.println(this.getClass()+"\t"+e);
+       return null;
+     }
+
+     return dummyMidiEvent;
+    }
+
+    /*
+     A method to create a meta midi event (used in  meta() method)
+    */
+    public MidiEvent createMetaMidiEvent(int theType, String theData1, long theTime) {
+     MetaMessage  dummyMetaMessage;
+     MidiEvent    dummyMidiEvent;
+
+     try {
+       dummyMetaMessage = new MetaMessage();
+       dummyMetaMessage.setMessage(theType, theData1.getBytes(), theData1.length());
+       dummyMidiEvent    = new MidiEvent(dummyMetaMessage,theTime);
+     }
+     catch (Exception e) {
+       System.out.println(e);
+       return null;
+     }
+
+     return dummyMidiEvent;
+    }
+
+    /*
+     the method is activated by each meta midi event
+     it puts out the actual tick position, as well as the WRONG total tick length and the RIGHT
+     tick length using the work around by dividing the total length by 64
+    */
+    public void meta(MetaMessage p1) {
+     if(p1.getType() ==47) {
+       return;
+     }
+     System.out.println("getTickPosition:\t"+theSequencer.getTickPosition()
+         +"\t Sequencer.getTickLength:\t"+theSequencer.getTickLength()
+         +"\tReal Length:\t"+lastTick
+         +"\t Sequence.getTickLength:\t"+theSequence.getTickLength()
+         //(theSequencer.getTickLength()/64));
+         );
+    }
+
+    public void checkLengths() throws Exception {
+        System.out.println("Sequencer.getTickLength() = "+theSequencer.getTickLength());
+        System.out.println("Sequence.getTickLength() = "+theSequence.getTickLength());
+        long diff = theSequencer.getTickLength() - theSequence.getTickLength();
+        if (diff > 100 || diff < -100) {
+                throw new Exception("Difference too large! Failed.");
+        }
+        System.out.println("Passed");
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (!hasSequencer()) {
+            return;
+        }
+         TickLength tlt = new TickLength();
+         //tlt.start();
+         tlt.checkLengths();
+    }
+
+    static boolean hasSequencer() {
+        try {
+            Sequencer seq = MidiSystem.getSequencer();
+            if (seq != null) {
+                seq.open();
+                seq.close();
+                return true;
+            }
+        } catch (Exception e) {}
+        System.out.println("No sequencer available! Cannot execute test.");
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/ShortMessage/FastShortMessage.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4851018
+ * @summary MidiMessage.getLength and .getData return wrong values.
+ *          also: 4890405: Reading MidiMessage byte array fails in 1.4.2
+ */
+public class FastShortMessage {
+    public static void main(String args[]) throws Exception {
+        int[] dataMes =  {ShortMessage.NOTE_ON | 9, 0x24, 0x50};
+        int res = 240;
+        Sequence midiData = new Sequence(Sequence.PPQ, res);
+
+        Track track = midiData.createTrack();
+        ShortMessage msg = new ShortMessage();
+        msg.setMessage(dataMes[0], dataMes[1], dataMes[2]);
+        track.add(new MidiEvent(msg, 0));
+
+        // save sequence to outputstream
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        MidiSystem.write(midiData, 0, baos);
+
+        // reload that sequence
+        InputStream is = new ByteArrayInputStream(baos.toByteArray());
+        Sequence seq = MidiSystem.getSequence(is);
+
+        track = seq.getTracks()[0];
+        msg = (ShortMessage) (track.get(0).getMessage());
+        byte[] msgData = msg.getMessage();
+
+        if (msgData.length != dataMes.length
+         || (msgData[0] & 0xFF) != dataMes[0]
+         || (msgData[1] & 0xFF) != dataMes[1]
+         || (msgData[2] & 0xFF) != dataMes[2]) {
+            throw new Exception("test failed. read length="+msgData.length);
+        }
+        System.out.println("Test Passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/ShortMessage/FastShortMessage2.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 5011306
+ * @summary FastShortMessage.setMessage does not use the data2 parameter
+ */
+public class FastShortMessage2 {
+
+    public static void main(String args[]) throws Exception {
+        int[] dataMes =  {ShortMessage.NOTE_ON | 9, 0x24, 0x50};
+
+        Sequence midiData = new Sequence(Sequence.PPQ, 240);
+        Track track = midiData.createTrack();
+        ShortMessage msg = new ShortMessage();
+        msg.setMessage(dataMes[0], dataMes[1], dataMes[2]);
+        track.add(new MidiEvent(msg, 0));
+        // save sequence to outputstream
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        MidiSystem.write(midiData, 0, baos);
+        // reload that sequence
+        InputStream is = new ByteArrayInputStream(baos.toByteArray());
+        Sequence seq = MidiSystem.getSequence(is);
+        track = seq.getTracks()[0];
+        msg = (ShortMessage) (track.get(0).getMessage());
+        if (!msg.getClass().toString().contains("FastShortMessage")) {
+            System.out.println("msg is not FastShortMessage, this test is useless then..."+msg.getClass());
+        }
+
+        msg.setMessage(dataMes[0], dataMes[1], dataMes[2]);
+        byte[] msgData = msg.getMessage();
+
+        if (msgData.length != dataMes.length
+         || (msgData[0] & 0xFF) != dataMes[0]
+         || (msgData[1] & 0xFF) != dataMes[1]
+         || (msgData[2] & 0xFF) != dataMes[2]) {
+            System.out.println("status="+(msgData[0] & 0xFF)+" and expected "+dataMes[0]);
+            System.out.println("data1="+(msgData[1] & 0xFF)+" and expected "+dataMes[1]);
+            System.out.println("data2="+(msgData[2] & 0xFF)+" and expected "+dataMes[2]);
+            throw new Exception("Test FAILED!");
+        }
+        System.out.println("Test Passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Soundbanks/ExtraCharInSoundbank.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.Synthesizer;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4429762
+ * @summary Some instrument names in some soundbanks include bad extra characters
+ */
+public class ExtraCharInSoundbank {
+
+    private static void printName(String loadedName)
+    {
+        System.out.println("Loaded Name: " + loadedName);
+        byte[] theLoadedNameByteArray = loadedName.getBytes();
+
+        System.out.print("Name Bytes: ");
+        for(int i = 0; i < theLoadedNameByteArray.length; i++)
+            System.out.print((Integer.toHexString((int)theLoadedNameByteArray[i]).toUpperCase()) + " ");
+        System.out.println("");
+        System.out.println("");
+    }
+
+    private static boolean containsControlChar(String name) {
+        byte[] bytes = name.getBytes();
+        for (int i = 0; i < bytes.length; i++) {
+            if (bytes[i] < 32) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean checkInstrumentNames(Synthesizer theSynthesizer)
+    {
+        boolean containsControlCharacters = false;
+
+        Instrument[] theLoadedInstruments = theSynthesizer.getLoadedInstruments();
+
+        System.out.println("Checking soundbank...");
+        for(int theInstrumentIndex = 0; theInstrumentIndex < theLoadedInstruments.length; theInstrumentIndex++) {
+            String name = theLoadedInstruments[theInstrumentIndex].getName();
+            if (containsControlChar(name)) {
+                containsControlCharacters = true;
+                System.out.print("Instrument[" + theInstrumentIndex + "] contains unexpected control characters: ");
+                printName(name);
+            }
+        }
+        return !containsControlCharacters;
+    }
+
+    public static void main(String[] args) throws Exception {
+        // the internal synthesizer needs a soundcard to work properly
+        if (!isSoundcardInstalled()) {
+            return;
+        }
+        Synthesizer theSynth = MidiSystem.getSynthesizer();
+        System.out.println("Got synth: "+theSynth);
+        theSynth.open();
+        try {
+            Soundbank theSoundbank = theSynth.getDefaultSoundbank();
+            System.out.println("Got soundbank: "+theSoundbank);
+            theSynth.loadAllInstruments(theSoundbank);
+            try {
+                    if (!checkInstrumentNames(theSynth)) {
+                            throw new Exception("Test failed");
+                    }
+            } finally {
+                    theSynth.unloadAllInstruments(theSoundbank);
+            }
+        } finally {
+            theSynth.close();
+        }
+        System.out.println("Test passed.");
+    }
+
+    /**
+     * Returns true if at least one soundcard is correctly installed
+     * on the system.
+     */
+    public static boolean isSoundcardInstalled() {
+        boolean result = false;
+        try {
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            if (mixers.length > 0) {
+                result = AudioSystem.getSourceDataLine(null) != null;
+            }
+        } catch (Exception e) {
+            System.err.println("Exception occured: "+e);
+        }
+        if (!result) {
+            System.err.println("Soundcard does not exist or sound drivers not installed!");
+            System.err.println("This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Soundbanks/GetSoundBankIOException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MidiSystem;
+
+/**
+ * @test
+ * @bug 4629810
+ * @summary MidiSystem.getSoundbank() throws unexpected IOException
+ */
+public class GetSoundBankIOException {
+
+    public static void main(String args[]) throws Exception {
+        boolean failed = false;
+        try {
+            String filename = "GetSoundBankIOException.java";
+            System.out.println("Opening "+filename+" as soundbank...");
+            File midiFile = new File(System.getProperty("test.src", "."), filename);
+            MidiSystem.getSoundbank(midiFile);
+            //Soundbank sBank = MidiSystem.getSoundbank(new NonMarkableIS());
+            System.err.println("InvalidMidiDataException was not thrown!");
+            failed = true;
+        } catch (InvalidMidiDataException invMidiEx) {
+            System.err.println("InvalidMidiDataException was thrown. OK.");
+        } catch (IOException ioEx) {
+            System.err.println("Unexpected IOException was caught!");
+            System.err.println(ioEx.getMessage());
+            ioEx.printStackTrace();
+            failed = true;
+        }
+
+        if (failed) throw new Exception("Test FAILED!");
+        System.out.println("Test passed.");
+    }
+
+    private static class NonMarkableIS extends InputStream {
+        int counter = 0;
+
+        public NonMarkableIS() {
+        }
+
+        public int read() throws IOException {
+            if (counter > 1000) return -1;
+            return (++counter) % 256;
+        }
+
+        public synchronized void mark(int readlimit) {
+            System.out.println("Called mark with readlimit= "+readlimit);
+        }
+
+        public synchronized void reset() throws IOException {
+            throw new IOException("mark/reset not supported");
+        }
+
+        public boolean markSupported() {
+            return false;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Synthesizer/AsynchronousMidiChannel.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import java.io.PrintStream;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.Synthesizer;
+
+/**
+ * @test
+ * @bug 4987585
+ * @summary Some MidiChannel methods are asynchronous
+ */
+public class AsynchronousMidiChannel {
+    static PrintStream log = System.err;
+    static PrintStream ref = System.out;
+
+    public static void main(String args[]) {
+        doIt(args);
+    }
+
+    public static void doIt(String args[]) {
+        Synthesizer synth = null;
+        MidiChannel mChanArr[];
+        MidiChannel chan = null;
+        boolean failed = false;
+        int i = 0;
+        int chanNum = 0;
+
+        int val = 1;
+        int contr = 0;
+        Soundbank sBank;
+        Instrument[] insArr;
+        Instrument instr = null;
+        Object ev = new Object();
+
+        try {
+            synth = MidiSystem.getSynthesizer();
+            System.out.println("Got synth: "+synth);
+            synth.open();
+
+            int latency = (int) synth.getLatency();
+            System.out.println("  -> latency: "
+                               +latency
+                               +" microseconds");
+
+            mChanArr = synth.getChannels();
+            while ((i < mChanArr.length) && (chan == null)) {
+                chanNum = i;
+                chan = mChanArr[i++];
+            }
+            if (chan == null) {
+                System.out.println("No channels in "
+                                   +"this synthesizer!");
+                return;
+            }
+            System.out.println("Got MidiChannel: "+chan);
+
+
+            sBank = synth.getDefaultSoundbank();
+            if (sBank == null) {
+                System.out.println("No default sound bank!");
+                return;
+            }
+
+
+            insArr = sBank.getInstruments();
+            for (int j = 0; j < insArr.length; j++) {
+                if (insArr[j].getPatch().getBank() == val) {
+                    instr = insArr[j];
+                    synth.loadInstrument(instr);
+                }
+            }
+            if (instr == null) {
+                System.out.println("No instr. with this bank!");
+                return;
+            }
+
+            chan.controlChange(contr, val);
+
+            // need to respect the synthesizer's latency
+            if (latency > 0) {
+                try {
+                    Thread.sleep(latency/1000);
+                } catch (InterruptedException inEx) {
+                }
+            }
+
+            if (chan.getController(contr) != val) {
+                failed = true;
+                System.err.println("getController() does not "
+                                   +"return proper value: "
+                + chan.getController(contr));
+            }  else {
+                System.out.println("getController("
+                + contr + ") returns proper value: "
+                + chan.getController(contr));
+            }
+
+        } catch (MidiUnavailableException mue) {
+            System.err.println("MidiUnavailableException was "
+                               +"thrown: " + mue);
+            System.out.println("could not test.");
+            return;
+        } catch(SecurityException se) {
+            se.printStackTrace();
+            System.err.println("Sound access is not denied but "
+            + "SecurityException was thrown!");
+            return;
+
+        } finally {
+            if (synth != null) synth.close();
+        }
+
+
+        if (failed == true) {
+            System.out.println("test failed");
+        } else {
+            System.out.println("OKAY");
+        }
+        return;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Synthesizer/Receiver/bug6186488.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2005, 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.
+ */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.MidiSystem;
+
+/**
+ * @test
+ * @bug 6186488
+ * @summary Tests that software Java Syntesizer processed
+ *          non-ShortMessage-derived messages
+ * @run main/manual=yesno bug6186488
+ */
+public class bug6186488 {
+    public static void main(String[] args) throws Exception {
+        MidiDevice/*Synthesizer*/ synth = null;
+
+        try {
+            synth = MidiSystem.getSynthesizer();
+            //synth = MidiSystem.getMidiDevice(infos[0]);
+
+            System.out.println("Synthesizer: " + synth.getDeviceInfo());
+            synth.open();
+            MidiMessage msg = new GenericMidiMessage(0x90, 0x3C, 0x40);
+            //ShortMessage msg = new ShortMessage();
+            //msg.setMessage(0x90, 0x3C, 0x40);
+
+            synth.getReceiver().send(msg, 0);
+            Thread.sleep(2000);
+
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            throw ex;
+        } finally {
+            if (synth != null && synth.isOpen())
+                synth.close();
+        }
+        System.out.print("Did you heard a note? (enter 'y' or 'n') ");
+        int result = System.in.read();
+        System.in.skip(1000);
+        if (result == 'y' || result == 'Y')
+        {
+            System.out.println("Test passed sucessfully.");
+        }
+        else
+        {
+            System.out.println("Test FAILED.");
+            throw new RuntimeException("Test failed.");
+        }
+    }
+
+    private static class GenericMidiMessage extends MidiMessage {
+        GenericMidiMessage(int... message) {
+            super(new byte[message.length]);
+            for (int i=0; i<data.length; i++) {
+                data[i] = (byte)(0xFF & message[i]);
+            }
+        }
+
+        GenericMidiMessage(byte... message) {
+            super(message);
+        }
+
+        public Object clone() {
+            return new GenericMidiMessage((byte[])data.clone());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Synthesizer/SynthesizerGetLatency.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Synthesizer;
+
+/**
+ * @test
+ * @bug 5029790
+ * @summary Synthesizer.getLatency returns wrong value
+ */
+public class SynthesizerGetLatency {
+
+    public static void main(String args[]) throws Exception {
+        Synthesizer synth = null;
+        boolean failed = false;
+        boolean notexec = false;
+        try {
+            synth = MidiSystem.getSynthesizer();
+            System.out.println("Got synth: "+synth);
+            synth.open();
+
+            int latency = (int) synth.getLatency();
+            System.out.println("  -> latency: "
+                               +latency
+                               +" microseconds");
+            if (latency < 5000 && latency > 0) {
+                System.out.println("## This latency is VERY small, probably due to this bug.");
+                System.out.println("## This causes failure of this test.");
+                failed = true;
+            }
+        } catch (MidiUnavailableException mue) {
+            System.err.println("MidiUnavailableException was "
+                               +"thrown: " + mue);
+            System.out.println("could not test.");
+            notexec = true;
+        } catch(SecurityException se) {
+            se.printStackTrace();
+            System.err.println("Sound access is not denied but "
+            + "SecurityException was thrown!");
+            notexec = true;
+        } finally {
+            if (synth != null) synth.close();
+        }
+
+
+        if (failed) {
+            throw new Exception("Test FAILED!");
+        }
+        if (notexec) {
+            System.out.println("Test not failed.");
+        } else {
+            System.out.println("Test Passed.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Synthesizer/bug4685396.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2006, 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.
+ */
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.Synthesizer;
+
+/**
+ * @test
+ * @bug 4685396
+ * @summary Tests that Synthesizer.remapInstrument works
+ * @run main bug4685396
+ * @key headful
+ */
+public class bug4685396 {
+
+    static Synthesizer synth = null;
+
+    public static boolean isInstrumentExist(Instrument inst, Instrument[] insts) {
+        for (int i = 0; i < insts.length; i++) {
+            if (inst.equals(insts[i]))
+                return true;
+        }
+        return false;
+    }
+
+    static boolean test(
+            boolean reloadInstr,    // reload all instruments?
+            boolean unloadFrom,     // unload "from" instrument?
+            boolean unloadTo        // unload "to" instrument?
+            ) throws Exception
+    {
+        log("Starting test: reloadInstr=" + reloadInstr
+                + ", unloadFrom=" + unloadFrom
+                + ", unloadTo=" + unloadTo
+                + "");
+
+        log("  creating synthesizer...");
+        synth = MidiSystem.getSynthesizer();
+        log("  opening synthesizer...");
+        synth.open();
+
+        Soundbank sbank = synth.getDefaultSoundbank();
+        if (sbank == null)
+            throw new RuntimeException("ERROR: Could not get default soundbank");
+
+        if (reloadInstr) {
+            synth.unloadAllInstruments(sbank);
+            synth.loadAllInstruments(sbank);
+        }
+
+        Instrument[] instrs = synth.getLoadedInstruments();
+
+        log("  " + instrs.length + " instruments loaded.");
+
+        if (instrs.length < 2)
+            throw new RuntimeException("ERROR: need at least 2 loaded instruments");
+
+        Instrument from = instrs[0];
+        Instrument to = instrs[instrs.length - 1];
+
+        if (unloadFrom)
+            synth.unloadInstrument(from);
+        if (unloadTo)
+            synth.unloadInstrument(to);
+
+        log("  from instrument (" + (unloadFrom ? "UNLOADED" : "LOADED")
+                                + "): " + from.toString());
+        log("  to instrument (" + (unloadTo ? "UNLOADED" : "LOADED")
+                                + "): " + to.toString());
+
+        boolean result = false;
+        boolean excepted = false;
+        try {
+            result = synth.remapInstrument(from, to);
+            log("  remapInstrument(from, to) returns " + result);
+        } catch (IllegalArgumentException ex) {
+            excepted = true;
+            log("  EXCEPTION:");
+            ex.printStackTrace(System.out);
+        }
+
+        instrs = synth.getLoadedInstruments();
+        log("  " + instrs.length + " instruments remains loaded.");
+
+        boolean toUnloaded = !isInstrumentExist(to, instrs);
+        boolean fromUnloaded = !isInstrumentExist(from, instrs);
+
+        log("  from instrument is " + (fromUnloaded ? "UNLOADED" : "LOADED"));
+        log("  to instrument is " + (toUnloaded ? "UNLOADED" : "LOADED"));
+
+        boolean bOK = true;
+        if (result) {
+            if (unloadTo) {
+                bOK = false;
+                log("ERROR: unloaded to, but sucessfull remap");
+            }
+            if (!fromUnloaded) {
+                bOK = false;
+                log("ERROR: sucessfull remap, but from hasn't been unloaded");
+            }
+            if (toUnloaded) {
+                bOK = false;
+                log("ERROR: to has been unloaded!");
+            }
+        } else {
+            if (!excepted) {
+                bOK = false;
+                log("ERROR: remap returns false, exception hasn't been thrown");
+            }
+            if (!unloadTo) {
+                bOK = false;
+                log("ERROR: to is loaded, but remap returns false");
+            }
+            if (unloadFrom != fromUnloaded) {
+                bOK = false;
+                log("ERROR: remap returns false, but status of from has been changed");
+            }
+        }
+
+        if (bOK) {
+            log("Test result: OK\n");
+        } else {
+            log("Test result: FAIL\n");
+        }
+
+        return bOK;
+    }
+
+    static void cleanup() {
+        if (synth != null) {
+            synth.close();
+            synth = null;
+        }
+    }
+
+    static boolean runTest(
+            boolean reloadInstr,    // reload all instruments?
+            boolean unloadTo,       // unload "to" instrument?
+            boolean unloadFrom      // unload "from" instrument?
+            )
+    {
+        boolean success = false;
+        try {
+            success = test(reloadInstr, unloadFrom, unloadTo);
+        } catch (Exception ex) {
+            log("Exception: " + ex.toString());
+        }
+        cleanup();
+        return success;
+    }
+
+    public static void main(String args[]) throws Exception {
+        boolean failed = false;
+        if (!runTest(true, false, false))
+            failed = true;
+        if (!runTest(true, false, true))
+            failed = true;
+        if (!runTest(true, true, false))
+            failed = true;
+        if (!runTest(true, true, true))
+            failed = true;
+
+        if (failed) {
+            throw new RuntimeException("Test FAILED.");
+        }
+        log("Test sucessfully passed.");
+    }
+
+
+    // helper routines
+    static long startTime = currentTimeMillis();
+    static long currentTimeMillis() {
+        //return System.nanoTime() / 1000000L;
+        return System.currentTimeMillis();
+    }
+    static void log(String s) {
+        long time = currentTimeMillis() - startTime;
+        long ms = time % 1000;
+        time /= 1000;
+        long sec = time % 60;
+        time /= 60;
+        long min = time % 60;
+        time /= 60;
+        System.out.println(""
+                + (time < 10 ? "0" : "") + time
+                + ":" + (min < 10 ? "0" : "") + min
+                + ":" + (sec < 10 ? "0" : "") + sec
+                + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms
+                + " (" + Thread.currentThread().getName() + ") " + s);
+    }
+    static void delay(int millis) {
+        try {
+            Thread.sleep(millis);
+        } catch (InterruptedException e) {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Track/TrackAddSameTick.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 4941944
+ * @summary Track may not have a determined order for inserting events at same
+ *          tick time
+ */
+public class TrackAddSameTick {
+
+    static boolean failed = false;
+    static MidiEvent[] evs = new MidiEvent[10];
+
+    public static void main(String argv[]) throws Exception {
+        Sequence seq = new Sequence(Sequence.PPQ, 240);
+        Track t = seq.createTrack();
+
+        log("add 10 events in random order");
+        t.add(createEvent(10, 5));
+        t.add(createEvent(0, 0));
+        t.add(createEvent(10, 6));
+        t.add(createEvent(11, 8));
+        t.add(createEvent(10, 7));
+        t.add(createEvent(0, 1));
+        t.add(createEvent(0, 2));
+        t.add(createEvent(15, 9));
+        t.add(createEvent(0, 3));
+        t.add(createEvent(1, 4));
+
+        // now compare the events.
+        // The note param will tell us the
+        // the expected position
+        long lastTick = 0;
+        for (int i = 0; i < t.size(); i++) {
+            MidiEvent ev = t.get(i);
+            if (ev.getMessage() instanceof ShortMessage) {
+                ShortMessage msg = (ShortMessage) ev.getMessage();
+                log(""+i+": ShortMessage at tick "+ev.getTick()
+                    +" with expected position "+msg.getData1());
+                if (ev.getTick() < lastTick) {
+                    log("  FAILED: last tick is larger than this event's tick!");
+                    failed = true;
+                }
+                if (i != msg.getData1()) {
+                    log("  FAILED: Track did not order correctly.");
+                    failed = true;
+                }
+            }
+        }
+
+        if (failed) throw new Exception("Test FAILED!");
+        log("Test passed.");
+    }
+
+    public static MidiEvent createEvent(long tick, int expectedPos)
+        throws Exception {
+        ShortMessage msg = new ShortMessage();
+        msg.setMessage(0x90, (int) expectedPos, 00);
+        MidiEvent ev = new MidiEvent(msg, tick);
+        return ev;
+    }
+
+    public static void log(String s) {
+        System.out.println(s);
+    }
+
+    public static void log(Exception e) {
+        //System.out.println(s);
+        e.printStackTrace();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Track/bug6416024.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2006, 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.
+ */
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Track;
+
+/**
+ * @test
+ * @bug 6416024
+ * @summary Tests that sequence correctly handle removing of EndOfTrack event
+ * @run main bug6416024
+ */
+public class bug6416024 {
+
+    boolean test() {
+        Sequence sequence = null;
+        Track track = null;
+        MidiEvent event = null;
+
+        log("creating sequence...");
+        try {
+            sequence = new Sequence(Sequence.PPQ, 10);
+            log("  - OK: " + sequence);
+        } catch(InvalidMidiDataException e ) {
+            log("  - FAILED: got exception");
+            e.printStackTrace(System.out);
+            return false;
+        }
+
+        log("creating track...");
+        track = sequence.createTrack();
+        log("  - OK: " + track);
+        log("initial track size=" + track.size());
+
+        log("removing all track events...");
+        while (track.size() > 0) {
+            try {
+                event = track.get(0);
+                log("  ..removing event " + event);
+                track.remove(event);
+                log("    - OK, track size=" + track.size());
+            } catch (Exception e) {
+                log("  - FAILED: got exception");
+                e.printStackTrace(System.out);
+                return false;
+            }
+        }
+
+        MetaMessage newMsg = new MetaMessage();
+        MidiEvent newEvent = new MidiEvent(newMsg, 10);
+        log("adding new event...");
+        try {
+            if (!track.add(newEvent)) {
+                log("event hasn't been added");
+                return false;
+            }
+            log("    - OK, track size=" + track.size());
+        } catch (Exception e) {
+            log("  - FAILED: got exception");
+            e.printStackTrace(System.out);
+            return false;
+        }
+
+        return true;
+    }
+
+    public static void main(String args[]) throws Exception {
+        bug6416024 This = new bug6416024();
+        if (This.test()) {
+            log("Test passed sucessfully.");
+        } else {
+            log("Test FAILED!");
+            delay(1000);
+            throw new RuntimeException("Test failed!");
+        }
+    }
+
+    // helper routines
+    static long startTime = currentTimeMillis();
+    static long currentTimeMillis() {
+        //return System.nanoTime() / 1000000L;
+        return System.currentTimeMillis();
+    }
+    static void log(String s) {
+        long time = currentTimeMillis() - startTime;
+        long ms = time % 1000;
+        time /= 1000;
+        long sec = time % 60;
+        time /= 60;
+        long min = time % 60;
+        time /= 60;
+        System.out.println(""
+                + (time < 10 ? "0" : "") + time
+                + ":" + (min < 10 ? "0" : "") + min
+                + ":" + (sec < 10 ? "0" : "") + sec
+                + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms
+                + " (" + Thread.currentThread().getName() + ") " + s);
+    }
+    static void delay(int millis) {
+        try {
+            Thread.sleep(millis);
+        } catch (InterruptedException e) {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/midi/Transmitter/bug6415669.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2006, 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.
+ */
+
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Transmitter;
+
+/**
+ * @test
+ * @bug 6415669
+ * @summary Tests that terminating thread which got transmitter doesn't cause
+ *          JVM crash (windows)
+ * @run main bug6415669
+ */
+public class bug6415669 {
+
+    public static void main(String args[]) throws Exception {
+        String osStr = System.getProperty("os.name");
+        boolean isWin = osStr.toLowerCase().startsWith("windows");
+        log("OS: " + osStr);
+        log("Arch: " + System.getProperty("os.arch"));
+        if (!isWin) {
+            log("The test is for Windows only");
+            return;
+        }
+
+        bug6415669 This = new bug6415669();
+        if (This.test()) {
+            log("Test sucessfully passed.");
+        } else {
+            log("Test FAILED!");
+            throw new RuntimeException("Test FAILED!");
+        }
+    }
+
+    volatile Transmitter transmitter = null;
+    Thread openThread = null;
+    boolean test() {
+        openThread = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    log("openThread: getting transmitter...");
+                    transmitter = MidiSystem.getTransmitter();
+                    log("openThread:   - OK: " + transmitter);
+                } catch (MidiUnavailableException ex) {
+                    log("openThread:   - Exception: ");
+                    ex.printStackTrace(System.out);
+                    log("openThread: skipping...");
+                }
+                log("openThread: exiting...");
+            }
+        });
+        log("starting openThread...");
+        openThread.start();
+
+        while (openThread.isAlive())
+            delay(500);
+        // make additional delay
+        delay(500);
+
+        if (transmitter == null) {
+            return true;   // midi is not available, just ignore
+        }
+
+        log("closing transmitter");
+        transmitter.close();
+        log("  - OK");
+
+        return true;
+    }
+
+    // helper routines
+    static long startTime = currentTimeMillis();
+    static long currentTimeMillis() {
+        //return System.nanoTime() / 1000000L;
+        return System.currentTimeMillis();
+    }
+    static void log(String s) {
+        long time = currentTimeMillis() - startTime;
+        long ms = time % 1000;
+        time /= 1000;
+        long sec = time % 60;
+        time /= 60;
+        long min = time % 60;
+        time /= 60;
+        System.out.println(""
+                + (time < 10 ? "0" : "") + time
+                + ":" + (min < 10 ? "0" : "") + min
+                + ":" + (sec < 10 ? "0" : "") + sec
+                + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms
+                + " (" + Thread.currentThread().getName() + ") " + s);
+    }
+    static void delay(int millis) {
+        try {
+            Thread.sleep(millis);
+        } catch (InterruptedException e) {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioFileFormat/AudioFileFormatToString.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * @test
+ * @bug 4672864
+ * @summary AudioFileFormat.toString() throws unexpected NullPointerException
+ */
+public class AudioFileFormatToString {
+
+    static final int STATUS_PASSED = 0;
+    static final int STATUS_FAILED = 2;
+    static final int STATUS_TEMP = 95;
+
+    public static void main(String argv[]) throws Exception {
+        int testExitStatus = run(argv, System.out);
+        if (testExitStatus != STATUS_PASSED) {
+            throw new Exception("Test FAILED " + testExitStatus);
+        }
+        System.out.println("Test passed.");
+    }
+
+    public static int run(String argv[], java.io.PrintStream out) {
+        int testResult = STATUS_PASSED;
+
+        out.println("\n==> Test for AudioFileFormat class:");
+
+        AudioFormat testAudioFormat =
+         new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,  // AudioFormat.Encoding
+                         (float) 44100.0, // float SampleRate
+                         (int) 8, // int sampleSizeInBits
+                         (int) 2, // int channels
+                         (int) 2,    // int frameSize
+                         (float) 110.0,    // float frameRate
+                         true    // boolean bigEndian
+                         );
+        AudioFormat nullAudioFormat = null;
+
+        AudioFileFormat.Type testAudioFileFormatType = AudioFileFormat.Type.WAVE;
+        AudioFileFormat.Type nullAudioFileFormatType = null;
+
+        AudioFileFormat testedAudioFileFormat = null;
+        out.println("\n>> public AudioFileFormat constructor for AudioFileFormat.Type = null: ");
+        try {
+         testedAudioFileFormat =
+             new AudioFileFormat(nullAudioFileFormatType,  // AudioFileFormat.Type
+                                 testAudioFormat, // AudioFormat
+                                 (int) 1024 // int frameLength
+                                 );
+         out.println(">  No any Exception was thrown!");
+         out.println(">  testedAudioFileFormat.getType():");
+         try {
+             AudioFileFormat.Type producedType = testedAudioFileFormat.getType();
+             out.println(">   PASSED: producedType = " + producedType);
+         } catch (Throwable thrown) {
+             out.println("##  FAILED: unexpected Exception was thrown:");
+             thrown.printStackTrace(out);
+             testResult = STATUS_FAILED;
+         }
+         out.println(">  testedAudioFileFormat.toString():");
+         try {
+             String producedString = testedAudioFileFormat.toString();
+             out.println(">   PASSED: producedString = " + producedString);
+         } catch (Throwable thrown) {
+             out.println("##  FAILED: unexpected Exception was thrown:");
+             thrown.printStackTrace(out);
+             testResult = STATUS_FAILED;
+         }
+        } catch (IllegalArgumentException illegArgExcept) {
+         out.println(">   PASSED: expected IllegalArgumentException was thrown:");
+         illegArgExcept.printStackTrace(out);
+        } catch (NullPointerException nullPE) {
+         out.println(">   PASSED: expected NullPointerException was thrown:");
+         nullPE.printStackTrace(out);
+        } catch (Throwable thrown) {
+         out.println("##  FAILED: unexpected Exception was thrown:");
+         thrown.printStackTrace(out);
+         testResult = STATUS_FAILED;
+        }
+
+        out.println("\n>> public AudioFileFormat constructor for AudioFormat = null: ");
+        try {
+         testedAudioFileFormat =
+             new AudioFileFormat(testAudioFileFormatType,  // AudioFileFormat.Type
+                                 nullAudioFormat, // AudioFormat
+                                 (int) 1024 // int frameLength
+                                 );
+         out.println(">  No any Exception was thrown!");
+         out.println(">  testedAudioFileFormat.getFormat():");
+         try {
+             AudioFormat producedFormat = testedAudioFileFormat.getFormat();
+             out.println(">   PASSED: producedFormat = " + producedFormat);
+         } catch (Throwable thrown) {
+             out.println("##  FAILED: unexpected Exception was thrown:");
+             thrown.printStackTrace(out);
+             testResult = STATUS_FAILED;
+         }
+         out.println(">  testedAudioFileFormat.toString():");
+         try {
+             String producedString = testedAudioFileFormat.toString();
+             out.println(">   PASSED: producedString = " + producedString);
+         } catch (Throwable thrown) {
+             out.println("##  FAILED: unexpected Exception was thrown:");
+             thrown.printStackTrace(out);
+             testResult = STATUS_FAILED;
+         }
+        } catch (IllegalArgumentException illegArgExcept) {
+            out.println(">   PASSED: expected IllegalArgumentException was thrown:");
+            illegArgExcept.printStackTrace(out);
+        } catch (NullPointerException nullPE) {
+            out.println(">   PASSED: expected NullPointerException was thrown:");
+            nullPE.printStackTrace(out);
+        } catch (Throwable thrown) {
+            out.println("##  FAILED: unexpected Exception was thrown:");
+            thrown.printStackTrace(out);
+            testResult = STATUS_FAILED;
+        }
+
+        out.println("\n>> protected AudioFileFormat constructor for AudioFileFormat.Type = null: ");
+        try {
+         testedAudioFileFormat =
+             new TestAudioFileFormat(nullAudioFileFormatType,  // AudioFileFormat.Type
+                                     (int) 1024, // byteLength
+                                     testAudioFormat, // AudioFormat
+                                     (int) 1024 // int frameLength
+                                     );
+         out.println(">  No any Exception was thrown!");
+         out.println(">  testedAudioFileFormat.getType():");
+         try {
+             AudioFileFormat.Type producedType = testedAudioFileFormat.getType();
+             out.println(">   PASSED: producedType = " + producedType);
+         } catch (Throwable thrown) {
+             out.println("##  FAILED: unexpected Exception was thrown:");
+             thrown.printStackTrace(out);
+             testResult = STATUS_FAILED;
+         }
+         out.println(">  testedAudioFileFormat.toString():");
+         try {
+             String producedString = testedAudioFileFormat.toString();
+             out.println(">   PASSED: producedString = " + producedString);
+         } catch (Throwable thrown) {
+             out.println("##  FAILED: unexpected Exception was thrown:");
+             thrown.printStackTrace(out);
+             testResult = STATUS_FAILED;
+         }
+        } catch (IllegalArgumentException illegArgExcept) {
+         out.println(">   PASSED: expected IllegalArgumentException was thrown:");
+         illegArgExcept.printStackTrace(out);
+        } catch (NullPointerException nullPE) {
+         out.println(">   PASSED: expected NullPointerException was thrown:");
+         nullPE.printStackTrace(out);
+        } catch (Throwable thrown) {
+         out.println("##  FAILED: unexpected Exception was thrown:");
+         thrown.printStackTrace(out);
+         testResult = STATUS_FAILED;
+        }
+
+        out.println("\n>> protected AudioFileFormat constructor for AudioFormat = null: ");
+        try {
+         testedAudioFileFormat =
+             new TestAudioFileFormat(testAudioFileFormatType,  // AudioFileFormat.Type
+                                     (int) 1024, // byteLength
+                                     nullAudioFormat, // AudioFormat
+                                     (int) 1024 // int frameLength
+                                     );
+         out.println(">  No any Exception was thrown!");
+         out.println(">  testedAudioFileFormat.getFormat():");
+         try {
+             AudioFormat producedFormat = testedAudioFileFormat.getFormat();
+             out.println(">   PASSED: producedFormat = " + producedFormat);
+         } catch (Throwable thrown) {
+             out.println("##  FAILED: unexpected Exception was thrown:");
+             thrown.printStackTrace(out);
+             testResult = STATUS_FAILED;
+         }
+         out.println(">  testedAudioFileFormat.toString():");
+         try {
+             String producedString = testedAudioFileFormat.toString();
+             out.println(">   PASSED: producedString = " + producedString);
+         } catch (Throwable thrown) {
+             out.println("##  FAILED: unexpected Exception was thrown:");
+             thrown.printStackTrace(out);
+             testResult = STATUS_FAILED;
+         }
+        } catch (IllegalArgumentException illegArgExcept) {
+         out.println(">   PASSED: expected IllegalArgumentException was thrown:");
+         illegArgExcept.printStackTrace(out);
+        } catch (NullPointerException nullPE) {
+         out.println(">   PASSED: expected NullPointerException was thrown:");
+         nullPE.printStackTrace(out);
+        } catch (Throwable thrown) {
+         out.println("##  FAILED: unexpected Exception was thrown:");
+         thrown.printStackTrace(out);
+         testResult = STATUS_FAILED;
+        }
+
+        if (testResult == STATUS_FAILED) {
+            out.println("\n==> test FAILED!");
+        } else {
+            out.println("\n==> test PASSED!");
+        }
+        return testResult;
+    }
+}
+
+class TestAudioFileFormat extends AudioFileFormat {
+
+    TestAudioFileFormat(AudioFileFormat.Type type, int byteLength,
+                        AudioFormat format, int frameLength) {
+        super(type, byteLength, format, frameLength);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioFileFormat/Properties.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.sound.midi.MidiFileFormat;
+import javax.sound.midi.Sequence;
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * @test
+ * @bug 4666845
+ * @summary RFE: Add properties to AudioFileFormat and MidiFileFormat
+ */
+public class Properties {
+
+    static boolean g_failed = false;
+
+    // all of p1 need to be in p2
+    static boolean compare(Map p1, Map p2) {
+        boolean failed = false;
+        for(String key: (Set<String>) p1.keySet()) {
+            out("  testing key: "+key);
+            if (!p2.containsKey(key)) {
+                out("  missing property: '"+key+"'. Failed");
+                failed = true;
+            }
+            Object v1 = p1.get(key);
+            Object v2 = p2.get(key);
+            if (((v1 == null) && (v2 != null))
+                || ((v1 != null) && (v2 == null))
+                || !(v1.equals(v2))) {
+                out("  property '"+key+"' is different: "
+                    +"expected='"+v1+"'  "
+                    +"actual='"+v2+"'. Failed");
+                failed = true;
+            }
+        }
+        // test if we can modify p2
+        try {
+             int oldSize = p2.size();
+             p2.clear();
+             if (oldSize > 0 && p2.size() == 0) {
+                 out("  could clear the properties! Failed.");
+                 failed = true;
+             }
+        } catch (Exception e) {
+            // correct
+        }
+        return failed;
+    }
+
+    public static void main(String argv[]) throws Exception {
+        // don't need to catch exceptions: any exception is a
+        // failure of this test
+
+        Map<String, Object> p = new HashMap<String,Object>();
+        p.put("author", "Florian");
+        p.put("duration", new Long(1000));
+        p.put("MyProp", "test");
+
+        out("Testing AudioFileFormat properties:");
+        // create an AudioFileFormat with properties
+        AudioFormat format = new AudioFormat( 44100.0f, 16, 2, true, false);
+        AudioFileFormat aff =
+            new AudioFileFormat(AudioFileFormat.Type.WAVE,
+                                format, 1000, p);
+        // test that it has the properties
+        boolean failed = compare(p, aff.properties());
+        // test getProperty()
+        Object o = aff.getProperty("author");
+        if (o == null || !o.equals("Florian")) {
+            out("  getProperty did not report an existing property!");
+            failed = true;
+        }
+        o = aff.getProperty("does not exist");
+        if (o != null) {
+            out("  getProperty returned something for a non-existing property!");
+            failed = true;
+        }
+        if (!failed) {
+            out("  OK");
+        } else {
+            g_failed = true;
+        }
+
+
+
+        out("Testing MidiFileFormat properties:");
+        // create a MidiFileFormat with properties
+        MidiFileFormat mff =
+            new MidiFileFormat(0, Sequence.PPQ, 240,
+                               1000, 100, p);
+        // test that it has the properties
+        failed = compare(p, mff.properties());
+        // test getProperty()
+        o = mff.getProperty("author");
+        if (o == null || !o.equals("Florian")) {
+            out("  getProperty did not report an existing property!");
+            failed = true;
+        }
+        o = mff.getProperty("does not exist");
+        if (o != null) {
+            out("  getProperty returned something for a non-existing property!");
+            failed = true;
+        }
+        if (!failed) {
+            out("  OK");
+        } else {
+            g_failed = true;
+        }
+
+
+        if (g_failed) throw new Exception("Test FAILED!");
+        System.out.println("Test passed.");
+    }
+
+    static void out(String s) {
+        System.out.println(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioFileFormat/TypeEquals.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioFileFormat;
+
+/**
+ * @test
+ * @bug 4925483
+ * @summary RFE: equals() should compare string in Encoding and Type
+ */
+public class TypeEquals {
+
+    public static void main(String argv[]) throws Exception {
+        // first test that we can create our own type
+        // (the constructor was made public)
+        AudioFileFormat.Type myType = new AudioFileFormat.Type("WAVE", "wav");
+
+        // then check if this one equals this new one
+        // with the static instance in AudioFileFormat.Type
+        if (!myType.equals(AudioFileFormat.Type.WAVE)) {
+         throw new Exception("Types do not equal!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioFormat/AudioFormatBitSize.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2002, 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 4754759
+ * @summary AudioFormat does not handle uncommon bit sizes correctly
+ */
+
+import javax.sound.sampled.AudioFormat;
+
+public class AudioFormatBitSize {
+
+    public static void main(String[] args) throws Exception {
+        int bits = 18;
+        AudioFormat format = new AudioFormat(44100.0f, bits, 1, true, false);
+        if (format.getFrameSize() * 8 < bits) {
+            System.out.println("bits = "+bits+" do not fit into a "+format.getFrameSize()+" bytes sample!");
+            throw new Exception("Test failed");
+        } else
+            System.out.println("bits = "+bits+" fit OK into a "+format.getFrameSize()+" bytes sample!");
+            System.out.println("Test passed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioFormat/EncodingEquals.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * @test
+ * @bug 4925483
+ * @summary RFE: equals() should compare string in Encoding and Type
+ */
+public class EncodingEquals {
+
+    public static void main(String argv[]) throws Exception {
+         // first test that we can create our own encoding
+         // (the constructor was made public)
+         AudioFormat.Encoding myType = new AudioFormat.Encoding("PCM_SIGNED");
+
+         // then check if this one equals this new one
+         // with the static instance in AudioFormat.Encoding
+         if (!myType.equals(AudioFormat.Encoding.PCM_SIGNED)) {
+             throw new Exception("Encodings do not equal!");
+         }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioFormat/Properties.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * @test
+ * @bug 4925767
+ * @summary RFE: Add Properties to AudioFormat
+ */
+public class Properties {
+
+    static boolean g_failed = false;
+
+    // all of p1 need to be in p2
+    static boolean compare(Map p1, Map p2) {
+        boolean failed = false;
+        for(String key: (Set<String>) p1.keySet()) {
+            out("  testing key: "+key);
+            if (!p2.containsKey(key)) {
+                out("  missing property: '"+key+"'. Failed");
+                failed = true;
+            }
+            Object v1 = p1.get(key);
+            Object v2 = p2.get(key);
+            if (((v1 == null) && (v2 != null))
+                || ((v1 != null) && (v2 == null))
+                || !(v1.equals(v2))) {
+                out("  property '"+key+"' is different: "
+                    +"expected='"+v1+"'  "
+                    +"actual='"+v2+"'. Failed");
+                failed = true;
+            }
+        }
+        // test if we can modify p2
+        try {
+             int oldSize = p2.size();
+             p2.clear();
+             if (oldSize > 0 && p2.size() == 0) {
+                 out("  could clear the properties! Failed.");
+                 failed = true;
+             }
+        } catch (Exception e) {
+            // correct
+        }
+        return failed;
+    }
+
+
+    public static void main(String argv[]) throws Exception {
+        // don't need to catch exceptions: any exception is a
+        // failure of this test
+
+        Map<String, Object> p = new HashMap<String,Object>();
+        p.put("bitrate", new Integer(128));
+        p.put("quality", new Integer(10));
+        p.put("MyProp", "test");
+
+        out("Testing AudioFileFormat properties:");
+        // create an AudioFileFormat with properties
+        AudioFormat format =
+            new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
+                            44100.0f, 16, 2, 4, 44100.0f, false, p);
+        // test that it has the properties
+        boolean failed = compare(p, format.properties());
+        // test getProperty()
+        Object o = format.getProperty("MyProp");
+        if (o == null || !o.equals("test")) {
+            out("  getProperty did not report an existing property!");
+            failed = true;
+        }
+        o = format.getProperty("does not exist");
+        if (o != null) {
+            out("  getProperty returned something for a non-existing property!");
+            failed = true;
+        }
+        if (!failed) {
+            out("  OK");
+        } else {
+            g_failed = true;
+        }
+
+        if (g_failed) throw new Exception("Test FAILED!");
+        System.out.println("Test passed.");
+    }
+
+    static void out(String s) {
+        System.out.println(s);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioInputStream/AISReadFraction.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4948663
+ * @summary AudioInputStream does not use the original stream passed to its constructor
+ */
+public class AISReadFraction {
+
+    static int failed = 0;
+    static byte[] testData = new byte[256];
+    static boolean DEBUG = false;
+
+    static AudioFormat[] formats = {
+        new AudioFormat(44100.0f, 8, 1, false, false), // frameSize = 1
+        new AudioFormat(44100.0f, 8, 2, false, false), // frameSize = 2
+        new AudioFormat(44100.0f, 16, 1, true, false), // frameSize = 2
+        new AudioFormat(44100.0f, 24, 1, true, false), // frameSize = 3
+        new AudioFormat(44100.0f, 16, 2, true, false), // frameSize = 4
+        new AudioFormat(44100.0f, 8, 5, false, false), // frameSize = 5
+        new AudioFormat(44100.0f, 16, 3, true, false), // frameSize = 6
+        new AudioFormat(44100.0f, 8, 7, false, false), // frameSize = 7
+        new AudioFormat(44100.0f, 32, 2, true, false)  // frameSize = 8
+    };
+
+
+    public static void main(String args[]) throws Exception {
+        for (int i = 0; i<testData.length; i++) {
+                testData[i] = (byte) (i % 128);
+        }
+
+        for (int f = 0; f < formats.length; f++) {
+                // first test without marking
+                doTest(formats[f], false);
+                // then with marking
+                doTest(formats[f], true);
+        }
+
+        out(""+failed+" failures.");
+        if (failed>0) throw new Exception("Test FAILED!");
+        out("Test passed.");
+    }
+
+    static void doTest(AudioFormat format, boolean doMark) {
+        out("Test with"+(doMark?"":"out")+" marking. Audio format: "
+            +"sampleSize="+format.getSampleSizeInBits()+"bits "
+            +"channels="+format.getChannels()+" "
+            +"frameSize="+format.getFrameSize()+"byte(s)");
+        int maxReadBytes = (testData.length / format.getFrameSize()) * format.getFrameSize();
+        InputStream is = new FractionalIS(testData, doMark);
+        AudioInputStream ais = new AudioInputStream(is, format, AudioSystem.NOT_SPECIFIED);
+        // first some general tests
+        if (ais.markSupported() && !doMark) {
+                out("  #AIS reports markSupported, but underlying stream cannot! FAILED");
+                failed ++;
+        }
+        if (!ais.markSupported() && doMark) {
+                out("  #AIS does not report markSupported, but underlying stream can mark! FAILED");
+                failed++;
+        }
+        byte[] data = new byte[1000];
+        int frameSize = format.getFrameSize();
+        int counter = 5;
+        int totalReadBytes = 0;
+        boolean hasRead0 = false;
+        boolean hasMarked = false;
+        boolean hasReset = false;
+        int markPos = 0;
+        while (true) {
+            try {
+                int toBeRead = frameSize * counter;
+                counter += 3;
+                if (counter > 14) {
+                        counter -= 14;
+                }
+                int read = ais.read(data, 0, toBeRead);
+                if (DEBUG) out("  -> ais.read(data, 0, "+toBeRead+"): "+read+"  (frameSize="+frameSize+")");
+                if ((totalReadBytes == maxReadBytes) && (read != -1)
+                     && ((read > 0) || hasRead0)) {
+                        if (read == 0) {
+                            out("  #stream was read to the end ("+maxReadBytes+"), but ais.read returned repeatedly 0 bytes. FAILED");
+                        } else {
+                            out("  #stream was read to the end ("+maxReadBytes+"), but ais.read returned "+read+" bytes... FAILED");
+                        }
+                        failed++;
+                        break;
+                }
+                if (read > 0) {
+                        verifyReadBytes(data, totalReadBytes, read);
+                        if ((read % frameSize) != 0) {
+                                out("  #Read non-integral number of frames: "+read+" bytes, frameSize="+frameSize+" bytes. FAILED");
+                                failed++;
+                        }
+                        totalReadBytes += read;
+                        hasRead0 = false;
+                }
+                else if (read == 0) {
+                        //out("  wanted to read "+toBeRead+" at position "+totalReadBytes+", but got 0 bytes!");
+                        if (hasRead0) {
+                                out("  read 0 twice in a row! FAILED");
+                                failed++;
+                                break;
+                        }
+                        hasRead0 = true;
+                } else {
+                        // end of stream
+                        out("  End of stream reached. Total read bytes: "+totalReadBytes);
+                        if (totalReadBytes != maxReadBytes) {
+                                out("  #Failed: should have read "+maxReadBytes+" bytes! FAILED.");
+                                failed++;
+                        }
+                        break;
+                }
+
+                // test marking
+                if (totalReadBytes > 50 && !hasMarked && !hasReset && doMark) {
+                        out("  Marking at position "+totalReadBytes);
+                        hasMarked = true;
+                        ais.mark(0);
+                        markPos = totalReadBytes;
+                }
+                if (totalReadBytes > 100 && hasMarked && !hasReset && doMark) {
+                        out("  Resetting at position "+totalReadBytes+" back to "+markPos);
+                        hasReset = true;
+                        ais.reset();
+                        totalReadBytes = markPos;
+                }
+
+            } catch (IOException e) {
+                out("  #caught unexpected exception:");
+                e.printStackTrace();
+                failed++;
+            }
+        }
+    }
+
+    static void verifyReadBytes(byte[] data, int offset, int len) {
+        int firstWrongByte = -1;
+        for (int i = 0; i < len; i++) {
+                int expected = ((offset + i) % 128);
+                if (data[i] != expected) {
+                        out("  read data is not correct! offset="+offset+"  expected="+expected+"  actual="+data[i]);
+                        failed++;
+                        break;
+                }
+        }
+    }
+
+
+    public static void out(String s) {
+        System.out.println(s);
+    }
+
+
+    static class FractionalIS extends InputStream {
+        byte[] data;
+        int pos = 0;
+        boolean canMark;
+        // a counter how many bytes are not returned
+        int missingBytes = 0;
+        int markPos = -1;
+
+        FractionalIS(byte[] data, boolean canMark) {
+                this.data = data;
+                this.canMark = canMark;
+        }
+
+        public int read() throws IOException {
+                if (pos >= data.length) {
+                        return -1;
+                }
+                return data[pos++] & 0xFF;
+        }
+
+        public int read(byte[] b, int off, int len) throws IOException {
+                if (++missingBytes > 5) {
+                        missingBytes = 0;
+                }
+                int reducedLen = len - missingBytes;
+                if (reducedLen <= 0) reducedLen = 1;
+                if (DEBUG) out("  FIS.read(data, 0, "+len+"): reducing len to "+reducedLen+" bytes.");
+                int ret = super.read(b, off, reducedLen);
+                if (DEBUG) out("                              returning "+ret+" bytes. Now at pos="+pos);
+                return ret;
+        }
+
+        public void mark(int readlimit) {
+                markPos = pos;
+                if (DEBUG) out("  FIS.mark(): marking at "+pos);
+        }
+
+        public void reset() throws IOException {
+                if (!canMark) {
+                        throw new IOException("reset not supported!");
+                }
+                if (markPos == -1) {
+                        throw new IOException("Mark position not set!");
+                }
+                pos = markPos;
+                if (DEBUG) out("  FIS.reset(): now back at "+pos);
+        }
+
+        public boolean markSupported() {
+                return canMark;
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioInputStream/bug6188860.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2005, 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.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 6188860
+ * @summary Tests that method AudioInputStream.read() returns right value
+ */
+public class bug6188860 {
+
+    public static void main(String[] args) throws Exception {
+        byte[] testData = new byte[256];
+
+        // fill data
+        for (int i = 0; i < testData.length; i++)
+            testData[i] = (byte) (i % 128);
+
+        InputStream streamSrc = new TestInputStream(testData);
+        AudioFormat format = new AudioFormat(44100.0f, 8, 1, false, false); // frameSize = 1
+        AudioInputStream streamAudio = new AudioInputStream(streamSrc, format, AudioSystem.NOT_SPECIFIED);
+
+        int nErrCount = 0;
+        int nTotal = 0;
+
+        int dataSrc, dataRead;
+        while (nTotal < (testData.length - 1)) {
+            dataRead = streamAudio.read();
+            if (dataRead < 0) {
+                System.out.println("end of stream");
+                break;
+            }
+
+            dataSrc = testData[nTotal];
+
+            if (dataRead != dataSrc) {
+                System.out.println("" + nTotal + " - mismatch :" + dataRead + " <> " + dataSrc);
+                nErrCount++;
+            }
+            nTotal++;
+        }
+
+        System.out.println("Total: " + nTotal + "; Mismatches: " + nErrCount);
+
+        if (nErrCount > 0) {
+            throw new RuntimeException("test failed: " + nErrCount + " mismatches of total " + nTotal + " bytes.");
+        }
+        System.out.println("Test sucessfully passed.");
+    }
+
+
+    static class TestInputStream extends InputStream {
+        byte[] data;
+        int pos = 0;
+
+        TestInputStream(byte[] data) {
+            this.data = data;
+        }
+
+        public int read() throws IOException {
+            if (pos >= data.length) {
+                return -1;
+            }
+            return data[pos++] & 0xFF;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioSystem/AudioFileTypes/AudioFileTypeUniqueness.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4883060
+ * @summary AudioSystem.getAudioFileTypes returns duplicates
+ */
+public class AudioFileTypeUniqueness {
+
+    public static void main(String[] args) throws Exception {
+        boolean foundDuplicates = false;
+        AudioFileFormat.Type[]  aTypes = AudioSystem.getAudioFileTypes();
+        for (int i = 0; i < aTypes.length; i++)
+        {
+            for (int j = 0; j < aTypes.length; j++)
+            {
+                if (aTypes[i].equals(aTypes[j]) && i != j) {
+                    foundDuplicates = true;
+                }
+            }
+        }
+        if (foundDuplicates) {
+            throw new Exception("Test failed");
+        } else {
+            System.out.println("Test passed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioSystem/AudioFileTypes/ShowAudioFileTypes.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2001, 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.
+ */
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4303037
+ * @summary Shows the existing audio file types of AudioSystem and checks
+ *          whether there are some at all
+ */
+public class ShowAudioFileTypes {
+
+    public static void main(String[] args) throws Exception {
+        AudioFileFormat.Type[]  aTypes = AudioSystem.getAudioFileTypes();
+        System.out.println(aTypes.length+" supported target types:");
+        for (int i = 0; i < aTypes.length; i++)
+        {
+            System.out.println("  "+(i+1)+". " + aTypes[i]+" with ext. '"+aTypes[i].getExtension()+"'");
+        }
+        if (aTypes.length<3) {
+            throw new Exception("Test failed");
+        } else {
+            System.out.println("Test passed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioSystem/DefaultMixers.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.util.List;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.Port;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+import javax.sound.sampled.spi.MixerProvider;
+
+import com.sun.media.sound.JDK13Services;
+
+/**
+ * @test
+ * @bug 4776511
+ * @summary RFE: Setting the default MixerProvider. Test the retrieving of lines
+ *          with defaut mixer properties.
+ * @modules java.desktop/com.sun.media.sound
+ */
+public class DefaultMixers {
+
+    private static final String ERROR_PROVIDER_CLASS_NAME = "abc";
+    private static final String ERROR_INSTANCE_NAME = "def";
+
+    private static final Class[] lineClasses = {
+        SourceDataLine.class,
+        TargetDataLine.class,
+        Clip.class,
+        Port.class,
+    };
+
+    public static void main(String[] args) throws Exception {
+        boolean allOk = true;
+        Mixer.Info[] infos;
+
+        out("Testing Mixers retrieved via AudioSystem");
+        infos = AudioSystem.getMixerInfo();
+        allOk &= testMixers(infos, null);
+
+        out("Testing MixerProviders");
+        List providers = JDK13Services.getProviders(MixerProvider.class);
+        for (int i = 0; i < providers.size(); i++) {
+            MixerProvider provider = (MixerProvider) providers.get(i);
+            infos = provider.getMixerInfo();
+            allOk &= testMixers(infos, provider.getClass().getName());
+        }
+
+        if (! allOk) {
+            throw new Exception("Test failed");
+        } else {
+            out("Test passed");
+        }
+    }
+
+    private static boolean testMixers(Mixer.Info[] infos,
+                                      String providerClassName) {
+        boolean allOk = true;
+
+        for (int i = 0; i < infos.length; i++) {
+            Mixer mixer = null;
+            try {
+                mixer = AudioSystem.getMixer(infos[i]);
+            } catch (NullPointerException e) {
+                out("Exception thrown; Test NOT failed.");
+                e.printStackTrace();
+            }
+            for (int j = 0; j < lineClasses.length; j++) {
+                if (mixer.isLineSupported(new Line.Info(lineClasses[j]))) {
+                    allOk &= testMixer(mixer, lineClasses[j],
+                                       providerClassName);
+                }
+            }
+        }
+        return allOk;
+    }
+
+    private static boolean testMixer(Mixer mixer, Class lineType,
+                                      String providerClassName) {
+        boolean allOk = true;
+        String instanceName = mixer.getMixerInfo().getName();
+
+        // no error
+        allOk &= testMixer(mixer, lineType,
+                           providerClassName, instanceName);
+
+        // erroneous provider class name, correct instance name
+        allOk &= testMixer(mixer, lineType,
+                           ERROR_PROVIDER_CLASS_NAME, instanceName);
+
+        // erroneous provider class name, no instance name
+        allOk &= testMixer(mixer, lineType,
+                           ERROR_PROVIDER_CLASS_NAME, "");
+
+        // erroneous provider class name, erroneous instance name
+        allOk &= testMixer(mixer, lineType,
+                           ERROR_PROVIDER_CLASS_NAME, ERROR_INSTANCE_NAME);
+
+        return allOk;
+    }
+
+    private static boolean testMixer(Mixer mixer, Class lineType,
+                                     String providerClassName,
+                                     String instanceName) {
+        boolean allOk = true;
+
+        try {
+            String propertyValue = (providerClassName != null) ? providerClassName: "" ;
+            propertyValue += "#" + instanceName;
+            out("property value: " + propertyValue);
+            System.setProperty(lineType.getName(), propertyValue);
+            Line line = null;
+            Line.Info info = null;
+            Line.Info[] infos;
+            AudioFormat format = null;
+            if (lineType == SourceDataLine.class || lineType == Clip.class) {
+                infos = mixer.getSourceLineInfo();
+                format = getFirstLinearFormat(infos);
+                info = new DataLine.Info(lineType, format);
+            } else if (lineType == TargetDataLine.class) {
+                infos = mixer.getTargetLineInfo();
+                format = getFirstLinearFormat(infos);
+                info = new DataLine.Info(lineType, format);
+            } else if (lineType == Port.class) {
+                /* Actually, a Ports Mixer commonly has source infos
+                   as well as target infos. We ignore this here, since we
+                   just need a random one. */
+                infos = mixer.getSourceLineInfo();
+                for (int i = 0; i < infos.length; i++) {
+                    if (infos[i] instanceof Port.Info) {
+                        info = infos[i];
+                        break;
+                    }
+                }
+            }
+            out("Line.Info: " + info);
+            line = AudioSystem.getLine(info);
+            out("line: " + line);
+            if (! lineType.isInstance(line)) {
+                out("type " + lineType + " failed: class should be '" +
+                    lineType + "' but is '" + line.getClass() + "'!");
+                allOk = false;
+            }
+        } catch (Exception e) {
+            out("Exception thrown; Test NOT failed.");
+            e.printStackTrace();
+        }
+        return allOk;
+    }
+
+    private static AudioFormat getFirstLinearFormat(Line.Info[] infos) {
+        for (int i = 0; i < infos.length; i++) {
+            if (infos[i] instanceof DataLine.Info) {
+                AudioFormat[] formats = ((DataLine.Info) infos[i]).getFormats();
+                for (int j = 0; j < formats.length; j++) {
+                    AudioFormat.Encoding encoding = formats[j].getEncoding();
+                    int sampleSizeInBits = formats[j].getSampleSizeInBits();
+                    if (encoding.equals(AudioFormat.Encoding.PCM_SIGNED) &&
+                        sampleSizeInBits == 16 ||
+                        encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED) &&
+                        sampleSizeInBits == 16) {
+                        return formats[j];
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioSystem/DefaultProperties.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.File;
+
+import com.sun.media.sound.JDK13Services;
+
+/**
+ * @test
+ * @bug 4776511
+ * @build DefaultProperties
+ * @run main/othervm DefaultProperties
+ * @summary RFE: Setting the default MixerProvider. Test the retrieving and
+ *          parsing of properties.
+ * @modules java.desktop/com.sun.media.sound
+ */
+public class DefaultProperties {
+
+    private static final Class[] lineTypeClasses = {
+        javax.sound.sampled.SourceDataLine.class,
+        javax.sound.sampled.TargetDataLine.class,
+        javax.sound.sampled.Clip.class,
+        javax.sound.sampled.Port.class,
+    };
+
+    public static void main(String[] args) throws Exception {
+        boolean allOk = true;
+        File file = new File(System.getProperty("test.src", "."), "testdata");
+        System.setProperty("java.home", file.getCanonicalPath());
+
+        for (int i = 0; i < lineTypeClasses.length; i++) {
+            Class cls = lineTypeClasses[i];
+            String propertyName = cls.getName();
+            String result;
+            String provClassName;
+            String instanceName;
+
+            // properties file, both provider class name and instance name
+            provClassName = "xyz";
+            instanceName = "123";
+            result = JDK13Services.getDefaultProviderClassName(cls);
+            if (! provClassName.equals(result)) {
+                out("type " + cls + " failed: provider class should be '" +
+                    provClassName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+            result = JDK13Services.getDefaultInstanceName(cls);
+            if (! instanceName.equals(result)) {
+                out("type " + cls + " failed: instance name should be '" +
+                    instanceName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+
+            // system property, provider class name only, no trailing hash
+            provClassName = "abc";
+            System.setProperty(propertyName, provClassName);
+            result = JDK13Services.getDefaultProviderClassName(cls);
+            if (! provClassName.equals(result)) {
+                out("type " + cls + " failed: provider class should be '" +
+                    provClassName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+            result = JDK13Services.getDefaultInstanceName(cls);
+            if (result != null) {
+                out("type " + cls + " failed: instance name should be " +
+                    "null but is '" + result + "'!");
+                allOk = false;
+            }
+
+            // system property, provider class name only, trailing hash
+            provClassName = "def";
+            System.setProperty(propertyName, provClassName + "#");
+            result = JDK13Services.getDefaultProviderClassName(cls);
+            if (! provClassName.equals(result)) {
+                out("type " + cls + " failed: provider class should be '" +
+                    provClassName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+            result = JDK13Services.getDefaultInstanceName(cls);
+            if (result != null) {
+                out("type " + cls + " failed: instance name should be " +
+                    "null but is '" + result + "'!");
+                allOk = false;
+            }
+
+            // system property, instance name only
+            instanceName = "ghi";
+            System.setProperty(propertyName, "#" + instanceName);
+            result = JDK13Services.getDefaultProviderClassName(cls);
+            if (result != null) {
+                out("type " + cls + " failed: provider class should be " +
+                    "null but is '" + result + "'!");
+                allOk = false;
+            }
+            result = JDK13Services.getDefaultInstanceName(cls);
+            if (! instanceName.equals(result)) {
+                out("type " + cls + " failed: instance name should be '" +
+                    instanceName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+
+            // system property, both provider class and instance name
+            provClassName = "jkl";
+            instanceName = "mno";
+            System.setProperty(propertyName, provClassName + "#" + instanceName);
+            result = JDK13Services.getDefaultProviderClassName(cls);
+            if (! provClassName.equals(result)) {
+                out("type " + cls + " failed: provider class should be '" +
+                    provClassName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+            result = JDK13Services.getDefaultInstanceName(cls);
+            if (! instanceName.equals(result)) {
+                out("type " + cls + " failed: instance name should be '" +
+                    instanceName + "' but is '" + result + "'!");
+                allOk = false;
+            }
+
+            // system property, empty
+            System.setProperty(propertyName, "");
+            result = JDK13Services.getDefaultProviderClassName(cls);
+            if (result != null) {
+                out("type " + cls + " failed: provider class should be " +
+                    "null but is '" + result + "'!");
+                allOk = false;
+            }
+            result = JDK13Services.getDefaultInstanceName(cls);
+            if (result != null) {
+                out("type " + cls + " failed: instance name should be " +
+                    "null but is '" + result + "'!");
+                allOk = false;
+            }
+        }
+        if (! allOk) {
+            throw new Exception("Test failed");
+        } else {
+            out("Test passed");
+        }
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioSystem/ProviderCacheing.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.util.List;
+import com.sun.media.sound.JDK13Services;
+
+/**
+ * @test
+ * @bug 4776511
+ * @summary RFE: Setting the default MixerProvider. Test the cacheing of
+ *          providers.
+ * @modules java.desktop/com.sun.media.sound
+ */
+public class ProviderCacheing {
+
+    private static final Class[] providerClasses = {
+        javax.sound.sampled.spi.AudioFileReader.class,
+        javax.sound.sampled.spi.AudioFileWriter.class,
+        javax.sound.sampled.spi.FormatConversionProvider.class,
+        javax.sound.sampled.spi.MixerProvider.class,
+    };
+
+    public static void main(String[] args) throws Exception {
+        boolean allCached = true;
+        for (int i = 0; i < providerClasses.length; i++) {
+            List list0 = JDK13Services.getProviders(providerClasses[i]);
+            List list1 = JDK13Services.getProviders(providerClasses[i]);
+            if (list0 == list1) {
+                out("Providers should not be cached for " + providerClasses[i]);
+                allCached = false;
+            }
+        }
+
+        if (! allCached) {
+            throw new Exception("Test failed");
+        } else {
+            out("Test passed");
+        }
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/AudioSystem/testdata/lib/conf/sound.properties	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2003, 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.
+#
+
+javax.sound.sampled.SourceDataLine=xyz#123
+javax.sound.sampled.TargetDataLine=xyz#123
+javax.sound.sampled.Clip=xyz#123
+javax.sound.sampled.Port=xyz#123
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Clip/ClipCloseLoss.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4946913
+ * @summary DirectClip doesn't kill the thread correctly, sometimes
+ * @run main/othervm ClipCloseLoss
+ * @key headful
+ */
+public class ClipCloseLoss {
+    static int frameCount = 441000; // lets say 10 seconds
+    static AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false);
+    static ByteArrayInputStream bais =
+    new ByteArrayInputStream(new byte[frameCount * format.getFrameSize()]);
+
+    static int success = 0;
+    static boolean failed = false;
+
+    public static void run(Mixer m) {
+        Clip clip = null;
+        try {
+            if (m == null) {
+                out("Using default mixer");
+                clip = (Clip) AudioSystem.getClip();
+            } else {
+                out("Using mixer: "+m);
+                DataLine.Info info = new DataLine.Info(Clip.class, format, AudioSystem.NOT_SPECIFIED);
+                clip = (Clip) m.getLine(info);
+            }
+            out(" got clip: "+clip);
+            if (!clip.getClass().toString().contains("Direct")) {
+                out(" no direct audio clip -> do not test.");
+                return;
+            }
+
+            out(" open");
+            bais.reset();
+            clip.open(new AudioInputStream(bais, format, frameCount));
+
+            out(" clip.close()");
+            //long t = System.currentTimeMillis();
+            clip.close();
+            //if (System.currentTimeMillis() - t > 1950) {
+            //  out(" clip.close needed more than 2 seconds! Causes failure of this test.");
+            //  failed = true;
+            //}
+            out(" clip closed");
+            success++;
+        } catch (LineUnavailableException luae) {
+            // line not available, test not failed
+            System.err.println(luae);
+        } catch (IllegalArgumentException iae) {
+            // line not available, test not failed
+            System.err.println(iae);
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+    }
+
+    public static int getClipThreadCount() {
+        int ret = 0;
+        ThreadGroup tg = Thread.currentThread().getThreadGroup();
+        while (tg.getParent() != null) { tg = tg.getParent(); }
+        Thread[] threads = new Thread[500];
+        int count = tg.enumerate(threads, true);
+        for (int i = 0; i < count; i++) {
+                if (threads[i].getName().contains("Direct")
+                    && threads[i].getName().contains("Clip")) {
+                        out("Found Direct Clip thread object: "+threads[i]);
+                        ret++;
+                }
+        }
+        return ret;
+    }
+
+    public static void main(String[] args) throws Exception    {
+        if (isSoundcardInstalled()) {
+            bais.mark(0);
+            run(null);
+            Mixer.Info[] infos = AudioSystem.getMixerInfo();
+            for (int i = 0; i<infos.length; i++) {
+                try {
+                    Mixer m = AudioSystem.getMixer(infos[i]);
+                    run(m);
+                } catch (Exception e) {
+                }
+            }
+            out("Waiting 1 second to dispose of all threads");
+            Thread.sleep(1000);
+            if (getClipThreadCount() > 0) {
+                out("Unused clip threads exist! Causes test failure");
+                failed = true;
+            }
+            if (failed) throw new Exception("Test FAILED!");
+            if (success > 0) {
+                out("Test passed.");
+            } else {
+                System.err.println("Test could not execute: please install an audio device");
+            }
+        }
+    }
+
+    /**
+    * Returns true if at least one soundcard is correctly installed
+    * on the system.
+    */
+    public static boolean isSoundcardInstalled() {
+        boolean result = false;
+        try {
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            if (mixers.length > 0) {
+                result = AudioSystem.getSourceDataLine(null) != null;
+            }
+        } catch (Exception e) {
+            System.err.println("Exception occured: "+e);
+        }
+        if (!result) {
+            System.err.println("Soundcard does not exist or sound drivers not installed!");
+            System.err.println("This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+
+    public static void out(String s) {
+        /*long t = System.nanoTime() / 1000000l;
+        String ts = ""+(t % 1000);
+        while (ts.length() < 3) ts = "0"+ts;
+        System.out.println(""+(t/1000)+":"+ts+" "+s);
+        System.out.flush();*/
+        System.out.println(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Clip/ClipFlushCrash.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4946945
+ * @summary Crash in javasound while running TicTacToe demo applet tiger b26
+ */
+public class ClipFlushCrash {
+    static int frameCount = 441000; // lets say 10 seconds
+    static AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false);
+    static ByteArrayInputStream bais =
+      new ByteArrayInputStream(new byte[frameCount * format.getFrameSize()]);
+
+    static int success = 0;
+
+    public static void run(Mixer m) {
+        Clip clip = null;
+        try {
+            if (m == null) {
+                out("Using default mixer");
+                clip = (Clip) AudioSystem.getClip();
+            } else {
+                out("Using mixer: "+m);
+                DataLine.Info info = new DataLine.Info(Clip.class, format, AudioSystem.NOT_SPECIFIED);
+                clip = (Clip) m.getLine(info);
+            }
+            out(" got clip: "+clip);
+            if (!clip.getClass().toString().contains("Direct")) {
+                out(" no direct audio clip -> do not test.");
+                return;
+            }
+
+            out(" open");
+            bais.reset();
+            clip.open(new AudioInputStream(bais, format, frameCount));
+
+            AT at1 = new AT(clip, "flush thread", 123) {
+                public void doAction() throws Exception {
+                        log("flush");
+                        clip.flush();
+                }
+            };
+            AT at2 = new AT(clip, "setFramePosition thread", 67) {
+                public void doAction() throws Exception {
+                        int pos = (int) (Math.random() * clip.getFrameLength());
+                        log("setPosition to frame "+pos);
+                        clip.setFramePosition(pos);
+                }
+            };
+            AT at3 = new AT(clip, "start/stop thread", 300) {
+                public void doAction() throws Exception {
+                        if (clip.isRunning()) {
+                                log("stop");
+                                clip.stop();
+                        } else {
+                                log("start");
+                                clip.setFramePosition(0);
+                                clip.start();
+                        }
+                }
+            };
+            AT at4 = new AT(clip, "open/close thread", 600) {
+                public synchronized void doAction() throws Exception {
+                        log("close");
+                        clip.close();
+                        wait(50);
+                        if (!terminated) {
+                                log("open");
+                                bais.reset();
+                                clip.open(new AudioInputStream(bais, format, frameCount));
+                        }
+                }
+            };
+
+            out(" clip.start");
+            clip.start();
+            out(" for 10 seconds, call start/stop, setFramePosition, and flush from other threads");
+            at1.start();
+            at2.start();
+            at3.start();
+            at4.start();
+            try {
+                Thread.sleep(10000);
+            } catch (InterruptedException ie) {}
+            out(" finished.");
+                at1.terminate();
+                at2.terminate();
+                at3.terminate();
+                at4.terminate();
+            out(" clip.close()");
+            clip.close();
+            success++;
+        } catch (LineUnavailableException luae) {
+            // line not available, test not failed
+            System.err.println(luae);
+        } catch (IllegalArgumentException iae) {
+            // line not available, test not failed
+            System.err.println(iae);
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args) throws Exception     {
+        if (isSoundcardInstalled()) {
+                bais.mark(0);
+            run(null);
+            Mixer.Info[] infos = AudioSystem.getMixerInfo();
+            for (int i = 0; i<infos.length; i++) {
+                try {
+                        Mixer m = AudioSystem.getMixer(infos[i]);
+                        run(m);
+                } catch (Exception e) {
+                }
+            }
+            if (success > 0) {
+                out("No crash -> Test passed");
+            } else {
+                System.err.println("Test could not execute: please install an audio device");
+            }
+        }
+    }
+
+    /**
+     * Returns true if at least one soundcard is correctly installed
+     * on the system.
+     */
+    public static boolean isSoundcardInstalled() {
+        boolean result = false;
+        try {
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            if (mixers.length > 0) {
+                result = AudioSystem.getSourceDataLine(null) != null;
+            }
+        } catch (Exception e) {
+            System.err.println("Exception occured: "+e);
+        }
+        if (!result) {
+            System.err.println("Soundcard does not exist or sound drivers not installed!");
+            System.err.println("This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+
+    public static void out(String s) {
+        /*long t = System.nanoTime() / 1000000l;
+        String ts = ""+(t % 1000);
+        while (ts.length() < 3) ts = "0"+ts;
+        System.out.println(""+(t/1000)+":"+ts+" "+s);
+        System.out.flush();*/
+        System.out.println(s);
+    }
+
+    private abstract static class AT extends Thread {
+        protected boolean terminated = false;
+        protected Clip clip;
+        private int waitTime;
+
+        public AT(Clip clip, String name, int waitTime) {
+                super(name);
+                this.clip = clip;
+                this.waitTime = waitTime;
+        }
+
+        public abstract void doAction() throws Exception;
+
+                public void run() {
+                        log("start");
+                        while (!terminated) {
+                                try {
+                                        synchronized(this) {
+                                            wait(waitTime);
+                                        }
+                                        if (!terminated) {
+                                                doAction();
+                                        }
+                                } catch(Exception e) {
+                                        log("exception: "+e);
+                                }
+                        }
+                        log("exit");
+                }
+
+                public synchronized void terminate() {
+                        log("terminate");
+                        terminated = true;
+                        notifyAll();
+                }
+
+        protected void log(String s) {
+            //out("   "+Thread.currentThread().getId()+" "+getName()+": "+s);
+            out("   "+getName()+": "+s);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Clip/Drain/ClipDrain.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4732218
+ * @summary Clip.drain does not actually block until all I/O is complete as
+ *          documented.
+ */
+public class ClipDrain {
+    static int successfulTests = 0;
+    static AudioFormat format = new AudioFormat(8000, 16, 1, true, false);
+    // create a 10-second file
+    static byte[] soundData = new byte[(int) (format.getFrameRate() * format.getFrameSize() * 10)];
+
+    static int TOLERANCE_MS = 2500; // how many milliseconds too short is tolerated...
+
+    private static void doMixerClip(Mixer mixer) throws Exception {
+        boolean waitedEnough=false;
+        try {
+            DataLine.Info info = new DataLine.Info(Clip.class, format);
+            Clip clip = (Clip) mixer.getLine(info);
+            clip.open(format, soundData, 0, soundData.length);
+
+            // sanity
+            if (clip.getMicrosecondLength()/1000 < 9900) {
+                throw new Exception("clip's microsecond length should be at least 9900000, but it is "+clip.getMicrosecondLength());
+            }
+            long start = System.currentTimeMillis();
+
+            System.out.println(" ---------- start --------");
+            clip.start();
+            // give time to actually start it. ALSA implementation needs that...
+            Thread.sleep(300);
+            System.out.println("drain ... ");
+            clip.drain();
+            long elapsedTime = System.currentTimeMillis() - start;
+            System.out.println("close ... ");
+            clip.close();
+            System.out.println("... done");
+            System.out.println("Playback duration: "+elapsedTime+" milliseconds.");
+            waitedEnough = elapsedTime >= ((clip.getMicrosecondLength() / 1000) - TOLERANCE_MS);
+        } catch (Throwable t) {
+                System.out.println("  - Caught exception. Not failed.");
+                System.out.println("  - "+t.toString());
+                return;
+        }
+        if (!waitedEnough) {
+            throw new Exception("Drain did not wait long enough to play entire clip.");
+        }
+        successfulTests++;
+    }
+
+
+    private static void doAll() throws Exception {
+        Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+        for (int i=0; i<mixers.length; i++) {
+            Mixer mixer = AudioSystem.getMixer(mixers[i]);
+            System.out.println("--------------");
+            System.out.println("Testing mixer: "+mixers[i]);
+            doMixerClip(mixer);
+        }
+        if (mixers.length==0) {
+            System.out.println("No mixers available!");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (!isSoundcardInstalled()) {
+            return;
+        }
+        doAll();
+        if (successfulTests==0) {
+            System.out.println("Could not execute any of the tests. Test NOT failed.");
+        } else {
+            System.out.println("Test PASSED.");
+        }
+    }
+
+    /**
+     * Returns true if at least one soundcard is correctly installed
+     * on the system.
+     */
+    public static boolean isSoundcardInstalled() {
+        boolean result = false;
+        try {
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            if (mixers.length > 0) {
+                result = AudioSystem.getSourceDataLine(null) != null;
+            }
+        } catch (Exception e) {
+            System.err.println("Exception occured: "+e);
+        }
+        if (!result) {
+            System.err.println("Soundcard does not exist or sound drivers not installed!");
+            System.err.println("This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Clip/Duration/ClipDuration.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2001, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4237703
+ * @summary Check that Clip.getMicrosecondLength() returns correct value.
+ */
+public class ClipDuration {
+
+    public static int run(Mixer m) {
+        int res=1; // failed
+        int frameCount = 441000; // lets say 10 seconds
+        AudioFormat f = new AudioFormat(44100.0f, 16, 2, true, false);
+        AudioInputStream audioInputStream =
+            new AudioInputStream(new ByteArrayInputStream(new byte[frameCount * f.getFrameSize()]),
+                                 f, frameCount);
+        AudioFormat     format = audioInputStream.getFormat();
+        Clip m_clip = null;
+        try {
+            if (m == null) {
+                m_clip = (Clip) AudioSystem.getClip();
+            } else {
+                DataLine.Info   info = new DataLine.Info(Clip.class, format, AudioSystem.NOT_SPECIFIED);
+                m_clip = (Clip) m.getLine(info);
+            }
+            System.out.println("Got clip: "+m_clip);
+            m_clip.open(audioInputStream);
+            long microseconds=m_clip.getMicrosecondLength();
+            System.out.println("getFrameLength()="+m_clip.getFrameLength()+" frames");
+            System.out.println("getMicrosecondLength()="+microseconds+" us");
+            if (Math.abs(microseconds-10000000)<50) {
+                System.out.println("->Clip OK");
+                res=0; // passes if less than 50us error
+            }
+        } catch (LineUnavailableException luae) {
+            System.err.println(luae);
+            res = 3; // line not available, test not failed
+        } catch (Throwable t) {
+            System.out.println("->Exception:"+t);
+            t.printStackTrace();
+            res=2; // exception
+        }
+        if (m_clip != null) {
+            m_clip.close();
+        }
+        return res;
+    }
+
+
+
+    public static void main(String[] args) throws Exception     {
+        if (isSoundcardInstalled()) {
+            int res=3;
+            res = run(null);
+            Mixer.Info[] infos = AudioSystem.getMixerInfo();
+            for (int i = 0; i<infos.length; i++) {
+                try {
+                        Mixer m = AudioSystem.getMixer(infos[i]);
+                        int r = run(m);
+                        if (r == 1) res = 1;
+                } catch (Exception e) {
+                }
+            }
+            if (res!=1) {
+                System.out.println("Test passed");
+            } else {
+                if (res==2) {
+                    System.err.println("Test could not execute: test threw unexpected Exception.");
+                    throw new Exception("Test threw exception");
+                }
+                else if (res==3) {
+                    System.err.println("Test could not execute: please install an audio device");
+                    return;
+                }
+                throw new Exception("Test returned wrong length");
+            }
+        }
+    }
+
+    /**
+     * Returns true if at least one soundcard is correctly installed
+     * on the system.
+     */
+    public static boolean isSoundcardInstalled() {
+        boolean result = false;
+        try {
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            if (mixers.length > 0) {
+                result = AudioSystem.getSourceDataLine(null) != null;
+            }
+        } catch (Exception e) {
+            System.err.println("Exception occured: "+e);
+        }
+        if (!result) {
+            System.err.println("Soundcard does not exist or sound drivers not installed!");
+            System.err.println("This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Clip/Endpoint/ClipSetEndPoint.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2005, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4385928
+ * @summary Verify that an endpoint -1 in Clip does not throw an exception
+ */
+//public class test048 extends TRTest
+public class ClipSetEndPoint {
+
+    private Clip theClip;
+
+    boolean testPassed = true;
+
+    //_______________________________________________
+    //      Method: runTest
+    //_______________________________________________
+    public boolean runTest() {
+        AudioInputStream theAudioInputStream = new AudioInputStream(
+                new ByteArrayInputStream(new byte[2000]),
+                new AudioFormat(8000.0f, 8, 1, false, false), 2000); //
+
+        AudioFormat theAudioFormat = theAudioInputStream.getFormat();
+
+        DataLine.Info info = new DataLine.Info(Clip.class, theAudioFormat,
+                                               AudioSystem.NOT_SPECIFIED);
+        try {
+            theClip = (Clip) AudioSystem.getLine(info);
+            theClip.open(theAudioInputStream);
+
+            int theStartLoopPoint = 0;
+            int theEndLoopPoint = -1;       //      -1 signifies the last frame
+
+            theClip.setLoopPoints(theStartLoopPoint, theEndLoopPoint);
+            //theClip.start();
+        } catch (LineUnavailableException e) {
+            e.printStackTrace();
+            testPassed = true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            testPassed = false;
+        }
+        return testPassed;
+    }
+
+    //_______________________________________________
+    //      Method: main
+    //_______________________________________________
+    public static void main(String[] args) throws Exception {
+        if (isSoundcardInstalled()) {
+            ClipSetEndPoint thisTest = new ClipSetEndPoint();
+            boolean testResult = thisTest.runTest();
+            if (testResult) {
+                System.out.println("Test passed");
+            } else {
+                System.out.println("Test failed");
+                throw new Exception("Test failed");
+            }
+        }
+    }
+
+    /**
+     * Returns true if at least one soundcard is correctly installed
+     * on the system.
+     */
+    public static boolean isSoundcardInstalled() {
+        boolean result = false;
+        try {
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            if (mixers.length > 0) {
+                result = AudioSystem.getSourceDataLine(null) != null;
+            }
+        } catch (Exception e) {
+            System.err.println("Exception occured: " + e);
+        }
+        if (!result) {
+            System.err.println(
+                    "Soundcard does not exist or sound drivers not installed!");
+            System.err.println(
+                    "This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Clip/IsRunningHang.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineUnavailableException;
+
+/**
+ * @test
+ * @bug 8156169
+ * @run main/othervm/timeout=300 IsRunningHang
+ */
+public final class IsRunningHang {
+
+    private static CountDownLatch go;
+
+    /**
+     * We will try to use all usually supported formats.
+     */
+    private static final List<AudioFormat> formats = new ArrayList<>();
+
+    private static final AudioFormat.Encoding[] encodings = {
+            AudioFormat.Encoding.ALAW, AudioFormat.Encoding.ULAW,
+            AudioFormat.Encoding.PCM_SIGNED, AudioFormat.Encoding.PCM_UNSIGNED,
+            AudioFormat.Encoding.PCM_FLOAT
+    };
+
+    private static final int[] sampleRates = {8000, 16000, 48000};
+
+    private static final int[] sampleBits = {8, 16, 24, 32, 64};
+
+    private static final int[] channels = {1, 2, 3, 5};
+
+    static {
+        for (final Boolean end : new boolean[]{false, true}) {
+            for (final int sampleSize : sampleBits) {
+                for (final int sampleRate : sampleRates) {
+                    for (final int channel : channels) {
+                        for (final AudioFormat.Encoding enc : encodings) {
+                            int s = ((sampleSize + 7) / 8) * channel;
+                            formats.add(new AudioFormat(enc, sampleRate,
+                                                        sampleSize, channel,
+                                                        s, sampleRate, end));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public static void main(final String[] args) throws Exception {
+        for (final AudioFormat format : formats) {
+            System.out.println("format = " + format);
+            // create a 0.5-second data
+            byte[] soundData = new byte[(int) (format.getFrameRate()
+                                                       * format.getFrameSize()
+                                                       / 2)];
+            try {
+                test(format, soundData);
+            } catch (LineUnavailableException | IllegalArgumentException ignored) {
+                // the test is not applicable
+            }
+        }
+    }
+
+    private static void test(final AudioFormat format, final byte[] data)
+            throws Exception {
+        final Line.Info info = new DataLine.Info(Clip.class, format);
+        final Clip clip = (Clip) AudioSystem.getLine(info);
+
+        go = new CountDownLatch(1);
+        clip.addLineListener(event -> {
+            if (event.getType().equals(LineEvent.Type.START)) {
+                go.countDown();
+            }
+        });
+
+        clip.open(format, data, 0, data.length);
+        clip.start();
+        go.await();
+        while (clip.isRunning()) {
+            // This loop should not hang
+        }
+        while (clip.isActive()) {
+            // This loop should not hang
+        }
+        clip.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Clip/Open/ClipOpenBug.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2001, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.FloatControl;
+
+/**
+ * @test
+ * @bug 4479444
+ * @summary Verify that the error string of Clip.open() is meaningful
+ */
+public class ClipOpenBug {
+
+    public static void main(String args[]) throws Exception {
+        boolean res = true;
+        try {
+            AudioInputStream ais = new AudioInputStream(
+                    new ByteArrayInputStream(new byte[2000]),
+                    new AudioFormat(8000.0f, 8, 1, false, false), 2000); //
+            AudioFormat format = ais.getFormat();
+            DataLine.Info info = new DataLine.Info(Clip.class, format,
+                                                   ((int) ais.getFrameLength()
+                                                            * format
+                                                           .getFrameSize()));
+            Clip clip = (Clip) AudioSystem.getLine(info);
+            clip.open();
+            FloatControl rateControl = (FloatControl) clip.getControl(
+                    FloatControl.Type.SAMPLE_RATE);
+            int c = 0;
+            while (c++ < 10) {
+                clip.stop();
+                clip.setFramePosition(0);
+                clip.start();
+                for (float frq = 22000; frq < 44100; frq = frq + 100) {
+                    try {
+                        Thread.currentThread().sleep(20);
+                    } catch (Exception e) {
+                        break;
+                    }
+                    rateControl.setValue(frq);
+                }
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            res = ex.getMessage().indexOf(
+                    "This method should not have been invoked!") < 0;
+        }
+        if (res) {
+            System.out.println("Test passed");
+        } else {
+            System.out.println("Test failed");
+            throw new Exception("Test failed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Clip/bug5070081.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.util.concurrent.TimeUnit;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+
+/*
+ * @test
+ * @bug 5070081
+ * @summary Tests that javax.sound.sampled.Clip does not loses position through
+ *          stop/start
+ * @key headful
+ */
+public class bug5070081 {
+
+    static AudioFormat format = new AudioFormat(22050, 8, 1, false, false);
+    // create a 3-second file
+    static byte[] soundData = new byte[(int) (format.getFrameRate() * format.getFrameSize() * 3)];
+
+    static final int LOOP_COUNT = 5;
+
+    static boolean test() throws Exception {
+        DataLine.Info info = new DataLine.Info(Clip.class, format);
+        Clip clip = (Clip)AudioSystem.getLine(info);
+        clip.open(format, soundData, 0, soundData.length);
+
+        boolean bSuccess = true;
+
+        long nLengthMS = clip.getMicrosecondLength()/1000;
+
+        System.out.println("  Clip length:");
+        System.out.println("    frames: " + clip.getFrameLength());
+        System.out.println("    seconds: " + nLengthMS/1000.0);
+
+        clip.start();                               // start playing
+        Thread.sleep(1000);                         // wait a sec
+        long time1 = currentTimeMillis();
+        long pos1 = clip.getFramePosition();        // store the position
+        clip.stop();                                // and then stop
+        long pos2 = clip.getFramePosition();        // 2nd try
+        long time2 = currentTimeMillis();
+
+        System.out.println("  Position before stop: " + pos1);
+        System.out.println("  Position after stop: " + pos2);
+
+        long timeDiff = Math.abs(time2 - time1);
+        // sample rate is 22050 per second, so 22.05 per ms
+        long posDiff = (long) (Math.abs(pos2 - pos1) / 22.05);
+        System.out.println("  d(time): " + timeDiff + " ms;"
+                + "d(clip pos time): " + posDiff + " ms.");
+
+        long nDerivation = posDiff - timeDiff;
+        // add 50 ms for deviation (delay for stopping and errors due timer precision)
+        if (nDerivation > 50) {
+            System.out.println("  ERROR(1): The deviation is too much: " + nDerivation + " ms");
+            bSuccess = false;
+        }
+
+        Thread.sleep(1000);
+        clip.start();                               // start again
+        Thread.sleep(100);
+        while(clip.isRunning());                    // wait for the sound to finish
+
+        int nEndPos = clip.getFramePosition();
+        System.out.println("  Position at end: " + nEndPos);
+        if (nEndPos > clip.getFrameLength()) {
+            System.out.println("  ERROR(2): end position if out of range");
+            bSuccess = false;
+        }
+
+        clip.close();
+
+        return bSuccess;
+    }
+
+    public static void main(String[] args) throws Exception {
+        for (int count=1; count <= LOOP_COUNT; count++)
+        {
+            System.out.println("loop " + count + "/" + LOOP_COUNT);
+            if (!test())
+            {
+                System.out.println("Test FAILED");
+                throw new RuntimeException("Test FAILED.");
+            }
+        }
+
+        System.out.println("Test passed sucessfully");
+    }
+
+    private static long currentTimeMillis() {
+        return TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Clip/bug6251460.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2005, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.LineUnavailableException;
+
+/**
+ * @test
+ * @bug 6251460 8047222
+ * @requires (os.family == "windows" | os.family == "mac")
+ * @summary Tests that JavaSound plays short sounds (less then 1 second)
+ */
+public class bug6251460 {
+    private static final class MutableBoolean {
+        public boolean value;
+
+        public MutableBoolean(boolean initialValue) {
+            value = initialValue;
+        }
+    }
+
+    // static helper routines
+    static long startTime = currentTimeMillis();
+    static long currentTimeMillis() {
+        return System.nanoTime() / 1000000L;
+    }
+    static void log(String s) {
+        long time = currentTimeMillis() - startTime;
+        long ms = time % 1000;
+        time /= 1000;
+        long sec = time % 60;
+        time /= 60;
+        long min = time % 60;
+        time /= 60;
+        System.out.println(""
+            + (time < 10 ? "0" : "") + time
+            + ":" + (min < 10 ? "0" : "") + min
+            + ":" + (sec < 10 ? "0" : "") + sec
+            + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms
+            + " " + s);
+    }
+
+
+    static private int countErrors = 0;
+    static private final int LOOP_COUNT = 30;
+
+    static AudioFormat format = new AudioFormat(8000, 16, 1, true, false);
+    // create a 250-ms clip
+    static byte[] soundData = new byte[(int) (format.getFrameRate() * format.getFrameSize() * 0.25)];
+
+    static protected void test()
+            throws LineUnavailableException, InterruptedException {
+        DataLine.Info info = new DataLine.Info(Clip.class, format);
+        Clip clip = (Clip)AudioSystem.getLine(info);
+        final MutableBoolean clipStoppedEvent = new MutableBoolean(false);
+        clip.addLineListener(new LineListener() {
+            @Override
+            public void update(LineEvent event) {
+                if (event.getType() == LineEvent.Type.STOP) {
+                    synchronized (clipStoppedEvent) {
+                        clipStoppedEvent.value = true;
+                        clipStoppedEvent.notifyAll();
+                    }
+                }
+            }
+        });
+        clip.open(format, soundData, 0, soundData.length);
+
+        long lengthClip = clip.getMicrosecondLength() / 1000;
+        log("Clip length " + lengthClip + " ms");
+        log("Playing...");
+        for (int i=1; i<=LOOP_COUNT; i++) {
+            long startTime = currentTimeMillis();
+            log(" Loop " + i);
+            clip.start();
+
+            synchronized (clipStoppedEvent) {
+                while (!clipStoppedEvent.value) {
+                    clipStoppedEvent.wait();
+                }
+                clipStoppedEvent.value = false;
+            }
+
+            long endTime = currentTimeMillis();
+            long lengthPlayed = endTime - startTime;
+
+            if (lengthClip > lengthPlayed + 20) {
+                log(" ERR: Looks like sound didn't play: played " + lengthPlayed + " ms instead " + lengthClip);
+                countErrors++;
+            } else {
+                log(" OK: played " + lengthPlayed + " ms");
+            }
+            clip.setFramePosition(0);
+
+        }
+        log("Played " + LOOP_COUNT + " times, " + countErrors + " errors detected.");
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+        try {
+            test();
+        } catch (LineUnavailableException | IllegalArgumentException
+                | IllegalStateException ignored) {
+            System.out.println("Test is not applicable. Automatically passed");
+            return;
+        }
+        if (countErrors > 0) {
+            throw new RuntimeException(
+                    "Test FAILED: " + countErrors + " error detected (total "
+                            + LOOP_COUNT + ")");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Controls/CompoundControl/ToString.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.CompoundControl;
+import javax.sound.sampled.Control;
+
+/**
+ * @test
+ * @bug 4629190
+ * @summary CompoundControl: getMemberControls() and toString() throw
+ *          NullPointerException
+ */
+public class ToString {
+    public static void main(String args[]) throws Exception {
+        System.out.println();
+        System.out.println();
+        System.out.println("4629190: CompoundControl: getMemberControls() and toString() throw NullPointerException");
+
+        String firstControlTypeName = "first_Control_Type_Name";
+        String secondControlTypeName = "second_Control_Type_Name";
+        String thirdControlTypeName = "third_Control_Type_Name";
+
+        Control.Type firstControlType = new TestControlType(firstControlTypeName);
+        Control.Type secondControlType = new TestControlType(secondControlTypeName);
+        Control.Type thirdControlType = new TestControlType(thirdControlTypeName);
+
+        Control firstControl = new TestControl(firstControlType);
+        Control secondControl = new TestControl(secondControlType);
+        Control thirdControl = new TestControl(thirdControlType);
+
+        String testCompoundControlTypeName = "CompoundControl_Type_Name";
+        CompoundControl.Type testCompoundControlType
+            = new TestCompoundControlType(testCompoundControlTypeName);
+
+        Control[] setControls = { firstControl, secondControl, thirdControl };
+        CompoundControl testedCompoundControl
+            = new TestCompoundControl(testCompoundControlType, setControls);
+
+        // this may throw exception if bug applies
+        Control[] producedControls = testedCompoundControl.getMemberControls();
+        System.out.println("Got "+producedControls.length+" member controls.");
+
+        // this may throw exception if bug applies
+        String producedString = testedCompoundControl.toString();
+        System.out.println("toString() returned: "+producedString);
+
+        System.out.println("Test passed.");
+    }
+
+}
+
+class TestControl extends Control {
+
+    TestControl(Control.Type type) {
+        super(type);
+    }
+}
+
+class TestControlType extends Control.Type {
+
+    TestControlType(String name) {
+        super(name);
+    }
+}
+
+class TestCompoundControl extends CompoundControl {
+
+    TestCompoundControl(CompoundControl.Type type, Control[] memberControls) {
+        super(type, memberControls);
+    }
+}
+
+class TestCompoundControlType extends CompoundControl.Type {
+
+    TestCompoundControlType(String name) {
+        super(name);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Controls/FloatControl/FloatControlBug.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2001, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.FloatControl;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4385654
+ * @summary Check that the MASTER_GAIN control has a valid precision
+ */
+//public class test047 extends TRTest
+public class FloatControlBug {
+
+    private Clip theClip;
+
+    boolean testPassed = true;
+
+    private AudioFormat.Encoding theEncoding = AudioFormat.Encoding.PCM_SIGNED;
+
+    private float theSampleRate = 44100;
+
+    private int theSampleSize = 16;
+
+    private int theNumberOfChannels = 1;
+
+    private int theFrameSize = 2;
+
+    private float theFrameRate = 44100;
+
+    private boolean isBigEndian = false;
+
+    //_______________________________________________
+    //      Method: runTest
+    //_______________________________________________
+    public boolean runTest() {
+        AudioInputStream theAudioInputStream = new AudioInputStream(
+                new ByteArrayInputStream(new byte[0]),
+                new AudioFormat(44100.0f, 16, 2, true, false), 441000);
+
+        AudioFormat theAudioFormat = theAudioInputStream.getFormat();
+
+        DataLine.Info info = new DataLine.Info(Clip.class, theAudioFormat,
+                                               AudioSystem.NOT_SPECIFIED);
+        try {
+            theClip = (Clip) AudioSystem.getLine(info);
+            theClip.open(theAudioInputStream);
+            FloatControl theFloatControl = (FloatControl) (theClip.getControl(
+                    FloatControl.Type.MASTER_GAIN));
+            float theFloatControlPrecision = theFloatControl.getPrecision();
+            System.out.println(
+                    "theFloatControlPrecision: " + theFloatControlPrecision);
+            System.out.println("Minimum: " + theFloatControl.getMinimum());
+            System.out.println("Maximum: " + theFloatControl.getMaximum());
+            System.out.println("Value  : " + theFloatControl.getValue());
+            testPassed = theFloatControlPrecision > 0;
+        } catch (LineUnavailableException e) {
+            e.printStackTrace();
+            testPassed = true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            testPassed = false;
+        }
+        return testPassed;
+    }
+
+    //_______________________________________________
+    //      Method: main
+    //_______________________________________________
+    public static void main(String[] args) throws Exception {
+        //test047 thisTest = new test047();
+        if (isSoundcardInstalled()) {
+            FloatControlBug thisTest = new FloatControlBug();
+            boolean testResult = thisTest.runTest();
+            if (testResult) {
+                System.out.println("Test passed");
+            } else {
+                System.out.println("Test failed");
+                throw new Exception("Test failed");
+            }
+        }
+    }
+
+    /**
+     * Returns true if at least one soundcard is correctly installed
+     * on the system.
+     */
+    public static boolean isSoundcardInstalled() {
+        boolean result = false;
+        try {
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            if (mixers.length > 0) {
+                result = AudioSystem.getSourceDataLine(null) != null;
+            }
+        } catch (Exception e) {
+            System.err.println("Exception occured: " + e);
+        }
+        if (!result) {
+            System.err.println(
+                    "Soundcard does not exist or sound drivers not installed!");
+            System.err.println(
+                    "This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/DataLine/DataLineInfoNegBufferSize.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 5021234
+ * @summary Using -2 for buffer size will fail retrieval of lines
+ */
+public class DataLineInfoNegBufferSize {
+
+    /**
+     * returns:
+     * 0: OK
+     * 1: IAE
+     * 2: other exception
+     * 3: line not available
+     */
+    public static int run(Mixer m, int bufferSize) {
+        int res;
+        int frameCount = 441000; // lets say 10 seconds
+        AudioFormat f = new AudioFormat(44100.0f, 16, 2, true, false);
+        Clip clip = null;
+        try {
+            System.out.println("Requesting clip from Mixer "
+                               +(m==null?"default":m.toString())
+                               +" with bufferSize"+bufferSize);
+            DataLine.Info info = new DataLine.Info(Clip.class, f, bufferSize);
+            if (m==null) {
+                clip = (Clip) AudioSystem.getLine(info);
+            } else {
+                clip = (Clip) m.getLine(info);
+            }
+            System.out.println("Got clip: "+clip+" with Buffer size "+clip.getBufferSize());
+
+            res = 0;
+        } catch (LineUnavailableException luae) {
+            System.out.println(luae);
+            res = 3; // line not available
+        } catch (IllegalArgumentException iae) {
+            System.out.println(iae);
+            res = 1;
+        } catch (Throwable t) {
+            System.out.println("->Exception:"+t);
+            t.printStackTrace();
+            res=2; // other exception
+        }
+        return res;
+    }
+
+    public static void main(String[] args) throws Exception     {
+        if (isSoundcardInstalled()) {
+            int res=0;
+            int count = 0;
+            Mixer.Info[] infos = AudioSystem.getMixerInfo();
+            for (int i = -1; i<infos.length; i++) {
+                try {
+                    Mixer m;
+                    if (i == -1) {
+                        m = null;
+                    } else {
+                        m = AudioSystem.getMixer(infos[i]);
+                    }
+                    int r = run(m, AudioSystem.NOT_SPECIFIED);
+                    // only continue if successful
+                    if (r == 0) {
+                        count++;
+                        r = run(m, -2);
+                        if (r == 1) {
+                            // only fail if IAE was thrown
+                            System.out.println("#FAILED: using -2 for buffer size does not work!");
+                            res = 1;
+                        }
+                    }
+                } catch (Exception e) {
+                }
+            }
+            if (res!=1) {
+                System.out.println("Test passed");
+            } else {
+                if (count == 0) {
+                    System.err.println("Test could not execute -- no suitable mixers installed. NOT failed");
+                }
+                throw new Exception("Test FAILED!");
+            }
+        }
+    }
+
+    /**
+     * Returns true if at least one soundcard is correctly installed
+     * on the system.
+     */
+    public static boolean isSoundcardInstalled() {
+        boolean result = false;
+        try {
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            if (mixers.length > 0) {
+                result = AudioSystem.getSourceDataLine(null) != null;
+            }
+        } catch (Exception e) {
+            System.err.println("Exception occured: "+e);
+        }
+        if (!result) {
+            System.err.println("Soundcard does not exist or sound drivers not installed!");
+            System.err.println("This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/DataLine/LineDefFormat.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+
+/**
+ * @test
+ * @bug 5053380
+ * @summary Verify that getting a line initializes it with the format in
+ *          DataLine.Info
+ */
+public class LineDefFormat {
+
+    final static int samplerate = 22050;
+    static int passed = 0;
+    static int failed = 0;
+
+    private static void doLine1(DataLine line, AudioFormat format) {
+        try {
+            System.out.println("  - got line: "+line);
+            System.out.println("  - line has format: "+line.getFormat());
+            if (!line.getFormat().matches(format)) {
+                System.out.println("  ## Error: expected this format: "+format);
+                failed++;
+            } else {
+                passed++;
+            }
+        } catch (Throwable t) {
+            System.out.println("  - Caught exception. Not failed.");
+            System.out.println("  - "+t.toString());
+        }
+    }
+
+    private static void doLine2(DataLine line, AudioFormat format) {
+        try {
+            System.out.println("  - call to open()");
+            line.open();
+            try {
+                System.out.println("  - line has format: "+line.getFormat());
+                if (!line.getFormat().matches(format)) {
+                    System.out.println("## Error: expected this format: "+format);
+                    failed++;
+                } else {
+                    passed++;
+                }
+            } finally {
+                line.close();
+                System.out.println("  - closed");
+            }
+        } catch (Throwable t) {
+            System.out.println("  - Caught exception. Not failed.");
+            System.out.println("  - "+t.toString());
+        }
+    }
+
+    private static void doMixerClip(Mixer mixer, AudioFormat format) {
+        if (mixer==null) return;
+        try {
+            System.out.println("Clip from mixer "+mixer+":");
+            System.out.println("   "+mixer.getMixerInfo());
+                DataLine.Info info = new DataLine.Info(
+                                          Clip.class,
+                                          format);
+
+            if (mixer.isLineSupported(info)) {
+                Clip clip = (Clip) mixer.getLine(info);
+                doLine1(clip, format);
+            } else {
+                System.out.println("  - Line not supported");
+            }
+        } catch (Throwable t) {
+            System.out.println("  - Caught exception. Not failed.");
+            System.out.println("  - "+t.toString());
+        }
+    }
+
+    private static void doMixerSDL(Mixer mixer, AudioFormat format) {
+        if (mixer==null) return;
+        try {
+            System.out.println("SDL from mixer "+mixer+":");
+                DataLine.Info info = new DataLine.Info(
+                                          SourceDataLine.class,
+                                          format);
+
+            if (mixer.isLineSupported(info)) {
+                SourceDataLine sdl = (SourceDataLine) mixer.getLine(info);
+                doLine1(sdl, format);
+                doLine2(sdl, format);
+            } else {
+                System.out.println("  - Line not supported");
+            }
+        } catch (Throwable t) {
+            System.out.println("  - Caught exception. Not failed.");
+            System.out.println("  - "+t.toString());
+        }
+    }
+
+    private static void doMixerTDL(Mixer mixer, AudioFormat format) {
+        if (mixer==null) return;
+        try {
+            System.out.println("TDL from mixer "+mixer+":");
+                DataLine.Info info = new DataLine.Info(
+                                          TargetDataLine.class,
+                                          format);
+            if (mixer.isLineSupported(info)) {
+                TargetDataLine tdl = (TargetDataLine) mixer.getLine(info);
+                doLine1(tdl, format);
+                doLine2(tdl, format);
+            } else {
+                System.out.println("  - Line not supported");
+            }
+        } catch (Throwable t) {
+            System.out.println("  - Caught exception. Not failed.");
+            System.out.println("  - "+t.toString());
+        }
+    }
+
+    private static void doAll() throws Exception {
+        Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+               AudioFormat pcm;
+        for (int i=0; i<mixers.length; i++) {
+            Mixer mixer = AudioSystem.getMixer(mixers[i]);
+            pcm = new AudioFormat(samplerate, 16, 1, true, false);
+            doMixerClip(mixer, pcm);
+            pcm = new AudioFormat(samplerate, 8, 1, false, false);
+            doMixerSDL(mixer, pcm);
+            pcm = new AudioFormat(samplerate, 16, 2, true, true);
+            doMixerTDL(mixer, pcm);
+        }
+        if (mixers.length==0) {
+            System.out.println("No mixers available!");
+        }
+
+    }
+
+    public static void main(String args[]) throws Exception{
+        doAll();
+        if (passed==0 && failed==0) {
+            System.out.println("Could not execute any of the tests. Test NOT failed.");
+        } else if (failed == 0) {
+            System.out.println("Test PASSED.");
+        } else {
+            throw new Exception("Test FAILED!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/DataLine/LongFramePosition.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 5049129
+ * @summary DataLine.getLongFramePosition
+ * @key headful
+ */
+public class LongFramePosition {
+
+    public static void main(String[] args) throws Exception {
+        boolean failed = false;
+        try {
+            AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false);
+            SourceDataLine sdl = AudioSystem.getSourceDataLine(format);
+            try {
+                sdl.open(format);
+                sdl.start();
+                sdl.write(new byte[16384], 0, 16384);
+                Thread.sleep(1000);
+                int intPos = sdl.getFramePosition();
+                long longPos = sdl.getLongFramePosition();
+                System.out.println("After 1 second: getFramePosition() = "+intPos);
+                System.out.println("            getLongFramePosition() = "+longPos);
+                if (intPos <= 0 || longPos <= 0) {
+                    failed = true;
+                    System.out.println("## FAILED: frame position did not advance, or negative!");
+                }
+                if (Math.abs(intPos - longPos) > 100) {
+                    failed = true;
+                    System.out.println("## FAILED: frame positions are not the same!");
+                }
+            } finally {
+                sdl.close();
+            }
+        } catch(LineUnavailableException e){
+            System.out.println(e);
+            System.out.println("Cannot execute test.");
+            return;
+        }
+        if (failed) throw new Exception("Test FAILED!");
+        System.out.println("Test Passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/DirectAudio/TickAtEndOfPlay.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 5001959
+ * @summary Short tick sound after finished playing with SourceDataLine
+ * @run main/manual TickAtEndOfPlay
+ */
+public class TickAtEndOfPlay {
+
+    static boolean WorkAround1 = false;
+    static boolean WorkAround2 = false;
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("This test should only be run on Windows.");
+        System.out.println("Make sure that the speakers are connected and the volume is up.");
+        System.out.println("Close all other programs that may use the soundcard.");
+
+        System.out.println("You'll hear a 2-second tone. when the tone finishes,");
+        System.out.println("  there should be no noise. If you hear a short tick/noise,");
+        System.out.println("  the bug still applies.");
+
+        System.out.println("Press ENTER to continue.");
+        System.in.read();
+
+        for (int i = 0; i < args.length; i++) {
+            if (args[i].equals("1")) WorkAround1 = true;
+            if (args[i].equals("2")) WorkAround2 = true;
+        }
+        if (WorkAround1) System.out.println("Using work around1: appending silence");
+        if (WorkAround2) System.out.println("Using work around2: waiting before close");
+
+        int zerolen = 0; // how many 0-bytes will be appended to playback
+        if (WorkAround1) zerolen = 1000;
+        int seconds = 2;
+        int sampleRate = 8000;
+        double frequency = 1000.0;
+        double RAD = 2.0 * Math.PI;
+        AudioFormat af = new AudioFormat((float)sampleRate,8,1,true,true);
+        System.out.println("Format: "+af);
+        DataLine.Info info = new DataLine.Info(SourceDataLine.class,af);
+        SourceDataLine source = (SourceDataLine)AudioSystem.getLine(info);
+        System.out.println("Line: "+source);
+        if (source.toString().indexOf("MixerSourceLine")>=0) {
+            System.out.println("This test only applies to non-Java Sound Audio Engine!");
+            return;
+        }
+        System.out.println("Opening...");
+        source.open(af);
+        System.out.println("Starting...");
+        source.start();
+        int datalen = sampleRate * seconds;
+        byte[] buf = new byte[datalen+zerolen];
+        for (int i=0; i<datalen; i++) {
+            buf[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
+        }
+        System.out.println("Writing...");
+        source.write(buf,0,buf.length);
+        System.out.println("Draining...");
+        source.drain();
+        System.out.println("Stopping...");
+        source.stop();
+        if (WorkAround2) {
+            System.out.println("Waiting 200 millis...");
+            Thread.sleep(200);
+        }
+        System.out.println("Closing...");
+        source.close();
+        System.out.println("Done.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/DirectAudio/bug6372428.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2006, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+
+/*
+ * @test
+ * @bug 6372428
+ * @summary playback and capture doesn't interrupt after terminating thread that
+ *          calls start()
+ * @run main bug6372428
+ * @key headful
+ */
+public class bug6372428 {
+    public bug6372428() {
+    }
+
+    public static void main(final String[] args) {
+        bug6372428 pThis = new bug6372428();
+        boolean failed1 = false;
+        boolean failed2 = false;
+        log("");
+        log("****************************************************************");
+        log("*** Playback Test");
+        log("****************************************************************");
+        log("");
+        try {
+            pThis.testPlayback();
+        } catch (IllegalArgumentException | LineUnavailableException e) {
+            System.out.println("Playback test is not applicable. Skipped");
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            failed1 = true;
+        }
+        log("");
+        log("");
+        log("****************************************************************");
+        log("*** Capture Test");
+        log("****************************************************************");
+        log("");
+        try {
+            pThis.testRecord();
+        } catch (IllegalArgumentException | LineUnavailableException e) {
+            System.out.println("Record test is not applicable. Skipped");
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            failed2 = true;
+        }
+        log("");
+        log("");
+        log("****************************************************************");
+        if (failed1 || failed2) {
+            String s = "";
+            if (failed1 && failed2)
+                s = "playback and capture";
+            else if (failed1)
+                s = "playback only";
+            else
+                s = "capture only";
+            throw new RuntimeException("Test FAILED (" + s + ")");
+        }
+        log("*** All tests passed successfully.");
+    }
+
+    final static int DATA_LENGTH        = 15;   // in seconds
+    final static int PLAYTHREAD_DELAY   = 5;   // in seconds
+
+    // playback test classes/routines
+
+    class PlayThread extends Thread {
+        SourceDataLine line;
+        public PlayThread(SourceDataLine line) {
+            this.line = line;
+            this.setDaemon(true);
+        }
+
+        public void run() {
+            log("PlayThread: starting...");
+            line.start();
+            log("PlayThread: delaying " + (PLAYTHREAD_DELAY * 1000) + "ms...");
+            delay(PLAYTHREAD_DELAY * 1000);
+            log("PlayThread: exiting...");
+        }
+    }
+
+    class WriteThread extends Thread {
+        SourceDataLine line;
+        byte[] data;
+        volatile int remaining;
+        volatile boolean stopRequested = false;
+        public WriteThread(SourceDataLine line, byte[] data) {
+            this.line = line;
+            this.data = data;
+            remaining = data.length;
+            this.setDaemon(true);
+        }
+
+        public void run() {
+            while (remaining > 0 && !stopRequested) {
+                int avail = line.available();
+                if (avail > 0) {
+                    if (avail > remaining)
+                        avail = remaining;
+                    int written = line.write(data, data.length - remaining, avail);
+                    remaining -= written;
+                    log("WriteThread: " + written + " bytes written");
+                } else {
+                    delay(100);
+                }
+            }
+            if (remaining == 0) {
+                log("WriteThread: all data has been written, draining");
+                line.drain();
+            } else {
+                log("WriteThread: stop requested");
+            }
+            log("WriteThread: stopping");
+            line.stop();
+            log("WriteThread: exiting");
+        }
+
+        public boolean isCompleted() {
+            return (remaining <= 0);
+        }
+
+        public void requestStop() {
+            stopRequested = true;
+        }
+    }
+
+    void testPlayback() throws LineUnavailableException {
+        // prepare audio data
+        AudioFormat format = new AudioFormat(22050, 8, 1, false, false);
+        byte[] soundData = new byte[(int) (format.getFrameRate() * format.getFrameSize() * DATA_LENGTH)];
+
+        // create & open source data line
+        //SourceDataLine line = AudioSystem.getSourceDataLine(format);
+        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
+        SourceDataLine line = (SourceDataLine)AudioSystem.getLine(info);
+
+        line.open(format);
+
+        // start write data thread
+        WriteThread p1 = new WriteThread(line, soundData);
+        p1.start();
+
+        // start line
+        PlayThread p2 = new PlayThread(line);
+        p2.start();
+
+        // monitor line
+        long lineTime1 = line.getMicrosecondPosition() / 1000;
+        long realTime1 = currentTimeMillis();
+        while (true) {
+            delay(500);
+            if (!line.isActive()) {
+                log("audio data played completely");
+                break;
+            }
+            long lineTime2 = line.getMicrosecondPosition() / 1000;
+            long realTime2 = currentTimeMillis();
+            long dLineTime = lineTime2 - lineTime1;
+            long dRealTime = realTime2 - realTime1;
+            log("line pos: " + lineTime2 + "ms" + ", thread is " + (p2.isAlive() ? "alive" : "DIED"));
+            if (dLineTime < 0) {
+                throw new RuntimeException("ERROR: line position have decreased from " + lineTime1 + " to " + lineTime2);
+            }
+            if (dRealTime < 450) {
+                // delay() has been interrupted?
+                continue;
+            }
+            lineTime1 = lineTime2;
+            realTime1 = realTime2;
+        }
+    }
+
+
+    // recording test classes/routines
+
+    class RecordThread extends Thread {
+        TargetDataLine line;
+        public RecordThread(TargetDataLine line) {
+            this.line = line;
+            this.setDaemon(true);
+        }
+
+        public void run() {
+            log("RecordThread: starting...");
+            line.start();
+            log("RecordThread: delaying " + (PLAYTHREAD_DELAY * 1000) + "ms...");
+            delay(PLAYTHREAD_DELAY * 1000);
+            log("RecordThread: exiting...");
+        }
+    }
+
+    class ReadThread extends Thread {
+        TargetDataLine line;
+        byte[] data;
+        volatile int remaining;
+        public ReadThread(TargetDataLine line, byte[] data) {
+            this.line = line;
+            this.data = data;
+            remaining = data.length;
+            this.setDaemon(true);
+        }
+
+        public void run() {
+            log("ReadThread: buffer size is " + data.length + " bytes");
+            delay(200);
+            while ((remaining > 0) && line.isOpen()) {
+                int avail = line.available();
+                if (avail > 0) {
+                    if (avail > remaining)
+                        avail = remaining;
+                    int read = line.read(data, data.length - remaining, avail);
+                    remaining -= read;
+                    log("ReadThread: " + read + " bytes read");
+                } else {
+                    delay(100);
+                }
+                if (remaining <= 0) {
+                    log("ReadThread: record buffer is full, exiting");
+                    break;
+                }
+            }
+            if (remaining > 0) {
+                log("ReadThread: line has been stopped, exiting");
+            }
+        }
+
+        public int getCount() {
+            return data.length - remaining;
+        }
+        public boolean isCompleted() {
+            return (remaining <= 0);
+        }
+    }
+
+    void testRecord() throws LineUnavailableException {
+        // prepare audio data
+        AudioFormat format = new AudioFormat(22050, 8, 1, false, false);
+
+        // create & open target data line
+        //TargetDataLine line = AudioSystem.getTargetDataLine(format);
+        DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
+        TargetDataLine line = (TargetDataLine)AudioSystem.getLine(info);
+
+        line.open(format);
+
+        // start read data thread
+        byte[] data = new byte[(int) (format.getFrameRate() * format.getFrameSize() * DATA_LENGTH)];
+        ReadThread p1 = new ReadThread(line, data);
+        p1.start();
+
+        // start line
+        //new RecordThread(line).start();
+        RecordThread p2 = new RecordThread(line);
+        p2.start();
+
+        // monitor line
+        long endTime = currentTimeMillis() + DATA_LENGTH * 1000;
+
+        long realTime1 = currentTimeMillis();
+        long lineTime1 = line.getMicrosecondPosition() / 1000;
+
+        while (realTime1 < endTime && !p1.isCompleted()) {
+            delay(100);
+            long lineTime2 = line.getMicrosecondPosition() / 1000;
+            long realTime2 = currentTimeMillis();
+            long dLineTime = lineTime2 - lineTime1;
+            long dRealTime = realTime2 - realTime1;
+            log("line pos: " + lineTime2 + "ms" + ", thread is " + (p2.isAlive() ? "alive" : "DIED"));
+            if (dLineTime < 0) {
+                line.stop();
+                line.close();
+                throw new RuntimeException("ERROR: line position have decreased from " + lineTime1 + " to " + lineTime2);
+            }
+            if (dRealTime < 450) {
+                // delay() has been interrupted?
+                continue;
+            }
+            lineTime1 = lineTime2;
+            realTime1 = realTime2;
+        }
+        log("stopping line...");
+        line.stop();
+        line.close();
+
+        /*
+        log("");
+        log("");
+        log("");
+        log("recording completed, delaying 5 sec");
+        log("recorded " + p1.getCount() + " bytes, " + DATA_LENGTH + " seconds: " + (p1.getCount() * 8 / DATA_LENGTH) + " bit/sec");
+        log("");
+        log("");
+        log("");
+        delay(5000);
+        log("starting playing...");
+        playRecorded(format, data);
+        */
+    }
+
+    void playRecorded(AudioFormat format, byte[] data) throws Exception {
+        //SourceDataLine line = AudioSystem.getSourceDataLine(format);
+        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
+        SourceDataLine line = (SourceDataLine)AudioSystem.getLine(info);
+
+        line.open();
+        line.start();
+
+        int remaining = data.length;
+        while (remaining > 0) {
+            int avail = line.available();
+            if (avail > 0) {
+                if (avail > remaining)
+                    avail = remaining;
+                int written = line.write(data, data.length - remaining, avail);
+                remaining -= written;
+                log("Playing: " + written + " bytes written");
+            } else {
+                delay(100);
+            }
+        }
+
+        line.drain();
+        line.stop();
+    }
+
+    // helper routines
+    static long startTime = currentTimeMillis();
+    static long currentTimeMillis() {
+        //return System.nanoTime() / 1000000L;
+        return System.currentTimeMillis();
+    }
+    static void log(String s) {
+        long time = currentTimeMillis() - startTime;
+        long ms = time % 1000;
+        time /= 1000;
+        long sec = time % 60;
+        time /= 60;
+        long min = time % 60;
+        time /= 60;
+        System.out.println(""
+            + (time < 10 ? "0" : "") + time
+            + ":" + (min < 10 ? "0" : "") + min
+            + ":" + (sec < 10 ? "0" : "") + sec
+            + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms
+            + " (" + Thread.currentThread().getName() + ") " + s);
+    }
+    static void delay(int millis) {
+        try {
+            Thread.sleep(millis);
+        } catch (InterruptedException e) {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/FileTypeExtension/FileTypeExtensionTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2000, 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.
+ */
+
+import javax.sound.sampled.AudioFileFormat;
+
+/**
+ * @test
+ * @bug 4300529
+ * @summary Filename extension test. The filename extensions for file types
+ *          AIFF-C, SND, and WAVE should not include a ".".
+ */
+public class FileTypeExtensionTest {
+
+    public static void main(String[] args) throws Exception {
+
+        AudioFileFormat.Type[] types = { AudioFileFormat.Type.AIFC,
+                                         AudioFileFormat.Type.AIFF,
+                                         AudioFileFormat.Type.AU,
+                                         AudioFileFormat.Type.SND,
+                                         AudioFileFormat.Type.WAVE };
+
+        boolean failed = false;
+
+        System.out.println("\nDefined file types and extensions:");
+
+        for (int i = 0; i < types.length; i++) {
+            System.out.println("\n");
+            System.out.println("  file type: " + types[i]);
+            System.out.println("  extension: " + types[i].getExtension());
+            if( types[i].getExtension().charAt(0) == '.' ) {
+                failed = true;
+            }
+        }
+
+        if (failed) {
+            System.err.println("Failed!");
+            throw new Exception("File type extensions begin with .");
+        } else {
+            System.err.println("Passed!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/LineEvent/LineInfoNPE.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.Control;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+
+/**
+ * @test
+ * @bug 4672865
+ * @summary LineEvent.toString() throws unexpected NullPointerException
+ */
+public class LineInfoNPE {
+
+    static final int STATUS_PASSED = 0;
+    static final int STATUS_FAILED = 2;
+    static final int STATUS_TEMP = 95;
+
+    public static void main(String argv[]) throws Exception {
+        int testExitStatus = run(argv, System.out);
+        if (testExitStatus != STATUS_PASSED) {
+            throw new Exception("test FAILED!");
+        }
+    }
+
+    public static int run(String argv[], java.io.PrintStream out) {
+        int testResult = STATUS_PASSED;
+
+        out.println("\n==> Test for LineEvent class:");
+
+        Line testLine = new TestLine();
+        Line nullLine = null;
+
+        LineEvent.Type testLineEventType = LineEvent.Type.OPEN;
+        LineEvent.Type nullLineEventType = null;
+
+        LineEvent testedLineEvent = null;
+        out.println("\n>> LineEvent constructor for Line = null: ");
+        try {
+            testedLineEvent =
+                new LineEvent(nullLine,  // the source Line of this event
+                                testLineEventType, // LineEvent.Type - the event type
+                                (long) 1000 // position - the number processed of sample frames
+                                );
+            out.println(">  No any Exception was thrown!");
+            out.println(">  testedLineEvent.getType():");
+            try {
+                Line producedLine = testedLineEvent.getLine();
+                out.println(">   PASSED: producedLine = " + producedLine);
+            } catch (Throwable thrown) {
+                out.println("##  FAILED: unexpected Exception was thrown:");
+                thrown.printStackTrace(out);
+                testResult = STATUS_FAILED;
+            }
+            out.println(">  testedLineEvent.toString():");
+            try {
+                String producedString = testedLineEvent.toString();
+                out.println(">   PASSED: producedString = " + producedString);
+            } catch (Throwable thrown) {
+                out.println("##  FAILED: unexpected Exception was thrown:");
+                thrown.printStackTrace(out);
+                testResult = STATUS_FAILED;
+            }
+        } catch (IllegalArgumentException illegArgExcept) {
+            out.println(">   PASSED: expected IllegalArgumentException was thrown:");
+            illegArgExcept.printStackTrace(out);
+        } catch (NullPointerException nullPE) {
+            out.println(">   PASSED: expected NullPointerException was thrown:");
+            nullPE.printStackTrace(out);
+        } catch (Throwable thrown) {
+            out.println("##  FAILED: unexpected Exception was thrown:");
+            thrown.printStackTrace(out);
+            testResult = STATUS_FAILED;
+        }
+
+        out.println("\n>> LineEvent constructor for LineEvent.Type = null: ");
+        try {
+            testedLineEvent =
+                new LineEvent(testLine,  // the source Line of this event
+                                nullLineEventType, // LineEvent.Type - the event type
+                                (long) 1000 // position - the number processed of sample frames
+                                );
+            out.println(">  No any Exception was thrown!");
+            out.println(">  testedLineEvent.getType():");
+            try {
+                LineEvent.Type producedType = testedLineEvent.getType();
+                out.println(">   PASSED: producedType = " + producedType);
+            } catch (Throwable thrown) {
+                out.println("##  FAILED: unexpected Exception was thrown:");
+                thrown.printStackTrace(out);
+                testResult = STATUS_FAILED;
+            }
+            out.println(">  testedLineEvent.toString():");
+            try {
+                String producedString = testedLineEvent.toString();
+                out.println(">   PASSED: producedString = " + producedString);
+            } catch (Throwable thrown) {
+                out.println("##  FAILED: unexpected Exception was thrown:");
+                thrown.printStackTrace(out);
+                testResult = STATUS_FAILED;
+            }
+        } catch (IllegalArgumentException illegArgExcept) {
+            out.println(">   PASSED: expected IllegalArgumentException was thrown:");
+            illegArgExcept.printStackTrace(out);
+        } catch (NullPointerException nullPE) {
+            out.println(">   PASSED: expected NullPointerException was thrown:");
+            nullPE.printStackTrace(out);
+        } catch (Throwable thrown) {
+            out.println("##  FAILED: unexpected Exception was thrown:");
+            thrown.printStackTrace(out);
+            testResult = STATUS_FAILED;
+        }
+
+        if ( testResult == STATUS_FAILED ) {
+            out.println("\n==> test FAILED!");
+        } else {
+            out.println("\n==> test PASSED!");
+        }
+        return testResult;
+    }
+}    // end of test class
+
+class TestLine implements Line {
+
+    public void addLineListener(LineListener listener) {
+    }
+
+    public void close() {
+    }
+
+    public Control getControl(Control.Type control) {
+        return null;
+    }
+
+    public Control[] getControls() {
+        return new Control[0];
+    }
+
+    public Line.Info getLineInfo() {
+        return null;
+    }
+
+    public boolean isOpen() {
+        return false;
+    }
+
+    public boolean isControlSupported(Control.Type control) {
+        return false;
+    }
+
+    public void open() {
+    }
+
+    public void removeLineListener(LineListener listener) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Lines/16and32KHz/Has16and32KHz.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2001, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+
+/**
+ * @test
+ * @bug 4479441
+ * @summary Verify that the lines report 16KHz and 32KHz capability
+ */
+public class Has16and32KHz {
+
+    public static boolean ok32=false;
+    public static boolean ok16=false;
+
+    public static void showMixerLines(Line.Info[] lineinfo) {
+        for (int j = 0; j < lineinfo.length; j++) {
+            boolean isSDL=false; // SourceDataLine
+            Line.Info thisInfo=lineinfo[j];
+            System.out.println("  " + thisInfo);
+            String impl="";
+            if (thisInfo.getLineClass().equals(SourceDataLine.class)) {
+                isSDL=true;
+                impl+="SourceDataLine";
+            }
+            if (thisInfo.getLineClass().equals(Clip.class)) {
+                impl+="Clip";
+            }
+            if (thisInfo.getLineClass().equals(DataLine.class)) {
+                impl+="DataLine";
+            }
+            if (thisInfo.getLineClass().equals(TargetDataLine.class)) {
+                impl+="TargetDataLine";
+            }
+            if (thisInfo.getLineClass().equals(Mixer.class)) {
+                impl+="Mixer";
+            }
+            System.out.println("  implements "+impl);
+            try {
+                AudioFormat[] formats = ((DataLine.Info)lineinfo[j]).getFormats();
+                for (int k = 0; k < formats.length; k++) {
+                    System.out.println("    " + formats[k] + ", "+ formats[k].getFrameSize()+" bytes/frame");
+                    if (isSDL) {
+                        if ((formats[k].getSampleRate()==AudioSystem.NOT_SPECIFIED)
+                            || (formats[k].getSampleRate()==32000.0f)) {
+                            ok32=true;
+                        }
+                        if ((formats[k].getSampleRate()==AudioSystem.NOT_SPECIFIED)
+                            || (formats[k].getSampleRate()==16000.0f)) {
+                            ok16=true;
+                        }
+                    }
+                }
+            } catch (ClassCastException e) {
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        boolean res=true;
+
+        Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
+        System.out.println(mixerInfo.length+" mixers on system.");
+        if (mixerInfo.length == 0) {
+            System.out.println("Cannot execute test. Not Failed!");
+        } else {
+            for (int i = 0; i < mixerInfo.length; i++) {
+                Mixer mixer = AudioSystem.getMixer(mixerInfo[i]);
+                System.out.println();
+                System.out.println(mixer+":");
+                showMixerLines(mixer.getSourceLineInfo());
+                showMixerLines(mixer.getTargetLineInfo());
+
+
+            }
+            res=ok16 && ok32;
+        }
+        if (res) {
+            System.out.println("Test passed");
+        } else {
+            System.out.println("Test failed");
+            throw new Exception("Test failed");
+        }
+        //ystem.exit(res?0:1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Lines/BufferSizeCheck.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4661602
+ * @summary Buffersize is checked when re-opening line
+ */
+public class BufferSizeCheck {
+
+    public static void main(String[] args) throws Exception {
+        boolean realTest = false;
+        if (!isSoundcardInstalled()) {
+            return;
+        }
+
+        try {
+            out("4661602: Buffersize is checked when re-opening line");
+            AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+            DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
+            SourceDataLine sdl = (SourceDataLine) AudioSystem.getLine(info);
+            out("Opening with buffersize 12000...");
+            sdl.open(format, 12000);
+            out("Opening with buffersize 11000...");
+            realTest=true;
+            sdl.open(format, 11000);
+            try {
+                sdl.close();
+            } catch(Throwable t) {}
+        } catch (Exception e) {
+            e.printStackTrace();
+            // do not fail if no audio device installed - bug 4742021
+            if (realTest || !(e instanceof LineUnavailableException)) {
+                throw e;
+            }
+        }
+        out("Test passed");
+    }
+
+    static void out(String s) {
+        System.out.println(s); System.out.flush();
+    }
+
+    /**
+     * Returns true if at least one soundcard is correctly installed
+     * on the system.
+     */
+    public static boolean isSoundcardInstalled() {
+        boolean result = false;
+        try {
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            if (mixers.length > 0) {
+                result = AudioSystem.getSourceDataLine(null) != null;
+            }
+        } catch (Exception e) {
+            System.err.println("Exception occured: "+e);
+        }
+        if (!result) {
+            System.err.println("Soundcard does not exist or sound drivers not installed!");
+            System.err.println("This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Lines/ChangingBuffer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4515126
+ * @summary Verify that the buffer passed to SourceDataLine.write() and
+ *          Clip.open() will not be changed
+ */
+public class ChangingBuffer {
+
+    final static int samplerate = 44100;
+    final static byte[] buffer = new byte[16384];
+    static int successfulTests = 0;
+
+    private static void makeBuffer() {
+        for (int i=0; i<buffer.length; i++) {
+            buffer[i] = (byte) (i % 128);
+        }
+    }
+
+    private static void checkBufferSDL() throws Exception {
+        successfulTests++;
+        for (int i=0; i<buffer.length; i++) {
+            if (buffer[i] != ((byte) (i % 128))) {
+                throw new Exception("Buffer was changed by SourceDataLine.write()!. Test FAILED");
+            }
+        }
+        System.out.println("  -> passed for this line");
+        System.out.println("");
+    }
+
+    private static void checkBufferClip() throws Exception {
+        for (int i=0; i<buffer.length; i++) {
+            if (buffer[i] != (i % 128)) {
+                throw new Exception("Buffer was changed by Clip.open()!. Test FAILED");
+            }
+        }
+        System.out.println("  -> passed for this clip");
+        System.out.println("");
+    }
+
+    private static boolean doMixerClip(Mixer mixer, AudioFormat format) {
+        if (mixer==null) return false;
+        try {
+            System.out.println("Trying mixer "+mixer+":");
+                DataLine.Info info = new DataLine.Info(
+                                          Clip.class,
+                                          format,
+                                          (int) samplerate);
+
+                Clip clip = (Clip) mixer.getLine(info);
+            System.out.println("  - got clip: "+clip);
+            System.out.println("  - open with format "+format);
+            clip.open(format, buffer, 0, buffer.length);
+            System.out.println("  - playing...");
+            clip.start();
+            System.out.println("  - waiting while it's active...");
+            while (clip.isActive())
+                    Thread.sleep(100);
+            System.out.println("  - waiting 100millis");
+            Thread.sleep(100);
+            System.out.println("  - drain1");
+            clip.drain();
+            System.out.println("  - drain2");
+            clip.drain();
+            System.out.println("  - stop");
+            clip.stop();
+            System.out.println("  - close");
+            clip.close();
+            System.out.println("  - closed");
+        } catch (Throwable t) {
+            System.out.println("  - Caught exception. Not failed.");
+            System.out.println("  - "+t.toString());
+            return false;
+        }
+        return true;
+    }
+
+    private static boolean doMixerSDL(Mixer mixer, AudioFormat format) {
+        if (mixer==null) return false;
+        try {
+            System.out.println("Trying mixer "+mixer+":");
+                DataLine.Info info = new DataLine.Info(
+                                          SourceDataLine.class,
+                                          format,
+                                          (int) samplerate);
+
+                SourceDataLine sdl = (SourceDataLine) mixer.getLine(info);
+            System.out.println("  - got sdl: "+sdl);
+            System.out.println("  - open with format "+format);
+            sdl.open(format);
+            System.out.println("  - start...");
+            sdl.start();
+            System.out.println("  - write...");
+            sdl.write(buffer, 0, buffer.length);
+            Thread.sleep(200);
+            System.out.println("  - drain...");
+            sdl.drain();
+            System.out.println("  - stop...");
+            sdl.stop();
+            System.out.println("  - close...");
+            sdl.close();
+            System.out.println("  - closed");
+        } catch (Throwable t) {
+            System.out.println("  - Caught exception. Not failed.");
+            System.out.println("  - "+t.toString());
+            return false;
+        }
+        return true;
+    }
+
+    private static void doAll(boolean bigEndian) throws Exception {
+        AudioFormat pcm = new AudioFormat(
+                            AudioFormat.Encoding.PCM_SIGNED,
+                            samplerate, 16, 1, 2, samplerate, bigEndian);
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            for (int i=0; i<mixers.length; i++) {
+                Mixer mixer = AudioSystem.getMixer(mixers[i]);
+                makeBuffer(); if (doMixerClip(mixer, pcm)) checkBufferClip();
+                makeBuffer(); if (doMixerSDL(mixer, pcm)) checkBufferSDL();
+            }
+            if (mixers.length==0) {
+                System.out.println("No mixers available!");
+            }
+
+    }
+
+    public static void main(String args[]) throws Exception{
+        doAll(true);
+        doAll(false);
+        if (successfulTests==0) {
+            System.out.println("Could not execute any of the tests. Test NOT failed.");
+        } else {
+            System.out.println("Test PASSED.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Lines/ClickInPlay/ClickInPlay.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.IOException;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * This is utility class for Test4218609.
+ */
+public class ClickInPlay {
+
+    static int sampleRate = 8000;
+    static double frequency = 2000.0;
+    static double RAD = 2.0 * Math.PI;
+
+    static byte[] audioData = new byte[sampleRate/2];
+    static DataLine.Info info;
+    static Clip source;
+
+    //static AudioInputStream ais = null;
+    static AudioFormat audioFormat;
+    //static String filename;
+
+    public static void print(String s) {
+        System.out.print(s);
+    }
+    public static void println(String s) {
+        System.out.println(s);
+    }
+
+    public static void key() {
+        println("");
+        print("Press ENTER to continue...");
+        try {
+            System.in.read();
+        } catch (IOException ioe) {
+        }
+    }
+
+    public static void play(Mixer mixer) {
+        int res = 0;
+        try {
+            println("Getting clip from mixer...");
+            source = (Clip) mixer.getLine(info);
+            println("Opening clip...");
+            source.open(audioFormat, audioData, 0, audioData.length);
+            println("Starting clip...");
+            source.loop(Clip.LOOP_CONTINUOUSLY);
+            println("Now open your ears:");
+            println("- if you hear a sine wave playing,");
+            println("  listen carefully if you can hear clicks.");
+            println("  If no, the bug is fixed.");
+            println("- if you don't hear anything, it's possible");
+            println("  that this mixer is not connected to an ");
+            println("  amplifier, or that its volume is set to 0");
+            key();
+        } catch (IllegalArgumentException iae) {
+            println("IllegalArgumentException: "+iae.getMessage());
+            println("Sound device cannot handle this audio format.");
+            println("ERROR: Test environment not correctly set up.");
+            if (source!=null) {
+                source.close();
+                source = null;
+            }
+            return;
+        } catch (LineUnavailableException lue) {
+            println("LineUnavailableException: "+lue.getMessage());
+            println("This is normal for some mixers.");
+        } catch (Exception e) {
+            println("Unexpected Exception: "+e.toString());
+        }
+        if (source != null) {
+            println("Stopping...");
+            source.stop();
+            println("Closing...");
+            source.close();
+            println("Closed.");
+            source = null;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        println("This is an interactive test.");
+        println("If you can hear clicks during playback in");
+        println("any mixer, the test is failed.");
+        println("");
+        println("Make sure that you have speakers connected");
+        println("and that the system mixer is not muted.");
+        println("");
+        println("Press a key to start the test.");
+        key();
+        Mixer.Info[] mixers=null;
+
+            println("   ...using self-generated sine wave for playback");
+            audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true);
+            for (int i=0; i<audioData.length; i++) {
+                audioData[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
+            }
+        info = new DataLine.Info(Clip.class, audioFormat);
+
+        mixers = AudioSystem.getMixerInfo();
+        int succMixers = 0;
+        for (int i=0; i<mixers.length; i++) {
+            try {
+                Mixer mixer = AudioSystem.getMixer(mixers[i]);
+                if (mixer.isLineSupported(info)) {
+                    succMixers++;
+                    println("  ...using mixer "+mixer.getMixerInfo());
+                    play(mixer);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        if (succMixers == 0) {
+                println("No mixers available! ");
+                println("Cannot run test.");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Lines/ClickInPlay/Test4218609.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.awt.Button;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.Panel;
+import java.awt.TextArea;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * @test
+ * @bug 4218609
+ * @summary A soft audio click is heard when playing some audio file
+ * @build ClickInPlay
+ * @run main/manual Test4218609
+ */
+public class Test4218609 {
+
+   private static void init() throws Exception {
+        //*** Create instructions for the user here ***
+
+        String[] instructions =
+        {
+         "To run the test follow these instructions:",
+         "1. Open a terminal window.",
+         "2. Type \"cd " + System.getProperty("test.classes") + "\".",
+         "3. Type \"" + System.getProperty("java.home") + "/bin/java ClickInPlay\".",
+         "4. Follow the instructions shown in the terminal window.",
+         "If no error occured during the test, and the java application ",
+         "in the termial exited successfully, press PASS, else press FAIL."
+       };
+
+      Sysout.createDialog( );
+      Sysout.printInstructions( instructions );
+
+    }
+
+ /*****************************************************
+     Standard Test Machinery Section
+      DO NOT modify anything in this section -- it's a
+      standard chunk of code which has all of the
+      synchronisation necessary for the test harness.
+      By keeping it the same in all tests, it is easier
+      to read and understand someone else's test, as
+      well as insuring that all tests behave correctly
+      with the test harness.
+     There is a section following this for test-defined
+      classes
+   ******************************************************/
+   private static boolean theTestPassed = false;
+   private static boolean testGeneratedInterrupt = false;
+   private static String failureMessage = "";
+
+   private static Thread mainThread = null;
+
+   private static int sleepTime = 300000;
+
+   public static void main( String args[] ) throws Exception
+    {
+      mainThread = Thread.currentThread();
+      try
+       {
+         init();
+       }
+      catch( TestPassedException e )
+       {
+         //The test passed, so just return from main and harness will
+         // interepret this return as a pass
+         return;
+       }
+      //At this point, neither test passed nor test failed has been
+      // called -- either would have thrown an exception and ended the
+      // test, so we know we have multiple threads.
+
+      //Test involves other threads, so sleep and wait for them to
+      // called pass() or fail()
+      try
+       {
+         Thread.sleep( sleepTime );
+         //Timed out, so fail the test
+         throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+       }
+      catch (InterruptedException e)
+       {
+         if( ! testGeneratedInterrupt ) throw e;
+
+         //reset flag in case hit this code more than once for some reason (just safety)
+         testGeneratedInterrupt = false;
+         if ( theTestPassed == false )
+          {
+            throw new RuntimeException( failureMessage );
+          }
+       }
+
+    }//main
+
+   public static synchronized void setTimeoutTo( int seconds )
+    {
+      sleepTime = seconds * 1000;
+    }
+
+   public static synchronized void pass()
+    {
+      Sysout.println( "The test passed." );
+      Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+      //first check if this is executing in main thread
+      if ( mainThread == Thread.currentThread() )
+       {
+         //Still in the main thread, so set the flag just for kicks,
+         // and throw a test passed exception which will be caught
+         // and end the test.
+         theTestPassed = true;
+         throw new TestPassedException();
+       }
+      //pass was called from a different thread, so set the flag and interrupt
+      // the main thead.
+      theTestPassed = true;
+      testGeneratedInterrupt = true;
+      mainThread.interrupt();
+    }//pass()
+
+   public static synchronized void fail()
+    {
+      //test writer didn't specify why test failed, so give generic
+      fail( "it just plain failed! :-)" );
+    }
+
+   public static synchronized void fail( String whyFailed )
+    {
+      Sysout.println( "The test failed: " + whyFailed );
+      Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+      //check if this called from main thread
+      if ( mainThread == Thread.currentThread() )
+       {
+         //If main thread, fail now 'cause not sleeping
+         throw new RuntimeException( whyFailed );
+       }
+      theTestPassed = false;
+      testGeneratedInterrupt = true;
+      failureMessage = whyFailed;
+      mainThread.interrupt();
+    }//fail()
+
+ }// class Orient
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+ {
+ }
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         Orient.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         Orient.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+ {
+   private static TestDialog dialog;
+
+   public static void createDialogWithInstructions( String[] instructions )
+    {
+      dialog = new TestDialog( new Frame(), "Instructions" );
+      dialog.printInstructions( instructions );
+      dialog.show();
+      println( "Any messages for the tester will display here." );
+    }
+
+   public static void createDialog( )
+    {
+      dialog = new TestDialog( new Frame(), "Instructions" );
+      String[] defInstr = { "Instructions will appear here. ", "" } ;
+      dialog.printInstructions( defInstr );
+      dialog.show();
+      println( "Any messages for the tester will display here." );
+    }
+
+
+   public static void printInstructions( String[] instructions )
+    {
+      dialog.printInstructions( instructions );
+    }
+
+
+   public static void println( String messageIn )
+    {
+      dialog.displayMessage( messageIn );
+    }
+
+ }// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog implements ActionListener
+ {
+
+   TextArea instructionsText;
+   TextArea messageText;
+   int maxStringLength = 80;
+   Panel  buttonP = new Panel();
+   Button passB = new Button( "pass" );
+   Button failB = new Button( "fail" );
+
+   //DO NOT call this directly, go through Sysout
+   public TestDialog( Frame frame, String name )
+    {
+      super( frame, name );
+      int scrollBoth = TextArea.SCROLLBARS_BOTH;
+      instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+      add( "North", instructionsText );
+
+      messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+      add("Center", messageText);
+
+      passB = new Button( "pass" );
+      passB.setActionCommand( "pass" );
+      passB.addActionListener( this );
+      buttonP.add( "East", passB );
+
+      failB = new Button( "fail" );
+      failB.setActionCommand( "fail" );
+      failB.addActionListener( this );
+      buttonP.add( "West", failB );
+
+      add( "South", buttonP );
+      pack();
+
+      show();
+    }// TestDialog()
+
+   //DO NOT call this directly, go through Sysout
+   public void printInstructions( String[] instructions )
+    {
+      //Clear out any current instructions
+      instructionsText.setText( "" );
+
+      //Go down array of instruction strings
+
+      String printStr, remainingStr;
+      for( int i=0; i < instructions.length; i++ )
+       {
+         //chop up each into pieces maxSringLength long
+         remainingStr = instructions[ i ];
+         while( remainingStr.length() > 0 )
+          {
+            //if longer than max then chop off first max chars to print
+            if( remainingStr.length() >= maxStringLength )
+             {
+               //Try to chop on a word boundary
+               int posOfSpace = remainingStr.
+                  lastIndexOf( ' ', maxStringLength - 1 );
+
+               if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+               printStr = remainingStr.substring( 0, posOfSpace + 1 );
+               remainingStr = remainingStr.substring( posOfSpace + 1 );
+             }
+            //else just print
+            else
+             {
+               printStr = remainingStr;
+               remainingStr = "";
+             }
+
+            instructionsText.append( printStr + "\n" );
+
+          }// while
+
+       }// for
+
+    }//printInstructions()
+
+   //DO NOT call this directly, go through Sysout
+   public void displayMessage( String messageIn )
+    {
+      messageText.append( messageIn + "\n" );
+    }
+
+   //catch presses of the passed and failed buttons.
+   //simply call the standard pass() or fail() static methods of
+   //DialogOrient
+   public void actionPerformed( ActionEvent e )
+    {
+      if( e.getActionCommand() == "pass" )
+       {
+         Test4218609.pass();
+       }
+      else
+       {
+         Test4218609.fail();
+       }
+    }
+
+ }// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Lines/ClipOpenException.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+
+/**
+ * @test
+ * @bug 4679187
+ * @summary Clip.open() throws unexpected Exceptions. verifies that clip,
+ *          sourcedataline and targetdataline throw IllegalArgumentExcepotion if
+ *          any field in the format is AudioFormat.NOT_SPECIFIED
+ */
+public class ClipOpenException {
+    static boolean failed = false;
+
+    static byte[] audioData = new byte[2048];
+    static AudioFormat[] formats = {
+        new AudioFormat(AudioSystem.NOT_SPECIFIED,
+                        AudioSystem.NOT_SPECIFIED,
+                        AudioSystem.NOT_SPECIFIED,
+                        true, false),
+        new AudioFormat(0, 0, 0, true, false)
+    };
+    static AudioFormat infoFormat = new AudioFormat(44100.0f,
+                                                16,
+                                                1,
+                                                true, false);
+    static DataLine.Info clipInfo = new DataLine.Info(Clip.class, infoFormat);
+    static DataLine.Info sdlInfo = new DataLine.Info(SourceDataLine.class, infoFormat);
+    static DataLine.Info tdlInfo = new DataLine.Info(TargetDataLine.class, infoFormat);
+
+
+    public static void print(String s) {
+        System.out.print(s);
+    }
+    public static void println(String s) {
+        System.out.println(s);
+    }
+
+    public static void test(Line line) {
+        for (int format = 0; format < formats.length; format++) {
+            try {
+                println("  Opening the line with format "+(format+1));
+                if (line instanceof Clip) {
+                    ((Clip) line).open(formats[format], audioData, 0, audioData.length);
+                } else
+                if (line instanceof SourceDataLine) {
+                    ((SourceDataLine) line).open(formats[format]);
+                } else
+                if (line instanceof TargetDataLine) {
+                    ((TargetDataLine) line).open(formats[format]);
+                } else {
+                    println("    Unknown type of line: "+line.getClass());
+                    return;
+                }
+                println("    No exception! not OK.");
+                failed = true;
+            } catch (IllegalArgumentException iae) {
+                println("    IllegalArgumentException: "+iae.getMessage());
+                println("    OK");
+            } catch (LineUnavailableException lue) {
+                println("    LineUnavailableException: "+lue.getMessage());
+                println("    Probably incorrect, but may happen if the test system is correctly set up.");
+            } catch (Exception e) {
+                println("    Unexpected Exception: "+e.toString());
+                println("    NOT OK!");
+                failed = true;
+            }
+            println("    Closing line.");
+            line.close();
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+        int succMixers = 0;
+        println("Using formats: ");
+        for (int i = 0 ; i<formats.length; i++) {
+                println(""+(i+1)+". "+formats[i]);
+        }
+        for (int i=0; i<mixers.length; i++) {
+            boolean succ = false;
+            try {
+                Mixer mixer = AudioSystem.getMixer(mixers[i]);
+                println("Mixer "+mixer.getMixerInfo()+":");
+                if (mixer.isLineSupported(clipInfo)) {
+                    println("Getting clip from mixer...");
+                    Clip clip = (Clip) mixer.getLine(clipInfo);
+                    succ = true;
+                    test(clip);
+                }
+                if (mixer.isLineSupported(sdlInfo)) {
+                    println("Getting source data line from mixer...");
+                    SourceDataLine sdl = (SourceDataLine) mixer.getLine(sdlInfo);
+                    succ = true;
+                    test(sdl);
+                }
+                if (mixer.isLineSupported(tdlInfo)) {
+                    println("Getting target data line from mixer...");
+                    TargetDataLine tdl = (TargetDataLine) mixer.getLine(tdlInfo);
+                    succ = true;
+                    test(tdl);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            if (succ) {
+                succMixers++;
+            }
+        }
+        if (succMixers == 0) {
+            println("No mixers available! ");
+            println("Cannot run test. NOT FAILED");
+        }
+        else if (failed) {
+            throw new Exception("Test FAILED");
+        }
+        println("Test passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Lines/FrameSize/FrameSizeTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2001, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4469409
+ * @summary Check that the frame size in the formats returned by lines is
+ *          correct
+ */
+public class FrameSizeTest {
+    public static void main(String[] args) throws Exception {
+        boolean res=true;
+        Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
+        for (int i = 0; i < mixerInfo.length; i++) {
+            Mixer mixer = AudioSystem.getMixer(mixerInfo[i]);
+            System.out.println(mixer);
+            Line.Info[] lineinfo = mixer.getSourceLineInfo();
+            for (int j = 0; j < lineinfo.length; j++) {
+                System.out.println("  " + lineinfo[j]);
+                try {
+                    AudioFormat[] formats = ((DataLine.Info)lineinfo[j]).getFormats();
+                    for (int k = 0; k < formats.length; k++) {
+                        if ( (formats[k].getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED)
+                              || formats[k].getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED))
+                             && (formats[k].getFrameSize() != AudioSystem.NOT_SPECIFIED)
+                             && ((formats[k].getSampleSizeInBits() == 16) || (formats[k].getSampleSizeInBits() == 8))
+                             && ((((formats[k].getSampleSizeInBits() + 7) / 8) * formats[k].getChannels()) != formats[k].getFrameSize())) {
+                            System.out.println(" # " + formats[k] + ", getFrameSize() wrongly returns"+ formats[k].getFrameSize());
+                            res=false;
+                        }
+                    }
+                } catch (ClassCastException e) {
+                }
+            }
+        }
+
+        if (res) {
+            System.out.println("Test passed");
+        } else {
+            System.out.println("Test failed");
+            throw new Exception("Test failed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Lines/GetLine.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioPermission;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4932835
+ * @summary REGRESSION: IAE for supported line in AudioSystem.getLine()
+ */
+public class GetLine {
+
+    static boolean isSoundAccessDenied = false;
+    static {
+        SecurityManager securityManager = System.getSecurityManager();
+        if (securityManager != null) {
+            try {
+                securityManager.checkPermission(new AudioPermission("*"));
+            } catch (SecurityException e) {
+                isSoundAccessDenied = true;
+            }
+        }
+    }
+
+    static final int STATUS_PASSED = 0;
+    static final int STATUS_FAILED = 2;
+    static final int STATUS_TEMP = 95;
+    static java.io.PrintStream log = System.err;
+
+    public static void main(String argv[]) throws Exception {
+        if (run(argv, System.out) == STATUS_FAILED) {
+            throw new Exception("Test FAILED");
+        }
+        System.out.println("Test passed.");
+    }
+
+    public static int run(String argv[], java.io.PrintStream out) {
+        String testCaseID = "LineListener2001";
+
+        log.println("===== " + testCaseID + " =====");
+
+        boolean failed = false;
+        Line l = null;
+
+
+
+        // get the default SourceDataLine
+
+        DataLine.Info s_info = new DataLine.Info(SourceDataLine.class, null);
+        Line.Info infos[] = AudioSystem.getSourceLineInfo( s_info );
+
+        if( infos.length < 1 ) {
+            log.println("Line.Info array == 0");
+            return STATUS_PASSED;
+        }
+        try {
+            l = AudioSystem.getLine(infos[0]);
+        } catch(SecurityException lue) {
+            log.println("SecurityException");
+            return STATUS_PASSED;
+        } catch (LineUnavailableException e1) {
+            log.println("LUE");
+            return STATUS_PASSED;
+        } catch (IllegalArgumentException iae) {
+            log.println("IllegalArgumentException should not be thrown "
+                     + "for supported line");
+            iae.printStackTrace(log);
+            return STATUS_FAILED;
+        }
+        out.println("Passed.");
+        return STATUS_PASSED;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Lines/SDLwrite.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4680710
+ * @summary SourceDataLine.write() behavior is not correct for not open or not
+ *          started lines
+ */
+public class SDLwrite {
+
+    static final int STATUS_PASSED = 0;
+    static final int STATUS_FAILED = 2;
+
+    public static void main(String argv[]) throws Exception {
+        int testExitStatus = run(argv, System.out);
+        if (testExitStatus != STATUS_PASSED) {
+            throw new Exception("test FAILED!");
+        }
+    }
+
+    public static int run(String argv[], java.io.PrintStream out) {
+        int testResult = STATUS_PASSED;
+
+        out.println
+            ("\n==> Test for SourceDataLine.write() method for not open and not started line:");
+
+        Mixer.Info[] installedMixersInfo = AudioSystem.getMixerInfo();
+
+        if ( installedMixersInfo == null ) {
+            out.println("## AudioSystem.getMixerInfo() returned unexpected result:");
+            out.println("#  expected: an array of Mixer.Info objects (may be array of length 0);");
+            out.println("#  produced: null;");
+            return STATUS_FAILED;
+        }
+
+        if ( installedMixersInfo.length == 0 ) {
+            // there are no mixers installed on the system - so this testcase can not be tested
+            return STATUS_PASSED;
+        }
+
+        Mixer testedMixer = null;
+        for (int i=0; i < installedMixersInfo.length; i++) {
+            try {
+                testedMixer = AudioSystem.getMixer(installedMixersInfo[i]);
+            } catch (SecurityException securityException) {
+                // installed Mixer is unavailable because of security restrictions
+                continue;
+            } catch (Throwable thrown) {
+                out.println("## AudioSystem.getMixer() threw unexpected exception:");
+                thrown.printStackTrace(out);
+                testResult = STATUS_FAILED;
+                continue;
+            }
+
+            try {
+                testedMixer.open();
+            } catch (LineUnavailableException lineUnavailableException) {
+                // testedMixer is not available due to resource restrictions
+                continue;
+            } catch (SecurityException securityException) {
+                // testedMixer is not available due to security restrictions
+                continue;
+            } catch (Throwable thrown) {
+                out.println("## Mixer.open() threw unexpected exception:");
+                out.println("#  Mixer = " + testedMixer);
+                thrown.printStackTrace(out);
+                testResult = STATUS_FAILED;
+                continue;
+            }
+            Line.Info supportedSourceLineInfo[] = null;
+            try {
+                supportedSourceLineInfo = testedMixer.getSourceLineInfo();
+            } catch (Throwable thrown) {
+                out.println("## Mixer.getSourceLineInfo() threw unexpected exception:");
+                out.println("#  Mixer = " + testedMixer);
+                thrown.printStackTrace(out);
+                testResult = STATUS_FAILED;
+                testedMixer.close();
+                continue;
+            }
+            if ( supportedSourceLineInfo == null ) {
+                out.println("## Mixer.getSourceLineInfo() returned null array");
+                out.println("#  Mixer = " + testedMixer);
+                testResult = STATUS_FAILED;
+                testedMixer.close();
+                continue;
+            }
+            out.println("\n>>>  testedMixer["+i+"] = " + testedMixer);
+            out.println("\n>>  supportedSourceLineInfo.length = " + supportedSourceLineInfo.length);
+
+            for (int j=0; j < supportedSourceLineInfo.length; j++) {
+                Line.Info testSourceLineInfo = supportedSourceLineInfo[j];
+
+                Line testSourceLine = null;
+                try {
+                    testSourceLine = testedMixer.getLine(testSourceLineInfo);
+                } catch (LineUnavailableException lineUnavailableException) {
+                    // line is not available due to resource restrictions
+                    continue;
+                } catch (SecurityException securityException) {
+                    // line is not available due to security restrictions
+                    continue;
+                } catch (Throwable thrown) {
+                    out.println("## Mixer.getLine(Line.Info) threw unexpected Exception:");
+                    out.println("#  Mixer = " + testedMixer);
+                    out.println("#  Line.Info = " + testSourceLineInfo);
+                    thrown.printStackTrace(out);
+                    testResult = STATUS_FAILED;
+                    continue;
+                }
+
+                out.println("\n>  testSourceLineInfo["+j+"] = " + testSourceLineInfo);
+                out.println(">  testSourceLine = " + testSourceLine);
+                if ( ! (testSourceLine instanceof SourceDataLine) ) {
+                    out.println(">  testSourceLine is not SourceDataLine");
+                    continue;
+                }
+
+                SourceDataLine testedSourceLine = (SourceDataLine)testSourceLine;
+                AudioFormat lineAudioFormat = testedSourceLine.getFormat();
+
+                int bufferSizeToWrite = 1;
+                if ( lineAudioFormat.getSampleSizeInBits() != AudioSystem.NOT_SPECIFIED ) {
+                    bufferSizeToWrite = lineAudioFormat.getSampleSizeInBits()/8;
+                    if ( lineAudioFormat.getSampleSizeInBits()%8 != 0 ) {
+                        bufferSizeToWrite++;
+                    }
+                }
+                if ( lineAudioFormat.getFrameSize() != AudioSystem.NOT_SPECIFIED ) {
+                    bufferSizeToWrite = lineAudioFormat.getFrameSize();
+                }
+                byte[] dataToWrite = new byte[bufferSizeToWrite];
+                for (int k=0; k < bufferSizeToWrite; k++) {
+                    dataToWrite[k] = (byte)1;
+                }
+                int offsetToWrite = 0;
+
+                out.println
+                    ("\n>  check SourceDataLine.write() for not open line with correct length of data:");
+                int writtenBytes = -1;
+                try {
+                    writtenBytes = testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
+                    out.println(">  Bytes written: number of written bytes = " + writtenBytes);
+                } catch (Throwable thrown) {
+                    out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
+                    out.println("#  Unexpected Exception is thrown");
+                    out.println("#  Mixer = " + testedMixer);
+                    out.println("#  SourceDataLine = " + testedSourceLine);
+                    thrown.printStackTrace(out);
+                    testResult = STATUS_FAILED;
+                }
+
+                out.println
+                    ("\n>  check SourceDataLine.write() for not open line with incorrect length of data:");
+                writtenBytes = -1;
+                bufferSizeToWrite--;
+                try {
+                    writtenBytes = testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
+                    out.println(">  Bytes written: number of written bytes = " + writtenBytes);
+                } catch (IllegalArgumentException illegalArgumentException) {
+                    out.println(">  Permissible IllegalArgumentException for the present instance is thrown:");
+                    illegalArgumentException.printStackTrace(out);
+                } catch (Throwable thrown) {
+                    out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
+                    out.println("#  Unexpected Exception is thrown");
+                    out.println("#  Mixer = " + testedMixer);
+                    out.println("#  SourceDataLine = " + testedSourceLine);
+                    thrown.printStackTrace(out);
+                    testResult = STATUS_FAILED;
+                }
+
+                out.println
+                    ("\n>  open tested line:");
+                bufferSizeToWrite++;
+                try {
+                    testedSourceLine.open(lineAudioFormat, bufferSizeToWrite);
+                    out.println(">  OK - line is opened");
+                } catch (LineUnavailableException lineUnavailableException) {
+                    out.println(">  Line is not available due to resource restrictions:");
+                    lineUnavailableException.printStackTrace(out);
+                    continue;
+                } catch (SecurityException securityException) {
+                    out.println("> Line is not available due to security restrictions:");
+                    securityException.printStackTrace(out);
+                    continue;
+                } catch (Throwable thrown) {
+                    out.println("## SourceDataLine.open(AudioFormat format) failed:");
+                    out.println("#  Unexpected Exception is thrown");
+                    out.println("#  Mixer = " + testedMixer);
+                    out.println("#  SourceDataLine = " + testedSourceLine);
+                    thrown.printStackTrace(out);
+                    testResult = STATUS_FAILED;
+                    continue;
+                }
+
+                out.println
+                    ("\n>  check SourceDataLine.write() for not started line with correct length of data:");
+                writtenBytes = -1;
+                try {
+                    writtenBytes = testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
+                    out.println(">  Bytes written: number of written bytes = " + writtenBytes);
+                } catch (Throwable thrown) {
+                    out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
+                    out.println("#  Unexpected Exception is thrown");
+                    out.println("#  Mixer = " + testedMixer);
+                    out.println("#  SourceDataLine = " + testedSourceLine);
+                    thrown.printStackTrace(out);
+                    testResult = STATUS_FAILED;
+                }
+
+                out.println
+                    ("\n>  check SourceDataLine.write() for not started line with incorrect length of data:");
+                writtenBytes = -1;
+                bufferSizeToWrite--;
+                try {
+                    writtenBytes = testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
+                    out.println(">  Bytes written: number of written bytes = " + writtenBytes);
+                } catch (IllegalArgumentException illegalArgumentException) {
+                    out.println(">  Permissible IllegalArgumentException for the present instance is thrown:");
+                    illegalArgumentException.printStackTrace(out);
+                } catch (Throwable thrown) {
+                    out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
+                    out.println("#  Unexpected Exception is thrown");
+                    out.println("#  Mixer = " + testedMixer);
+                    out.println("#  SourceDataLine = " + testedSourceLine);
+                    thrown.printStackTrace(out);
+                    testResult = STATUS_FAILED;
+                }
+                testedSourceLine.close();
+
+            }  // for (int j=0; j < supportedSourceLineInfo.length; j++)
+            testedMixer.close();
+
+        }  // for (int i=0; i < installedMixersInfo.length; i++)
+
+        if ( testResult == STATUS_FAILED ) {
+            out.println("\n==> test FAILED!");
+        } else {
+            out.println("\n==> test PASSED!");
+        }
+        return testResult;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Lines/SourceDataLineDefaultBufferSizeCrash.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4681384
+ * @summary SourceDataLine.write() causes Unexpected Signal 11 in native code
+ *          outside the VM
+ */
+public class SourceDataLineDefaultBufferSizeCrash {
+
+    static final int STATUS_PASSED = 0;
+    static final int STATUS_FAILED = 2;
+    static final int STATUS_TEMP = 95;
+
+    public static void main(String argv[]) throws Exception {
+        int testExitStatus = run(argv, System.out) + STATUS_TEMP;
+    }
+
+    public static int run(String argv[], java.io.PrintStream out) throws Exception {
+        int testResult = STATUS_PASSED;
+
+        int framesNumberToExceed = 2;
+        if ( argv.length > 0 ) {
+            try {
+                framesNumberToExceed = Integer.parseInt(argv[0]);
+            }
+            catch (NumberFormatException e) {
+            }
+        }
+
+        out.println
+            ("\n==> Test for SourceDataLine.write() method:");
+
+        Mixer.Info[] installedMixersInfo = AudioSystem.getMixerInfo();
+
+        if ( installedMixersInfo == null ) {
+            out.println("## AudioSystem.getMixerInfo() returned unexpected result:");
+            out.println("#  expected: an array of Mixer.Info objects (may be array of length 0);");
+            out.println("#  produced: null;");
+            return STATUS_FAILED;
+        }
+
+        if ( installedMixersInfo.length == 0 ) {
+            // there are no mixers installed on the system -
+            // so this testcase can not be tested
+            out.println("\n>>>  There are no mixers installed on the system!");
+            return STATUS_PASSED;
+        }
+
+        out.println("\n>>>  Number of mixers installed on the system = "
+            + installedMixersInfo.length);
+        Mixer installedMixer = null;
+        for (int i=0; i < installedMixersInfo.length; i++) {
+            try {
+                installedMixer = AudioSystem.getMixer(installedMixersInfo[i]);
+            } catch (SecurityException securityException) {
+                // installed Mixer is unavailable because of security restrictions
+                out.println("\n>>>  installedMixer[" + i
+                    + "] is unavailable because of security restrictions");
+                continue;
+            } catch (Throwable thrown) {
+                out.println("\n##  installedMixer[" + i + "] is unavailable because of");
+                out.println("#  AudioSystem.getMixer() threw unexpected exception:");
+                thrown.printStackTrace(out);
+                testResult = STATUS_FAILED;
+                continue;
+            }
+
+            out.println("\n>>>  installedMixer["+i+"] = " + installedMixer);
+            try {
+                installedMixer.open();
+            } catch (LineUnavailableException lineUnavailableException) {
+                // installedMixer is not available due to resource restrictions
+                out.println(">>   installedMixer[" + i
+                    + "] is not opened because of resource restrictions");
+                continue;
+            } catch (SecurityException securityException) {
+                // installedMixer is not available due to security restrictions
+                out.println(">>   installedMixer[" + i
+                    + "] is not opened because of security restrictions");
+                continue;
+            } catch (Throwable thrown) {
+                out.println("## installedMixer.open() throws unexpected exception:");
+                thrown.printStackTrace(out);
+                testResult = STATUS_FAILED;
+                continue;
+            }
+            Line.Info supportedSourceLineInfo[] = null;
+            try {
+                supportedSourceLineInfo = installedMixer.getSourceLineInfo();
+            } catch (Throwable thrown) {
+                out.println("## installedMixer.getSourceLineInfo() throws "
+                    + "unexpected exception:");
+                thrown.printStackTrace(out);
+                testResult = STATUS_FAILED;
+                installedMixer.close();
+                continue;
+            }
+            if ( supportedSourceLineInfo == null ) {
+                out.println("## installedMixer.getSourceLineInfo() returned null array");
+                out.println("#  Mixer = " + installedMixer);
+                testResult = STATUS_FAILED;
+                installedMixer.close();
+                continue;
+            }
+            out.println("\n>>  Number of SourceLineInfo supported by installedMixer ="
+                + supportedSourceLineInfo.length);
+
+            for (int j=0; j < supportedSourceLineInfo.length; j++) {
+                Line.Info testSourceLineInfo = supportedSourceLineInfo[j];
+
+                out.println("\n>  testSourceLineInfo["+j+"] = " + testSourceLineInfo);
+                Line testSourceLine = null;
+                try {
+                    testSourceLine = installedMixer.getLine(testSourceLineInfo);
+                } catch (LineUnavailableException lineUnavailableException) {
+                    // line is not available due to resource restrictions
+                    out.println(">  Line for this SourceLine Info is not available "
+                        + "due to resource restrictions");
+                    continue;
+                } catch (SecurityException securityException) {
+                    // line is not available due to security restrictions
+                    out.println(">  Line for this SourceLine Info is not available "
+                        + "due to security restrictions");
+                    continue;
+                } catch (Throwable thrown) {
+                    out.println("## installedMixer.getLine(testSourceLineInfo) throws"
+                        + "unexpected Exception:");
+                    thrown.printStackTrace(out);
+                    testResult = STATUS_FAILED;
+                    continue;
+                }
+
+                out.println(">  testedSourceLine = " + testSourceLine);
+                if ( ! (testSourceLine instanceof SourceDataLine) ) {
+                    out.println(">  testSourceLine is not SourceDataLine");
+                    continue;
+                }
+
+                SourceDataLine testedSourceLine = (SourceDataLine)testSourceLine;
+                AudioFormat lineAudioFormat = testedSourceLine.getFormat();
+
+                out.println("\n>  opening tested SourceLine:");
+                try {
+                    //testedSourceLine.open(lineAudioFormat, 2048);
+                    testedSourceLine.open(lineAudioFormat);
+                    out.println(">  OK - line is opened with "+testedSourceLine.getBufferSize()+" bytes buffer");
+                } catch (LineUnavailableException lineUnavailableException) {
+                    out.println(">  Line is not available due to resource restrictions:");
+                    lineUnavailableException.printStackTrace(out);
+                    continue;
+                } catch (SecurityException securityException) {
+                    out.println("> Line is not available due to security restrictions:");
+                    securityException.printStackTrace(out);
+                    continue;
+                } catch (Throwable thrown) {
+                    out.println("## SourceDataLine.open(AudioFormat format) failed:");
+                    out.println("#  Unexpected Exception is thrown");
+                    out.println("#  Mixer = " + installedMixer);
+                    out.println("#  SourceDataLine = " + testedSourceLine);
+                    thrown.printStackTrace(out);
+                    testResult = STATUS_FAILED;
+                    continue;
+                }
+
+                testedSourceLine.start();
+
+                int frameSize = 1;
+                if ( lineAudioFormat.getFrameSize() != AudioSystem.NOT_SPECIFIED ) {
+                    frameSize = lineAudioFormat.getFrameSize();
+                } else {
+                    if ( lineAudioFormat.getSampleSizeInBits() != AudioSystem.NOT_SPECIFIED ) {
+                        frameSize = lineAudioFormat.getSampleSizeInBits()/8;
+                        if ( lineAudioFormat.getSampleSizeInBits()%8 != 0 ) {
+                            frameSize++;
+                        }
+                    }
+                }
+                int bufferSizeToWrite = testedSourceLine.available()
+                    + (frameSize * framesNumberToExceed);
+                byte[] dataToWrite = new byte[bufferSizeToWrite];
+                for (int k=0; k < bufferSizeToWrite; k++) {
+                    dataToWrite[k] = (byte)1;
+                }
+                int offsetToWrite = 0;
+
+                out.println("\n>  check SourceDataLine.write() to write more data "
+                    + "than can currently be written:");
+
+                out.println(">  testedSourceLine.available() = " + testedSourceLine.available());
+                out.println(">  frame size = " + frameSize);
+                out.println(">  number of bytes to write = " + bufferSizeToWrite);
+                int writtenBytes = -1;
+                try {
+                    writtenBytes =
+                        testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
+                    out.println(">  OK - number of written bytes = " + writtenBytes);
+                } catch (Throwable thrown) {
+                    out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
+                    out.println("#  Unexpected Exception is thrown");
+                    thrown.printStackTrace(out);
+                    testResult = STATUS_FAILED;
+                }
+
+                testedSourceLine.close();
+
+            }  // for (int j=0; j < supportedSourceLineInfo.length; j++)
+            installedMixer.close();
+
+        }  // for (int i=0; i < installedMixersInfo.length; i++)
+
+        if ( testResult == STATUS_FAILED ) {
+            throw new Exception("Test FAILED!");
+        } else {
+            out.println("\n==> test PASSED!");
+        }
+        return testResult;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Lines/StopStart.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.File;
+import java.util.Random;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4828556
+ * @summary stopping and starting sampled audio plays small chunk in infinite
+ *          loop
+ */
+public class StopStart implements Runnable {
+
+    static int sampleRate = 8000;
+    static double frequency = 2000.0;
+    static double RAD = 2.0 * Math.PI;
+    static Random random = new Random();
+
+    static byte[] audioData = new byte[sampleRate/2];
+    static SourceDataLine source;
+
+    static boolean terminated = false;
+
+    static int buffersWritten = 0;
+    static long bytesWritten = 0;
+    static int buffersWrittenAfter5Seconds;
+
+    static AudioInputStream ais = null;
+    static AudioFormat audioFormat;
+    static String filename;
+
+    static int executedTests=0;
+    static int successfulTests = 0;
+
+    public static void constructAIS() throws Exception {
+        ais = AudioSystem.getAudioInputStream(new File(filename));
+    }
+
+    public static void doStartStopTest1() throws Exception {
+        System.out.println("TEST 1: play for 3 seconds, stop/start/stop/start/play for 3 seconds...");
+        source.start();
+        Thread.sleep(100);
+        bytesWritten = 0;
+        System.out.println("Waiting for 3 seconds...");
+        Thread.sleep(3000);
+        buffersWrittenAfter5Seconds = buffersWritten;
+        System.out.println("Buffers Written: "+buffersWritten);
+        System.out.println("stop()->start()->stop()->start()");
+        source.stop();
+        //System.out.println("start()");
+        source.start();
+        //System.out.println("stop()2 ----------------------------------------------------------");
+        source.stop();
+        //System.out.println("start()");
+        source.start();
+        System.out.println("Buffers Written: "+buffersWritten);
+        System.out.println("Waiting for 3 seconds...");
+        Thread.sleep(3000);
+        System.out.println("Buffers Written: "+buffersWritten);
+        if (buffersWritten >= ((buffersWrittenAfter5Seconds * 2) - ((buffersWrittenAfter5Seconds / 4)))) {
+            successfulTests++;
+        }
+    }
+
+    private static int nextWaitTime() {
+        int waitTime = random.nextInt(25);
+        waitTime*=waitTime;
+        if (waitTime<20) waitTime = 0;
+        return waitTime;
+    }
+
+
+    public static void doStartStopTest2() throws Exception {
+        System.out.println("TEST 2: start and stop 100 times with random wait in between");
+        int max=100;
+        for (int i=0; i<max; i++) {
+            System.out.println("Round "+i);
+            System.out.println("Start....");
+            source.start();
+            int waitTime = nextWaitTime();
+            System.out.println("Waiting for "+waitTime+"ms...");
+            if (waitTime>0) {
+                Thread.sleep(waitTime);
+            }
+            System.out.println("stop()");
+            source.stop();
+            waitTime = nextWaitTime();
+            System.out.println("Waiting for "+waitTime+"ms...");
+            if (waitTime>0) {
+                Thread.sleep(waitTime);
+            }
+        }
+    }
+
+    public static void doStartStopTest3() throws Exception {
+        System.out.println("TEST 3: start and stop 100 times with random wait only every 10 rounds ");
+        int max=100;
+        for (int i=0; i<max; i++) {
+            System.out.println("Round "+i);
+            System.out.println("Start....");
+            source.start();
+            if (i % 10 == 9) {
+                int waitTime = nextWaitTime();
+                System.out.println("Waiting for "+waitTime+"ms...");
+                if (waitTime>0) {
+                    Thread.sleep(waitTime);
+                }
+            }
+            System.out.println("stop()");
+            source.stop();
+            if (i % 13 == 12) {
+                int waitTime = nextWaitTime();
+                System.out.println("Waiting for "+waitTime+"ms...");
+                if (waitTime>0) {
+                    Thread.sleep(waitTime);
+                }
+            }
+        }
+    }
+
+    public static void runTest(int testNum) {
+        terminated = false;
+        Thread thread = null;
+        buffersWrittenAfter5Seconds = 0;
+        // make the tests reproduceable by always seeding with same value
+        random.setSeed(1);
+        try {
+            executedTests++;
+            thread = new Thread(new StopStart());
+            thread.start();
+            switch (testNum) {
+            case 1: doStartStopTest1(); break;
+            case 2: doStartStopTest2(); break;
+            case 3: doStartStopTest3(); break;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        source.stop();
+        source.close();
+        if (thread!=null) {
+            terminated = true;
+            System.out.println("Waiting for thread to die...");
+            try {
+                thread.join();
+            } catch (InterruptedException ie) {
+                ie.printStackTrace();
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        filename = null;
+        if (args.length>0) {
+            File f = new File(args[0]);
+            if (f.exists()) {
+                filename = args[0];
+                System.out.println("Opening "+filename);
+                constructAIS();
+                audioFormat = ais.getFormat();
+            }
+        }
+        if (filename == null) {
+            audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true);
+            for (int i=0; i<audioData.length; i++) {
+                audioData[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
+            }
+        }
+        long startTime = System.currentTimeMillis();
+        Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+        for (int i=0; i<mixers.length; i++) {
+            try {
+                Mixer mixer = AudioSystem.getMixer(mixers[i]);
+                DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
+                String mixerName = mixer.getMixerInfo().getName();
+                try {
+                    source = (SourceDataLine) mixer.getLine(info);
+                    source.open(audioFormat);
+                } catch (IllegalArgumentException iae) {
+                    System.out.println("Mixer "+mixerName+" does not provide a SourceDataLine.");
+                    continue;
+                } catch (LineUnavailableException lue) {
+                    System.out.println("Mixer "+mixerName+": no lines available.");
+                    continue;
+                }
+                System.out.println("***** Testing on Mixer "+mixerName+":");
+                //runTest(2);
+                //runTest(3);
+                runTest(1);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        if (mixers.length==0) {
+            System.out.println("No mixers available!");
+        } else {
+            long duration = System.currentTimeMillis() - startTime;
+
+            System.out.println("Test took "+(duration/1000)+"s and "+(duration % 1000)+"ms.");
+        }
+
+        System.out.println("Exiting main()");
+        if (executedTests>0) {
+            if (successfulTests == 0) {
+                if (args.length == 0) {
+                    throw new Exception("Test FAILED");
+                }
+                System.out.println("test FAILED.");
+            } else {
+                System.out.println("test successful.");
+            }
+        } else {
+            System.out.println("Could not execute any tests - are soundcards correctly installed?");
+            System.out.println("Test NOT FAILED.");
+        }
+    }
+
+    public void run() {
+        int len = audioData.length;
+        int offset = len;
+        System.out.println("Thread: started. Beginning audio i/o");
+        while (!terminated) {
+            try {
+                //if (!source.isActive()) {
+                //      Thread.sleep(50);
+                //}
+                if (offset >= len) {
+                    offset = 0;
+                    if (ais!=null) {
+                        do {
+                            len = ais.read(audioData, 0, audioData.length);
+                            if (len < 0) {
+                                constructAIS();
+                            }
+                        } while (len < 0);
+                    }
+                }
+                int toWrite = len - offset;
+                int written = source.write(audioData, offset, toWrite);
+                offset+=written;
+                bytesWritten += written;
+                buffersWritten = (int) (bytesWritten / audioData.length);
+            } catch (Exception e) {
+                e.printStackTrace();
+                terminated = true;
+            }
+        }
+        System.out.println("Thread: closing line");
+        source.stop();
+        source.close();
+        System.out.println("Thread finished");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/LinuxBlock/PlaySine.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4834461
+ * @summary Applet hang when you load it during sound card is in use
+ * @run main/manual PlaySine
+ */
+public class PlaySine {
+
+    static int sampleRate = 8000;
+    static double frequency = 2000.0;
+    static double RAD = 2.0 * Math.PI;
+
+    static byte[] audioData = new byte[sampleRate/2];
+    static SourceDataLine source;
+    static Mixer mixer = null;
+
+    static AudioInputStream ais = null;
+    static AudioFormat audioFormat;
+    static String filename;
+
+    public static void constructAIS() {
+        try {
+            ais = AudioSystem.getAudioInputStream(new File(filename));
+        } catch (Exception e) {
+            println("ERROR: could not open "+filename+": "+e.getMessage());
+        }
+    }
+
+    public static void print(String s) {
+        System.out.print(s);
+    }
+    public static void println(String s) {
+        System.out.println(s);
+    }
+
+    public static void key() {
+        println("");
+        print("Press ENTER to continue...");
+        try {
+            System.in.read();
+        } catch (IOException ioe) {
+        }
+    }
+
+    static int audioLen = -1;
+    static int audioOffset = -1;
+
+    public static void writeData() {
+        if (audioLen == -1) {
+            audioLen = audioData.length;
+        }
+        if (audioOffset < 0) {
+            audioOffset = audioLen;
+        }
+        try {
+            if (audioOffset >= audioLen) {
+                audioOffset = 0;
+                if (ais!=null) {
+                    do {
+                        audioLen = ais.read(audioData, 0, audioData.length);
+                        if (audioLen < 0) {
+                            constructAIS();
+                        }
+                    } while (audioLen < 0);
+                }
+            }
+            int toWrite = audioLen - audioOffset;
+            int written = source.write(audioData, audioOffset, toWrite);
+            audioOffset+=written;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    public static int play(boolean shouldPlay) {
+        int res = 0;
+        DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
+        try {
+            println("Getting line from mixer...");
+            source = (SourceDataLine) mixer.getLine(info);
+            println("Opening line...");
+            println("  -- if the program is hanging here, kill the process that has blocks the audio device now.");
+            source.open(audioFormat);
+            println("Starting line...");
+            source.start();
+            println("Writing audio data for 1 second...");
+            long startTime = System.currentTimeMillis();
+            while (System.currentTimeMillis() - startTime < 1000) {
+                writeData();
+                Thread.sleep(100);
+            }
+            res = 1;
+        } catch (IllegalArgumentException iae) {
+            println("IllegalArgumentException: "+iae.getMessage());
+            println("Sound device cannot handle this audio format.");
+            println("ERROR: Test environment not correctly set up.");
+            if (source!=null) {
+                source.close();
+            }
+            return 3;
+        } catch (LineUnavailableException lue) {
+            println("LineUnavailableException: "+lue.getMessage());
+            if (shouldPlay) {
+                println("ERROR: the line should be available now!.");
+                println("       Verify that you killed the other audio process.");
+            } else {
+                println("Correct behavior! the bug is fixed.");
+            }
+            res = 2;
+        } catch (Exception e) {
+            println("Unexpected Exception: "+e.toString());
+        }
+        if (source != null) {
+            println("Draining...");
+            try {
+                source.drain();
+            } catch (NullPointerException npe) {
+                println("(NullPointerException: bug fixed in J2SE 1.4.2");
+            }
+            println("Stopping...");
+            source.stop();
+            println("Closing...");
+            source.close();
+            source = null;
+        }
+        return res;
+    }
+
+    public static void main(String[] args) throws Exception {
+        println("This is an interactive test. You can run it with a filename as argument");
+        println("It is only meant to be run on linux, with the (old) OSS kernel drivers (/dev/dsp)");
+        println("This test should not be run on systems with ALSA installed, or kernel 2.6 or higher.");
+        println("");
+        println("The test verifies that Java Sound fails correctly if another process is blocking");
+        println("the audio device.");
+        println("");
+        println("Checking sanity...");
+        Mixer.Info[] mixers=null;
+
+        mixers = AudioSystem.getMixerInfo();
+        for (int i=0; i<mixers.length; i++) {
+            try {
+                Mixer thisMixer = AudioSystem.getMixer(mixers[i]);
+                String mixerName = thisMixer.getMixerInfo().getName();
+                if (mixerName.indexOf("Java Sound")>=0
+                    && mixerName.indexOf("Engine")>=0) {
+                    mixer = thisMixer;
+                    break;
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        if (mixer == null) {
+            if (mixers.length==0) {
+                System.out.println("ERROR: No mixers available!");
+            } else {
+                println("ERROR: Java Sound Engine could not be found.");
+            }
+            println("Cannot run this test.");
+            return;
+        }
+        println("  ...using mixer "+mixer.getMixerInfo());
+
+        String osname = System.getProperty("os.name");
+        if ((osname == null) || (osname.toLowerCase().indexOf("linux")<0)) {
+            println("ERROR: not running on linux (you are running on "+osname+")");
+            return;
+        }
+        println("  ...running on "+osname);
+        println("  ...sanity test OK.");
+
+        filename = null;
+        if (args.length>0) {
+            File f = new File(args[0]);
+            if (f.exists()) {
+                filename = args[0];
+                println("Opening "+filename);
+                constructAIS();
+                if (ais!=null) {
+                    audioFormat = ais.getFormat();
+                }
+            }
+        }
+        if (ais == null) {
+            println("Using self-generated sine wave for playback");
+            audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true);
+            for (int i=0; i<audioData.length; i++) {
+                audioData[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
+            }
+        }
+
+        println("");
+        println("Now, on a second console, run the following command:");
+        println("    cat - < /dev/zero > /dev/dsp");
+        key();
+        println("After you press ENTER now, the mixer will be opened.");
+        println("There are 3 possible cases that can occur:");
+        println("1) you'll hear a sine wave");
+        println("   -> you are running with mixing OSS drivers. ");
+        println("      Some soundcards only provide mixing OSS drivers.");
+        println("      Test environment not valid. ");
+        println("      Repeat on another machine where you can reproduce the bug first.");
+        println("2) this program stops doing anything after 'Opening line...'");
+        println("   -> this is the bug.");
+        println("      Kill the command on the other console with Ctrl-C, this program");
+        println("      should continue working then.");
+        println("3) this program reports a LineUnavailableException");
+        println("   -> bug is fixed.");
+        println("      OR you run with non-blocking OSS drivers.");
+        println("      make sure that you can reproduce this bug first with e.g. J2SE 1.4.1");
+        key();
+        int playedFirst = play(false);
+        int playedSecond = 0;
+
+        if (playedFirst == 2) {
+            println("");
+            println("Now kill the other process with Ctrl-C.");
+            println("After that, this program should be able to play ");
+            println("the sine wave without problems.");
+            key();
+            playedSecond = play(true);
+        }
+        println("");
+        if (playedFirst == 1) {
+            println("Test FAILED.");
+        }
+        else if (playedFirst == 2 && playedSecond == 1) {
+            println("Test SUCCESSFUL");
+        } else {
+            println("Test not failed (but not successful either...).");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/LinuxCrash/ClipLinuxCrash.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+
+/**
+ * @test
+ * @bug 4498848
+ * @summary Sound causes crashes on Linux (part 1)
+ */
+public class ClipLinuxCrash {
+
+    static Clip clip;
+
+    public static long bytes2Ms(long bytes, AudioFormat format) {
+        return (long) (bytes / format.getFrameRate() * 1000
+                               / format.getFrameSize());
+    }
+
+    static int staticLen = 1000;
+
+    static boolean addLen = true;
+
+    public static long start() throws Exception {
+        AudioFormat fmt = new AudioFormat(44100, 16, 2, true, false);
+        if (addLen) {
+            staticLen += (int) (staticLen / 5) + 1000;
+        } else {
+            staticLen -= (int) (staticLen / 5) + 1000;
+        }
+        if (staticLen > 8 * 44100 * 4) {
+            staticLen = 8 * 44100 * 4;
+            addLen = !addLen;
+        }
+        if (staticLen < 1000) {
+            staticLen = 1000;
+            addLen = !addLen;
+        }
+        int len = staticLen;
+        len -= (len % 4);
+        byte[] fakedata = new byte[len];
+        InputStream is = new ByteArrayInputStream(fakedata);
+        AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
+                                             44100, 16, 2, 4, 44100, false);
+        AudioInputStream ais = new AudioInputStream(is, format, fakedata.length
+                / format.getFrameSize());
+
+        out("    preparing to play back " + len + " bytes == " + bytes2Ms(len,
+                                                                          format)
+                    + "ms audio...");
+
+        DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat());
+        clip = (Clip) AudioSystem.getLine(info);
+        clip.addLineListener(new LineListener() {
+            public void update(LineEvent e) {
+                if (e.getType() == LineEvent.Type.STOP) {
+                    out("    calling close() from event dispatcher thread");
+                    ((Clip) e.getSource()).close();
+                } else if (e.getType() == LineEvent.Type.CLOSE) {
+                }
+            }
+        });
+
+        out("    opening...");
+        try {
+            clip.open(ais);
+        } catch (Throwable t) {
+            t.printStackTrace();
+            clip.close();
+            clip = null;
+        }
+        ais.close();
+        if (clip != null) {
+            out("    starting...");
+            clip.start();
+        }
+        return bytes2Ms(fakedata.length, format);
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (AudioSystem.getMixerInfo().length == 0) {
+            System.out.println("Cannot execute test: no mixers installed!");
+            System.out.println("Not Failed.");
+            return;
+        }
+        try {
+            int COUNT = 10;
+            out();
+            out("4498848 Sound causes crashes on Linux (testing with Clip)");
+            if (args.length > 0) {
+                COUNT = Integer.parseInt(args[0]);
+            }
+            for (int i = 0; i < COUNT; i++) {
+                out("  trial " + (i + 1) + "/" + COUNT);
+                start();
+                int waitTime = 500 + (1000 * (i
+                                                      % 2)); // every second
+                // time wait 1500, rather than 500ms.
+                out("    waiting for " + waitTime
+                            + " ms for audio playback to stop...");
+                Thread.sleep(waitTime);
+                out("    calling close() from main thread");
+                if (clip != null) {
+                    clip.close();
+                }
+                // let the subsystem enough time to actually close the soundcard
+                out("    waiting for 2 seconds...");
+                Thread.sleep(2000);
+                out();
+            }
+            out("  waiting for 1 second...");
+            Thread.sleep(1000);
+        } catch (Exception e) {
+            e.printStackTrace();
+            out("  waiting for 1 second");
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ie) {
+            }
+            throw e;
+        }
+        out("Test passed");
+    }
+
+    static void out() {
+        out("");
+    }
+
+    static void out(String s) {
+        System.out.println(s);
+        System.out.flush();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/LinuxCrash/ClipLinuxCrash2.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4498848
+ * @summary Sound causes crashes on Linux (part 3)
+ */
+public class ClipLinuxCrash2 implements LineListener{
+    Clip clip;
+    int stopOccured;
+    static final Object lock = new Object();
+
+    public static long bytes2Ms(long bytes, AudioFormat format) {
+        return (long) (bytes/format.getFrameRate()*1000/format.getFrameSize());
+    }
+
+    static int staticLen=1000;
+    static boolean addLen=true;
+
+    ClipLinuxCrash2() {
+    }
+
+    public void update(LineEvent e) {
+        if (e.getType() == LineEvent.Type.STOP) {
+            stopOccured++;
+            out("  Test program: receives STOP event for clip="+clip.toString()+" no."+stopOccured);
+            out("  Test program: Calling close() in event dispatcher thread");
+            clip.close();
+            synchronized (lock) {
+                lock.notifyAll();
+            }
+        }
+        else if (e.getType() == LineEvent.Type.CLOSE) {
+            out("  Test program: receives CLOSE event for "+clip.toString());
+            synchronized (lock) {
+                lock.notifyAll();
+            }
+        }
+        else if (e.getType() == LineEvent.Type.START) {
+            out("  Test program: receives START event for "+clip.toString());
+        }
+        else if (e.getType() == LineEvent.Type.OPEN) {
+            out("  Test program: receives OPEN event for "+clip.toString());
+        }
+    }
+
+    public long start() throws Exception {
+        AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+
+        if (addLen) {
+            staticLen+=(int) (staticLen/5)+1000;
+        } else {
+            staticLen-=(int) (staticLen/5)+1000;
+        }
+        if (staticLen>8*44100*4) {
+            staticLen = 8*44100*4;
+            addLen=!addLen;
+        }
+        if (staticLen<1000) {
+            staticLen = 1000;
+            addLen=!addLen;
+        }
+        int len = staticLen;
+        len -= (len % 4);
+        out("  Test program: preparing to play back "+len+" bytes == "+bytes2Ms(len, format)+"ms audio...");
+
+        byte[] fakedata=new byte[len];
+        InputStream is = new ByteArrayInputStream(fakedata);
+        AudioInputStream ais = new AudioInputStream(is, format, fakedata.length/format.getFrameSize());
+
+        DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat());
+        clip = (Clip) AudioSystem.getLine(info);
+        clip.addLineListener(this);
+
+        out("  Test program: opening clip="+((clip==null)?"null":clip.toString()));
+        clip.open(ais);
+        ais.close();
+        out("  Test program: starting clip="+((clip==null)?"null":clip.toString()));
+        clip.start();
+        return bytes2Ms(fakedata.length, format);
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (!isSoundcardInstalled()) {
+            return;
+        }
+
+        try {
+            int COUNT=10;
+            out();
+            out("4498848 Sound causes crashes on Linux");
+            if (args.length>0) {
+                COUNT=Integer.parseInt(args[0]);
+            }
+            for (int i=0; i<COUNT; i++) {
+                out("trial "+(i+1)+"/"+COUNT);
+                ClipLinuxCrash2 t = new ClipLinuxCrash2();
+                t.start();
+                int waitTime = 300+(1300*(i % 2)); // every 2nd time wait 1600, rather than 300ms.
+                out("  Test program: waiting for "+waitTime+" ms for audio playback to stop...");
+                Thread.sleep(waitTime);
+                out("  Test program: calling close() from main thread");
+                t.clip.close();
+                // let the subsystem enough time to actually close the soundcard
+                //out("  Test program: waiting for 2 seconds...");
+                //Thread.sleep(2000);
+                //out();
+            }
+            out("  Test program: waiting for 1 second...");
+            Thread.sleep(1000);
+        } catch (Exception e) {
+            e.printStackTrace();
+            out("  Test program: waiting for 1 second");
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ie) {}
+            // do not fail if no audio device installed - bug 4742021
+            if (!(e instanceof LineUnavailableException)) {
+                throw e;
+            }
+        }
+        out("Test passed");
+    }
+
+    static void out() {
+        out("");
+    }
+
+    static void out(String s) {
+        System.out.println(s); System.out.flush();
+    }
+
+    /**
+     * Returns true if at least one soundcard is correctly installed
+     * on the system.
+     */
+    public static boolean isSoundcardInstalled() {
+        boolean result = false;
+        try {
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            if (mixers.length > 0) {
+                result = AudioSystem.getSourceDataLine(null) != null;
+            }
+        } catch (Exception e) {
+            System.err.println("Exception occured: "+e);
+        }
+        if (!result) {
+            System.err.println("Soundcard does not exist or sound drivers not installed!");
+            System.err.println("This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/LinuxCrash/SDLLinuxCrash.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * @test
+ * @bug 4498848
+ * @summary Sound causes crashes on Linux (part 2)
+ */
+public class SDLLinuxCrash implements Runnable {
+    SourceDataLine sdl;
+    int size;
+
+    SDLLinuxCrash(SourceDataLine sdl, int size) {
+        this.sdl = sdl;
+        this.size = size - (size % 4);
+    }
+
+    public void run() {
+        int written=0;
+        //byte[] buffer = new byte[4096];
+        byte[] buffer = data;
+        out("    starting data line feed thread.");
+        try {
+            while (written<size) {
+                int toWrite = buffer.length;
+                if (toWrite+written > size) {
+                    toWrite = size-written;
+                }
+                toWrite -= (toWrite % 4);
+                //out("    writing "+toWrite+" bytes.");
+                int thisWritten = sdl.write(buffer, 0, toWrite);
+                if (thisWritten<toWrite) {
+                    out("    only wrote "+thisWritten+" bytes instead of "+toWrite);
+                }
+                if (thisWritten<=0) {
+                    break;
+                }
+                written += thisWritten;
+            }
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+        out("    leaving data line feed thread.");
+    }
+
+    public static long bytes2Ms(long bytes, AudioFormat format) {
+        return (long) (bytes/format.getFrameRate()*1000/format.getFrameSize());
+    }
+
+    static int staticLen=1000;
+    static boolean addLen=true;
+
+    public static SourceDataLine start() throws Exception {
+        AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+        if (addLen) {
+            staticLen+=(int) (staticLen/5)+1000;
+        } else {
+            staticLen-=(int) (staticLen/5)+1000;
+        }
+        if (staticLen>8*44100*4) {
+            staticLen = 8*44100*4;
+            addLen=!addLen;
+        }
+        if (staticLen<1000) {
+            staticLen = 1000;
+            addLen=!addLen;
+        }
+        int len = staticLen;
+        len -= (len % 4);
+        out("    preparing to play back "+len+" bytes == "+bytes2Ms(len, format)+"ms audio...");
+
+        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
+        SourceDataLine sdl = (SourceDataLine) AudioSystem.getLine(info);
+        sdl.addLineListener(new LineListener() {
+                public void update(LineEvent e) {
+                    if (e.getType() == LineEvent.Type.STOP) {
+                        out("    calling close() from event dispatcher thread");
+                        ((SourceDataLine) e.getSource()).close();
+                    }
+                    else if (e.getType() == LineEvent.Type.CLOSE) {
+                    }
+                }
+            });
+
+        out("    opening...");
+        sdl.open();
+        out("    starting...");
+        sdl.start();
+        (new Thread(new SDLLinuxCrash(sdl, len))).start();
+        return sdl;
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (!isSoundcardInstalled()) {
+            return;
+        }
+
+        try {
+            int COUNT=10;
+            out();
+            out("4498848 Sound causes crashes on Linux (testing with SourceDataLine)");
+            if (args.length>0) {
+                COUNT=Integer.parseInt(args[0]);
+            }
+            for (int i=0; i<COUNT; i++) {
+                out("  trial "+(i+1)+"/"+COUNT);
+                SourceDataLine sdl = start();
+                int waitTime = 500+(1000*(i % 2)); // every 2nd time wait 1500, rather than 500ms.
+                out("    waiting for "+waitTime+" ms for audio playback to stop...");
+                Thread.sleep(waitTime);
+                out("    calling close() from main thread");
+                sdl.close();
+                // let the subsystem enough time to actually close the soundcard
+                out("    waiting for 2 seconds...");
+                Thread.sleep(2000);
+                out();
+            }
+            out("  waiting for 1 second...");
+            Thread.sleep(1000);
+        } catch (Exception e) {
+            e.printStackTrace();
+            out("  waiting for 1 second");
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ie) {}
+            // do not fail if no audio device installed - bug 4742021
+            if (!(e instanceof LineUnavailableException)) {
+                throw e;
+            }
+        }
+        out("Test passed");
+    }
+
+    static void out() {
+        out("");
+    }
+
+    static void out(String s) {
+        System.out.println(s); System.out.flush();
+    }
+
+    /**
+     * Returns true if at least one soundcard is correctly installed
+     * on the system.
+     */
+    public static boolean isSoundcardInstalled() {
+        boolean result = false;
+        try {
+            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+            if (mixers.length > 0) {
+                result = AudioSystem.getSourceDataLine(null) != null;
+            }
+        } catch (Exception e) {
+            System.err.println("Exception occured: "+e);
+        }
+        if (!result) {
+            System.err.println("Soundcard does not exist or sound drivers not installed!");
+            System.err.println("This test requires sound drivers for execution.");
+        }
+        return result;
+    }
+
+
+
+    static final byte[] data = new byte[] {
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120,
+        123, 110, 100, 60, 11, 10, 10, 10, 9, 9,
+        9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6,
+        7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
+        9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 122, 122
+    };
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Mixers/BogusMixers.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4667064
+ * @summary Java Sound provides bogus SourceDataLine and TargetDataLine
+ */
+public class BogusMixers {
+
+    public static void main(String[] args) throws Exception {
+        try {
+            out("4667064: Java Sound provides bogus SourceDataLine and TargetDataLine");
+
+            Mixer.Info[]    aInfos = AudioSystem.getMixerInfo();
+            out("  available Mixers:");
+            for (int i = 0; i < aInfos.length; i++) {
+                if (aInfos[i].getName().startsWith("Java Sound Audio Engine")) {
+                    Mixer mixer = AudioSystem.getMixer(aInfos[i]);
+                    Line.Info[] tlInfos = mixer.getTargetLineInfo();
+                    for (int ii = 0; ii<tlInfos.length; ii++) {
+                        if (tlInfos[ii].getLineClass() == DataLine.class) {
+                            throw new Exception("Bogus TargetDataLine with DataLine info present!");
+                        }
+                    }
+                }
+                if (aInfos[i].getName().startsWith("WinOS,waveOut,multi threaded")) {
+                    throw new Exception("Bogus mixer 'WinOS,waveOut,multi threaded' present!");
+                }
+                out(aInfos[i].getName());
+            }
+            if (aInfos.length == 0)
+            {
+                out("[No mixers available] - not a failure of this test case.");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw e;
+        }
+        out("Test passed");
+    }
+
+    static void out(String s) {
+        System.out.println(s); System.out.flush();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Mixers/BothEndiansAndSigns.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4936397
+ * @summary Verify that there'll for a given endianness, there's also the little
+ *          endian version
+ */
+public class BothEndiansAndSigns {
+    static boolean failed = false;
+    static int testedFormats = 0;
+
+    public static void main(String[] args) throws Exception {
+        out("4936397: Verify that there'll for a given endianness, there's also the little endian version");
+        out("         and the same for signed'ness for 8-bit formats");
+
+        Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
+        for (int i = 0; i < aInfos.length; i++) {
+            try {
+                Mixer mixer = AudioSystem.getMixer(aInfos[i]);
+                out("Mixer "+aInfos[i]);
+                checkLines(mixer, mixer.getSourceLineInfo());
+                checkLines(mixer, mixer.getTargetLineInfo());
+            } catch (Exception e) {
+                out("Unexpected exception when getting a mixer: "+e);
+            }
+        }
+        if (testedFormats == 0) {
+            out("[No appropriate lines available] - cannot exercise this test.");
+        } else {
+            if (failed) {
+                throw new Exception("Test FAILED!");
+            }
+            out("Test passed");
+        }
+    }
+
+    public static void checkLines(Mixer mixer, Line.Info[] infos) {
+        for (int i = 0; i<infos.length; i++) {
+            try {
+                if (infos[i] instanceof DataLine.Info) {
+                    DataLine.Info info = (DataLine.Info) infos[i];
+                    System.out.println(" Line "+info+" (max. "+mixer.getMaxLines(info)+" simultaneously): ");
+                    AudioFormat[] formats = info.getFormats();
+                    for (int f = 0; f < formats.length; f++) {
+                        try {
+                            AudioFormat otherEndianOrSign = getOtherEndianOrSign(formats[f]);
+                            if (otherEndianOrSign != null) {
+                                checkFormat(formats, otherEndianOrSign);
+                            }
+                        } catch (Exception e1) {
+                            out("  Unexpected exception when getting a format: "+e1);
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                out(" Unexpected exception when getting a line: "+e);
+            }
+        }
+    }
+
+    public static void checkFormat(AudioFormat[] formats, AudioFormat format) {
+        for (int i = 0; i < formats.length; i++) {
+            testedFormats++;
+            if (formats[i].matches(format)) {
+                return;
+            }
+        }
+        out("  ## expected this format: "+format
+            +" ("+format.getChannels()+" channels, "
+            +"frameSize="+format.getFrameSize()+", "
+            +(format.isBigEndian()?"big endian":"little endian")
+            +")");
+        failed = true;
+    }
+
+    public static AudioFormat getOtherEndianOrSign(AudioFormat format) {
+        AudioFormat.Encoding newEnc = null;
+        boolean newEndian = format.isBigEndian();
+        boolean isSigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED);
+        boolean isUnsigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED);
+        if ((isSigned || isUnsigned) && format.getSampleSizeInBits() > 0) {
+            if (format.getSampleSizeInBits() == 8) {
+                // return the other signed'ness
+                if (isSigned) {
+                    newEnc = AudioFormat.Encoding.PCM_UNSIGNED;
+                } else {
+                    newEnc = AudioFormat.Encoding.PCM_SIGNED;
+                }
+            } else {
+                newEnc = format.getEncoding();
+                newEndian = !newEndian;
+            }
+            if (newEnc != null) {
+                return new AudioFormat(newEnc, format.getSampleRate(),
+                                       format.getSampleSizeInBits(),
+                                       format.getChannels(),
+                                       format.getFrameSize(),
+                                       format.getFrameRate(),
+                                       newEndian);
+            }
+        }
+        return null;
+    }
+
+    static void out(String s) {
+        System.out.println(s); System.out.flush();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Mixers/DirectSoundRepeatingBuffer/DirectSoundRepeatingBuffer.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import java.io.IOException;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * This is utility class for Test4997635.
+ */
+public class DirectSoundRepeatingBuffer {
+
+    static int sampleRate = 8000;
+    static double frequency = 1000.0;
+    static double RAD = 2.0 * Math.PI;
+
+    static byte[] audioData = new byte[sampleRate/8];
+    static DataLine.Info info;
+    static SourceDataLine source;
+
+    //static AudioInputStream ais = null;
+    static AudioFormat audioFormat;
+    //static String filename;
+
+    public static void print(String s) {
+        System.out.print(s);
+    }
+    public static void println(String s) {
+        System.out.println(s);
+    }
+
+    public static void key() {
+        println("");
+        print("Press ENTER to continue...");
+        try {
+            System.in.read();
+        } catch (IOException ioe) {
+        }
+        println("");
+    }
+
+    public static void play(Mixer mixer) {
+        int res = 0;
+        try {
+            println("Getting SDL from mixer...");
+            source = (SourceDataLine) mixer.getLine(info);
+            println("Opening SDL...");
+            source.open(audioFormat);
+            println("Writing data to SDL...");
+            source.write(audioData, 0, audioData.length);
+            println("Starting SDL...");
+            source.start();
+            println("Now open your ears:");
+            println("- you should have heard a short tone,");
+            println("  followed by silence.");
+            println("- if after a while you hear repeated tones,");
+            println("  the bug is NOT fixed.");
+            println("- if the program remains silent after the ");
+            println("  initial tone, the bug is fixed.");
+            key();
+        } catch (IllegalArgumentException iae) {
+            println("IllegalArgumentException: "+iae.getMessage());
+            println("Sound device cannot handle this audio format.");
+            println("ERROR: Test environment not correctly set up.");
+            if (source!=null) {
+                source.close();
+                source = null;
+            }
+            return;
+        } catch (LineUnavailableException lue) {
+            println("LineUnavailableException: "+lue.getMessage());
+            println("This is normal for some mixers.");
+        } catch (Exception e) {
+            println("Unexpected Exception: "+e.toString());
+        }
+        if (source != null) {
+            println("Stopping...");
+            source.stop();
+            println("Closing...");
+            source.close();
+            println("Closed.");
+            source = null;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        println("This is an interactive test for DirectAudio.");
+        println("If the tone repeats, the test is failed.");
+        println("");
+        println("Make sure that you have speakers connected");
+        println("and that the system mixer is not muted.");
+        println("");
+        println("Press a key to start the test.");
+        key();
+        Mixer.Info[] mixers=null;
+
+            println("   ...using self-generated sine wave for playback");
+            audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true);
+            for (int i=0; i<audioData.length; i++) {
+                audioData[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
+            }
+        info = new DataLine.Info(SourceDataLine.class, audioFormat);
+
+        mixers = AudioSystem.getMixerInfo();
+        int succMixers = 0;
+        for (int i=0; i<mixers.length; i++) {
+            println(""+mixers[i]+":");
+            if ((mixers[i].getName()+mixers[i].getDescription()+mixers[i].getVendor()).indexOf("Direct") < 0) {
+                println("  ->not a DirectAudio Mixer!");
+            } else {
+            try {
+                Mixer mixer = AudioSystem.getMixer(mixers[i]);
+                if (!mixer.isLineSupported(info)) {
+                        println("  ->doesn't support SourceDataLine!");
+                } else {
+                    succMixers++;
+                    println("  -> is getting tested.");
+                    play(mixer);
+                }
+            } catch (Exception e) {
+                println("  -> Exception occured: "+e);
+                e.printStackTrace();
+            }
+          }
+        }
+        if (succMixers == 0) {
+                println("No DirectAudio mixers available! ");
+                println("Cannot run test.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Mixers/DirectSoundRepeatingBuffer/Test4997635.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import java.awt.Button;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.Panel;
+import java.awt.TextArea;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * @test
+ * @bug 4997635
+ * @summary Win: SourceDataLine playback loops endlessly unless you manually
+ *          stop()
+ * @build DirectSoundRepeatingBuffer
+ * @run main/manual Test4997635
+ */
+public class Test4997635 {
+
+   private static void init() throws Exception {
+        //*** Create instructions for the user here ***
+
+        String[] instructions =
+        {
+         "To run the test follow these instructions:",
+         "1. Open a terminal window.",
+         "2. Type \"cd " + System.getProperty("test.classes") + "\".",
+         "3. Type \"" + System.getProperty("java.home") + "/bin/java DirectSoundRepeatingBuffer\".",
+         "4. Follow the instructions shown in the terminal window.",
+         "If no error occured during the test, and the java application ",
+         "in the termial exited successfully, press PASS, else press FAIL."
+       };
+
+      Sysout.createDialog( );
+      Sysout.printInstructions( instructions );
+
+    }
+
+ /*****************************************************
+     Standard Test Machinery Section
+      DO NOT modify anything in this section -- it's a
+      standard chunk of code which has all of the
+      synchronisation necessary for the test harness.
+      By keeping it the same in all tests, it is easier
+      to read and understand someone else's test, as
+      well as insuring that all tests behave correctly
+      with the test harness.
+     There is a section following this for test-defined
+      classes
+   ******************************************************/
+   private static boolean theTestPassed = false;
+   private static boolean testGeneratedInterrupt = false;
+   private static String failureMessage = "";
+
+   private static Thread mainThread = null;
+
+   private static int sleepTime = 300000;
+
+   public static void main( String args[] ) throws Exception
+    {
+      mainThread = Thread.currentThread();
+      try
+       {
+         init();
+       }
+      catch( TestPassedException e )
+       {
+         //The test passed, so just return from main and harness will
+         // interepret this return as a pass
+         return;
+       }
+      //At this point, neither test passed nor test failed has been
+      // called -- either would have thrown an exception and ended the
+      // test, so we know we have multiple threads.
+
+      //Test involves other threads, so sleep and wait for them to
+      // called pass() or fail()
+      try
+       {
+         Thread.sleep( sleepTime );
+         //Timed out, so fail the test
+         throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+       }
+      catch (InterruptedException e)
+       {
+         if( ! testGeneratedInterrupt ) throw e;
+
+         //reset flag in case hit this code more than once for some reason (just safety)
+         testGeneratedInterrupt = false;
+         if ( theTestPassed == false )
+          {
+            throw new RuntimeException( failureMessage );
+          }
+       }
+
+    }//main
+
+   public static synchronized void setTimeoutTo( int seconds )
+    {
+      sleepTime = seconds * 1000;
+    }
+
+   public static synchronized void pass()
+    {
+      Sysout.println( "The test passed." );
+      Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+      //first check if this is executing in main thread
+      if ( mainThread == Thread.currentThread() )
+       {
+         //Still in the main thread, so set the flag just for kicks,
+         // and throw a test passed exception which will be caught
+         // and end the test.
+         theTestPassed = true;
+         throw new TestPassedException();
+       }
+      //pass was called from a different thread, so set the flag and interrupt
+      // the main thead.
+      theTestPassed = true;
+      testGeneratedInterrupt = true;
+      mainThread.interrupt();
+    }//pass()
+
+   public static synchronized void fail()
+    {
+      //test writer didn't specify why test failed, so give generic
+      fail( "it just plain failed! :-)" );
+    }
+
+   public static synchronized void fail( String whyFailed )
+    {
+      Sysout.println( "The test failed: " + whyFailed );
+      Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+      //check if this called from main thread
+      if ( mainThread == Thread.currentThread() )
+       {
+         //If main thread, fail now 'cause not sleeping
+         throw new RuntimeException( whyFailed );
+       }
+      theTestPassed = false;
+      testGeneratedInterrupt = true;
+      failureMessage = whyFailed;
+      mainThread.interrupt();
+    }//fail()
+
+ }// class Orient
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+ {
+ }
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         Orient.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         Orient.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+ {
+   private static TestDialog dialog;
+
+   public static void createDialogWithInstructions( String[] instructions )
+    {
+      dialog = new TestDialog( new Frame(), "Instructions" );
+      dialog.printInstructions( instructions );
+      dialog.show();
+      println( "Any messages for the tester will display here." );
+    }
+
+   public static void createDialog( )
+    {
+      dialog = new TestDialog( new Frame(), "Instructions" );
+      String[] defInstr = { "Instructions will appear here. ", "" } ;
+      dialog.printInstructions( defInstr );
+      dialog.show();
+      println( "Any messages for the tester will display here." );
+    }
+
+
+   public static void printInstructions( String[] instructions )
+    {
+      dialog.printInstructions( instructions );
+    }
+
+
+   public static void println( String messageIn )
+    {
+      dialog.displayMessage( messageIn );
+    }
+
+ }// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog implements ActionListener
+ {
+
+   TextArea instructionsText;
+   TextArea messageText;
+   int maxStringLength = 80;
+   Panel  buttonP = new Panel();
+   Button passB = new Button( "pass" );
+   Button failB = new Button( "fail" );
+
+   //DO NOT call this directly, go through Sysout
+   public TestDialog( Frame frame, String name )
+    {
+      super( frame, name );
+      int scrollBoth = TextArea.SCROLLBARS_BOTH;
+      instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+      add( "North", instructionsText );
+
+      messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+      add("Center", messageText);
+
+      passB = new Button( "pass" );
+      passB.setActionCommand( "pass" );
+      passB.addActionListener( this );
+      buttonP.add( "East", passB );
+
+      failB = new Button( "fail" );
+      failB.setActionCommand( "fail" );
+      failB.addActionListener( this );
+      buttonP.add( "West", failB );
+
+      add( "South", buttonP );
+      pack();
+
+      show();
+    }// TestDialog()
+
+   //DO NOT call this directly, go through Sysout
+   public void printInstructions( String[] instructions )
+    {
+      //Clear out any current instructions
+      instructionsText.setText( "" );
+
+      //Go down array of instruction strings
+
+      String printStr, remainingStr;
+      for( int i=0; i < instructions.length; i++ )
+       {
+         //chop up each into pieces maxSringLength long
+         remainingStr = instructions[ i ];
+         while( remainingStr.length() > 0 )
+          {
+            //if longer than max then chop off first max chars to print
+            if( remainingStr.length() >= maxStringLength )
+             {
+               //Try to chop on a word boundary
+               int posOfSpace = remainingStr.
+                  lastIndexOf( ' ', maxStringLength - 1 );
+
+               if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+               printStr = remainingStr.substring( 0, posOfSpace + 1 );
+               remainingStr = remainingStr.substring( posOfSpace + 1 );
+             }
+            //else just print
+            else
+             {
+               printStr = remainingStr;
+               remainingStr = "";
+             }
+
+            instructionsText.append( printStr + "\n" );
+
+          }// while
+
+       }// for
+
+    }//printInstructions()
+
+   //DO NOT call this directly, go through Sysout
+   public void displayMessage( String messageIn )
+    {
+      messageText.append( messageIn + "\n" );
+    }
+
+   //catch presses of the passed and failed buttons.
+   //simply call the standard pass() or fail() static methods of
+   //DialogOrient
+   public void actionPerformed( ActionEvent e )
+    {
+      if( e.getActionCommand() == "pass" )
+       {
+         Test4997635.pass();
+       }
+      else
+       {
+         Test4997635.fail();
+       }
+    }
+
+ }// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Mixers/DirectSoundUnderrunSilence/DirectSoundUnderrunSilence.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.IOException;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * This is utility class for Test5032020.
+ */
+public class DirectSoundUnderrunSilence {
+
+    static int sampleRate = 8000;
+    static double frequency = 1000.0;
+    static double RAD = 2.0 * Math.PI;
+
+    static byte[] audioData = new byte[sampleRate/8];
+    static DataLine.Info info;
+    static SourceDataLine source;
+
+    //static AudioInputStream ais = null;
+    static AudioFormat audioFormat;
+    //static String filename;
+
+    public static void print(String s) {
+        System.out.print(s);
+    }
+    public static void println(String s) {
+        System.out.println(s);
+    }
+
+    public static void key() {
+        println("");
+        print("Press ENTER to continue...");
+        try {
+            System.in.read();
+        } catch (IOException ioe) {
+        }
+        println("");
+    }
+
+    public static void play(Mixer mixer) {
+        int res = 0;
+        try {
+            println("Getting SDL from mixer...");
+            source = (SourceDataLine) mixer.getLine(info);
+            println("Opening SDL...");
+            source.open(audioFormat);
+            println("Writing data to SDL...");
+            source.write(audioData, 0, audioData.length);
+            println("Starting SDL...");
+            source.start();
+            println("Now open your ears:");
+            println("You should have heard a short tone,");
+            println("followed by silence (no repeating tones).");
+            key();
+            source.write(audioData, 0, audioData.length);
+            println("Now you should have heard another short tone.");
+            println("If you did not hear a second tone, or more than 2 tones,");
+            println("the test is FAILED.");
+            println("otherwise, if you heard a total of 2 tones, the bug is fixed.");
+            key();
+        } catch (IllegalArgumentException iae) {
+            println("IllegalArgumentException: "+iae.getMessage());
+            println("Sound device cannot handle this audio format.");
+            println("ERROR: Test environment not correctly set up.");
+            if (source!=null) {
+                source.close();
+                source = null;
+            }
+            return;
+        } catch (LineUnavailableException lue) {
+            println("LineUnavailableException: "+lue.getMessage());
+            println("This is normal for some mixers.");
+        } catch (Exception e) {
+            println("Unexpected Exception: "+e.toString());
+        }
+        if (source != null) {
+            println("Stopping...");
+            source.stop();
+            println("Closing...");
+            source.close();
+            println("Closed.");
+            source = null;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        println("This is an interactive test for DirectAudio.");
+        println("If it's impossible to play data after an underun, the test fails.");
+        println("");
+        println("Make sure that you have speakers connected");
+        println("and that the system mixer is not muted.");
+        println("Also stop all other programs playing sounds:");
+        println("It has been seen that it alters the results.");
+        println("");
+        println("Press a key to start the test.");
+        key();
+        Mixer.Info[] mixers=null;
+
+        println("   ...using self-generated sine wave for playback");
+        audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true);
+        for (int i=0; i<audioData.length; i++) {
+            audioData[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
+        }
+        info = new DataLine.Info(SourceDataLine.class, audioFormat);
+
+        mixers = AudioSystem.getMixerInfo();
+        int succMixers = 0;
+        for (int i=0; i<mixers.length; i++) {
+            println(""+mixers[i]+":");
+            if ((mixers[i].getName()+mixers[i].getDescription()+mixers[i].getVendor()).indexOf("Direct") < 0) {
+                println("  ->not a DirectAudio Mixer!");
+            } else {
+                try {
+                    Mixer mixer = AudioSystem.getMixer(mixers[i]);
+                    if (!mixer.isLineSupported(info)) {
+                        println("  ->doesn't support SourceDataLine!");
+                    } else {
+                        succMixers++;
+                        println("  -> is getting tested.");
+                        play(mixer);
+                    }
+                } catch (Exception e) {
+                    println("  -> Exception occured: "+e);
+                    e.printStackTrace();
+                }
+            }
+        }
+        if (succMixers == 0) {
+            println("No DirectAudio mixers available! ");
+            println("Cannot run test.");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Mixers/DirectSoundUnderrunSilence/Test5032020.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.awt.Button;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.Panel;
+import java.awt.TextArea;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * @test
+ * @bug 5032020
+ * @summary Win: Direct Audio is silent after underrun
+ * @build DirectSoundUnderrunSilence
+ * @run main/manual Test5032020
+ */
+public class Test5032020 {
+
+   private static void init() throws Exception {
+        //*** Create instructions for the user here ***
+
+        String[] instructions =
+        {
+         "To run the test follow these instructions:",
+         "1. Open a terminal window.",
+         "2. Type \"cd " + System.getProperty("test.classes") + "\".",
+         "3. Type \"" + System.getProperty("java.home") + "/bin/java DirectSoundUnderrunSilence\".",
+         "4. Follow the instructions shown in the terminal window.",
+         "If no error occured during the test, and the java application ",
+         "in the termial exited successfully, press PASS, else press FAIL."
+       };
+
+      Sysout.createDialog( );
+      Sysout.printInstructions( instructions );
+
+    }
+
+ /*****************************************************
+     Standard Test Machinery Section
+      DO NOT modify anything in this section -- it's a
+      standard chunk of code which has all of the
+      synchronisation necessary for the test harness.
+      By keeping it the same in all tests, it is easier
+      to read and understand someone else's test, as
+      well as insuring that all tests behave correctly
+      with the test harness.
+     There is a section following this for test-defined
+      classes
+   ******************************************************/
+   private static boolean theTestPassed = false;
+   private static boolean testGeneratedInterrupt = false;
+   private static String failureMessage = "";
+
+   private static Thread mainThread = null;
+
+   private static int sleepTime = 300000;
+
+   public static void main( String args[] ) throws Exception
+    {
+      mainThread = Thread.currentThread();
+      try
+       {
+         init();
+       }
+      catch( TestPassedException e )
+       {
+         //The test passed, so just return from main and harness will
+         // interepret this return as a pass
+         return;
+       }
+      //At this point, neither test passed nor test failed has been
+      // called -- either would have thrown an exception and ended the
+      // test, so we know we have multiple threads.
+
+      //Test involves other threads, so sleep and wait for them to
+      // called pass() or fail()
+      try
+       {
+         Thread.sleep( sleepTime );
+         //Timed out, so fail the test
+         throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+       }
+      catch (InterruptedException e)
+       {
+         if( ! testGeneratedInterrupt ) throw e;
+
+         //reset flag in case hit this code more than once for some reason (just safety)
+         testGeneratedInterrupt = false;
+         if ( theTestPassed == false )
+          {
+            throw new RuntimeException( failureMessage );
+          }
+       }
+
+    }//main
+
+   public static synchronized void setTimeoutTo( int seconds )
+    {
+      sleepTime = seconds * 1000;
+    }
+
+   public static synchronized void pass()
+    {
+      Sysout.println( "The test passed." );
+      Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+      //first check if this is executing in main thread
+      if ( mainThread == Thread.currentThread() )
+       {
+         //Still in the main thread, so set the flag just for kicks,
+         // and throw a test passed exception which will be caught
+         // and end the test.
+         theTestPassed = true;
+         throw new TestPassedException();
+       }
+      //pass was called from a different thread, so set the flag and interrupt
+      // the main thead.
+      theTestPassed = true;
+      testGeneratedInterrupt = true;
+      mainThread.interrupt();
+    }//pass()
+
+   public static synchronized void fail()
+    {
+      //test writer didn't specify why test failed, so give generic
+      fail( "it just plain failed! :-)" );
+    }
+
+   public static synchronized void fail( String whyFailed )
+    {
+      Sysout.println( "The test failed: " + whyFailed );
+      Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+      //check if this called from main thread
+      if ( mainThread == Thread.currentThread() )
+       {
+         //If main thread, fail now 'cause not sleeping
+         throw new RuntimeException( whyFailed );
+       }
+      theTestPassed = false;
+      testGeneratedInterrupt = true;
+      failureMessage = whyFailed;
+      mainThread.interrupt();
+    }//fail()
+
+ }// class Orient
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+ {
+ }
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         Orient.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         Orient.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+ {
+   private static TestDialog dialog;
+
+   public static void createDialogWithInstructions( String[] instructions )
+    {
+      dialog = new TestDialog( new Frame(), "Instructions" );
+      dialog.printInstructions( instructions );
+      dialog.show();
+      println( "Any messages for the tester will display here." );
+    }
+
+   public static void createDialog( )
+    {
+      dialog = new TestDialog( new Frame(), "Instructions" );
+      String[] defInstr = { "Instructions will appear here. ", "" } ;
+      dialog.printInstructions( defInstr );
+      dialog.show();
+      println( "Any messages for the tester will display here." );
+    }
+
+
+   public static void printInstructions( String[] instructions )
+    {
+      dialog.printInstructions( instructions );
+    }
+
+
+   public static void println( String messageIn )
+    {
+      dialog.displayMessage( messageIn );
+    }
+
+ }// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog implements ActionListener
+ {
+
+   TextArea instructionsText;
+   TextArea messageText;
+   int maxStringLength = 80;
+   Panel  buttonP = new Panel();
+   Button passB = new Button( "pass" );
+   Button failB = new Button( "fail" );
+
+   //DO NOT call this directly, go through Sysout
+   public TestDialog( Frame frame, String name )
+    {
+      super( frame, name );
+      int scrollBoth = TextArea.SCROLLBARS_BOTH;
+      instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+      add( "North", instructionsText );
+
+      messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+      add("Center", messageText);
+
+      passB = new Button( "pass" );
+      passB.setActionCommand( "pass" );
+      passB.addActionListener( this );
+      buttonP.add( "East", passB );
+
+      failB = new Button( "fail" );
+      failB.setActionCommand( "fail" );
+      failB.addActionListener( this );
+      buttonP.add( "West", failB );
+
+      add( "South", buttonP );
+      pack();
+
+      show();
+    }// TestDialog()
+
+   //DO NOT call this directly, go through Sysout
+   public void printInstructions( String[] instructions )
+    {
+      //Clear out any current instructions
+      instructionsText.setText( "" );
+
+      //Go down array of instruction strings
+
+      String printStr, remainingStr;
+      for( int i=0; i < instructions.length; i++ )
+       {
+         //chop up each into pieces maxSringLength long
+         remainingStr = instructions[ i ];
+         while( remainingStr.length() > 0 )
+          {
+            //if longer than max then chop off first max chars to print
+            if( remainingStr.length() >= maxStringLength )
+             {
+               //Try to chop on a word boundary
+               int posOfSpace = remainingStr.
+                  lastIndexOf( ' ', maxStringLength - 1 );
+
+               if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+               printStr = remainingStr.substring( 0, posOfSpace + 1 );
+               remainingStr = remainingStr.substring( posOfSpace + 1 );
+             }
+            //else just print
+            else
+             {
+               printStr = remainingStr;
+               remainingStr = "";
+             }
+
+            instructionsText.append( printStr + "\n" );
+
+          }// while
+
+       }// for
+
+    }//printInstructions()
+
+   //DO NOT call this directly, go through Sysout
+   public void displayMessage( String messageIn )
+    {
+      messageText.append( messageIn + "\n" );
+    }
+
+   //catch presses of the passed and failed buttons.
+   //simply call the standard pass() or fail() static methods of
+   //DialogOrient
+   public void actionPerformed( ActionEvent e )
+    {
+      if( e.getActionCommand() == "pass" )
+       {
+         Test5032020.pass();
+       }
+      else
+       {
+         Test5032020.fail();
+       }
+    }
+
+ }// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Mixers/DisabledAssertionCrash.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+
+/**
+ * @test
+ * @bug 4991672
+ * @summary disabled assertion at maximum thread priority causes audio crash
+ * @run main/timeout=600 DisabledAssertionCrash
+ */
+public class DisabledAssertionCrash {
+    private static final int bufferSize = 1024;
+
+    public static void main(String[] args) {
+
+        System.out.println("This program hangs if priority is set,");
+        System.out.println("and assertion is in the code.");
+        System.out.println("The program crashes the entire Windows system");
+        System.out.println("if assertions are disabled.");
+        try {
+            Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
+            AudioFormat audioFormat = new AudioFormat(44100,16,1,true,true);
+            Line.Info sourceDataLineInfo = new DataLine.Info(SourceDataLine.class,audioFormat);
+            SourceDataLine sourceDataLine =
+            (SourceDataLine) AudioSystem.getLine(sourceDataLineInfo);
+            System.out.println("SourceDataLine: "+sourceDataLine);
+            sourceDataLine.open(audioFormat, bufferSize);
+            sourceDataLine.start();
+            Line.Info targetDataLineInfo =
+            new DataLine.Info(TargetDataLine.class,audioFormat);
+            TargetDataLine targetDataLine =
+            (TargetDataLine) AudioSystem.getLine(targetDataLineInfo);
+            System.out.println("TargetDataLine: "+targetDataLine);
+            targetDataLine.open(audioFormat, bufferSize);
+            targetDataLine.start();
+            byte[] data = new byte[bufferSize];
+
+            // execute for 20 seconds
+            float bufferTime = (((float) data.length) / audioFormat.getFrameSize()) / audioFormat.getFrameRate();
+            int count = (int) (20.0f / bufferTime);
+            System.out.println("Buffer time: "+(bufferTime * 1000)+" millis. "+count+" iterations.");
+            for (int i = 0; i < count; i++) {
+                int cnt = targetDataLine.read(data,0,data.length);
+                sourceDataLine.write(data,0,cnt);
+                assert cnt == data.length;
+            }
+            System.out.println("Successfully recorded/played "+count+" buffers. Passed");
+        } catch(LineUnavailableException lue) {
+            System.out.println("Audio hardware is not available!");
+            lue.printStackTrace();
+            System.out.println("Cannot execute test. NOT failed.");
+        } catch(IllegalArgumentException iae) {
+            System.out.println("No audio hardware is installed!");
+            iae.printStackTrace();
+            System.out.println("Test system not correctly setup.");
+            System.out.println("Cannot execute test. NOT failed.");
+        } catch(Exception e) {
+            System.out.println("Unexpected Exception: "+e);
+            e.printStackTrace();
+            System.out.println("Cannot execute test. NOT failed.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Mixers/NoSimpleInputDevice.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4936397
+ * @summary Verify that there'll be either SimpleInputDevice OR DirectAudioDevice
+ */
+public class NoSimpleInputDevice {
+
+    public static void main(String[] args) throws Exception {
+        out("4936397: Verify that there'll be either SimpleInputDevice OR DirectAudioDevice");
+        boolean foundSimpleInputDevice = false;
+        boolean foundDirectAudioDevice = false;
+
+        Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
+        for (int i = 0; i < aInfos.length; i++) {
+            try {
+                Mixer mixer = AudioSystem.getMixer(aInfos[i]);
+                String mixerClass = mixer.getClass().toString();
+                if (mixerClass.indexOf("SimpleInputDevice") >= 0) {
+                    out("Found SimpleInputDevice: "+aInfos[i]);
+                    foundSimpleInputDevice = true;
+                }
+                if (mixerClass.indexOf("DirectAudioDevice") >= 0) {
+                    out("Found DirectAudioDevice: "+aInfos[i]);
+                    foundDirectAudioDevice = true;
+                }
+            } catch (Exception e) {
+                out("Unexpected exception: "+e);
+            }
+        }
+        if (aInfos.length == 0) {
+            out("[No mixers available] - cannot exercise this test.");
+        } else {
+            if (foundSimpleInputDevice && foundDirectAudioDevice) {
+                out("Found both types of capture devices!");
+                throw new Exception("Test FAILED!");
+            }
+            out("Did not find both types of capture devices. Test passed");
+        }
+    }
+
+    static void out(String s) {
+        System.out.println(s); System.out.flush();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Mixers/PhantomMixers.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+
+/**
+ * @test
+ * @bug 4794104
+ * @summary mixers are always present, independent of available soundcards
+ * @run main/manual PhantomMixers
+ */
+public class PhantomMixers {
+
+    public static void main(String args[]) throws Exception {
+        int SDLformats = 0;
+        int TDLformats = 0;
+        Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
+        for(int i=0; i<mixerInfo.length; i++){
+            Mixer.Info thisMixerInfo = mixerInfo[i];
+            System.out.println("Mixer #"+i+": "
+                               + thisMixerInfo.getName()
+                               + ": " + thisMixerInfo.getDescription());
+            Mixer mixer = AudioSystem.getMixer(thisMixerInfo);
+            Line.Info[] srcLineInfo = mixer.getSourceLineInfo();
+            Line.Info[] dstLineInfo = mixer.getTargetLineInfo();
+            int count = srcLineInfo.length + dstLineInfo.length;
+            System.out.print(" -> " + (srcLineInfo.length + dstLineInfo.length) + " line");
+            switch (count) {
+                case 0: System.out.println("s"); break;
+                case 1: System.out.println(""); break;
+                default: System.out.println("s:"); break;
+            }
+            int l;
+            for (l = 0; l < srcLineInfo.length; l++) {
+                System.out.println("    "+srcLineInfo[l].toString());
+                if (srcLineInfo[l].getLineClass() == SourceDataLine.class
+                    && (srcLineInfo[l] instanceof DataLine.Info)) {
+                    SDLformats += ((DataLine.Info) srcLineInfo[l]).getFormats().length;
+                }
+            }
+            for (l = 0; l < dstLineInfo.length; l++) {
+                System.out.println("    "+dstLineInfo[l].toString());
+                if (dstLineInfo[l].getLineClass() == TargetDataLine.class
+                    && (dstLineInfo[l] instanceof DataLine.Info)) {
+                    TDLformats += ((DataLine.Info) dstLineInfo[l]).getFormats().length;
+                }
+            }
+        }
+        if (mixerInfo.length == 0) {
+            System.out.println("[no mixers present]");
+        }
+        System.out.println(""+SDLformats+" total formats for SourceDataLines");
+        System.out.println(""+TDLformats+" total formats for TargetDataLines");
+        System.out.println("");
+        System.out.println("If there are audio devices correctly installed on your");
+        System.out.println("system, you should see at least one Mixer, and in total");
+        System.out.println("at least each one SourceDataLine and TargetDataLine, both");
+        System.out.println("providing at least one format.");
+        System.out.println("");
+        System.out.println("Now disable your soundcard and repeat the test.");
+        System.out.println("The corresponding mixer(s) should not provide any formats");
+        System.out.println("anymore. If you disable all available soundcards");
+        System.out.println("on your computer, the number of formats above should be");
+        System.out.println("0 for both line types (although mixers are allowed to exist).");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Mixers/PlugHwMonoAnd8bitAvailable.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 5013897
+ * @summary Verify that plughw: provides mono and 8-bit lines
+ */
+public class PlugHwMonoAnd8bitAvailable {
+    static int failed = 0;
+    static int testedFormats = 0;
+
+    public static void main(String[] args) throws Exception {
+        out("5013897: Verify that plughw: provides mono and 8-bit lines");
+
+        Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
+        for (int i = 0; i < aInfos.length; i++) {
+            try {
+                Mixer mixer = AudioSystem.getMixer(aInfos[i]);
+                out("Mixer "+aInfos[i]);
+                if (aInfos[i].getName().contains("plughw")) {
+                    checkLines(mixer, mixer.getSourceLineInfo());
+                    checkLines(mixer, mixer.getTargetLineInfo());
+                } else {
+                    out("  -> not plughw, ignored.");
+                }
+            } catch (Exception e) {
+                out("Unexpected exception when getting a mixer: "+e);
+            }
+        }
+        if (testedFormats == 0) {
+            out("[No appropriate lines available] - cannot exercise this test.");
+        } else {
+            if (failed>0) {
+                throw new Exception("Test FAILED!");
+            }
+            out("Successfully verified "+testedFormats+" formats.");
+            out("Test passed");
+        }
+    }
+
+    public static void checkLines(Mixer mixer, Line.Info[] infos) {
+        for (int i = 0; i<infos.length; i++) {
+                try {
+                        System.out.println(" Line "+infos[i]+" (max. "+mixer.getMaxLines(infos[i])+" simultaneously): ");
+                        if (infos[i] instanceof DataLine.Info) {
+                                DataLine.Info info = (DataLine.Info) infos[i];
+                                int thisTestedFormats = testedFormats;
+                                int thisFailed = failed;
+                                AudioFormat[] formats = info.getFormats();
+                                for (int f = 0; f < formats.length; f++) {
+                                        if (formats[f].getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED)
+                                        || formats[f].getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED)) {
+                                                try {
+                                                        if (formats[f].getSampleSizeInBits() > 16) {
+                                                                // if a bit size larger than 16 is available, also 16-bit must be there
+                                                                checkFormat(formats, getOtherBits(formats[f], 16));
+                                                        } else
+                                                        if (formats[f].getSampleSizeInBits() > 8) {
+                                                                // if a bit size larger than 8 is available, also 8-bit must be there
+                                                                checkFormat(formats, getOtherBits(formats[f], 8));
+                                                        }
+                                                        if (formats[f].getChannels() > 2) {
+                                                                // if more than 2 channels, also 2 channels must be there
+                                                                checkFormat(formats, getOtherChannels(formats[f], 2));
+                                                        } else
+                                                        if (formats[f].getChannels() > 1) {
+                                                                // if more than 1 channel, also 1 channel must be there
+                                                                checkFormat(formats, getOtherChannels(formats[f], 1));
+                                                        }
+                                                } catch (Exception e1) {
+                                                        out("  Unexpected exception when getting a format: "+e1);
+                                                }
+                                        }
+                                }
+                                if (testedFormats - thisTestedFormats == 0) {
+                                        out(" -->could not test any formats");
+                                } else if (failed - thisFailed == 0) {
+                                        out(" -->"+(testedFormats - thisTestedFormats)+" formats tested OK");
+                                }
+
+                        } else {
+                                out("  --> not a DataLine");
+                        }
+                } catch (Exception e) {
+                        out(" Unexpected exception when getting a line: "+e);
+                }
+        }
+    }
+
+    public static void checkFormat(AudioFormat[] formats, AudioFormat format) {
+        testedFormats++;
+        for (int i = 0; i < formats.length; i++) {
+            if (formats[i].matches(format)) {
+                return;
+            }
+        }
+        out("  ## expected this format: "+format
+            +" ("+format.getChannels()+" channels, "
+            +"frameSize="+format.getFrameSize()+", "
+            +(format.isBigEndian()?"big endian":"little endian")
+            +")");
+        failed++;
+    }
+
+    // only works for PCM encodings
+    public static AudioFormat getOtherBits(AudioFormat format, int newBits) {
+        boolean isSigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED);
+        return new AudioFormat(format.getSampleRate(),
+                               newBits,
+                               format.getChannels(),
+                               isSigned,
+                               (newBits>8)?format.isBigEndian():false);
+    }
+
+    // only works for PCM encodings
+    public static AudioFormat getOtherChannels(AudioFormat format, int newChannels) {
+        int newFrameSize;
+        if (newChannels <= 0 || format.getChannels() <= 0 || format.getFrameSize() <= 0) {
+            newFrameSize = -1;
+        } else {
+            newFrameSize = format.getFrameSize() / format.getChannels() * newChannels;
+        }
+        return new AudioFormat(format.getEncoding(),
+                               format.getSampleRate(),
+                               format.getSampleSizeInBits(),
+                               newChannels,
+                               newFrameSize,
+                               format.getFrameRate(),
+                               format.isBigEndian());
+    }
+
+
+    static void out(String s) {
+        System.out.println(s); System.out.flush();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Mixers/UnexpectedIAE.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2004, 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.
+ */
+
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+
+/**
+ * @test
+ * @bug 4964288
+ * @summary Unexpected IAE raised while getting TargetDataLine
+ */
+public class UnexpectedIAE {
+
+    public static void main(String argv[]) throws Exception {
+        boolean success = true;
+
+        Mixer.Info [] infos = AudioSystem.getMixerInfo();
+
+        for (int i=0; i<infos.length; i++) {
+            Mixer mixer = AudioSystem.getMixer(infos[i]);
+            System.out.println("Mixer is: " + mixer);
+            Line.Info [] target_line_infos = mixer.getTargetLineInfo();
+            for (int j = 0; j < target_line_infos.length; j++) {
+                try {
+                    System.out.println("Trying to get:" + target_line_infos[j]);
+                    mixer.getLine(target_line_infos[j]);
+                } catch (IllegalArgumentException iae) {
+                    System.out.println("Unexpected IllegalArgumentException raised:");
+                    iae.printStackTrace();
+                    success = false;
+                } catch (LineUnavailableException lue) {
+                    System.out.println("Unexpected LineUnavailableException raised:");
+                    lue.printStackTrace();
+                    success = false;
+                }
+            }
+        }
+        if (success) {
+            System.out.println("Test passed");
+        } else {
+            throw new Exception("Test FAILED");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/Recording/TargetDataLineFlush.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.TargetDataLine;
+
+/**
+ * @test
+ * @bug 4836433
+ * @summary Windows: TargetDataLine.flush() does not work. Since this test has
+ *          some real-time variance, I disabled it by making it a manual test.
+ * @run main/manual TargetDataLineFlush
+ */
+public class TargetDataLineFlush {
+    TargetDataLine inLine;
+    int SAMPLE_RATE = 11025;
+    int BUFFER_MILLIS = 1000;
+    int WAIT_MILLIS;
+    int BITS = 16;
+    int CHANNELS = 2;
+    int bufferSize;
+    AudioFormat format;
+    Mixer.Info[] mixers;
+    static boolean failed = false;
+
+    public TargetDataLineFlush() {
+        mixers = AudioSystem.getMixerInfo();
+    }
+
+    private void init() {
+        // float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian
+        format = new AudioFormat( (float) SAMPLE_RATE, BITS, CHANNELS, true, false);
+        bufferSize = SAMPLE_RATE * BUFFER_MILLIS / 1000 * format.getFrameSize();
+    }
+
+    boolean openInputLine(int num)  throws LineUnavailableException {
+        init();
+        DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); // format is an AudioFormat object
+        // Obtain and open a outLine.
+        if (num < 0) {
+            if (!AudioSystem.isLineSupported(info)) {
+                System.out.println("TargetDataLine is not supported by default mixer.");
+                return false;
+            }
+            inLine = (TargetDataLine) AudioSystem.getLine(info);
+        } else {
+            Mixer mixer = AudioSystem.getMixer(mixers[num]);
+            if (!mixer.isLineSupported(info)) {
+                System.out.println("TargetDataLine is not supported by this mixer.");
+                return false;
+            }
+            inLine = (TargetDataLine) mixer.getLine(info);
+        }
+        inLine.open(format, bufferSize);
+        /*if (Math.abs(inLine.getBufferSize() - bufferSize) > 100) {
+                inLine.close();
+                System.out.println("TargetDataLine does not support buffer size of "+bufferSize+" bytes!");
+                return false;
+        }*/
+        bufferSize = inLine.getBufferSize();
+        /* 3/4 of buffer size ot wait */
+        WAIT_MILLIS = (int) (bufferSize / format.getFrameSize() * 750 / format.getFrameRate());
+        System.out.println("Buffer size: "+bufferSize+" bytes = "
+            +((int) (bufferSize / format.getFrameSize() * 750 / format.getFrameRate()))+" millis");
+        return true;
+    }
+
+    private String available() {
+        int avail = inLine.available();
+        int availMillis = (int) (avail / format.getFrameSize() * 1000 / format.getFrameRate());
+        return "available "+avail+" bytes = "+availMillis+" millis";
+    }
+
+    private boolean recordSound(int num)  throws LineUnavailableException {
+        if (!openInputLine(num)) {
+            return false;
+        }
+        byte data[] = new byte[1000];
+        try {
+            System.out.println("Got line: "+inLine);
+            System.out.println("Start recording" );
+            inLine.start();
+            System.out.print("Warm-up...");
+            //System.out.print("Waiting 500 millis...");
+            try { Thread.sleep(500); } catch (InterruptedException ie) {}
+            //System.out.println("done. "+available());
+            //System.out.print("Reading all data...");
+            int avail0 = inLine.available();
+            if (avail0 == 0) {
+                System.out.println("Problem: TargetDataLine did not deliver any data!");
+                System.out.println("Not a test failure, but serious failure nonetheless.");
+            } else {
+                while ((avail0 -= inLine.read(data, 0, Math.min(data.length, avail0))) > 0);
+                System.out.println("done.  "+available());
+                System.out.print("Waiting "+(WAIT_MILLIS)+" millis...");
+                try { Thread.sleep(WAIT_MILLIS); } catch (InterruptedException ie) {}
+                int avail1 = inLine.available();
+                System.out.println("done. "+available());
+
+                System.out.print("Flushing...");
+                inLine.flush();
+                System.out.println("done.            "+available());
+                System.out.print("Waiting "+(WAIT_MILLIS)+" millis...");
+                try { Thread.sleep(WAIT_MILLIS); } catch (InterruptedException ie) {}
+                int avail2 = inLine.available();
+                System.out.println("done.  "+available());
+                if (avail2 > avail1) {
+                    failed = true;
+                    System.out.println("Failed: Flushing with native flush() should "
+                                       +"result in fewer bytes available.");
+                }
+                if (avail2 == 0) {
+                    failed = true;
+                    System.out.println("Failed: Recording after flush() did not work at all!");
+                }
+            }
+        } finally {
+            System.out.print("Closing line....");
+            inLine.close();
+            System.out.println("done");
+        }
+        return true;
+    }
+
+    public void runTests(int testRuns) {
+        if (mixers.length > 0) {
+            for (int num = -1; num < mixers.length; num++) {
+                try {
+                    if (num<0) {
+                        System.out.println("------Using default line...." );
+                    } else {
+                        System.out.println("------Using line "+num+" from mixer "+mixers[num]+"...");
+                    }
+                    for (int testRun = 0; testRun < testRuns; testRun++) {
+                        if (testRuns>1) {
+                            System.out.println("--Run "+(testRun+1)+"/"+testRuns+":");
+                        }
+                        if (!recordSound(num)) {
+                            break;
+                        }
+                    }
+                } catch (Exception ex) {
+                    System.out.println("Caught " + ex );
+                }
+                System.out.println("------------------------------------------------------");
+                if (failed) {
+                    break;
+                }
+            }
+        } else {
+            System.out.println("No mixers present. Cannot execute this test.");
+        }
+    }
+
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("Test TargetDataLineFlush");
+        System.out.println("This verifies that TargetDataLine.flush() actually");
+        System.out.println("flushes the native buffers. This is done by");
+        System.out.println("comparing a manual flush (i.e. just discarding");
+        System.out.println("everything that is currently available in the TargetDataLine)");
+        System.out.println("to a flushed line");
+        TargetDataLineFlush app = new TargetDataLineFlush();
+        int testRuns = 1;
+        if (args.length > 0) {
+            try {
+                testRuns = Integer.parseInt(args[0]);
+            } catch (NumberFormatException nfe) {
+                System.out.println("Usage: java TargetDataLineFlush [number of runs]");
+                System.out.println("Parameters ignored.");
+            }
+        }
+        app.runTests(testRuns);
+        if (failed) {
+            throw new Exception("Test FAILED");
+        }
+        // test always passes if it gets here
+        System.out.println("Test PASSED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/spi/AudioFileReader/AIFFCp037.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4369044
+ * @summary javax.sound.sampled.AudioSystem.getAudioInputStream() works wrong
+ *          with Cp037
+ */
+public class AIFFCp037 {
+
+    public static void main(String args[]) throws Exception {
+        System.setProperty("file.encoding", "Cp037");
+        // try to read this file with Cp037 encoding
+        AudioSystem.getAudioInputStream(new ByteArrayInputStream(SHORT_AIFF));
+        System.out.println("  test passed.");
+    }
+
+    public static String getString(byte b) {
+        //String res = Integer.toHexString(b & 0xFF).toUpperCase();
+        //while (res.length()<2) res="0"+res;
+        //return res;
+        return String.valueOf(b);
+    }
+
+
+    public static void printFile(String filename) throws Exception {
+        File file = new File(filename);
+        FileInputStream fis = new FileInputStream(file);
+        byte[] data = new byte[(int) file.length()];
+        fis.read(data);
+        String s = "";
+        for (int i=0; i<data.length; i++) {
+            s+=getString(data[i])+", ";
+            if (s.length()>72) {
+                System.out.println(s);
+                s="";
+            }
+        }
+        System.out.println(s);
+    }
+
+    public static byte[] SHORT_AIFF = {
+        70, 79, 82, 77, 0, 0, 4, -54, 65, 73, 70, 70, 67, 79, 77, 77, 0, 0, 0, 18,
+        0, 1, 0, 0, 2, 78, 0, 16, 64, 12, -84, 68, 0, 0, 0, 0, 0, 0, 83, 83, 78,
+        68, 0, 0, 4, -92, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -2, 0, -2, 0, 0, 0, 0, 0,
+        -3, 0, -5, 0, -2, 0, 3, 0, 1, 0, -3, 0, -5, 0, -6, 0, -6, 0, -5, 0, -2, 0,
+        -2, 0, -5, 0, -6, 0, -3, 0, 0, 0, 0, 0, -3, 0, -5, 0, -6, 0, -8, 0, -5, 0,
+        1, 0, 4, 0, 1, 0, -5, 0, -8, 0, -3, 0, 3, 0, 4, 0, 0, 0, -8, 0, -11, 0, -8,
+        0, -3, 0, 0, 0, 0, 0, 1, 0, 0, 0, -5, 0, -9, 0, -8, 0, 0, 0, 6, 0, 7, 0,
+        0, 0, -8, 0, -11, 0, -8, 0, 0, 0, 4, 0, 6, 0, 3, 0, -2, 0, -5, 0, -5, 0,
+        0, 0, 6, 0, 6, 0, 1, 0, -5, 0, -3, 0, 1, 0, 6, 0, 6, 0, 1, 0, -3, 0, -3,
+        0, 0, 0, 3, 0, 3, 0, 0, 0, -3, 0, -2, 0, 3, 0, 6, 0, 4, 0, 0, 0, -2, 0, -2,
+        0, 1, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -3, 0, 1, 0, 6,
+        0, 6, 0, 1, 0, 0, 0, 1, 0, 0, 0, -2, 0, -2, 0, 3, 0, 4, 0, 0, 0, -5, 0, -3,
+        0, 1, 0, 4, 0, 4, 0, 0, 0, -2, 0, 1, 0, 1, 0, -2, 0, -6, 0, -6, 0, -2, 0,
+        6, 0, 7, 0, 4, 0, 0, 0, -5, 0, -6, 0, -5, 0, 0, 0, 4, 0, 4, 0, 0, 0, -5,
+        0, -8, 0, -8, 0, -5, 0, 1, 0, 3, 0, 1, 0, -3, 0, -6, 0, -6, 0, -5, 0, -5,
+        0, -3, 0, 1, 0, 3, 0, 1, 0, -2, 0, -5, 0, -5, 0, -5, 0, -3, 0, 3, 0, 6, 0,
+        6, 0, 0, 0, -3, 0, -3, 0, 0, 0, 1, 0, 0, 0, 3, 0, 4, 0, 0, 0, -3, 0, -5,
+        0, -2, 0, 1, 0, -2, 0, -2, 0, 1, 0, 4, 0, 1, 0, -3, 0, -2, 0, 0, 0, 0, 0,
+        -3, 0, -6, 0, -5, 0, 0, 0, 3, 0, 0, 0, -3, 0, -5, 0, -5, 0, -2, 0, -2, 0,
+        -5, 0, -6, 0, -3, 0, 1, 0, 1, 0, -2, 0, -8, 0, -8, 0, -3, 0, 1, 0, 3, 0,
+        1, 0, -5, 0, -8, 0, -6, 0, -2, 0, 3, 0, 4, 0, -2, 0, -5, 0, -6, 0, -3, 0,
+        -2, 0, -2, 0, -2, 0, -2, 0, -3, 0, -5, 0, -6, 0, -5, 0, -2, 0, 0, 0, 0, 0,
+        -2, 0, -3, 0, -5, 0, -5, 0, -3, 0, -3, 0, -2, 0, -2, 0, 0, 0, 1, 0, 1, 0,
+        0, 0, 1, 0, 1, 0, -2, 0, -5, 0, -3, 0, 1, 0, 4, 0, 6, 0, 4, 0, 1, 0, 0, 0,
+        0, 0, 3, 0, 4, 0, 1, 0, -3, 0, -3, 0, 1, 0, 6, 0, 4, 0, 1, 0, -3, 0, -5,
+        0, -2, 0, 3, 0, 6, 0, 7, 0, 1, 0, -5, 0, -5, 0, 1, 0, 7, 0, 6, 0, 3, 0, 1,
+        0, -2, 0, -5, 0, -5, 0, -2, 0, 3, 0, 3, 0, 3, 0, 0, 0, -3, 0, -5, 0, -3,
+        0, 0, 0, 6, 0, 9, 0, 4, 0, -2, 0, -6, 0, -5, 0, -2, 0, 3, 0, 4, 0, 3, 0,
+        -2, 0, -6, 0, -3, 0, 1, 0, 3, 0, -3, 0, -6, 0, 0, 0, 4, 0, 1, 0, -6, 0, -9,
+        0, -5, 0, 1, 0, 1, 0, 0, 0, -2, 0, -3, 0, -5, 0, -6, 0, -5, 0, 0, 0, 3, 0,
+        3, 0, -2, 0, -6, 0, -6, 0, -3, 0, -2, 0, -2, 0, -5, 0, -6, 0, -5, 0, -2,
+        0, 0, 0, -2, 0, -3, 0, -3, 0, -3, 0, -2, 0, 0, 0, 1, 0, 0, 0, -2, 0, -2,
+        0, -3, 0, -5, 0, -5, 0, -2, 0, 0, 0, 3, 0, 3, 0, 0, 0, -3, 0, -3, 0, 0, 0,
+        -2, 0, -5, 0, -3, 0, 0, 0, 1, 0, -3, 0, -8, 0, -6, 0, -2, 0, -2, 0, -6, 0,
+        -6, 0, -5, 0, -3, 0, -3, 0, -6, 0, -6, 0, -3, 0, -3, 0, -3, 0, -3, 0, 0,
+        0, 1, 0, -3, 0, -6, 0, -3, 0, 1, 0, 0, 0, -6, 0, -9, 0, -9, 0, -6, 0, -2,
+        0, 1, 0, 3, 0, -3, 0, -5, 0, -3, 0, -2, 0, -3, 0, -6, 0, -5, 0, -2, 0, -2,
+        0, -5, 0, -5, 0, -2, 0, -2, 0, -5, 0, -6, 0, -6, 0, -2, 0, -2, 0, -2, 0,
+        -3, 0, -5, 0, -5, 0, -3, 0, 1, 0, 0, 0, 1, 0, 1, 0, 3, 0, 6, 0, 6, 0, 3,
+        0, -6, 0, -12, 0, -8, 0, 1, 0, 9, 0, 7, 0, 1, 0, -3, 0, 0, 0, 3, 0, 0, 0,
+        0, 0, 3, 0, 6, 0, 7, 0, 3, 0, -3, 0, -5, 0, 0, 0, 4, 0, 4, 0, 3, 0, 1, 0,
+        3, 0, 3, 0, 0, 0, -2, 0, 0, 0, 1, 0, 1, 0, 1, 0, 3, 0, 3, 0, 1, 0, 0, 0,
+        0, 0, 3, 0, 1, 0, -2, 0, -2, 0, 1, 0, 1, 0, -3, 0, -3, 0, 0, 0, 4, 0, 6,
+        0, 6, 0, 3, 0, -3, 0, -8, 0, -5, 0, 1, 0, 3, 0, 1, 0, 1, 0, 0, 0, -3, 0,
+        -6, 0, -5, 0, 1, 0, 3, 0, -2, 0, -3, 0, 0, 0, 1, 0, 1, 0, -3, 0, -5, 0, -2,
+        0, -2, 0, -2, 0, 0, 0, 1, 0, 1, 0, -2, 0, -5, 0, -8, 0, -6, 0, -5, 0, -2,
+        0, 1, 0, 0, 0, -5, 0, -6, 0, 0, 0, 4, 0, 1, 0, -5, 0, -5, 0, -3, 0, -2, 0,
+        -3, 0, -3, 0, 0, 0, 0, 0, -2, 0, -3, 0, -2, 0, 1, 0, -2, 0, -5, 0, -3, 0,
+        0, 0, 3, 0, 0, 0, -3, 0, -3, 0, -3, 0, -3, 0, -3, 0, 0, 0, 3, 0, 4, 0, -2,
+        0, -8, 0, -8, 0, -5, 0, 3, 0, 3, 0, -2, 0, -6, 0, -8, 0, -3, 0, 1, 0, 0,
+        0, -5, 0, -5, 0, -2, 0, -2, 0, -3, 0, -5, 0, -3, 0, 0, 0, 0, 0, -2, 0, -5,
+        0, -6, 0, -5, 0, -3, 0, 0, 0, 0, 0, -3, 0, -3, 0, -5, 0, -5, 0, -6, 0, -6,
+        0, -6, 0, -5, 0, 0, 0, 1, 0, 0, 0, -5, 0, -6, 0, -5, 0, -2, 0, -2, 0, -3,
+        0, -5, 0, -8, 0, -9, 0, -6, 0, -2, 0, 0, 0, -2, 0, -5, 0, -5, 0, -2, 0, 3,
+        0, 4, 0, 0, 0, -2, 0, -2, 0, 1, 0, 1, 0, 1, 0, 3, 0
+    };
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/spi/AudioFileReader/AIFFLargeHeader.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4399551
+ * @summary Repost of bug candidate: cannot replay aif file. AIFF headers were
+ *          checked for certain size also tests that ulaw encoded AIFC files can
+ *          be read.
+ */
+public class AIFFLargeHeader {
+
+    public static void main(String args[]) throws Exception {
+        System.out.println();
+        System.out.println();
+        System.out.println("4399551: Repost of bug candidate: cannot replay aif file (Review ID: 108108)");
+        // try to read this file
+        AudioSystem.getAudioInputStream(new ByteArrayInputStream(SHORT_AIFC_ULAW));
+        System.out.println("  test passed.");
+    }
+
+    public static String getString(byte b) {
+        //String res = Integer.toHexString(b & 0xFF).toUpperCase();
+        //while (res.length()<2) res="0"+res;
+        //return res;
+        return String.valueOf(b);
+    }
+
+
+    public static void printFile(String filename) throws Exception {
+        File file = new File(filename);
+        FileInputStream fis = new FileInputStream(file);
+        byte[] data = new byte[(int) file.length()];
+        fis.read(data);
+        String s = "";
+        for (int i=0; i<data.length; i++) {
+            s+=getString(data[i])+", ";
+            if (s.length()>72) {
+                System.out.println(s);
+                s="";
+            }
+        }
+        System.out.println(s);
+    }
+
+    public static byte[] SHORT_AIFC_ULAW = {
+        70, 79, 82, 77, 0, 0, 2, 50, 65, 73, 70, 67, 70, 86, 69, 82, 0, 0, 0, 4,
+        -94, -128, 81, 64, 67, 79, 77, 77, 0, 0, 0, 30, 0, 1, 0, 1, 118, -9, 0, 16,
+        64, 12, -84, 68, 0, 0, 0, 0, 0, 0, 117, 108, 97, 119, 7, 117, 110, 107, 110,
+        111, 119, 110, 83, 83, 78, 68, 0, 0, 1, -13, 0, 0, 0, 0, 0, 0, 0, 0, 103,
+        103, 103, -1, -1, 91, 77, 103, -45, -25, 91, 77, 73, 73, 77, 103, 103, 77,
+        73, 91, -1, -1, 91, 77, 73, 65, 77, -25, -51, -25, 77, 65, 91, -45, -51,
+        -1, 65, 58, 65, 91, -1, -1, -25, -1, 77, 62, 65, -1, -59, -63, -1, 65, 58,
+        65, -1, -51, -59, -45, 103, 77, 77, -1, -59, -59, -25, 77, 91, -25, -59,
+        -59, -25, 91, 91, -1, -45, -45, -1, 91, 103, -45, -59, -51, -1, 103, 103,
+        -25, -25, -45, -45, -1, -1, -1, -1, 103, 91, -25, -59, -59, -25, -1, -25,
+        -1, 103, 103, -45, -51, -1, 77, 91, -25, -51, -51, -1, 103, -25, -25, 103,
+        73, 73, 103, -59, -63, -51, -1, 77, 73, 77, -1, -51, -51, -1, 77, 65, 65,
+        77, -25, -45, -25, 91, 73, 73, 77, 77, 91, -25, -45, -25, 103, 77, 77, 77,
+        91, -45, -59, -59, -1, 91, 91, -1, -25, -1, -45, -51, -1, 91, 77, 103, -25,
+        103, 103, -25, -51, -25, 91, 103, -1, -1, 91, 73, 77, -1, -45, -1, 91, 77,
+        77, 103, 103, 77, 73, 91, -25, -25, 103, 65, 65, 91, -25, -45, -25, 77, 65,
+        73, 103, -45, -51, 103, 77, 73, 91, 103, 103, 103, 103, 91, 77, 73, 77, 103,
+        -1, -1, 103, 91, 77, 77, 91, 91, 103, 103, -1, -25, -25, -1, -25, -25, 103,
+        77, 91, -25, -51, -59, -51, -25, -1, -1, -45, -51, -25, 91, 91, -25, -59,
+        -51, -25, 91, 77, 103, -45, -59, -63, -25, 77, 77, -25, -63, -59, -45, -25,
+        103, 77, 77, 103, -45, -45, -45, -1, 91, 77, 91, -1, -59, -68, -51, 103,
+        73, 77, 103, -45, -51, -45, 103, 73, 91, -25, -45, 91, 73, -1, -51, -25,
+        73, 62, 77, -25, -25, -1, 103, 91, 77, 73, 77, -1, -45, -45, 103, 73, 73,
+        91, 103, 103, 77, 73, 77, 103, -1, 103, 91, 91, 91, 103, -1, -25, -1, 103,
+        103, 91, 77, 77, 103, -1, -45, -45, -1, 91, 91, -1, 103, 77, 91, -1, -25,
+        91, 65, 73, 103, 103, 73, 73, 77, 91, 91, 73, 73, 91, 91, 91, 91, -1, -25,
+        91, 73, 91, -25, -1, 73, 62, 62, 73, 103, -25, -45, 91, 77, 91, 103, 91,
+        73, 77, 103, 103, 77, 77, 103, 103, 77, 73, 73, 103, 103, 103, 91, 77, 77,
+        91, -25, -1, -25, -25, -45, -59, -59, -45, 73, 56, 65, -25, -68, -63, -25,
+        91, -1, -45, -1, -1, -45, -59, -63, -1, 103, 103, -25, -25, 103, 91, -1,
+        -45, -51, -25, 103, 91, 91, 103, -25, -25, -25, 103, 73, 77, -1, -51, -45,
+        103, 91, 103, -25, -1, 91, 91, 91, -1, -45, -51, -25, 91, 77, 103, -1, -1,
+        91, -1, -1, -1, 103, 91, 91, 73, 77, 103, -25, -25, 103, 91, 103, 103, 103,
+        -1, -45, -1, 77, 77, -1
+    };
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/spi/AudioFileReader/Aiff12bit.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4895934
+ * @summary AudioInputStream.getFrameLength returns wrong value for 12-bit AIFF
+ *          file
+ */
+public class Aiff12bit {
+
+    public static void test(byte[] file) throws Exception {
+        InputStream inputStream = new ByteArrayInputStream(file);
+        AudioFileFormat aff = AudioSystem.getAudioFileFormat(inputStream);
+
+        if (aff.getFormat().getSampleSizeInBits() != 12) {
+            throw new Exception("Wrong sample size. test FAILED");
+        }
+        if (aff.getFormat().getFrameSize() != 2) {
+            throw new Exception("Wrong frame size. test FAILED");
+        }
+        if (aff.getFrameLength() != 100) {
+            throw new Exception("Wrong file length. test FAILED");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        test(AIFF_12BIT);
+
+        System.out.println("Test passed.");
+    }
+
+    public static byte[] AIFF_12BIT = {
+        70,   79,   82,   77,    0,    0,    0,  -10,   65,   73,   70,   70,   67,   79,   77,   77,
+        0,    0,    0,   18,    0,    1,    0,    0,    0,  100,    0,   12,   64,    8,   -6,    0,
+        0,    0,    0,    0,    0,    0,   83,   83,   78,   68,    0,    0,    0,  -48,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,   16,    0,   32,    0,   48,    0,   64,
+        0,   80,    0,   96,    0,  112,    0, -128,    0, -112,    0,  -96,    0,  -80,    0,  -64,
+        0,  -48,    0,  -32,    0,  -16,    1,    0,    1,   16,    1,   32,    1,   48,    1,   64,
+        1,   80,    1,   96,    1,  112,    1, -128,    1, -112,    1,  -96,    1,  -80,    1,  -64,
+        1,  -48,    1,  -32,    1,  -16,    2,    0,    2,   16,    2,   32,    2,   48,    2,   64,
+        2,   80,    2,   96,    2,  112,    2, -128,    2, -112,    2,  -96,    2,  -80,    2,  -64,
+        2,  -48,    2,  -32,    2,  -16,    3,    0,    3,   16,    3,   32,    3,   48,    3,   64,
+        3,   80,    3,   96,    3,  112,    3, -128,    3, -112,    3,  -96,    3,  -80,    3,  -64,
+        3,  -48,    3,  -32,    3,  -16,    4,    0,    4,   16,    4,   32,    4,   48,    4,   64,
+        4,   80,    4,   96,    4,  112,    4, -128,    4, -112,    4,  -96,    4,  -80,    4,  -64,
+        4,  -48,    4,  -32,    4,  -16,    5,    0,    5,   16,    5,   32,    5,   48,    5,   64,
+        5,   80,    5,   96,    5,  112,    5, -128,    5, -112,    5,  -96,    5,  -80,    5,  -64,
+        5,  -48,    5,  -32,    5,  -16,    6,    0,    6,   16,    6,   32,    6,   48,
+    };
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/spi/AudioFileReader/AuNotSpecified.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4940459
+ * @summary AudioInputStream.getFrameLength() returns 0 instead of NOT_SPECIFIED
+ */
+public class AuNotSpecified {
+    public static boolean failed = false;
+
+    public static void main(String[] params) throws Exception {
+
+        AudioInputStream is =
+            AudioSystem.getAudioInputStream(new
+                                            ByteArrayInputStream(new byte[] {
+                                                (byte)0x2E, (byte)0x73, (byte)0x6E, (byte)0x64, (byte)0x00,
+                                                (byte)0x00, (byte)0x00, (byte)0x18,
+                                                (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0x00,
+                                                (byte)0x00, (byte)0x00, (byte)0x03,
+                                                (byte)0x00, (byte)0x00, (byte)0x1F, (byte)0x40, (byte)0x00,
+                                                (byte)0x00, (byte)0x00, (byte)0x01,
+                                                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                                                (byte)0x00, (byte)0x00, (byte)0x00,
+                                            }));
+        if (is.getFrameLength() != AudioSystem.NOT_SPECIFIED) {
+            System.out.println("frame length should be NOT_SPECIFIED, but is: "+is.getFrameLength());
+            failed=true;
+        }
+        //assertTrue(is.getFrameLength() == AudioSystem.NOT_SPECIFIED);
+        //assertTrue(is.read(new byte[8]) == 8);
+        //assertTrue(is.read(new byte[2]) == -1);
+        if (failed) throw new Exception("Test FAILED!");
+        System.out.println("Test Passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/spi/AudioFileReader/AuZeroLength.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4629669
+ * @summary AU file reader: problems with empty files
+ */
+public class AuZeroLength {
+
+    public static String getString(byte b) {
+        //String res = Integer.toHexString(b & 0xFF).toUpperCase();
+        //while (res.length()<2) res="0"+res;
+        //return res;
+        return String.valueOf(b);
+    }
+
+
+    public static void printFile(String filename) throws Exception {
+        File file = new File(filename);
+        FileInputStream fis = new FileInputStream(file);
+        byte[] data = new byte[(int) file.length()];
+        fis.read(data);
+        String s = "";
+        for (int i=0; i<data.length; i++) {
+            s+=getString(data[i])+", ";
+            if (s.length()>72) {
+                System.out.println(s);
+                s="";
+            }
+        }
+        System.out.println(s);
+    }
+
+    public static void test(byte[] file) throws Exception {
+        InputStream inputStream = new ByteArrayInputStream(file);
+        AudioFileFormat aff = AudioSystem.getAudioFileFormat(inputStream);
+
+        if (aff.getFrameLength() != 0) {
+            throw new Exception("File length is "+aff.getFrameLength()+" instead of 0. test FAILED");
+        }
+        System.out.println(aff.getType()+" file length is 0.");
+    }
+
+    public static void main(String[] args) throws Exception {
+        test(ZERO_AU);
+        test(ZERO_WAV);
+        test(ZERO_AIFF);
+
+        System.out.println("Test passed.");
+    }
+
+    public static byte[] ZERO_AU = {
+        46, 115, 110, 100, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, -84, 68, 0,
+        0, 0, 1, 116, 101, 115, 116, 46, 119, 97, 118
+    };
+
+    public static byte[] ZERO_WAV = {
+        82, 73, 70, 70, 36, 0, 0, 0, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0, 0,
+        0, 1, 0, 1, 0, 68, -84, 0, 0, -120, 88, 1, 0, 2, 0, 16, 0, 100, 97, 116,
+        97, 0, 0, 0, 0
+    };
+
+    public static byte[] ZERO_AIFF = {
+        70, 79, 82, 77, 0, 0, 0, 46, 65, 73, 70, 70, 67, 79, 77, 77, 0, 0, 0, 18,
+        0, 1, 0, 0, 0, 0, 0, 16, 64, 14, -84, 68, 0, 0, 0, 0, 0, 0, 83, 83, 78, 68,
+        0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0
+    };
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/spi/AudioFileReader/OpenWaveFile.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4489272
+ * @summary AudioSystem.getAudioFileFormat() fails for InputStream, but works
+ *          for URL
+ */
+public class OpenWaveFile {
+
+    static void check(Object source) throws Exception {
+         AudioFileFormat aff2 = null;
+         if (source instanceof File) {
+            aff2 = AudioSystem.getAudioFileFormat((File) source);
+         }
+         else if (source instanceof InputStream) {
+            aff2 = AudioSystem.getAudioFileFormat((InputStream) source);
+         }
+         else if (source instanceof URL) {
+            aff2 = AudioSystem.getAudioFileFormat((URL) source);
+         } else throw new Exception("wrong source. Test FAILED");
+         System.out.println("Got: "+aff2);
+         if (aff2.getFormat().getSampleSizeInBits()==-1) {
+            throw new Exception("wrong audio format. Test FAILED");
+         }
+    }
+
+    public static void main(String args[]) throws Exception {
+         //check(new File(args[0]));
+         //check(new URL("file", "", args[0]));
+         check(new ByteArrayInputStream(SHORT_AU));
+         check(new ByteArrayInputStream(SHORT_WAVE));
+         check(new ByteArrayInputStream(SHORT_AIFF));
+         System.out.println("Test passed.");
+
+         //printFile(args[0]);
+     }
+
+    public static String getString(byte b) {
+        //String res = Integer.toHexString(b & 0xFF).toUpperCase();
+        //while (res.length()<2) res="0"+res;
+        //return res;
+        return String.valueOf(b);
+    }
+
+
+    public static void printFile(String filename) throws Exception {
+        File file = new File(filename);
+        FileInputStream fis = new FileInputStream(file);
+        byte[] data = new byte[(int) file.length()];
+        fis.read(data);
+        String s = "";
+        for (int i=0; i<data.length; i++) {
+            s+=getString(data[i])+", ";
+            if (s.length()>72) {
+                System.out.println(s);
+                s="";
+            }
+        }
+        System.out.println(s);
+    }
+
+    public static byte[] SHORT_WAVE = {
+        82, 73, 70, 70, -120, 0, 0, 0, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0,
+        0, 0, 1, 0, 1, 0, 34, 86, 0, 0, 34, 86, 0, 0, 1, 0, 8, 0, 100, 97, 116, 97,
+        100, 0, 0, 0, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+        -128, -128, -128, -128, -128, -128, -128, -128, -128, 127, 127, -128, 127,
+        127, 127, -128, -128, -128, -128, 127, 127, -128, -128, 127, -128, -128,
+        -128, 127, 127, 127, -128, -128, -128, 127, 127, 127, 127, -128, -128, -128,
+        -128, -128, -128, 127, 127, 127, -128, -128, -128, -128, -128, 127, -128,
+        -128, 127, -128, -128, 127, 127, -128, -128, 127, 127, -128, -128, -128,
+        -128, -128, 127, 127, -128, -128, -128, 127, 127, 127, -128, 127, -128, -128,
+        127, 127, 127, -128, -128, -128, 127, 127, -128, -128,
+    };
+
+    public static byte[] SHORT_AU = {
+        46, 115, 110, 100, 0, 0, 0, 24, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 86, 34, 0,
+        0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
+        0, -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, -1, 0, 0, 0, -1, -1, -1, 0, 0, 0,
+        -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, -1,
+        0, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, -1, -1, -1, 0,
+        -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1, 0, 0,
+    };
+
+    public static byte[] SHORT_AIFF = {
+        70, 79, 82, 77, 0, 0, 0, -110, 65, 73, 70, 70, 67, 79, 77, 77, 0, 0, 0, 18,
+        0, 1, 0, 0, 0, 100, 0, 8, 64, 13, -84, 68, 0, 0, 0, 0, 0, 0, 83, 83, 78,
+        68, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0,
+        -1, 0, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1,
+        -1, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, 0,
+        0, -1, -1, 0, 0, 0, -1, -1, -1, 0, -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1,
+        0, 0,
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/spi/AudioFileWriter/AUwithULAW.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4391108
+ * @summary Writing au files with ulaw encoding is broken
+ */
+public class AUwithULAW {
+    public static void main(String args[]) throws Exception {
+        System.out.println();
+        System.out.println();
+        System.out.println("4391108: Writing au files with ulaw encoding is broken");
+        byte[] fakedata=new byte[1234];
+        InputStream is = new ByteArrayInputStream(fakedata);
+        AudioFormat inFormat = new AudioFormat(AudioFormat.Encoding.ULAW, 8000, 8, 1, 1, 8000, false);
+
+        AudioInputStream ais = new AudioInputStream(is, inFormat, fakedata.length);
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream(1500);
+        System.out.println("  ulaw data will be written as AU to stream...");
+        int t = AudioSystem.write(ais, AudioFileFormat.Type.AU, out);
+        byte[] writtenData = out.toByteArray();
+        is = new ByteArrayInputStream(writtenData);
+        System.out.println("  Get AudioFileFormat of written file");
+        AudioFileFormat fileformat = AudioSystem.getAudioFileFormat(is);
+        AudioFileFormat.Type type = fileformat.getType();
+        System.out.println("  The file format type: "+type);
+        if (fileformat.getFrameLength()!=fakedata.length
+                && fileformat.getFrameLength()!=AudioSystem.NOT_SPECIFIED) {
+            throw new Exception("The written file's frame length is "+fileformat.getFrameLength()+" but should be "+fakedata.length+" !");
+        }
+        ais = AudioSystem.getAudioInputStream(is);
+        System.out.println("  Got Stream with format: "+ais.getFormat());
+        System.out.println("  test passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/spi/AudioFileWriter/AiffSampleRate.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4914639
+ * @summary JavaSound writes wrong sample rates to AIFF files
+ */
+public class AiffSampleRate {
+
+    private static final float[] testSampleRates =
+    {8000.0F, 8000.0F + 0.011F, 8193.975F, 10000.0F, 11025.0F, 12000.0F,
+     16000.0F, 22050.0F, 24000.0F, 32000.0F, 44100.0F - 1.22222F, 44100.0F,
+     47888.888F, 48000.0F, 96000.0F, 192000.0F};
+
+    public static void main(String[] args) throws Exception {
+        boolean isTestPassed = true;
+
+        out("#4914639: JavaSound writes wrong sample rates to AIFF files");
+        for (int i = 0; i < testSampleRates.length; i++) {
+            isTestPassed &= testSampleRate(testSampleRates[i]);
+        }
+        if (isTestPassed) {
+            out("Test PASSED.");
+        } else {
+            throw new Exception("Test FAILED.");
+        }
+    }
+
+    private static boolean testSampleRate(float sampleRate) {
+        boolean result = true;
+
+        try {
+            // create AudioInputStream with sample rate of 10000 Hz
+            ByteArrayInputStream data = new ByteArrayInputStream(new byte[1]);
+            AudioFormat format = new AudioFormat(sampleRate, 8, 1, true, true);
+            AudioInputStream stream = new AudioInputStream(data, format, 1);
+
+            // write to AIFF file
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            AudioSystem.write(stream, AudioFileFormat.Type.AIFF, outputStream);
+            byte[] fileData = outputStream.toByteArray();
+            InputStream inputStream = new ByteArrayInputStream(fileData);
+            AudioFileFormat aff = AudioSystem.getAudioFileFormat(inputStream);
+            if (! equals(sampleRate, aff.getFormat().getFrameRate())) {
+                out("error for sample rate " + sampleRate);
+                result = false;
+            }
+        } catch (Exception e) {
+            out(e);
+            out("Test NOT FAILED");
+        }
+        return result;
+    }
+
+    private static boolean equals(float f1, float f2) {
+        return Math.abs(f2 - f1) < 1.0E-9;
+    }
+
+    private static void out(Throwable t) {
+        t.printStackTrace(System.out);
+    }
+
+    private static void out(String message) {
+        System.out.println(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/spi/AudioFileWriter/RIFFHeader.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2006, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4636355
+ * @summary Check that RIFF headers are written with extra data length field.
+ */
+public class RIFFHeader {
+
+    public static void main(String args[]) throws Exception {
+        System.out.println();
+        System.out.println();
+        System.out.println("4636355: Check that RIFF headers are written with extra data length field.");
+        byte[] fakedata=new byte[1234];
+        MyByteArrayInputStream is = new MyByteArrayInputStream(fakedata);
+        AudioFormat inFormat = new AudioFormat(AudioFormat.Encoding.ULAW, 8000, 8, 1, 1, 8000, true);
+
+        AudioInputStream ais = new AudioInputStream((InputStream) is, inFormat, fakedata.length);
+        ByteArrayOutputStream out = new ByteArrayOutputStream(1500);
+        System.out.println("  ulaw data will be written as WAVE to stream...");
+        int t = AudioSystem.write(ais, AudioFileFormat.Type.WAVE, out);
+        byte[] writtenData = out.toByteArray();
+        // now header must have at least 46 bytes
+        System.out.println("  Length should be "+(fakedata.length+46)+" bytes: "+writtenData.length);
+        // re-read this file
+        is = new MyByteArrayInputStream(writtenData);
+        System.out.println("  Get AudioFileFormat of written file");
+        AudioFileFormat fileformat = AudioSystem.getAudioFileFormat(is);
+        AudioFileFormat.Type type = fileformat.getType();
+        System.out.println("  The file format type: "+type);
+        if (fileformat.getFrameLength()!=fakedata.length
+            && fileformat.getFrameLength()!=AudioSystem.NOT_SPECIFIED) {
+            throw new Exception("The written file's frame length is "+fileformat.getFrameLength()+" but should be "+fakedata.length+" !");
+        }
+        ais = AudioSystem.getAudioInputStream(is);
+        System.out.println("  Got Stream with format: "+ais.getFormat());
+        if (is.getPos()<46) {
+            throw new Exception("After reading the header, stream position must be at least 46, but is "+is.getPos()+" !");
+        }
+        System.out.println("  test passed.");
+    }
+
+    static class MyByteArrayInputStream extends ByteArrayInputStream {
+
+        MyByteArrayInputStream(byte[] data) {
+            super(data);
+        }
+
+        int getPos() {
+            return pos;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/spi/AudioFileWriter/WaveBigEndian.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2006, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 5001952
+ * @summary Writing WAVE with big endian data produces corrupt file. WAVE should
+ *          always write signed 16-bit, little endian, regardless of the
+ *          endianness of the input data.
+ */
+public class WaveBigEndian {
+
+    static boolean failed = false;
+
+    public static byte[] writeDataAndGetAIS(boolean bigEndian) throws Exception {
+        if (bigEndian) {
+                out("Create WAVE file from big endian data...");
+        } else {
+                out("Create WAVE file from little endian data...");
+        }
+        byte[] data = new byte[3000];
+        for (int i = 0; i < data.length; i+=2) {
+                if (bigEndian) {
+                        data[i] = (byte) i;
+                        data[i+1] = (byte) (i+1);
+                } else {
+                        data[i] = (byte) (i+1);
+                        data[i+1] = (byte) i;
+                }
+        }
+        AudioFormat format = new AudioFormat(44100.0f, 16, 1, true, bigEndian);
+        InputStream is = new ByteArrayInputStream(data);
+        AudioInputStream ais = new AudioInputStream(is, format, data.length);
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        int written = AudioSystem.write(ais, AudioFileFormat.Type.WAVE, os);
+        data = os.toByteArray();
+        out("Wrote "+written+" bytes, got "+data.length+" bytes in written file.");
+        is = new ByteArrayInputStream(data);
+        ais = AudioSystem.getAudioInputStream(is);
+        out("Got AIS with length = "+ais.getFrameLength()+" frames.");
+        return data;
+    }
+
+
+    public static void main(String args[]) throws Exception {
+        byte[] data1 = writeDataAndGetAIS(false);
+        byte[] data2 = writeDataAndGetAIS(true);
+
+        if (data1.length != data2.length) {
+                out("# data1.length != data2.length!");
+                failed = true;
+        } else {
+                for (int i = 0 ; i < data1.length; i++) {
+                        if (data1[i] != data2[i]) {
+                                out("# At index "+i+": le="+(data1[i] & 0xFF)+" be="+(data2[i] & 0xFF)+" !");
+                                failed = true;
+                        }
+                }
+        }
+
+        if (failed) throw new Exception("Test FAILED!");
+        out("Files are identical.");
+        out("test passed");
+    }
+
+    static void out(String s) {
+        System.out.println(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/spi/AudioFileWriter/WriteAuUnspecifiedLength.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4351296
+ * @summary Cannot write AudioInputStream with unspecified length
+ */
+public class WriteAuUnspecifiedLength {
+
+    public static void main(String argv[]) throws Exception {
+        AudioFormat format = new AudioFormat(44100, 16, 2, true, true);
+        InputStream is = new ByteArrayInputStream(new byte[1000]);
+        AudioInputStream ais = new AudioInputStream(is, format, AudioSystem.NOT_SPECIFIED);
+        AudioSystem.write(ais, AudioFileFormat.Type.AU, new ByteArrayOutputStream());
+        System.out.println("Test passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/sound/sampled/spi/FormatConversionProvider/AlawUlaw.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 4714846
+ * @summary JavaSound ULAW (8-bit) encoder erroneously depends on endian-ness
+ */
+public class AlawUlaw {
+    static ByteArrayInputStream in;
+    static int byteLength = 1000;
+
+    static boolean failed = false;
+
+    public static void main(String[] args) throws Exception {
+        // generate some random data
+        byte[] soundData = new byte[byteLength];
+        for (int i=0; i<soundData.length; i++) {
+            soundData[i] = (byte) ((i % 256) - 128);
+        }
+
+        // create an AudioInputStream from it
+        in = new ByteArrayInputStream(soundData);
+        in.mark(1);
+
+        test1(PCM_FORMAT_1, ULAW_FORMAT_1, ULAW_FORMAT_2);
+        test1(PCM_FORMAT_2, ULAW_FORMAT_1, ULAW_FORMAT_2);
+        test2(ULAW_FORMAT_1, ULAW_FORMAT_2, PCM_FORMAT_1);
+        test2(ULAW_FORMAT_1, ULAW_FORMAT_2, PCM_FORMAT_2);
+
+        test1(PCM_FORMAT_1, ALAW_FORMAT_1, ALAW_FORMAT_2);
+        test1(PCM_FORMAT_2, ALAW_FORMAT_1, ALAW_FORMAT_2);
+        test2(ALAW_FORMAT_1, ALAW_FORMAT_2, PCM_FORMAT_1);
+        test2(ALAW_FORMAT_1, ALAW_FORMAT_2, PCM_FORMAT_2);
+
+        if (failed) {
+                throw new Exception("Test failed!");
+        }
+    }
+
+    public static String printFormat(AudioFormat format) {
+        return format.toString()+"  "+(format.isBigEndian()?"big":"little")+" endian";
+    }
+
+
+    public static void test1(AudioFormat inFormat, AudioFormat outFormat1, AudioFormat outFormat2) throws Exception {
+        AudioInputStream inStream = new AudioInputStream(in, inFormat, -1);
+        System.out.println("Input Format: " + printFormat(inStream.getFormat()));
+
+        // get a converted stream
+        AudioInputStream stream1 = AudioSystem.getAudioInputStream(outFormat1, inStream);
+        System.out.println("Output Format 1: " + printFormat(stream1.getFormat()));
+
+        // get a converted stream in big endian ulaw
+        AudioInputStream stream2 = AudioSystem.getAudioInputStream(outFormat2, inStream);
+        System.out.println("Output Format 2: " + printFormat(stream2.getFormat()));
+
+        compareStreams(stream1, stream2);
+    }
+
+    public static void test2(AudioFormat inFormat1, AudioFormat inFormat2, AudioFormat outFormat) throws Exception {
+        AudioInputStream inStream1 = new AudioInputStream(in, inFormat1, -1);
+        System.out.println("Input Format1: " + printFormat(inStream1.getFormat()));
+
+        // get a converted stream
+        AudioInputStream stream1 = AudioSystem.getAudioInputStream(outFormat, inStream1);
+        System.out.println("Output Format 1: " + printFormat(stream1.getFormat()));
+
+        AudioInputStream inStream2 = new AudioInputStream(in, inFormat2, -1);
+        System.out.println("Input Format1: " + printFormat(inStream2.getFormat()));
+
+        // get a converted stream in big endian ulaw
+        AudioInputStream stream2 = AudioSystem.getAudioInputStream(outFormat, inStream2);
+        System.out.println("Output Format 2: " + printFormat(stream2.getFormat()));
+
+        compareStreams(stream1, stream2);
+    }
+
+    public static void compareStreams(InputStream stream1, InputStream stream2) throws Exception {
+        ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
+        ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
+
+        in.reset();
+        writeDirectly(stream1, baos1);
+        in.reset();
+        writeDirectly(stream2, baos2);
+
+        if (baos1.size() != baos2.size()) {
+            System.out.println("   stream1 has length = "+baos1.size()+", stream2 has length = "+baos2.size());
+        }
+        int len = baos1.size();
+        if (len > baos2.size()) {
+                len = baos2.size();
+        }
+        byte[] data1=baos1.toByteArray();
+        byte[] data2=baos2.toByteArray();
+        for (int i=0; i<len; i++) {
+                if (data1[i] != data2[i]) {
+                        System.out.println("  FAILED! Difference encountered at position "+i);
+                        failed = true;
+                        return;
+                }
+        }
+        if (baos1.size() != baos2.size()) {
+                System.out.println("  No difference, but different length!");
+                failed = true;
+                return;
+        }
+        System.out.println("   PASSED");
+    }
+
+    public static void writeDirectly(InputStream in, OutputStream out) throws Exception {
+            // read data from the stream until we reach the end of the stream
+            byte tmp[] = new byte[16384];
+            while (true) {
+                int bytesRead = in.read(tmp, 0, tmp.length);
+                if (bytesRead == -1) {
+                        break;
+                }
+                out.write(tmp, 0, bytesRead);
+            } // while
+    }
+
+    public static final AudioFormat PCM_FORMAT_1 =
+        new AudioFormat( AudioFormat.Encoding.PCM_SIGNED,
+                         8000f, //sample rate
+                         16, //bits per sample
+                         1, //channels
+                         2, //frame size
+                         8000f, // frame rate
+                         false); //isBigEndian
+    public static final AudioFormat PCM_FORMAT_2 =
+        new AudioFormat( AudioFormat.Encoding.PCM_SIGNED,
+                         8000f, //sample rate
+                         16, //bits per sample
+                         1, //channels
+                         2, //frame size
+                         8000f, // frame rate
+                         true); //isBigEndian
+
+    public static final AudioFormat ULAW_FORMAT_1 =
+        new AudioFormat( AudioFormat.Encoding.ULAW,
+                         8000f, //sample rate
+                         8, //bits per sample
+                         1, //channels
+                         1, //frame size
+                         8000f, // frame rate
+                         false); //isBigEndian
+
+    public static final AudioFormat ULAW_FORMAT_2 =
+        new AudioFormat( AudioFormat.Encoding.ULAW,
+                         8000f, //sample rate
+                         8, //bits per sample
+                         1, //channels
+                         1, //frame size
+                         8000f, // frame rate
+                         true); //isBigEndian
+
+    public static final AudioFormat ALAW_FORMAT_1 =
+        new AudioFormat( AudioFormat.Encoding.ALAW,
+                         8000f, //sample rate
+                         8, //bits per sample
+                         1, //channels
+                         1, //frame size
+                         8000f, // frame rate
+                         false); //isBigEndian
+
+    public static final AudioFormat ALAW_FORMAT_2 =
+        new AudioFormat( AudioFormat.Encoding.ALAW,
+                         8000f, //sample rate
+                         8, //bits per sample
+                         1, //channels
+                         1, //frame size
+                         8000f, // frame rate
+                         true); //isBigEndian
+}
--- a/test/javax/swing/JFileChooser/6868611/bug6868611.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/javax/swing/JFileChooser/6868611/bug6868611.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -21,73 +21,74 @@
  * questions.
  */
 
-/* @test
-   @bug 6868611
-   @summary FileSystemView throws NullPointerException
-   @author Pavel Porvatov
-   @run main bug6868611
-*/
+/*
+ * @test
+ * @bug 6868611 8198004
+ * @summary FileSystemView throws NullPointerException
+ * @author Pavel Porvatov
+ * @run main bug6868611
+ */
 
 import javax.swing.*;
 import javax.swing.filechooser.FileSystemView;
 import java.io.File;
+import java.nio.file.Files;
 
 public class bug6868611 {
     private static final int COUNT = 1000;
+    private static File tempFolder;
+    private static File files[] = new File[COUNT];
 
     public static void main(String[] args) throws Exception {
-        String tempDirProp = System.getProperty("java.io.tmpdir");
-
-        final String tempDir = tempDirProp == null || !new File(tempDirProp).isDirectory() ?
-            System.getProperty("user.home") : tempDirProp;
-
-        System.out.println("Temp directory: " + tempDir);
+        int fileCount = 0;
+        try {
+            tempFolder = Files.createTempDirectory("temp_folder").toFile();
 
-        // Create 1000 files
-        for (int i = 0; i < 1000; i++) {
-            new File(tempDir, "temp" + i).createNewFile();
-        }
-
-        // Init default FileSystemView
-        SwingUtilities.invokeAndWait(new Runnable() {
-            public void run() {
-                FileSystemView.getFileSystemView().getFiles(new File(tempDir), false);
+            // Try creating 1000 files
+            for (fileCount = 0; fileCount < COUNT; fileCount++) {
+                files[fileCount] = new
+                        File(tempFolder, "temp" + fileCount + ".txt");
+                files[fileCount].createNewFile();
             }
-        });
 
-        for (int i = 0; i < COUNT; i++) {
-            Thread thread = new MyThread(tempDir);
+            // Init default FileSystemView
+            SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    FileSystemView.getFileSystemView().
+                            getFiles(tempFolder, false);
+                }
+            });
 
-            thread.start();
-
-            Thread.sleep((long) (Math.random() * 100));
-
-            thread.interrupt();
+            for (int i = 0; i < COUNT; i++) {
+                Thread thread = new MyThread(tempFolder);
 
-            if (i % 100 == 0) {
-                System.out.print("*");
-            }
-        }
+                thread.start();
+
+                Thread.sleep((long) (Math.random() * 100));
 
-        System.out.println();
-
-        // Remove 1000 files
-        for (int i = 0; i < 1000; i++) {
-            new File(tempDir, "temp" + i).delete();
+                thread.interrupt();
+            }
+        } finally {
+            // Remove created files
+            for (int i = 0; i < fileCount; i++) {
+                Files.delete(files[i].toPath());
+            }
+            Files.delete(tempFolder.toPath());
         }
     }
 
     private static class MyThread extends Thread {
-        private final String dir;
+        private final File dir;
 
-        private MyThread(String dir) {
+        private MyThread(File dir) {
             this.dir = dir;
         }
 
         public void run() {
             FileSystemView fileSystemView = FileSystemView.getFileSystemView();
 
-            fileSystemView.getFiles(new File(dir), false);
+            fileSystemView.getFiles(dir, false);
         }
     }
 }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/swing/JTree/4633594/JTreeFocusTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 4633594 8172012
+   @summary No way to pass focus from a JTree to a GUI placed inside the tree node
+   @run main JTreeFocusTest
+*/
+import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.util.EventObject;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.JTree;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.border.BevelBorder;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.LineBorder;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellEditor;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.DefaultTreeModel;
+
+public class JTreeFocusTest {
+
+    private static DefaultMutableTreeNode root;
+    Robot robot;
+    static boolean passed = false;
+    boolean rootSelected = false;
+    boolean keysTyped = false;
+    private volatile Point p = null;
+    private static JFrame fr;
+    private static volatile JTree tree = null;
+
+    public static void main(String[] args) throws Exception{
+         new JTreeFocusTest();
+    }
+
+    void blockTillDisplayed(JComponent comp) throws Exception {
+        while (p == null) {
+            try {
+                SwingUtilities.invokeAndWait(() -> {
+                    p = comp.getLocationOnScreen();
+                });
+            } catch (IllegalStateException e) {
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException ie) {
+                }
+            }
+        }
+    }
+
+    public JTreeFocusTest() throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+            fr = new JFrame("Test");
+
+            root = new DefaultMutableTreeNode("root");
+            JPanel p = new JPanel();
+            p.setBorder(new CompoundBorder(new BevelBorder(BevelBorder.RAISED),
+                    new LineBorder(UIManager.getColor("control"), 7)));
+            p.setLayout(new GridLayout(2,2));
+            p.add(new JLabel("one"));
+            JTextField tf1  = new JTextField(10);
+            p.add(tf1);
+            p.add(new JLabel("two"));
+            p.add(new JTextField(10));
+            root.add(new DefaultMutableTreeNode(p));
+
+            tf1.addFocusListener(new FocusAdapter() {
+                public void focusGained(FocusEvent e) {
+                    setPassed(true);
+                }
+            });
+
+            DefaultTreeModel model = new DefaultTreeModel(root);
+            tree = new JTree(model) {
+                public void processKeyEvent(KeyEvent e) {
+                    super.processKeyEvent(e);
+                    if (e.getKeyCode()==KeyEvent.VK_F2) {
+                        synchronized (JTreeFocusTest.this) {
+                            keysTyped = true;
+                            JTreeFocusTest.this.notifyAll();
+                        }
+                    }
+                }
+            };
+
+            tree.addTreeSelectionListener(new TreeSelectionListener() {
+                public void valueChanged(TreeSelectionEvent e) {
+                    if ( root.equals(e.getPath().getLastPathComponent()) ) {
+                        synchronized (JTreeFocusTest.this) {
+                            rootSelected = true;
+                            JTreeFocusTest.this.notifyAll();
+                        }
+                    }
+                }
+            });
+
+            tree.setEditable(true);
+            DefaultTreeCellRenderer renderer = new FormRenderer();
+            tree.setCellRenderer(renderer);
+            DefaultTreeCellEditor editor = new FormEditor(tree, renderer);
+            tree.setCellEditor(editor);
+            fr.getContentPane().add(tree);
+
+            fr.setSize(300,400);
+            fr.setVisible(true);
+        });
+        blockTillDisplayed(tree);
+        SwingUtilities.invokeAndWait(() -> {
+            tree.requestFocus();
+            tree.setSelectionRow(0);
+        });
+
+        try {
+            synchronized (this) {
+                while (!rootSelected) {
+                    JTreeFocusTest.this.wait();
+                }
+            }
+
+            robot = new Robot();
+            robot.setAutoDelay(50);
+            robot.delay(150);
+            robot.keyPress(KeyEvent.VK_DOWN);
+            robot.keyRelease(KeyEvent.VK_DOWN);
+            robot.keyPress(KeyEvent.VK_RIGHT);
+            robot.keyRelease(KeyEvent.VK_RIGHT);
+            robot.keyPress(KeyEvent.VK_F2);
+            robot.keyRelease(KeyEvent.VK_F2);
+
+            synchronized (this) {
+                while (!keysTyped) {
+                    JTreeFocusTest.this.wait();
+                }
+            }
+            Thread.sleep(3000);
+        } catch(Throwable t) {
+            t.printStackTrace();
+        }
+        destroy();
+    }
+
+    public void destroy() throws Exception {
+        SwingUtilities.invokeAndWait(()->fr.dispose());
+        if ( !isPassed() ) {
+            throw new RuntimeException("Focus wasn't transferred to the proper component");
+        }
+    }
+
+    synchronized void setPassed(boolean passed) {
+        this.passed = passed;
+    }
+
+    synchronized boolean isPassed() {
+        return passed;
+    }
+
+    static JTree createTree() {
+        return tree;
+    }
+
+    class FormRenderer extends DefaultTreeCellRenderer {
+        public Component getTreeCellRendererComponent(JTree tree, Object value,
+                                                      boolean sel,
+                                                      boolean expanded,
+                                                      boolean leaf, int row,
+                                                      boolean hasFocus) {
+            Object obj = ((DefaultMutableTreeNode)value).getUserObject();
+            if (obj instanceof Component){
+                return (Component)((DefaultMutableTreeNode)value).getUserObject();
+            }
+            return super.getTreeCellRendererComponent(tree, value, sel,
+                                                      expanded, leaf, row,
+                                                      hasFocus);
+        }
+    }
+
+    class FormEditor extends DefaultTreeCellEditor {
+        public FormEditor(JTree tree, DefaultTreeCellRenderer renderer) {
+            super(tree, renderer);
+        }
+
+        public Component getTreeCellEditorComponent(JTree tree, Object value,
+                                                      boolean sel,
+                                                      boolean expanded,
+                                                      boolean leaf, int row) {
+            Object obj = ((DefaultMutableTreeNode)value).getUserObject();
+            if (obj instanceof Component){
+                return (Component)((DefaultMutableTreeNode)value).getUserObject();
+            }
+            return super.getTreeCellEditorComponent(tree, value, sel,
+                                                    expanded, leaf, row);
+        }
+
+        public boolean shouldSelectCell(EventObject anEvent) {
+            //return super.shouldSelectCell(anEvent);
+            return true;
+        }
+    }
+}
--- a/test/javax/xml/crypto/dsig/GenerationTests.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/javax/xml/crypto/dsig/GenerationTests.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -24,11 +24,11 @@
 /**
  * @test
  * @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184
- * 8038349 8046724 8074784 8079693 8210736
+ * 8038349 8046724 8074784 8079693 8177334 8210736 8217878
  * @summary Basic unit tests for generating XML Signatures with JSR 105
  * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
  *     X509KeySelector.java GenerationTests.java
- * @run main/othervm -Dsun.net.httpserver.nodelay=true GenerationTests
+ * @run main/othervm/timeout=300 -Dsun.net.httpserver.nodelay=true GenerationTests
  * @author Sean Mullan
  */
 
@@ -36,6 +36,7 @@
 import com.sun.net.httpserver.HttpHandler;
 import com.sun.net.httpserver.HttpServer;
 import java.io.*;
+import java.lang.reflect.Modifier;
 import java.math.BigInteger;
 import java.net.InetSocketAddress;
 import java.security.Key;
@@ -64,6 +65,7 @@
 import java.security.spec.RSAPrivateKeySpec;
 import java.security.spec.RSAPublicKeySpec;
 import java.util.*;
+import java.util.stream.Stream;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import javax.xml.XMLConstants;
@@ -88,8 +90,8 @@
 import org.w3c.dom.*;
 
 /**
- * Test that recreates merlin-xmldsig-twenty-three test vectors but with
- * different keys and X.509 data.
+ * Test that recreates merlin-xmldsig-twenty-three test vectors (and more)
+ * but with different keys and X.509 data.
  */
 public class GenerationTests {
 
@@ -97,11 +99,13 @@
     private static KeyInfoFactory kifac;
     private static DocumentBuilder db;
     private static CanonicalizationMethod withoutComments;
-    private static SignatureMethod dsaSha1, dsaSha256, rsaSha1,
-                                   rsaSha256, rsaSha384, rsaSha512,
-                                   ecdsaSha1;
-    private static DigestMethod sha1, sha256, sha384, sha512;
-    private static KeyInfo dsa1024, dsa2048, rsa, rsa1024,
+    private static SignatureMethod dsaSha1, dsaSha256,
+            rsaSha1, rsaSha224, rsaSha256, rsaSha384, rsaSha512,
+            ecdsaSha1, ecdsaSha224, ecdsaSha256, ecdsaSha384, ecdsaSha512,
+            hmacSha1, hmacSha224, hmacSha256, hmacSha384, hmacSha512,
+            rsaSha1mgf1, rsaSha224mgf1, rsaSha256mgf1, rsaSha384mgf1, rsaSha512mgf1;
+    private static DigestMethod sha1, sha224, sha256, sha384, sha512;
+    private static KeyInfo dsa1024, dsa2048, rsa, rsa1024, rsa2048,
                            p256ki, p384ki, p521ki;
     private static KeySelector kvks = new KeySelectors.KeyValueKeySelector();
     private static KeySelector sks;
@@ -119,8 +123,12 @@
     private final static String CRL =
         DATA_DIR + System.getProperty("file.separator") + "certs" +
         System.getProperty("file.separator") + "crl";
+    // XML Document with a DOCTYPE declaration
     private final static String ENVELOPE =
         DATA_DIR + System.getProperty("file.separator") + "envelope.xml";
+    // XML Document without a DOCTYPE declaration
+    private final static String ENVELOPE2 =
+        DATA_DIR + System.getProperty("file.separator") + "envelope2.xml";
     private static URIDereferencer httpUd = null;
     private final static String STYLESHEET =
         "http://www.w3.org/TR/xml-stylesheet";
@@ -183,11 +191,74 @@
         null, Transform.BASE64
     };
 
-    private static final String[] signatureMethods = new String[] {
-        SignatureMethod.DSA_SHA1,
-        SignatureMethod.RSA_SHA1,
-        SignatureMethod.HMAC_SHA1
-    };
+    // It will be too time consuming to test all combinations of
+    // all digest methods and signature methods. So we pick some
+    // majors one and only test a combination when a major method
+    // (either digest or signature) is included.
+    //
+    //              *  *  *
+    //              *  *  *
+    //              *  *  *
+    //     *  *  *  *  *  *  *  *  *
+    //     *  *  *  *  *  *  *  *  *
+    //     *  *  *  *  *  *  *  *  *
+    //              *  *  *
+    //              *  *  *
+    //              *  *  *
+
+    private static List<String> majorSignatureMethods;
+    static {
+        List<String> tmpList = Arrays.asList(
+            "http://www.w3.org/2009/xmldsig11#dsa-sha256",
+            "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
+            "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256",
+            "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
+            "http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1");
+        majorSignatureMethods = Collections.unmodifiableList(tmpList);
+    }
+
+    private static final String[] allSignatureMethods
+            = Stream.of(SignatureMethod.class.getDeclaredFields())
+                .filter(f -> Modifier.isStatic(f.getModifiers()))
+                .map(f -> {
+                    try {
+                        return (String)f.get(null);
+                    } catch (Exception e) {
+                        throw new Error("should not happen");
+                    }
+                })
+                .toArray(String[]::new);
+
+    private static final List<String> majorDigestMethods;
+    static {
+        List<String> tmpList = Arrays.asList(
+            DigestMethod.SHA1,
+            DigestMethod.SHA256);
+        majorDigestMethods = Collections.unmodifiableList(tmpList);
+    }
+
+    private static final String[] allDigestMethods
+            = Stream.of(DigestMethod.class.getDeclaredFields())
+                .filter(f -> Modifier.isStatic(f.getModifiers())
+                                && !f.getName().equals("RIPEMD160"))
+                .map(f -> {
+                    try {
+                        return (String)f.get(null);
+                    } catch (Exception e) {
+                        throw new Error("should not happen");
+                    }
+                })
+                .toArray(String[]::new);
+
+    // As of JDK 8, the number of defined algorithms are...
+    static {
+        if (allSignatureMethods.length != 3
+                || allDigestMethods.length != 3) {
+            System.out.println(Arrays.toString(allSignatureMethods));
+            System.out.println(Arrays.toString(allDigestMethods));
+            throw new AssertionError("Not all methods are counted");
+        }
+    }
 
     private static enum Content {
         Xml, Text, Base64, NotExisitng
@@ -207,10 +278,15 @@
         test_create_signature_enveloping_dsa();
         test_create_signature_enveloping_hmac_sha1_40();
         test_create_signature_enveloping_hmac_sha256();
+        test_create_signature_enveloping_hmac_sha224();
         test_create_signature_enveloping_hmac_sha384();
         test_create_signature_enveloping_hmac_sha512();
         test_create_signature_enveloping_rsa();
         test_create_signature_enveloping_p256_sha1();
+        test_create_signature_enveloping_p256_sha224();
+        test_create_signature_enveloping_p256_sha256();
+        test_create_signature_enveloping_p256_sha384();
+        test_create_signature_enveloping_p256_sha512();
         test_create_signature_enveloping_p384_sha1();
         test_create_signature_enveloping_p521_sha1();
         test_create_signature_external_b64_dsa();
@@ -227,11 +303,22 @@
         test_create_sign_spec();
         test_create_signature_enveloping_sha256_dsa();
         test_create_signature_enveloping_sha384_rsa_sha256();
+        test_create_signature_enveloping_sha224_rsa_sha256();
         test_create_signature_enveloping_sha512_rsa_sha384();
+        test_create_signature_enveloping_sha512_rsa_sha224();
         test_create_signature_enveloping_sha512_rsa_sha512();
+        test_create_signature_enveloping_sha512_rsa_sha1_mgf1();
+        test_create_signature_enveloping_sha512_rsa_sha224_mgf1();
+        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_reference_dependency();
         test_create_signature_with_attr_in_no_namespace();
         test_create_signature_with_empty_id();
+        test_create_signature_enveloping_over_doc(ENVELOPE, true);
+        test_create_signature_enveloping_over_doc(ENVELOPE2, true);
+        test_create_signature_enveloping_over_doc(ENVELOPE, false);
+        test_create_signature_enveloping_dom_level1();
 
         // run tests for detached signatures with local http server
         try (Http server = Http.startServer()) {
@@ -239,30 +326,39 @@
 
             // tests for XML documents
             Arrays.stream(canonicalizationMethods).forEach(c ->
-                Arrays.stream(signatureMethods).forEach(s ->
-                    Arrays.stream(xml_transforms).forEach(t ->
-                        Arrays.stream(KeyInfoType.values()).forEach(k -> {
-                            test_create_detached_signature(c, s, t, k,
-                                    Content.Xml, server.getPort(), false, null);
-                        }))));
+                Arrays.stream(allSignatureMethods).forEach(s ->
+                    Arrays.stream(allDigestMethods).forEach(d ->
+                        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);
+                                }
+                        })))));
 
             // tests for text data with no transform
             Arrays.stream(canonicalizationMethods).forEach(c ->
-                Arrays.stream(signatureMethods).forEach(s ->
-                    Arrays.stream(KeyInfoType.values()).forEach(k -> {
-                        test_create_detached_signature(c, s, null, k,
-                                Content.Text, server.getPort(), false, null);
-                    })));
+                Arrays.stream(allSignatureMethods).forEach(s ->
+                    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);
+                            }
+                        }))));
 
             // tests for base64 data
             Arrays.stream(canonicalizationMethods).forEach(c ->
-                Arrays.stream(signatureMethods).forEach(s ->
-                    Arrays.stream(non_xml_transforms).forEach(t ->
-                        Arrays.stream(KeyInfoType.values()).forEach(k -> {
-                            test_create_detached_signature(c, s, t, k,
-                                    Content.Base64, server.getPort(),
-                                    false, null);
-                        }))));
+                Arrays.stream(allSignatureMethods).forEach(s ->
+                    Arrays.stream(allDigestMethods).forEach(d ->
+                        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);
+                                }
+                        })))));
 
             // negative tests
 
@@ -270,6 +366,7 @@
             test_create_detached_signature(
                     CanonicalizationMethod.EXCLUSIVE + BOGUS,
                     SignatureMethod.DSA_SHA1,
+                    DigestMethod.SHA1,
                     CanonicalizationMethod.INCLUSIVE,
                     KeyInfoType.KeyName,
                     Content.Xml,
@@ -281,6 +378,18 @@
             test_create_detached_signature(
                     CanonicalizationMethod.EXCLUSIVE,
                     SignatureMethod.DSA_SHA1 + BOGUS,
+                    DigestMethod.SHA1,
+                    CanonicalizationMethod.INCLUSIVE,
+                    KeyInfoType.KeyName, Content.Xml,
+                    server.getPort(),
+                    true,
+                    NoSuchAlgorithmException.class);
+
+            // unknown DigestMethod
+            test_create_detached_signature(
+                    CanonicalizationMethod.EXCLUSIVE,
+                    SignatureMethod.DSA_SHA1,
+                    DigestMethod.SHA1 + BOGUS,
                     CanonicalizationMethod.INCLUSIVE,
                     KeyInfoType.KeyName, Content.Xml,
                     server.getPort(),
@@ -291,6 +400,7 @@
             test_create_detached_signature(
                     CanonicalizationMethod.EXCLUSIVE,
                     SignatureMethod.DSA_SHA1,
+                    DigestMethod.SHA1,
                     CanonicalizationMethod.INCLUSIVE + BOGUS,
                     KeyInfoType.KeyName, Content.Xml,
                     server.getPort(),
@@ -301,6 +411,7 @@
             test_create_detached_signature(
                     CanonicalizationMethod.EXCLUSIVE,
                     SignatureMethod.DSA_SHA1,
+                    DigestMethod.SHA1,
                     CanonicalizationMethod.INCLUSIVE,
                     KeyInfoType.KeyName,
                     Content.NotExisitng,
@@ -312,6 +423,7 @@
             test_create_detached_signature(
                     CanonicalizationMethod.EXCLUSIVE,
                     SignatureMethod.DSA_SHA1,
+                    DigestMethod.SHA1,
                     CanonicalizationMethod.INCLUSIVE,
                     KeyInfoType.KeyName,
                     Content.Text,
@@ -325,6 +437,12 @@
         }
     }
 
+    // Do not test on all combinations.
+    private static boolean isMajor(String signatureMethod, String digestMethod) {
+        return majorDigestMethods.contains(digestMethod)
+                || majorSignatureMethods.contains(signatureMethod);
+    }
+
     private static void setup() throws Exception {
         fac = XMLSignatureFactory.getInstance();
         kifac = fac.getKeyInfoFactory();
@@ -345,11 +463,13 @@
             (CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec)null);
         dsaSha1 = fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null);
         dsaSha256 = fac.newSignatureMethod(DSA_SHA256, null);
+
         sha1 = fac.newDigestMethod(DigestMethod.SHA1, null);
+        sha224 = fac.newDigestMethod("http://www.w3.org/2001/04/xmldsig-more#sha224", null);
         sha256 = fac.newDigestMethod(DigestMethod.SHA256, null);
-        sha384 = fac.newDigestMethod
-            ("http://www.w3.org/2001/04/xmldsig-more#sha384", null);
+        sha384 = fac.newDigestMethod("http://www.w3.org/2001/04/xmldsig-more#sha384", null);
         sha512 = fac.newDigestMethod(DigestMethod.SHA512, null);
+
         dsa1024 = kifac.newKeyInfo(Collections.singletonList
             (kifac.newKeyValue(validatingKey)));
         dsa2048 = kifac.newKeyInfo(Collections.singletonList
@@ -358,21 +478,39 @@
             (kifac.newKeyValue(getPublicKey("RSA", 512))));
         rsa1024 = kifac.newKeyInfo(Collections.singletonList
             (kifac.newKeyValue(getPublicKey("RSA", 1024))));
+        rsa2048 = kifac.newKeyInfo(Collections.singletonList
+                (kifac.newKeyValue(getPublicKey("RSA", 2048))));
         p256ki = kifac.newKeyInfo(Collections.singletonList
             (kifac.newKeyValue(getECPublicKey("P256"))));
         p384ki = kifac.newKeyInfo(Collections.singletonList
             (kifac.newKeyValue(getECPublicKey("P384"))));
         p521ki = kifac.newKeyInfo(Collections.singletonList
             (kifac.newKeyValue(getECPublicKey("P521"))));
+
         rsaSha1 = fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
-        rsaSha256 = fac.newSignatureMethod
-            ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null);
-        rsaSha384 = fac.newSignatureMethod
-            ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", null);
-        rsaSha512 = fac.newSignatureMethod
-            ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", null);
-        ecdsaSha1 = fac.newSignatureMethod
-            ("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1", null);
+        rsaSha224 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha224", null);
+        rsaSha256 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null);
+        rsaSha384 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", null);
+        rsaSha512 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", null);
+
+        rsaSha1mgf1 = fac.newSignatureMethod("http://www.w3.org/2007/05/xmldsig-more#sha1-rsa-MGF1", null);
+        rsaSha224mgf1 = fac.newSignatureMethod("http://www.w3.org/2007/05/xmldsig-more#sha224-rsa-MGF1", null);
+        rsaSha256mgf1 = fac.newSignatureMethod("http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1", null);
+        rsaSha384mgf1 = fac.newSignatureMethod("http://www.w3.org/2007/05/xmldsig-more#sha384-rsa-MGF1", null);
+        rsaSha512mgf1 = fac.newSignatureMethod("http://www.w3.org/2007/05/xmldsig-more#sha512-rsa-MGF1", null);
+
+        ecdsaSha1 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1", null);
+        ecdsaSha224 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224", null);
+        ecdsaSha256 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256", null);
+        ecdsaSha384 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384", null);
+        ecdsaSha512 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512", null);
+
+        hmacSha1 = fac.newSignatureMethod(SignatureMethod.HMAC_SHA1, null);
+        hmacSha224 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#hmac-sha224", null);
+        hmacSha256 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#hmac-sha256", null);
+        hmacSha384 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#hmac-sha384", null);
+        hmacSha512 = fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#hmac-sha512", null);
+
         sks = new KeySelectors.SecretKeySelector("secret".getBytes("ASCII"));
 
         httpUd = new HttpURIDereferencer();
@@ -459,8 +597,6 @@
     static void test_create_signature_enveloping_hmac_sha1_40()
         throws Exception {
         System.out.println("* Generating signature-enveloping-hmac-sha1-40.xml");
-        SignatureMethod hmacSha1 = fac.newSignatureMethod
-            (SignatureMethod.HMAC_SHA1, new HMACParameterSpec(40));
         try {
             test_create_signature_enveloping(sha1, hmacSha1, null,
                 getSecretKey("secret".getBytes("ASCII")), sks, false);
@@ -475,18 +611,22 @@
     static void test_create_signature_enveloping_hmac_sha256()
         throws Exception {
         System.out.println("* Generating signature-enveloping-hmac-sha256.xml");
-        SignatureMethod hmacSha256 = fac.newSignatureMethod
-            ("http://www.w3.org/2001/04/xmldsig-more#hmac-sha256", null);
         test_create_signature_enveloping(sha1, hmacSha256, null,
             getSecretKey("secret".getBytes("ASCII")), sks, false);
         System.out.println();
     }
 
+    static void test_create_signature_enveloping_hmac_sha224()
+            throws Exception {
+        System.out.println("* Generating signature-enveloping-hmac-sha224.xml");
+        test_create_signature_enveloping(sha1, hmacSha224, null,
+                getSecretKey("secret".getBytes("ASCII")), sks, false);
+        System.out.println();
+    }
+
     static void test_create_signature_enveloping_hmac_sha384()
         throws Exception {
         System.out.println("* Generating signature-enveloping-hmac-sha384.xml");
-        SignatureMethod hmacSha384 = fac.newSignatureMethod
-            ("http://www.w3.org/2001/04/xmldsig-more#hmac-sha384", null);
         test_create_signature_enveloping(sha1, hmacSha384, null,
             getSecretKey("secret".getBytes("ASCII")), sks, false);
         System.out.println();
@@ -495,8 +635,6 @@
     static void test_create_signature_enveloping_hmac_sha512()
         throws Exception {
         System.out.println("* Generating signature-enveloping-hmac-sha512.xml");
-        SignatureMethod hmacSha512 = fac.newSignatureMethod
-            ("http://www.w3.org/2001/04/xmldsig-more#hmac-sha512", null);
         test_create_signature_enveloping(sha1, hmacSha512, null,
             getSecretKey("secret".getBytes("ASCII")), sks, false);
         System.out.println();
@@ -517,6 +655,14 @@
         System.out.println();
     }
 
+    static void test_create_signature_enveloping_sha224_rsa_sha256()
+            throws Exception {
+        System.out.println("* Generating signature-enveloping-sha224-rsa_sha256.xml");
+        test_create_signature_enveloping(sha224, rsaSha256, rsa,
+                getPrivateKey("RSA", 512), kvks, false);
+        System.out.println();
+    }
+
     static void test_create_signature_enveloping_sha512_rsa_sha384()
         throws Exception {
         System.out.println("* Generating signature-enveloping-sha512-rsa_sha384.xml");
@@ -525,6 +671,14 @@
         System.out.println();
     }
 
+    static void test_create_signature_enveloping_sha512_rsa_sha224()
+            throws Exception {
+        System.out.println("* Generating signature-enveloping-sha512-rsa_sha224.xml");
+        test_create_signature_enveloping(sha512, rsaSha224, rsa1024,
+                getPrivateKey("RSA", 1024), kvks, false);
+        System.out.println();
+    }
+
     static void test_create_signature_enveloping_sha512_rsa_sha512()
         throws Exception {
         System.out.println("* Generating signature-enveloping-sha512-rsa_sha512.xml");
@@ -533,6 +687,46 @@
         System.out.println();
     }
 
+    static void test_create_signature_enveloping_sha512_rsa_sha1_mgf1()
+            throws Exception {
+        System.out.println("* Generating signature-enveloping-sha512-rsa_sha1_mgf1.xml");
+        test_create_signature_enveloping(sha512, rsaSha1mgf1, rsa1024,
+                getPrivateKey("RSA", 1024), kvks, false);
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_sha512_rsa_sha224_mgf1()
+            throws Exception {
+        System.out.println("* Generating signature-enveloping-sha512-rsa_sha224_mgf1.xml");
+        test_create_signature_enveloping(sha512, rsaSha224mgf1, rsa1024,
+                getPrivateKey("RSA", 1024), kvks, false);
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_sha512_rsa_sha256_mgf1()
+            throws Exception {
+        System.out.println("* Generating signature-enveloping-sha512-rsa_sha256_mgf1.xml");
+        test_create_signature_enveloping(sha512, rsaSha256mgf1, rsa1024,
+                getPrivateKey("RSA", 1024), kvks, false);
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_sha512_rsa_sha384_mgf1()
+            throws Exception {
+        System.out.println("* Generating signature-enveloping-sha512-rsa_sha384_mgf1.xml");
+        test_create_signature_enveloping(sha512, rsaSha384mgf1, rsa1024,
+                getPrivateKey("RSA", 1024), kvks, false);
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_sha512_rsa_sha512_mgf1()
+            throws Exception {
+        System.out.println("* Generating signature-enveloping-sha512-rsa_sha512_mgf1.xml");
+        test_create_signature_enveloping(sha512, rsaSha512mgf1, rsa2048,
+                getPrivateKey("RSA", 2048), kvks, false);
+        System.out.println();
+    }
+
     static void test_create_signature_enveloping_p256_sha1() throws Exception {
         System.out.println("* Generating signature-enveloping-p256-sha1.xml");
         test_create_signature_enveloping(sha1, ecdsaSha1, p256ki,
@@ -540,6 +734,34 @@
         System.out.println();
     }
 
+    static void test_create_signature_enveloping_p256_sha224() throws Exception {
+        System.out.println("* Generating signature-enveloping-p256-sha224.xml");
+        test_create_signature_enveloping(sha1, ecdsaSha224, p256ki,
+                getECPrivateKey("P256"), kvks, false);
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_p256_sha256() throws Exception {
+        System.out.println("* Generating signature-enveloping-p256-sha256.xml");
+        test_create_signature_enveloping(sha1, ecdsaSha256, p256ki,
+                getECPrivateKey("P256"), kvks, false);
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_p256_sha384() throws Exception {
+        System.out.println("* Generating signature-enveloping-p256-sha384.xml");
+        test_create_signature_enveloping(sha1, ecdsaSha384, p256ki,
+                getECPrivateKey("P256"), kvks, false);
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_p256_sha512() throws Exception {
+        System.out.println("* Generating signature-enveloping-p256-sha512.xml");
+        test_create_signature_enveloping(sha1, ecdsaSha512, p256ki,
+                getECPrivateKey("P256"), kvks, false);
+        System.out.println();
+    }
+
     static void test_create_signature_enveloping_p384_sha1() throws Exception {
         System.out.println("* Generating signature-enveloping-p384-sha1.xml");
         test_create_signature_enveloping(sha1, ecdsaSha1, p384ki,
@@ -765,6 +987,109 @@
                                                "signature", null);
         DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 512), doc);
         sig.sign(dsc);
+
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_over_doc(String filename,
+        boolean pass) throws Exception
+    {
+        System.out.println("* Generating signature-enveloping-over-doc.xml");
+
+        // create reference
+        Reference ref = fac.newReference("#object", sha256);
+
+        // create SignedInfo
+        SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha256,
+            Collections.singletonList(ref));
+
+        // create object
+        Document doc = null;
+        try (FileInputStream fis = new FileInputStream(filename)) {
+            doc = db.parse(fis);
+        }
+        DOMStructure ds = pass ? new DOMStructure(doc.getDocumentElement())
+                               : new DOMStructure(doc);
+        XMLObject obj = fac.newXMLObject(Collections.singletonList(ds),
+            "object", null, "UTF-8");
+
+        // This creates an enveloping signature over the entire XML Document
+        XMLSignature sig = fac.newXMLSignature(si, rsa,
+                                               Collections.singletonList(obj),
+                                               "signature", null);
+        DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 1024), doc);
+        try {
+            sig.sign(dsc);
+            if (!pass) {
+                // A Document node can only exist at the root of the doc so this
+                // should fail
+                throw new Exception("Test unexpectedly passed");
+            }
+        } catch (Exception e) {
+            if (!pass) {
+                System.out.println("Test failed as expected: " + e);
+            } else {
+                throw e;
+            }
+        }
+
+        if (pass) {
+            DOMValidateContext dvc = new DOMValidateContext
+                (getPublicKey("RSA", 1024), doc.getDocumentElement());
+            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");
+            }
+        }
+
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_dom_level1() throws Exception {
+        System.out.println("* Generating signature-enveloping-dom-level1.xml");
+
+        // create reference
+        Reference ref = fac.newReference("#object", sha256);
+
+        // create SignedInfo
+        SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha256,
+            Collections.singletonList(ref));
+
+        // create object using DOM Level 1 methods
+        Document doc = db.newDocument();
+        Element child = doc.createElement("Child");
+        child.setAttribute("Version", "1.0");
+        child.setAttribute("Id", "child");
+        child.setIdAttribute("Id", true);
+        child.appendChild(doc.createComment("Comment"));
+        XMLObject obj = fac.newXMLObject(
+            Collections.singletonList(new DOMStructure(child)),
+            "object", null, "UTF-8");
+
+        XMLSignature sig = fac.newXMLSignature(si, rsa,
+                                               Collections.singletonList(obj),
+                                               "signature", null);
+        DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 1024), doc);
+        sig.sign(dsc);
+
+        DOMValidateContext dvc = new DOMValidateContext
+            (getPublicKey("RSA", 1024), doc.getDocumentElement());
+        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");
+        }
+
+        System.out.println();
     }
 
     static void test_create_signature() throws Exception {
@@ -1119,8 +1444,7 @@
 
         // create reference 1
         refs.add(fac.newReference
-            ("#xpointer(id('to-be-signed'))",
-             fac.newDigestMethod(DigestMethod.SHA1, null),
+            ("#xpointer(id('to-be-signed'))", sha1,
              Collections.singletonList
                 (fac.newTransform(CanonicalizationMethod.EXCLUSIVE,
                  (TransformParameterSpec) null)),
@@ -1132,16 +1456,14 @@
         prefixList.add("#default");
         ExcC14NParameterSpec params = new ExcC14NParameterSpec(prefixList);
         refs.add(fac.newReference
-            ("#xpointer(id('to-be-signed'))",
-             fac.newDigestMethod(DigestMethod.SHA1, null),
+            ("#xpointer(id('to-be-signed'))", sha1,
              Collections.singletonList
                 (fac.newTransform(CanonicalizationMethod.EXCLUSIVE, params)),
              null, null));
 
         // create reference 3
         refs.add(fac.newReference
-            ("#xpointer(id('to-be-signed'))",
-             fac.newDigestMethod(DigestMethod.SHA1, null),
+            ("#xpointer(id('to-be-signed'))", sha1,
              Collections.singletonList(fac.newTransform
                 (CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS,
                  (TransformParameterSpec) null)),
@@ -1153,8 +1475,7 @@
         prefixList.add("#default");
         params = new ExcC14NParameterSpec(prefixList);
         refs.add(fac.newReference
-            ("#xpointer(id('to-be-signed'))",
-             fac.newDigestMethod(DigestMethod.SHA1, null),
+            ("#xpointer(id('to-be-signed'))", sha1,
              Collections.singletonList(fac.newTransform
                 (CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS, params)),
              null, null));
@@ -1164,7 +1485,7 @@
             fac.newCanonicalizationMethod
                 (CanonicalizationMethod.EXCLUSIVE,
                  (C14NMethodParameterSpec) null),
-            fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null), refs);
+                    dsaSha1, refs);
 
         // create KeyInfo
         List<XMLStructure> kits = new ArrayList<XMLStructure>(2);
@@ -1222,8 +1543,7 @@
         types.add(new XPathType(" //ReallyToBeSigned ",
             XPathType.Filter.UNION));
         XPathFilter2ParameterSpec xp1 = new XPathFilter2ParameterSpec(types);
-        refs.add(fac.newReference
-            ("", fac.newDigestMethod(DigestMethod.SHA1, null),
+        refs.add(fac.newReference("", sha1,
              Collections.singletonList(fac.newTransform(Transform.XPATH2, xp1)),
              null, null));
 
@@ -1235,15 +1555,14 @@
             (Collections.singletonList
                 (new XPathType(" / ", XPathType.Filter.UNION)));
         trans2.add(fac.newTransform(Transform.XPATH2, xp2));
-        refs.add(fac.newReference("#signature-value",
-            fac.newDigestMethod(DigestMethod.SHA1, null), trans2, null, null));
+        refs.add(fac.newReference("#signature-value", sha1, trans2, null, null));
 
         // create SignedInfo
         SignedInfo si = fac.newSignedInfo(
             fac.newCanonicalizationMethod
                 (CanonicalizationMethod.INCLUSIVE,
                  (C14NMethodParameterSpec) null),
-            fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null), refs);
+                    dsaSha1, refs);
 
         // create KeyInfo
         List<XMLStructure> kits = new ArrayList<XMLStructure>(2);
@@ -1306,28 +1625,26 @@
         System.out.println();
     }
 
-    static void test_create_detached_signature(String canonicalizationMethod,
-            String signatureMethod, String transform, KeyInfoType keyInfo,
+    // Only print if there is an error.
+    static void test_create_detached_signature(
+            String canonicalizationMethod, String signatureMethod,
+            String digestMethod, String transform, KeyInfoType keyInfo,
             Content contentType, int port, boolean expectedFailure,
             Class expectedException) {
 
-        final String digestMethod = DigestMethod.SHA1;
-        System.out.println("Test detached signature:");
-        System.out.println("    Canonicalization method: "
-                + canonicalizationMethod);
-        System.out.println("    Signature method: " + signatureMethod);
-        System.out.println("    Transform: " + transform);
-        System.out.println("    Digest method: " + digestMethod);
-        System.out.println("    KeyInfoType: " + keyInfo);
-        System.out.println("    Content type: " + contentType);
-        System.out.println("    Expected failure: "
-                + (expectedFailure ? "yes" : "no"));
-        System.out.println("    Expected exception: "
-                + (expectedException == null ?
-                        "no" : expectedException.getName()));
+        String title = "\nTest detached signature:"
+                + "\n    Canonicalization method: " + canonicalizationMethod
+                + "\n    Signature method: " + signatureMethod
+                + "\n    Transform: " + transform
+                + "\n    Digest method: " + digestMethod
+                + "\n    KeyInfoType: " + keyInfo
+                + "\n    Content type: " + contentType
+                + "\n    Expected failure: " + (expectedFailure ? "yes" : "no")
+                + "\n    Expected exception: " + (expectedException == null ?
+                            "no" : expectedException.getName());
 
         try {
-            boolean success = test_create_detached_signature(
+            boolean success = test_create_detached_signature0(
                     canonicalizationMethod,
                     signatureMethod,
                     digestMethod,
@@ -1337,12 +1654,15 @@
                     port);
 
             if (success && expectedFailure) {
+                System.out.println(title);
                 System.out.println("Signature validation unexpectedly passed");
                 result = false;
             } else if (!success && !expectedFailure) {
+                System.out.println(title);
                 System.out.println("Signature validation unexpectedly failed");
                 result = false;
             } else if (expectedException != null) {
+                System.out.println(title);
                 System.out.println("Expected " + expectedException
                         + " not thrown");
                 result = false;
@@ -1350,23 +1670,21 @@
         } catch (Exception e) {
             if (expectedException == null
                     || !e.getClass().isAssignableFrom(expectedException)) {
+                System.out.println(title);
                 System.out.println("Unexpected exception: " + e);
                 e.printStackTrace(System.out);
                 result = false;
-            } else {
-                System.out.println("Expected exception: " + e);
             }
         }
-
-        if (result) System.out.println("Test case passed");
     }
 
-    static boolean test_create_detached_signature(String canonicalizationMethod,
+    // Print out as little as possible. This method will be called many times.
+    static boolean test_create_detached_signature0(String canonicalizationMethod,
             String signatureMethod, String digestMethod, String transform,
             KeyInfoType keyInfo, Content contentType, int port)
             throws Exception {
 
-        System.out.print("Sign ...");
+        System.out.print("-S");
 
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         dbf.setNamespaceAware(true);
@@ -1410,20 +1728,34 @@
 
         Key signingKey;
         Key validationKey;
-        switch (signatureMethod) {
-            case SignatureMethod.DSA_SHA1:
-            case SignatureMethod.RSA_SHA1:
-                KeyPair kp = generateKeyPair(sm);
-                validationKey = kp.getPublic();
-                signingKey = kp.getPrivate();
-                break;
-            case SignatureMethod.HMAC_SHA1:
-                KeyGenerator kg = KeyGenerator.getInstance("HmacSHA1");
-                signingKey = kg.generateKey();
-                validationKey = signingKey;
-                break;
-            default:
+        if (signatureMethod.contains("#hmac-")) {
+            // http://...#hmac-sha1 -> hmac-sha1 -> hmacsha1
+            String algName = signatureMethod
+                    .substring(signatureMethod.indexOf('#') + 1)
+                    .replace("-", "");
+            KeyGenerator kg = KeyGenerator.getInstance(algName);
+            signingKey = kg.generateKey();
+            validationKey = signingKey;
+        } else {
+            KeyPairGenerator kpg;
+            SecureRandom random = new SecureRandom();
+            if (signatureMethod.contains("#rsa-")
+                    || signatureMethod.contains("-rsa-MGF1")) {
+                kpg = KeyPairGenerator.getInstance("RSA");
+                kpg.initialize(signatureMethod.contains("#sha512-rsa-MGF1")
+                        ? 2048 : 1024, random);
+            } else if (signatureMethod.contains("#dsa-")) {
+                kpg = KeyPairGenerator.getInstance("DSA");
+                kpg.initialize(1024, random);
+            } else if (signatureMethod.contains("#ecdsa-")) {
+                kpg = KeyPairGenerator.getInstance("EC");
+                kpg.initialize(256, random);
+            } else {
                 throw new RuntimeException("Unsupported signature algorithm");
+            }
+            KeyPair kp = kpg.generateKeyPair();
+            validationKey = kp.getPublic();
+            signingKey = kp.getPrivate();
         }
 
         SignedInfo si = fac.newSignedInfo(cm, sm, refs, null);
@@ -1464,7 +1796,7 @@
             signatureString = writer.toString();
         }
 
-        System.out.print("Validate ... ");
+        System.out.print("V");
         try (ByteArrayInputStream bis = new ByteArrayInputStream(
                 signatureString.getBytes())) {
             doc = dbf.newDocumentBuilder().parse(bis);
@@ -1487,11 +1819,11 @@
 
         boolean success = signature.validate(vc);
         if (!success) {
-            System.out.println("Core signature validation failed");
+            System.out.print("x");
             if (!secondChanceGranted && OS.contains("SunOS")) {
                 removePKCS11Provider();
                 // set up the test again
-                return test_create_detached_signature(canonicalizationMethod,
+                return test_create_detached_signature0(canonicalizationMethod,
                     signatureMethod, digestMethod, transform,
                     keyInfo, contentType, port);
             } else {
@@ -1501,7 +1833,7 @@
 
         success = signature.getSignatureValue().validate(vc);
         if (!success) {
-            System.out.println("Cryptographic validation of signature failed");
+            System.out.print("X");
             return false;
         }
 
@@ -1567,6 +1899,26 @@
         "237008997971129772408397621801631622129297063463868593083106979716" +
         "204903524890556839550490384015324575598723478554854070823335021842" +
         "210112348400928769";
+    private static final String RSA_2048_MOD = "243987087691547796017401146540"
+        + "9844666035826535295137885613771811531602666348704672255163984907599"
+        + "4298308997053582963763109207465354916871136820987101812436158377530"
+        + "6117270010853232249007544652859474372258057062943608962079402484091"
+        + "8121307687901225514249308620012025884376216406019656605767311580224"
+        + "4715304950770504195751384382230005665573033547124060755957932161045"
+        + "7288008201789401237690181537646952377591671113513382933711547044631"
+        + "6055957820531234310030119265612054594720774653570278810236807313332"
+        + "5293876225940483622056721445101719346295263740434720907474414905706"
+        + "086605825077661246082956613711071075569880930102141";
+    private static final String RSA_2048_PRIV = "12265063405401593206575340300"
+        + "5824698296458954796982342251774894076489082263237675553422307220014"
+        + "4395010131540855227949365446755185799985229111139387016816011165826"
+        + "5498929552020323994756478872375078784799489891112924298115119573429"
+        + "3677627114115546751555523555375278381312502020990154549150867571006"
+        + "4470674155961982582802981649643127000520693025433874996570667724459"
+        + "3395670697152709457274026580106078581585077146782827694403672461289"
+        + "9143004401242754355097671446183871158504602884373174300123820136505"
+        + "6449932139773607305129273545117363975014750743804523418307647791195"
+        + "6408859873123458434820062206102268853256685162004893";
     private static final String EC_P256_X =
         "335863644451761614592446380116804721648611739647823420286081723541" +
         "6166183710";
@@ -1652,6 +2004,9 @@
             } else if (keysize == 1024) {
                 kspec = new RSAPublicKeySpec(new BigInteger(RSA_1024_MOD),
                                              new BigInteger(RSA_PUB));
+            } else if (keysize == 2048) {
+                kspec = new RSAPublicKeySpec(new BigInteger(RSA_2048_MOD),
+                                             new BigInteger(RSA_PUB));
             } else throw new RuntimeException("Unsupported keysize:" + keysize);
         } else throw new RuntimeException("Unsupported key algorithm " + algo);
         return kf.generatePublic(kspec);
@@ -1704,10 +2059,13 @@
             if (keysize == 512) {
                 kspec = new RSAPrivateKeySpec
                     (new BigInteger(RSA_MOD), new BigInteger(RSA_PRIV));
-            } else {
+            } else if (keysize == 1024) {
                 kspec = new RSAPrivateKeySpec(new BigInteger(RSA_1024_MOD),
-                                              new BigInteger(RSA_1024_PRIV));
-            }
+                        new BigInteger(RSA_1024_PRIV));
+            } else if (keysize == 2048) {
+                kspec = new RSAPrivateKeySpec(new BigInteger(RSA_2048_MOD),
+                        new BigInteger(RSA_2048_PRIV));
+            } else throw new RuntimeException("Unsupported key algorithm " + algo);
         } else throw new RuntimeException("Unsupported key algorithm " + algo);
         return kf.generatePrivate(kspec);
     }
@@ -1744,25 +2102,6 @@
         };
     }
 
-    static KeyPair generateKeyPair(SignatureMethod sm)
-            throws NoSuchAlgorithmException {
-        KeyPairGenerator keygen;
-        switch (sm.getAlgorithm()) {
-            case SignatureMethod.DSA_SHA1:
-                keygen = KeyPairGenerator.getInstance("DSA");
-                break;
-            case SignatureMethod.RSA_SHA1:
-                keygen = KeyPairGenerator.getInstance("RSA");
-                break;
-            default:
-                throw new RuntimeException("Unsupported signature algorithm");
-        }
-
-        SecureRandom random = new SecureRandom();
-        keygen.initialize(1024, random);
-        return keygen.generateKeyPair();
-    }
-
     /**
      * This URIDereferencer returns locally cached copies of http content to
      * avoid test failures due to network glitches, etc.
--- a/test/javax/xml/crypto/dsig/KeySelectors.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/javax/xml/crypto/dsig/KeySelectors.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -30,14 +30,7 @@
 import javax.crypto.SecretKey;
 import javax.xml.crypto.*;
 import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dom.*;
 import javax.xml.crypto.dsig.keyinfo.*;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.DocumentBuilder;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.Element;
-import org.w3c.dom.traversal.*;
 import sun.security.util.DerValue;
 import sun.security.x509.X500Name;
 
@@ -173,26 +166,11 @@
         }
 
         static boolean algEquals(String algURI, String algName) {
-            if (algName.equalsIgnoreCase("DSA") &&
-                algURI.equals(SignatureMethod.DSA_SHA1) ||
-                algURI.equals("http://www.w3.org/2009/xmldsig11#dsa-sha256")) {
-                return true;
-            } else if (algName.equalsIgnoreCase("RSA") &&
-                (algURI.equals(SignatureMethod.RSA_SHA1) ||
-                 algURI.equals
-                    ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256") ||
-                 algURI.equals
-                    ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384") ||
-                 algURI.equals
-                    ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"))) {
-                return true;
-            } else if (algName.equalsIgnoreCase("EC") &&
-                (algURI.equals
-                    ("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"))) {
-                return true;
-            } else {
-                return false;
-            }
+            algName = algName.toUpperCase(Locale.ROOT);
+            return algName.equals("DSA") && algURI.contains("#dsa-")
+                    || algName.equals("RSA")
+                            && (algURI.contains("#rsa-") || algURI.contains("-rsa-MGF1"))
+                    || algName.equals("EC") && algURI.contains("#ecdsa-");
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/crypto/dsig/data/envelope2.xml	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Preamble -->
+<Envelope xmlns:foo="http://example.org/foo" xmlns="http://example.org/usps">
+  <DearSir>foo</DearSir>
+  <Body>bar</Body>
+  <YoursSincerely>
+  </YoursSincerely>
+  <PostScript>bar</PostScript>
+  <Notaries xmlns="" Id="notaries">
+    <Notary name="Great, A. T." />
+    <Notary name="Hun, A. T." />
+  </Notaries>
+  <!-- Commentary -->
+</Envelope>
+<!-- Postamble -->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/internal/platform/cgroup/TestCgroupMetrics.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @library /lib /
+ * @run main TestCgroupMetrics
+ */
+
+import jdk.test.lib.containers.cgroup.MetricsTester;
+import jdk.internal.platform.Metrics;
+
+public class TestCgroupMetrics {
+
+    public static void main(String[] args) throws Exception {
+        // If cgroups is not configured, report success.
+        Metrics metrics = Metrics.systemMetrics();
+        if (metrics == null) {
+            System.out.println("TEST PASSED!!!");
+            return;
+        }
+
+        MetricsTester metricsTester = new MetricsTester();
+        metricsTester.setup();
+        metricsTester.testCpuAccounting();
+        metricsTester.testCpuSchedulingMetrics();
+        metricsTester.testCpuSets();
+        metricsTester.testMemorySubsystem();
+        metricsTester.testBlkIO();
+        metricsTester.testCpuConsumption();
+        metricsTester.testMemoryUsage();
+        System.out.println("TEST PASSED!!!");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/internal/platform/docker/Dockerfile-BasicTest	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,8 @@
+FROM oraclelinux:7.2
+MAINTAINER mikhailo.seledtsov@oracle.com
+
+COPY /jdk /jdk
+
+ENV JAVA_HOME=/jdk
+
+CMD ["/bin/bash"]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/internal/platform/docker/Dockerfile-BasicTest-aarch64	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,8 @@
+# Use generic ubuntu Linux on AArch64
+FROM aarch64/ubuntu
+
+COPY /jdk /jdk
+
+ENV JAVA_HOME=/jdk
+
+CMD ["/bin/bash"]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/internal/platform/docker/Dockerfile-BasicTest-ppc64le	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,10 @@
+# test on x86_64 uses Oracle Linux but we do not have this for ppc64le
+# so use some other Linux where OpenJDK works 
+# FROM oraclelinux:7.2
+FROM ppc64le/ubuntu
+
+COPY /jdk /jdk
+
+ENV JAVA_HOME=/jdk
+
+CMD ["/bin/bash"]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/internal/platform/docker/Dockerfile-BasicTest-s390x	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,7 @@
+FROM s390x/ubuntu
+
+COPY /jdk /jdk
+
+ENV JAVA_HOME=/jdk
+
+CMD ["/bin/bash"]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/internal/platform/docker/MetricsCpuTester.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,178 @@
+/*
+ * 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.
+ */
+
+import java.util.Arrays;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+import jdk.internal.platform.Metrics;
+
+public class MetricsCpuTester {
+    public static void main(String[] args) {
+        System.out.println(Arrays.toString(args));
+        switch (args[0]) {
+            case "cpusets":
+                testCpuSets(args[1]);
+                break;
+            case "cpuquota":
+                testCpuQuotaAndPeriod(Long.parseLong(args[1]), Long.parseLong(args[2]));
+                break;
+            case "cpushares":
+                testCpuShares(Long.parseLong(args[1]));
+                break;
+            case "cpus":
+                testCpuThrottling();
+                break;
+            case "cpumems":
+                testCpuSetMemNodes(args[1]);
+                break;
+            case "combo":
+                testCombo(args[1], Long.parseLong(args[2]), Long.parseLong(args[3]), Long.parseLong(args[4]));
+                break;
+        }
+    }
+
+    private static void testCpuQuotaAndPeriod(long quota, long period) {
+        Metrics metrics = Metrics.systemMetrics();
+        long newQuota = metrics.getCpuQuota();
+        long newPeriod = metrics.getCpuPeriod();
+        if (quota != newQuota || period != newPeriod) {
+            throw new RuntimeException("CPU quota or period not equal, expected : ["
+                    + quota + "," + period + "]" + ", got : " + "[" + newQuota
+                    + "," + newPeriod + "]");
+        }
+
+        long cpuNumPeriods = metrics.getCpuNumPeriods();
+        long current = System.currentTimeMillis();
+        while (System.currentTimeMillis() - current < 1000) ;    // 1sec
+        long newCpuNumPeriods = metrics.getCpuNumPeriods();
+        if (newCpuNumPeriods <= cpuNumPeriods) {
+            throw new RuntimeException("CPU shares failed, expected : ["
+                    + cpuNumPeriods + "]" + ", got : " + "["
+                    + newCpuNumPeriods + "]");
+        }
+        System.out.println("TEST PASSED!!!");
+    }
+
+    private static void testCpuSets(String cpuset) {
+        int[] ipCpuSet;
+        String[] tokens = cpuset.split("-");
+        if (tokens.length > 1) { // we are given range of CPUs
+            ipCpuSet = IntStream.rangeClosed(Integer.parseInt(tokens[0]),
+                    Integer.parseInt(tokens[1])).toArray();
+        } else if (cpuset.split(",").length > 1) {   // list of cpus
+            ipCpuSet = Stream.of(cpuset.split(",")).mapToInt(Integer::parseInt).toArray();
+        } else { // just a single cpu
+            ipCpuSet = new int[]{Integer.parseInt(cpuset)};
+        }
+
+        Metrics metrics = Metrics.systemMetrics();
+        int[] cpuSets = metrics.getCpuSetCpus();
+
+        int[] effectiveCpus = metrics.getEffectiveCpuSetCpus();
+
+        if (!Arrays.equals(ipCpuSet, cpuSets)) {
+            throw new RuntimeException("Cpusets not equal, expected : "
+                    + Arrays.toString(ipCpuSet) + ", got : " + Arrays.toString(cpuSets));
+        }
+
+        if (!Arrays.equals(ipCpuSet, effectiveCpus)) {
+            throw new RuntimeException("Effective Cpusets not equal, expected : "
+                    + Arrays.toString(ipCpuSet) + ", got : "
+                    + Arrays.toString(effectiveCpus));
+        }
+        System.out.println("TEST PASSED!!!");
+    }
+
+    private static void testCpuSetMemNodes(String cpusetMems) {
+        Metrics metrics = Metrics.systemMetrics();
+        int[] cpuSets = metrics.getCpuSetMems();
+
+        int[] ipCpuSet;
+        String[] tokens = cpusetMems.split("-");
+        if (tokens.length > 1) { // we are given range of CPUs
+            ipCpuSet = IntStream.rangeClosed(Integer.parseInt(tokens[0]),
+                    Integer.parseInt(tokens[1])).toArray();
+        } else if (cpusetMems.split(",").length > 1) {   // list of cpus
+            ipCpuSet = Stream.of(cpusetMems.split(",")).mapToInt(Integer::parseInt).toArray();
+        } else { // just a single cpu
+            ipCpuSet = new int[]{Integer.parseInt(cpusetMems)};
+        }
+
+        int[] effectiveMems = metrics.getEffectiveCpuSetMems();
+
+
+        if (!Arrays.equals(ipCpuSet, cpuSets)) {
+            throw new RuntimeException("Cpuset.mems not equal, expected : "
+                    + Arrays.toString(ipCpuSet) + ", got : "
+                    + Arrays.toString(cpuSets));
+        }
+
+        if (!Arrays.equals(ipCpuSet, effectiveMems)) {
+            throw new RuntimeException("Effective mem nodes not equal, expected : "
+                    + Arrays.toString(ipCpuSet) + ", got : "
+                    + Arrays.toString(effectiveMems));
+        }
+        System.out.println("TEST PASSED!!!");
+    }
+
+    private static void testCpuShares(long shares) {
+        Metrics metrics = Metrics.systemMetrics();
+        long newShares = metrics.getCpuShares();
+        if (newShares != shares) {
+            throw new RuntimeException("CPU shares not equal, expected : ["
+                    + shares + "]" + ", got : " + "[" + newShares + "]");
+        }
+        System.out.println("TEST PASSED!!!");
+    }
+
+    private static void testCpuThrottling() {
+        Metrics metrics = Metrics.systemMetrics();
+        long throttledTime = metrics.getCpuThrottledTime();
+        long numThrottled = metrics.getCpuNumThrottled();
+
+        long current = System.currentTimeMillis();
+
+        while (System.currentTimeMillis() - current < 2000) ;  // 2 sec
+
+        long newthrottledTime = metrics.getCpuThrottledTime();
+        long newnumThrottled = metrics.getCpuNumThrottled();
+        if (newthrottledTime <= throttledTime) {
+            throw new RuntimeException("CPU throttle failed, expected : ["
+                    + newthrottledTime + "]" + ", got : "
+                    + "[" + throttledTime + "]");
+        }
+
+        if (newnumThrottled <= numThrottled) {
+            throw new RuntimeException("CPU num throttle failed, expected : ["
+                    + newnumThrottled + "]" + ", got : " + "["
+                    + numThrottled + "]");
+        }
+        System.out.println("TEST PASSED!!!");
+    }
+
+    private static void testCombo(String cpuset, long quota, long period, long shares) {
+        testCpuSets(cpuset);
+        testCpuQuotaAndPeriod(quota, period);
+        testCpuShares(shares);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/internal/platform/docker/MetricsMemoryTester.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+import java.util.Arrays;
+import jdk.internal.platform.Metrics;
+
+public class MetricsMemoryTester {
+    public static void main(String[] args) {
+        System.out.println(Arrays.toString(args));
+        switch (args[0]) {
+            case "memory":
+                testMemoryLimit(args[1]);
+                break;
+            case "memoryswap":
+                testMemoryAndSwapLimit(args[1], args[2]);
+                break;
+            case "kernelmem":
+                testKernelMemoryLimit(args[1]);
+                break;
+            case "oomkill":
+                testOomKillFlag(Boolean.parseBoolean(args[2]));
+                break;
+            case "failcount":
+                testMemoryFailCount();
+                break;
+            case "softlimit":
+                testMemorySoftLimit(args[1]);
+                break;
+        }
+    }
+
+    private static void testMemoryLimit(String value) {
+        long limit = getMemoryValue(value);
+
+        if (limit != Metrics.systemMetrics().getMemoryLimit()) {
+            throw new RuntimeException("Memory limit not equal, expected : ["
+                    + limit + "]" + ", got : ["
+                    + Metrics.systemMetrics().getMemoryLimit() + "]");
+        }
+        System.out.println("TEST PASSED!!!");
+    }
+
+    private static void testMemoryFailCount() {
+        long count = Metrics.systemMetrics().getMemoryFailCount();
+
+        // Allocate 512M of data
+        long[][] longs = new long[64][];
+        for (int i = 1; i <= 64; i++) {
+            try {
+                longs[i] = new long[8 * 1024 * 1024];
+            } catch (Error e) { // OOM error
+                break;
+            }
+        }
+        if (Metrics.systemMetrics().getMemoryFailCount() <= count) {
+            throw new RuntimeException("Memory fail count : new : ["
+                    + Metrics.systemMetrics().getMemoryFailCount() + "]"
+                    + ", old : [" + count + "]");
+        }
+        System.out.println("TEST PASSED!!!");
+    }
+
+    private static void testMemorySoftLimit(String softLimit) {
+
+        long memorySoftLimit = Metrics.systemMetrics().getMemorySoftLimit();
+        long newmemorySoftLimit = getMemoryValue(softLimit);
+
+        if (newmemorySoftLimit != memorySoftLimit) {
+            throw new RuntimeException("Memory softlimit not equal, Actual : ["
+                    + newmemorySoftLimit + "]" + ", Expected : ["
+                    + memorySoftLimit + "]");
+        }
+        System.out.println("TEST PASSED!!!");
+    }
+
+    private static void testKernelMemoryLimit(String value) {
+        long limit = getMemoryValue(value);
+        if (limit != Metrics.systemMetrics().getKernelMemoryLimit()) {
+            throw new RuntimeException("Kernel Memory limit not equal, expected : ["
+                    + limit + "]" + ", got : ["
+                    + Metrics.systemMetrics().getKernelMemoryLimit() + "]");
+        }
+        System.out.println("TEST PASSED!!!");
+    }
+
+    private static void testMemoryAndSwapLimit(String memory, String memAndSwap) {
+        long expectedMem = getMemoryValue(memory);
+        long expectedMemAndSwap = getMemoryValue(memAndSwap);
+
+        if (expectedMem != Metrics.systemMetrics().getMemoryLimit()
+                || expectedMemAndSwap != Metrics.systemMetrics().getMemoryAndSwapLimit()) {
+            System.err.println("Memory and swap limit not equal, expected : ["
+                    + expectedMem + ", " + expectedMemAndSwap + "]"
+                    + ", got : [" + Metrics.systemMetrics().getMemoryLimit()
+                    + ", " + Metrics.systemMetrics().getMemoryAndSwapLimit() + "]");
+        }
+        System.out.println("TEST PASSED!!!");
+    }
+
+    private static long getMemoryValue(String value) {
+        long result;
+        if (value.endsWith("m")) {
+            result = Long.parseLong(value.substring(0, value.length() - 1))
+                    * 1024 * 1024;
+        } else if (value.endsWith("g")) {
+            result = Long.parseLong(value.substring(0, value.length() - 1))
+                    * 1024 * 1024 * 1024;
+        } else {
+            result = Long.parseLong(value);
+        }
+        return result;
+    }
+
+    private static void testOomKillFlag(boolean oomKillFlag) {
+        if (!(oomKillFlag ^ Metrics.systemMetrics().isMemoryOOMKillEnabled())) {
+            throw new RuntimeException("oomKillFlag error");
+        }
+        System.out.println("TEST PASSED!!!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/internal/platform/docker/TestDockerCpuMetrics.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import jdk.internal.platform.Metrics;
+import jdk.test.lib.Utils;
+import jdk.test.lib.containers.cgroup.CPUSetsReader;
+import jdk.test.lib.containers.docker.Common;
+import jdk.test.lib.containers.docker.DockerRunOptions;
+import jdk.test.lib.containers.docker.DockerTestUtils;
+
+/*
+ * @test
+ * @summary Test JDK Metrics class when running inside docker container
+ * @library /lib /
+ * @build MetricsCpuTester
+ * @run main/timeout=360 TestDockerCpuMetrics
+ */
+
+public class TestDockerCpuMetrics {
+    private static final String imageName = Common.imageName("metrics-cpu");
+
+    public static void main(String[] args) throws Exception {
+        if (!DockerTestUtils.canTestDocker()) {
+            return;
+        }
+
+        // These tests create a docker image and run this image with
+        // varying docker cpu options.  The arguments passed to the docker
+        // container include the Java test class to be run along with the
+        // resource to be examined and expected result.
+
+        DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
+
+        try {
+            int numCpus = CPUSetsReader.getNumCpus();
+            testCpuSet("0");
+            testCpuSet("0-" + (numCpus - 1));
+            if (numCpus > 2) {
+                testCpuSet("0-" + ((numCpus - 1) / 2));
+                testCpuSet((((numCpus - 1) / 2) + 1) + "-" + (numCpus - 1));
+            }
+            testCpuSet(IntStream.range(0, numCpus).mapToObj(a -> Integer.toString(a)).collect(Collectors.joining(",")));
+
+            testCpuQuota(50 * 1000, 100 * 1000);
+            testCpuQuota(100 * 1000, 100 * 1000);
+            testCpuQuota(150 * 1000, 100 * 1000);
+            testCpuQuota(400 * 1000, 100 * 1000);
+
+            testCpuShares(256);
+            testCpuShares(2048);
+            testCpuShares(4096);
+
+            testCpuThrottling(0.5);// --cpus=<value>
+
+            int[] cpuSetMems = Metrics.systemMetrics().getCpuSetMems();
+            String memNodes = null;
+            if (cpuSetMems.length > 1) {
+                int endNode = (cpuSetMems[cpuSetMems.length - 1] - cpuSetMems[0]) / 2 + cpuSetMems[0];
+                memNodes = cpuSetMems[0] + "-" + endNode;
+            } else if (cpuSetMems.length == 1) {
+                memNodes = cpuSetMems[0] + "";
+            }
+
+            if(memNodes != null)
+                testCpuSetMems(memNodes);
+
+            testComboOptions("0-" + (numCpus - 1), 200 * 1000, 100 * 1000, 4 * 1024);
+            testComboOptions("0", 200 * 1000, 100 * 1000, 1023);
+        } finally {
+            DockerTestUtils.removeDockerImage(imageName);
+        }
+    }
+
+    private static void testCpuSetMems(String value) throws Exception {
+        Common.logNewTestCase("testCpuSetMems, mem nodes = " + value);
+        DockerRunOptions opts =
+                new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsCpuTester");
+        opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/");
+        opts.addDockerOpts("--cpuset-mems=" + value);
+        opts.addJavaOpts("-cp", "/test-classes/");
+        opts.addClassOptions("cpumems", value);
+        DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+    }
+
+    private static void testCpuSet(String value) throws Exception {
+        Common.logNewTestCase("testCpuSet, value = " + value);
+        DockerRunOptions opts =
+                new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsCpuTester");
+        opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/");
+        opts.addJavaOpts("-cp", "/test-classes/");
+        opts.addClassOptions("cpusets", value);
+        opts.addDockerOpts("--cpuset-cpus=" + value);
+        DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+    }
+
+    private static void testCpuQuota(long quota, long period) throws Exception {
+        Common.logNewTestCase("testCpuQuota, quota = " + quota + ", period = " + period);
+        DockerRunOptions opts =
+                new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsCpuTester");
+        opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/");
+        opts.addDockerOpts("--cpu-period=" + period).addDockerOpts("--cpu-quota=" + quota);
+        opts.addJavaOpts("-cp", "/test-classes/");
+        opts.addClassOptions("cpuquota", quota + "", period + "");
+        DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+    }
+
+    private static void testCpuShares(int shares) throws Exception {
+        Common.logNewTestCase("testCpuShares, shares = " + shares);
+        DockerRunOptions opts =
+                new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsCpuTester");
+        opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/");
+        opts.addDockerOpts("--cpu-shares=" + shares);
+        opts.addJavaOpts("-cp", "/test-classes/");
+        opts.addClassOptions("cpushares", shares + "");
+        DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+    }
+
+    private static void testCpuThrottling(double cpus) throws Exception {
+        Common.logNewTestCase("testCpuThrottling, cpus = " + cpus);
+        DockerRunOptions opts =
+                new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsCpuTester");
+        opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/");
+        opts.addDockerOpts("--cpus=" + cpus);
+        opts.addJavaOpts("-cp", "/test-classes/");
+        opts.addClassOptions("cpus", cpus + "");
+        DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+    }
+
+    private static void testComboOptions(String cpuset, int quota, int period, int shares) throws Exception {
+        Common.logNewTestCase("testComboOptions, shares = " + shares);
+        DockerRunOptions opts =
+                new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsCpuTester");
+        opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/");
+        opts.addDockerOpts("--cpuset-cpus", "" + cpuset)
+                .addDockerOpts("--cpu-period=" + period)
+                .addDockerOpts("--cpu-quota=" + quota)
+                .addDockerOpts("--cpu-shares=" + shares);
+        opts.addJavaOpts("-cp", "/test-classes/");
+        opts.addClassOptions("combo", cpuset, quota + "", period + "", shares + "");
+        DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/internal/platform/docker/TestDockerMemoryMetrics.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+import jdk.test.lib.Utils;
+import jdk.test.lib.containers.docker.Common;
+import jdk.test.lib.containers.docker.DockerRunOptions;
+import jdk.test.lib.containers.docker.DockerTestUtils;
+
+/*
+ * @test
+ * @summary Test JDK Metrics class when running inside docker container
+ * @library /lib /
+ * @build MetricsMemoryTester
+ * @run main/timeout=360 TestDockerMemoryMetrics
+ */
+
+public class TestDockerMemoryMetrics {
+    private static final String imageName = Common.imageName("metrics-memory");
+
+    public static void main(String[] args) throws Exception {
+        if (!DockerTestUtils.canTestDocker()) {
+            return;
+        }
+
+        // These tests create a docker image and run this image with
+        // varying docker memory options.  The arguments passed to the docker
+        // container include the Java test class to be run along with the
+        // resource to be examined and expected result.
+
+        DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
+        try {
+            testMemoryLimit("200m");
+            testMemoryLimit("1g");
+
+            testMemoryAndSwapLimit("200m", "1g");
+            testMemoryAndSwapLimit("100m", "200m");
+
+            testKernelMemoryLimit("100m");
+            testKernelMemoryLimit("1g");
+
+            testOomKillFlag("100m", false);
+            testOomKillFlag("100m", true);
+
+            testMemoryFailCount("20m");
+
+            testMemorySoftLimit("500m","200m");
+
+        } finally {
+            DockerTestUtils.removeDockerImage(imageName);
+        }
+    }
+
+    private static void testMemoryLimit(String value) throws Exception {
+        Common.logNewTestCase("testMemoryLimit, value = " + value);
+        DockerRunOptions opts =
+                new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsMemoryTester");
+        opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/")
+                .addDockerOpts("--memory=" + value)
+                .addJavaOpts("-cp", "/test-classes/")
+                .addClassOptions("memory", value);
+        DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+    }
+
+    private static void testMemoryFailCount(String value) throws Exception {
+        Common.logNewTestCase("testMemoryFailCount" + value);
+        DockerRunOptions opts =
+                new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsMemoryTester");
+        opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/")
+                .addDockerOpts("--memory=" + value)
+                .addJavaOpts("-cp", "/test-classes/")
+                .addClassOptions("failcount");
+        DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+    }
+
+    private static void testMemoryAndSwapLimit(String memory, String memandswap) throws Exception {
+        Common.logNewTestCase("testMemoryAndSwapLimit, memory = " + memory + ", memory and swap = " + memandswap);
+        DockerRunOptions opts =
+                new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsMemoryTester");
+        opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/")
+                .addDockerOpts("--memory=" + memory)
+                .addDockerOpts("--memory-swap=" + memandswap)
+                .addJavaOpts("-cp", "/test-classes/")
+                .addClassOptions("memoryswap", memory, memandswap);
+        DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+    }
+
+    private static void testKernelMemoryLimit(String value) throws Exception {
+        Common.logNewTestCase("testKernelMemoryLimit, value = " + value);
+        DockerRunOptions opts =
+                new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsMemoryTester");
+        opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/")
+                .addDockerOpts("--kernel-memory=" + value)
+                .addJavaOpts("-cp", "/test-classes/")
+                .addClassOptions("kernelmem", value);
+        DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+    }
+
+    private static void testOomKillFlag(String value, boolean oomKillFlag) throws Exception {
+        Common.logNewTestCase("testOomKillFlag, oomKillFlag = " + oomKillFlag);
+        DockerRunOptions opts =
+                new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsMemoryTester");
+        opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/")
+                .addDockerOpts("--memory=" + value);
+        if (!oomKillFlag) {
+            opts.addDockerOpts("--oom-kill-disable");
+        }
+        opts.addJavaOpts("-cp", "/test-classes/")
+                .addClassOptions("memory", value, oomKillFlag + "");
+        DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+    }
+
+    private static void testMemorySoftLimit(String mem, String softLimit) throws Exception {
+        Common.logNewTestCase("testMemorySoftLimit, memory = " + mem + ", soft limit = " + softLimit);
+        DockerRunOptions opts =
+                new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsMemoryTester");
+        opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/")
+                .addDockerOpts("--memory=" + mem)
+                .addDockerOpts("--memory-reservation=" + softLimit);
+        opts.addJavaOpts("-cp", "/test-classes/")
+                .addClassOptions("softlimit", softLimit);
+        DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/internal/platform/docker/TestSystemMetrics.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Test JDK Metrics class when running inside docker container
+ * @library /lib
+ * @run main TestSystemMetrics
+ */
+
+import jdk.test.lib.Utils;
+import jdk.test.lib.containers.docker.Common;
+import jdk.test.lib.containers.docker.DockerRunOptions;
+import jdk.test.lib.containers.docker.DockerTestUtils;
+import jdk.test.lib.containers.cgroup.MetricsTester;
+
+public class TestSystemMetrics {
+    private static final String imageName = Common.imageName("metrics");
+
+    public static void main(String[] args) throws Exception {
+        if (!DockerTestUtils.canTestDocker()) {
+            return;
+        }
+
+        DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
+
+        try {
+            Common.logNewTestCase("Test SystemMetrics");
+            DockerRunOptions opts =
+                    new DockerRunOptions(imageName, "/jdk/bin/java", "jdk.test.lib.containers.cgroup.MetricsTester");
+            opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/");
+            opts.addJavaOpts("-cp", "/test-classes/");
+            DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
+        } finally {
+            DockerTestUtils.removeDockerImage(imageName);
+        }
+    }
+}
--- a/test/jdk/jfr/tool/TestPrint.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/jdk/jfr/tool/TestPrint.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -47,7 +47,7 @@
         output.shouldContain("missing file");
 
         output = ExecuteHelper.jfr("print", "missing.jfr");
-        output.shouldContain("could not find file ");
+        output.shouldContain("could not open file ");
 
         Path file = Utils.createTempFile("faked-print-file",  ".jfr");
         FileWriter fw = new FileWriter(file.toFile());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/JliLaunchTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+import java.util.Map;
+import jdk.test.lib.Utils;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class JliLaunchTest {
+    public static void main(String[] args) throws IOException {
+        Path launcher = Paths.get(System.getProperty("test.nativepath"),
+            "JliLaunchTest" + (Platform.isWindows() ? ".exe" : ""));
+        System.out.println("Launcher = " + launcher + (Files.exists(launcher) ? " (exists)" : " (not exists)"));
+        ProcessBuilder pb = new ProcessBuilder(launcher.toString(), "-version");
+        Map<String, String> env = pb.environment();
+        // On windows, the DLL should be in JDK/bin, else in JDK/lib.
+        String libdir = Paths.get(Utils.TEST_JDK).resolve(Platform.isWindows() ? "bin" : "jre/lib/jli")
+            .toAbsolutePath().toString();
+        String pathEnvVar = Platform.sharedLibraryPathVariableName();
+        env.compute(pathEnvVar, (k, v) -> (v == null) ? libdir : libdir + File.pathSeparator + v);
+
+        OutputAnalyzer outputf = new OutputAnalyzer(pb.start());
+        outputf.shouldHaveExitValue(0);
+
+        if (Platform.isOSX()) {
+            Path javaHome = Paths.get(Utils.TEST_JDK);
+            if (javaHome.getFileName().toString().equals("Home")) {
+                // To exercise this test path you need to make sure the JDK under test is
+                // the MacOS bundle and not the simple jdk image. This can currently be
+                // achieved by running something like this (from the build output dir):
+                // $ JDK_IMAGE_DIR=$PWD/images/j2sdk-bundle/jdk1.8.0.jdk/Contents/Home
+                // $ jtreg -jdk:$JDK_IMAGE_DIR $TESTROOT/jdk/tools/launcher/JliLaunchTest.sh
+                System.out.println("MacOS bundle distribution detected, also testing Contents/MacOS/libjli.dylib");
+                String macosDir = javaHome.getParent().resolve("MacOS").toString();
+                ProcessBuilder pb2 = new ProcessBuilder(launcher.toString(), "-version");
+                env = pb2.environment();
+                env.compute(pathEnvVar, (k, v) -> (v == null) ? macosDir : macosDir + File.pathSeparator + v);
+
+                OutputAnalyzer output2 = new OutputAnalyzer(pb2.start());
+                output2.shouldHaveExitValue(0);
+            } else {
+                System.out.println("Not a MacOS bundle distribution, not testing Contents/MacOS/libjli.dylib");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/JliLaunchTest.sh	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,33 @@
+#!/bin/bash -xe
+
+# @test JliLaunchTest.sh
+# @bug 8238225
+# @library /lib
+# @build JliLaunchTest
+# @run shell JliLaunchTest.sh
+
+OS=`uname -s`
+if [ "${OS}" != "Darwin" ]; then
+    echo "This is a MacOSX only test"
+    exit 0;
+fi
+
+gcc_cmd=`which gcc`
+if [ "x$gcc_cmd" == "x" ]; then
+    echo "WARNING: gcc not found. Cannot execute test." 2>&1
+    exit 0;
+fi
+
+JDK_TOPDIR="${TESTROOT}/.."
+
+$gcc_cmd -o ${TESTCLASSES}/JliLaunchTest \
+    -I${JDK_TOPDIR}/src/share/bin \
+    -I${JDK_TOPDIR}/src/share/javavm/export \
+    -I${JDK_TOPDIR}/src/macosx/javavm/export \
+    -I${JDK_TOPDIR}/src/solaris/bin \
+    -L${TESTJAVA}/jre/lib/jli -ljli \
+    ${TESTSRC}/exeJliLaunchTest.c
+
+${TESTJAVA}/bin/java -Dtest.jdk=${TESTJAVA} \
+    -Dtest.nativepath=${TESTCLASSES} \
+    -cp ${TESTCLASSPATH} JliLaunchTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/exeJliLaunchTest.c	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,44 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+
+/*
+ * This file contains the main entry point into the launcher code
+ * this is the only file which will be repeatedly compiled by other
+ * tools. The rest of the files will be linked in.
+ */
+
+#include "java.h"
+
+int
+main(int argc, char **argv)
+{
+    return JLI_Launch(argc, argv,
+                   0, NULL,
+                   0, NULL,
+                   "1", "0",
+                   *argv, *argv,
+                   0, 0, 0, 0);
+}
--- a/test/lib/jdk/test/lib/Platform.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/lib/jdk/test/lib/Platform.java	Sat Oct 24 01:11:51 2020 +0100
@@ -351,6 +351,21 @@
     }
 
     /*
+     * Returns name of system variable containing paths to shared native libraries.
+     */
+    public static String sharedLibraryPathVariableName() {
+        if (isWindows()) {
+            return "PATH";
+        } else if (isOSX()) {
+            return "DYLD_LIBRARY_PATH";
+        } else if (isAix()) {
+            return "LIBPATH";
+        } else {
+            return "LD_LIBRARY_PATH";
+        }
+    }
+
+    /*
      * This should match the #if condition in ClassListParser::load_class_from_source().
      */
     public static boolean areCustomLoadersSupportedForCDS() {
--- a/test/lib/jdk/test/lib/containers/cgroup/MetricsTester.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/lib/jdk/test/lib/containers/cgroup/MetricsTester.java	Sat Oct 24 01:11:51 2020 +0100
@@ -423,7 +423,7 @@
             }
         }).toArray(Integer[]::new);
         Arrays.sort(newVal);
-        if (Arrays.compare(oldVal, newVal) != 0) {
+        if (!Arrays.equals(oldVal, newVal)) {
             fail(SubSystem.CPUSET, "cpuset.cpus", Arrays.toString(oldVal),
                 Arrays.toString(newVal));
         }
@@ -445,7 +445,7 @@
                 }
             }).toArray(Integer[]::new);
             Arrays.sort(newVal);
-            if (Arrays.compare(oldVal, newVal) != 0) {
+            if (!Arrays.equals(oldVal, newVal)) {
                 fail(SubSystem.CPUSET, "cpuset.effective_cpus", Arrays.toString(oldVal),
                         Arrays.toString(newVal));
             }
@@ -464,7 +464,7 @@
             }
         }).toArray(Integer[]::new);
         Arrays.sort(newVal);
-        if (Arrays.compare(oldVal, newVal) != 0) {
+        if (!Arrays.equals(oldVal, newVal)) {
             fail(SubSystem.CPUSET, "cpuset.mems", Arrays.toString(oldVal),
                     Arrays.toString(newVal));
         }
@@ -486,7 +486,7 @@
                 }
             }).toArray(Integer[]::new);
             Arrays.sort(newVal);
-            if (Arrays.compare(oldVal, newVal) != 0) {
+            if (!Arrays.equals(oldVal, newVal)) {
                 fail(SubSystem.CPUSET, "cpuset.effective_mems", Arrays.toString(oldVal),
                         Arrays.toString(newVal));
             }
--- a/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 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
@@ -37,7 +37,7 @@
 if [[ $OS == CYGWIN_NT* ]] ; then
     OS="Windows_NT"
     if [ -z "$SystemRoot" ] ;  then
-	SystemRoot=$SYSTEMROOT
+        SystemRoot=`cygpath $SYSTEMROOT`
     fi
 fi
 
@@ -69,17 +69,17 @@
     if [ "$OS" = "Windows_NT" ]; then
         USER=`id -u -n`
         CACLS="$SystemRoot/system32/cacls.exe"
-        REVOKEALL="${TESTSRC}/../../windows/revokeall.exe"
+        TEST_SRC=`cygpath ${TESTSRC}`
+        REVOKEALL="$TEST_SRC/../../windows/revokeall.exe"
         if [ ! -f "$REVOKEALL" ] ; then
             echo "$REVOKEALL missing"
             exit 1
         fi
+        chmod ug+x $REVOKEALL
     fi
-
-
     ;;
 *)
-    echo "Unrecognized system!"
+    echo "Unrecognized system! $OS"
     exit 1
     ;;
 esac
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/net/www/protocol/http/NULLTargetInfoTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,57 @@
+/*
+ * 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 8151788
+ * @summary NullPointerException from ntlm.Client.type3
+ * @run main NULLTargetInfoTest
+ */
+import com.sun.security.ntlm.Client;
+
+public class NULLTargetInfoTest {
+
+    public static void main(String[] args) throws Exception {
+        Client c = new Client(null, "host", "user", "domain", "pass".toCharArray());
+        c.type1();
+        // this input does have the 0x800000 bit(NTLMSSP_NEGOTIATE_TARGET_INFO) set
+        // but after offset 40 all eight bytes are all zero which means there is no
+        // security buffer for target info.
+        byte[] type2 = hex(
+                "4E 54 4C 4D 53 53 50 00 02 00 00 00 00 00 00 00"
+                + "00 00 00 00 05 82 89 00 0B 87 81 B6 2D 6E 8B C1"
+                + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00");
+        byte[] nonce = new byte[10];
+        c.type3(type2, nonce);
+    }
+
+    private static byte[] hex(String str) {
+        str = str.replaceAll("\\s", "");
+        byte[] response = new byte[str.length() / 2];
+        int index = 0;
+        for (int i = 0; i < str.length(); i += 2) {
+            response[index++] = Integer.valueOf(str.substring(i, i + 2), 16).byteValue();
+        }
+        return response;
+    }
+}
--- a/test/sun/security/krb5/auto/ReferralsTest.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/sun/security/krb5/auto/ReferralsTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Red Hat, Inc.
+ * Copyright (c) 2019, 2020, 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
@@ -37,15 +37,19 @@
 import java.util.Set;
 import javax.security.auth.kerberos.KerberosTicket;
 import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
 
 import org.ietf.jgss.GSSName;
 
 import sun.security.jgss.GSSUtil;
+import sun.security.krb5.Config;
 import sun.security.krb5.PrincipalName;
 
 public class ReferralsTest {
     private static final boolean DEBUG = true;
     private static final String krbConfigName = "krb5-localkdc.conf";
+    private static final String krbConfigNameNoCanonicalize =
+            "krb5-localkdc-nocanonicalize.conf";
     private static final String realmKDC1 = "RABBIT.HOLE";
     private static final String realmKDC2 = "DEV.RABBIT.HOLE";
     private static final char[] password = "123qwe@Z".toCharArray();
@@ -99,6 +103,7 @@
             testDelegation();
             testImpersonation();
             testDelegationWithReferrals();
+            testNoCanonicalize();
         } finally {
             cleanup();
         }
@@ -138,14 +143,20 @@
         kdc2.setOption(KDC.Option.ALLOW_S4U2PROXY, mapKDC2);
 
         KDC.saveConfig(krbConfigName, kdc1, kdc2,
-                    "forwardable=true");
+                "forwardable=true", "canonicalize=true");
+        KDC.saveConfig(krbConfigNameNoCanonicalize, kdc1, kdc2,
+                "forwardable=true");
         System.setProperty("java.security.krb5.conf", krbConfigName);
     }
 
     private static void cleanup() {
-        File f = new File(krbConfigName);
-        if (f.exists()) {
-            f.delete();
+        String[] configFiles = new String[]{krbConfigName,
+                krbConfigNameNoCanonicalize};
+        for (String configFile : configFiles) {
+            File f = new File(configFile);
+            if (f.exists()) {
+                f.delete();
+            }
         }
     }
 
@@ -324,4 +335,23 @@
             throw new Exception("Unexpected initiator or acceptor names");
         }
     }
+
+    /*
+     * The client tries to get a TGT (AS protocol) as in testSubjectCredentials
+     * but without the canonicalize setting in krb5.conf. The KDC
+     * must not return a referral but a failure because the client
+     * is not in the local database.
+     */
+    private static void testNoCanonicalize() throws Exception {
+        System.setProperty("java.security.krb5.conf",
+                krbConfigNameNoCanonicalize);
+        Config.refresh();
+        try {
+            Context.fromUserPass(new Subject(),
+                    clientKDC1Name, password, false);
+            throw new Exception("should not succeed");
+        } catch (LoginException e) {
+            // expected
+        }
+    }
 }
--- a/test/sun/security/mscapi/SmallPrimeExponentP.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/sun/security/mscapi/SmallPrimeExponentP.java	Sat Oct 24 01:11:51 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -21,6 +21,16 @@
  * questions.
  */
 
+ /*
+ * @test
+ * @bug 8023546 8151834
+ * @summary Test prime exponent (p) lengths 63 and 65 bytes with SunMSCAPI.
+ *         The seed 76 has the fastest test execution now (only 5 rounds) and is
+ *         hard-coded in run tag. This number might change if algorithms for
+ *         RSA key pair generation or BigInteger prime searching gets updated.
+ * @requires os.family == "windows"
+ * @run main SmallPrimeExponentP 76
+ */
 import sun.security.tools.keytool.CertAndKeyGen;
 import sun.security.x509.X500Name;
 
@@ -28,47 +38,63 @@
 import java.security.SecureRandom;
 import java.security.cert.X509Certificate;
 import java.security.interfaces.RSAPrivateCrtKey;
+import java.util.Random;
 
-/*
- * @test
- * @bug 8023546
- * @summary sun/security/mscapi/ShortRSAKey1024.sh fails intermittently
- * @requires os.family == "windows"
- */
 public class SmallPrimeExponentP {
 
     public static void main(String argv[]) throws Exception {
 
-        String osName = System.getProperty("os.name");
-        if (!osName.startsWith("Windows")) {
-            System.out.println("Not windows");
-            return;
-        }
+        long seed = Long.parseLong(argv[0]);
+        System.out.println("Seed for SecureRandom = " + seed + "L");
+
         KeyStore ks = KeyStore.getInstance("Windows-MY");
         ks.load(null, null);
+
         CertAndKeyGen ckg = new CertAndKeyGen("RSA", "SHA1withRSA");
-        ckg.setRandom(new SecureRandom());
-        boolean see63 = false, see65 = false;
+        ckg.setRandom(new MySecureRandom(seed));
+
+        boolean see63 = false;
+        boolean see65 = false;
         while (!see63 || !see65) {
             ckg.generate(1024);
             RSAPrivateCrtKey k = (RSAPrivateCrtKey) ckg.getPrivateKey();
+
             int len = k.getPrimeExponentP().toByteArray().length;
+            System.out.println("Length of P = " + len);
             if (len == 63 || len == 65) {
                 if (len == 63) {
-                    if (see63) continue;
-                    else see63 = true;
+                    if (see63) {
+                        continue;
+                    } else {
+                        see63 = true;
+                    }
                 }
                 if (len == 65) {
-                    if (see65) continue;
-                    else see65 = true;
+                    if (see65) {
+                        continue;
+                    } else {
+                        see65 = true;
+                    }
                 }
-                System.err.print(len);
                 ks.setKeyEntry("anything", k, null, new X509Certificate[]{
-                        ckg.getSelfCertificate(new X500Name("CN=Me"), 1000)
+                    ckg.getSelfCertificate(new X500Name("CN=Me"), 1000)
                 });
             }
-            System.err.print('.');
         }
         ks.store(null, null);
     }
+
+    static class MySecureRandom extends SecureRandom {
+
+        final Random random;
+
+        public MySecureRandom(long seed) {
+            random = new Random(seed);
+        }
+
+        @Override
+        public void nextBytes(byte[] bytes) {
+            random.nextBytes(bytes);
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/rsa/TestKeyPairGeneratorInit.java	Sat Oct 24 01:11:51 2020 +0100
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug     8211049
+ * @summary make sure the supplied SecureRandom object is used
+ */
+
+import java.security.*;
+import java.security.interfaces.*;
+
+public class TestKeyPairGeneratorInit {
+
+    private static class MySecureRandom extends SecureRandom {
+        boolean isUsed = false;
+        public MySecureRandom() {
+            super();
+        }
+
+        public void nextBytes(byte[] bytes) {
+            isUsed = true;
+            super.nextBytes(bytes);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        KeyPairGenerator kpg =
+            KeyPairGenerator.getInstance("RSA", "SunRsaSign");
+        MySecureRandom rnd = new MySecureRandom();
+        kpg.initialize(2048, rnd);
+        System.out.println("Generate keypair then check");
+        KeyPair kp = kpg.generateKeyPair();
+        if (!rnd.isUsed) {
+            throw new RuntimeException("ERROR: Supplied random not used");
+        } else {
+            System.out.println("=> Test passed");
+        }
+    }
+}
--- a/test/sun/security/rsa/pss/PSSParametersTest.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/sun/security/rsa/pss/PSSParametersTest.java	Sat Oct 24 01:11:51 2020 +0100
@@ -31,7 +31,7 @@
 
 /**
  * @test
- * @bug 8146293
+ * @bug 8146293 8242556
  * @summary Test RSASSA-PSS AlgorithmParameters impl of SunRsaSign provider.
  * @run main PSSParametersTest
  */
@@ -41,34 +41,41 @@
      */
     private static final String PROVIDER = "SunRsaSign";
 
-    private static final String ALGO = "RSASSA-PSS";
+    private static final String PSS_ALGO = "RSASSA-PSS";
+    private static final String PSS_OID = "1.2.840.113549.1.1.10";
 
     public static void main(String[] args) throws Exception {
         System.out.println("Testing against DEFAULT parameters");
         test(PSSParameterSpec.DEFAULT);
         System.out.println("Testing against custom parameters");
-        test(new PSSParameterSpec("SHA-512/224", "MGF1", MGF1ParameterSpec.SHA384,
-            100, 1));
+        test(new PSSParameterSpec("SHA-512/224", "MGF1",
+                MGF1ParameterSpec.SHA384, 100, 1));
         System.out.println("Test Passed");
     }
 
-    // test against the given spec by initializing w/ it, generate the DER bytes,
-    // then initialize another instance w/ the DER bytes, retrieve the spec.
-    // compare both spec for equality and throw exception if the comparison failed.
+    // test the given spec by first initializing w/ it, generate the DER
+    // bytes, then initialize w/ the DER bytes, retrieve the spec.
+    // compare both spec for equality and throw exception if the check failed.
     private static void test(PSSParameterSpec spec) throws Exception {
-        AlgorithmParameters params = AlgorithmParameters.getInstance(ALGO, PROVIDER);
-        params.init(spec);
-        byte[] encoded = params.getEncoded();
-        AlgorithmParameters params2 = AlgorithmParameters.getInstance(ALGO, PROVIDER);
-        params2.init(encoded);
-        PSSParameterSpec spec2 = params2.getParameterSpec(PSSParameterSpec.class);
-        if (!isEqual(spec, spec2)) {
-            throw new RuntimeException("Spec check Failed");
+        String ALGORITHMS[] = { PSS_ALGO, PSS_OID };
+        for (String alg : ALGORITHMS) {
+            AlgorithmParameters params = AlgorithmParameters.getInstance
+                    (alg, PROVIDER);
+            params.init(spec);
+            byte[] encoded = params.getEncoded();
+            AlgorithmParameters params2 = AlgorithmParameters.getInstance
+                    (alg, PROVIDER);
+            params2.init(encoded);
+            PSSParameterSpec spec2 = params2.getParameterSpec
+                (PSSParameterSpec.class);
+            if (!isEqual(spec, spec2)) {
+                throw new RuntimeException("Spec check Failed for " +  alg);
+            }
         }
     }
 
-    private static boolean isEqual(PSSParameterSpec spec, PSSParameterSpec spec2)
-        throws Exception {
+    private static boolean isEqual(PSSParameterSpec spec,
+            PSSParameterSpec spec2) throws Exception {
         if (spec == spec2) return true;
         if (spec == null || spec2 == null) return false;
 
@@ -107,8 +114,9 @@
                     ((MGF1ParameterSpec)mgfParams).getDigestAlgorithm().equals
                          (((MGF1ParameterSpec)mgfParams2).getDigestAlgorithm());
                 if (!result) {
-                    System.out.println("Different Digest algo in MGF Parameters: " +
-                        ((MGF1ParameterSpec)mgfParams).getDigestAlgorithm() + " vs " +
+                    System.out.println("Different MGF1 digest algorithms: " +
+                        ((MGF1ParameterSpec)mgfParams).getDigestAlgorithm() +
+                        " vs " +
                         ((MGF1ParameterSpec)mgfParams2).getDigestAlgorithm());
                 }
                 return result;
--- a/test/sun/security/rsa/pss/TestPSSKeySupport.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/sun/security/rsa/pss/TestPSSKeySupport.java	Sat Oct 24 01:11:51 2020 +0100
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8146293
+ * @bug 8146293 8242556
  * @summary Test RSASSA-PSS Key related support such as KeyPairGenerator
  * and KeyFactory of the SunRsaSign provider
  */
@@ -148,5 +148,8 @@
         KeyFactory kf = KeyFactory.getInstance(ALGO, "SunRsaSign");
         test(kf, kp.getPublic());
         test(kf, kp.getPrivate());
+        test(kf, kp2.getPublic());
+        test(kf, kp2.getPrivate());
+
     }
 }
--- a/test/tools/launcher/Settings.java	Wed Oct 14 03:38:19 2020 +0100
+++ b/test/tools/launcher/Settings.java	Sat Oct 24 01:11:51 2020 +0100
@@ -65,11 +65,15 @@
     private static final String VM_SETTINGS = "VM settings:";
     private static final String PROP_SETTINGS = "Property settings:";
     private static final String LOCALE_SETTINGS = "Locale settings:";
+    private static final String SYSTEM_SETTINGS = "Operating System Metrics:";
 
     static void containsAllOptions(TestResult tr) {
         checkContains(tr, VM_SETTINGS);
         checkContains(tr, PROP_SETTINGS);
         checkContains(tr, LOCALE_SETTINGS);
+        if (System.getProperty("os.name").contains("Linux")) {
+            checkContains(tr, SYSTEM_SETTINGS);
+        }
     }
 
     static void runTestOptionDefault() throws IOException {
@@ -94,6 +98,20 @@
         }
     }
 
+    static void runTestOptionSystem() throws IOException {
+        TestResult tr = doExec(javaCmd, "-XshowSettings:system");
+        if (System.getProperty("os.name").contains("Linux")) {
+            checkNoContains(tr, VM_SETTINGS);
+            checkNoContains(tr, PROP_SETTINGS);
+            checkNoContains(tr, LOCALE_SETTINGS);
+            checkContains(tr, SYSTEM_SETTINGS);
+        } else {
+            // -XshowSettings prints all available settings when
+            // settings argument is not recognized.
+            containsAllOptions(tr);
+        }
+    }
+
     static void runTestOptionAll() throws IOException {
         init();
         TestResult tr = null;
@@ -151,6 +169,7 @@
             runTestOptionVM();
             runTestOptionProperty();
             runTestOptionLocale();
+            runTestOptionSystem();
             runTestBadOptions();
             runTest7123582();
         } catch (IOException ioe) {