Merge
authorduke
Wed, 05 Jul 2017 16:46:22 +0200
changeset 1861 4087969c2d08
parent 1860 03eb3b436021 (current diff)
parent 1859 6379062ed1b9 (diff)
child 1878 66c8fff7b93a
Merge
jdk/make/javax/sound/jsoundhs/FILES.gmk
jdk/make/javax/sound/jsoundhs/Makefile
jdk/make/javax/sound/jsoundhs/mapfile-vers
jdk/src/share/classes/com/sun/beans/ObjectHandler.java
jdk/src/share/lib/audio/soundbank.gm
--- a/.hgtags-top-repo	Thu Jan 29 13:21:02 2009 -0800
+++ b/.hgtags-top-repo	Wed Jul 05 16:46:22 2017 +0200
@@ -19,3 +19,4 @@
 94052b87287303527125026fe4b2698cf867ea83 jdk7-b42
 848e684279d2ba42577d9621d5b2e5af3823d12d jdk7-b43
 a395e3aac4744cc9033fcd819fad1239a45add52 jdk7-b44
+99846f001ca214015578d593802d26e27246a802 jdk7-b45
--- a/corba/.hgtags	Thu Jan 29 13:21:02 2009 -0800
+++ b/corba/.hgtags	Wed Jul 05 16:46:22 2017 +0200
@@ -19,3 +19,4 @@
 ccd6a16502e0650d91d85c4b86be05cbcd461a87 jdk7-b42
 9cd740d48a4855321d69f137a7109c00bcda76be jdk7-b43
 9803dac7254041b30ca65e3852d4c566b9757c3b jdk7-b44
+68814aa5b44b1f16931a97e7cd4028c70eb9586b jdk7-b45
--- a/hotspot/.hgtags	Thu Jan 29 13:21:02 2009 -0800
+++ b/hotspot/.hgtags	Wed Jul 05 16:46:22 2017 +0200
@@ -19,3 +19,4 @@
 ad8c8ca4ab0f4c86e74c061958f44a8f4a930f2c jdk7-b42
 fc6a5ae3fef5ebacfa896dbb3ae37715e388e282 jdk7-b43
 809e899c638bd9b21836abf9d09ab2a30ff3900b jdk7-b44
+945bf754069766e76873c53102fae48abf04cf5b jdk7-b45
--- a/jaxp/.hgtags	Thu Jan 29 13:21:02 2009 -0800
+++ b/jaxp/.hgtags	Wed Jul 05 16:46:22 2017 +0200
@@ -19,3 +19,4 @@
 036e0dca841a5a17f784d15c86a9da88d2a6f1e6 jdk7-b42
 96fe28d4a9131e1a97bfe00f779e5626cd09c4d0 jdk7-b43
 b203df0741af3eb08687bc5eb798bac87363758d jdk7-b44
+0f113667880d335cfa2c35721b1b45144fb757f5 jdk7-b45
--- a/jdk/.hgtags	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/.hgtags	Wed Jul 05 16:46:22 2017 +0200
@@ -19,3 +19,4 @@
 3ef0bdfa7609f79d4f2ea621f30cf593a2e432ce jdk7-b42
 50c67678b0d180063ade199d398b67a54063fa7f jdk7-b43
 d8eb2738db6b148911177d9bcfe888109b7f2f71 jdk7-b44
+527b426497a259d0605d069e3930e838948531a6 jdk7-b45
--- a/jdk/make/com/sun/org/apache/xml/Makefile	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/com/sun/org/apache/xml/Makefile	Wed Jul 05 16:46:22 2017 +0200
@@ -41,7 +41,7 @@
 # Resources
 #
 LOCALE_SET_DEFINITION = jre
-NEW_RESOURCE_BUNDLES_PROPERTIES = \
+NEW_RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES = \
    $(PKGDIR)/internal/security/resource/config.dtd \
    $(PKGDIR)/internal/security/resource/config.xml \
    $(PKGDIR)/internal/security/resource/xmlsecurity_de.properties \
--- a/jdk/make/com/sun/rowset/Makefile	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/com/sun/rowset/Makefile	Wed Jul 05 16:46:22 2017 +0200
@@ -41,7 +41,7 @@
 # Resources
 #
 LOCALE_SET_DEFINITION = jre
-RESOURCE_BUNDLES_PROPERTIES = $(PKGDIR)/RowSetResourceBundle.properties
+RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES = $(PKGDIR)/RowSetResourceBundle.properties
 
 #
 # Rules
--- a/jdk/make/common/Release.gmk	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/common/Release.gmk	Wed Jul 05 16:46:22 2017 +0200
@@ -912,14 +912,6 @@
 	done
   ifeq ($(PLATFORM), windows)
 	@#
-	@# Audio soundbank - Bug# 4236400
-	@# Windows only: adding audio files to JDK's jre/lib directory.
-	@#
-	($(CD) $(LIBDIR) && $(TAR) cf - \
-	    `$(FIND) audio -depth -print`) | \
-	    ($(CD) $(JDK_IMAGE_DIR)/jre/lib && $(TAR) xf -)
-	@#
-	@#
 	@# lib/
 	@#
 	$(CP) $(LIBDIR)/$(LIB_PREFIX)jvm.$(LIB_SUFFIX) $(JDK_IMAGE_DIR)/lib
--- a/jdk/make/common/internal/BinaryPlugs.gmk	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/common/internal/BinaryPlugs.gmk	Wed Jul 05 16:46:22 2017 +0200
@@ -29,9 +29,7 @@
 
 # Names of native shared libraries
 
-PLUG_JSOUND_LIBRARY=$(LIB_PREFIX)jsoundhs.$(LIBRARY_SUFFIX)
-PLUG_LIBRARY_NAMES = \
-    $(PLUG_JSOUND_LIBRARY)
+PLUG_LIBRARY_NAMES=
 
 # Sub-directory where native shared libraries are located (e.g. jre/bin or...)
 
@@ -74,62 +72,10 @@
 com/sun/jmx/snmp/daemon/SnmpTimerServer.class \
 com/sun/jmx/snmp/daemon/WaitQ.class
 
-PLUG_SOUND_CLASS_NAMES = \
-com/sun/media/sound/AbstractPlayer.class \
-com/sun/media/sound/CircularBuffer.class \
-com/sun/media/sound/HeadspaceInstrument.class \
-com/sun/media/sound/HeadspaceMixer\$$1.class \
-com/sun/media/sound/HeadspaceMixer\$$MidiLine.class \
-com/sun/media/sound/HeadspaceMixer\$$MidiLineInfo.class \
-com/sun/media/sound/HeadspaceMixer\$$MixerInfo.class \
-com/sun/media/sound/HeadspaceMixer\$$MixerReverbControl\$$MixerReverbType.class \
-com/sun/media/sound/HeadspaceMixer\$$MixerReverbControl.class \
-com/sun/media/sound/HeadspaceMixer.class \
-com/sun/media/sound/HeadspaceMixerProvider.class \
-com/sun/media/sound/HeadspaceSample.class \
-com/sun/media/sound/HeadspaceSoundbank.class \
-com/sun/media/sound/HsbParser.class \
-com/sun/media/sound/MixerClip\$$1.class \
-com/sun/media/sound/MixerClip\$$MixerClipApplyReverbControl.class \
-com/sun/media/sound/MixerClip\$$MixerClipGainControl.class \
-com/sun/media/sound/MixerClip\$$MixerClipMuteControl.class \
-com/sun/media/sound/MixerClip\$$MixerClipPanControl.class \
-com/sun/media/sound/MixerClip\$$MixerClipSampleRateControl.class \
-com/sun/media/sound/MixerClip.class \
-com/sun/media/sound/MixerMidiChannel.class \
-com/sun/media/sound/MixerSequencer\$$1.class \
-com/sun/media/sound/MixerSequencer\$$ControllerVectorElement.class \
-com/sun/media/sound/MixerSequencer\$$MixerSequencerInfo.class \
-com/sun/media/sound/MixerSequencer\$$RecordingTrack.class \
-com/sun/media/sound/MixerSequencer.class \
-com/sun/media/sound/MixerSequencerProvider.class \
-com/sun/media/sound/MixerSourceLine\$$1.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLineApplyReverbControl.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLineGainControl.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLineMuteControl.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLinePanControl.class \
-com/sun/media/sound/MixerSourceLine\$$MixerSourceLineSampleRateControl.class \
-com/sun/media/sound/MixerSourceLine.class \
-com/sun/media/sound/MixerSynth\$$1.class \
-com/sun/media/sound/MixerSynth\$$MixerSynthInfo.class \
-com/sun/media/sound/MixerSynth\$$SynthReceiver.class \
-com/sun/media/sound/MixerSynth.class \
-com/sun/media/sound/MixerSynthProvider.class \
-com/sun/media/sound/MixerThread.class \
-com/sun/media/sound/RmfFileReader.class \
-com/sun/media/sound/SimpleInputDevice\$$1.class \
-com/sun/media/sound/SimpleInputDevice\$$InputDeviceDataLine.class \
-com/sun/media/sound/SimpleInputDevice\$$InputDevicePort.class \
-com/sun/media/sound/SimpleInputDevice\$$InputDevicePortInfo.class \
-com/sun/media/sound/SimpleInputDevice.class \
-com/sun/media/sound/SimpleInputDeviceProvider\$$1.class \
-com/sun/media/sound/SimpleInputDeviceProvider\$$InputDeviceInfo.class \
-com/sun/media/sound/SimpleInputDeviceProvider.class
-
 # Class list temp files (used by both import and export of plugs)
 
 PLUG_TEMPDIR=$(ABS_TEMPDIR)/plugs
-PLUG_CLASS_AREAS = jmf sound
+PLUG_CLASS_AREAS = jmf
 PLUG_CLISTS = $(PLUG_CLASS_AREAS:%=$(PLUG_TEMPDIR)/%.clist)
 
 # Create jargs file command
@@ -147,18 +93,11 @@
 	@for i in $(PLUG_JMF_CLASS_NAMES) ; do \
 	  $(ECHO) "$$i" >> $@; \
 	done
-$(PLUG_TEMPDIR)/sound.clist:
-	@$(prep-target)
-	@for i in $(PLUG_SOUND_CLASS_NAMES) ; do \
-	  $(ECHO) "$$i" >> $@ ; \
-	done
 $(PLUG_TEMPDIR)/all.clist: $(PLUG_CLISTS)
 	@$(prep-target)
 	$(CAT) $(PLUG_CLISTS) > $@
 $(PLUG_TEMPDIR)/jmf.jargs: $(PLUG_TEMPDIR)/jmf.clist
 	$(plug-create-jargs)
-$(PLUG_TEMPDIR)/sound.jargs: $(PLUG_TEMPDIR)/sound.clist
-	$(plug-create-jargs)
 $(PLUG_TEMPDIR)/all.jargs: $(PLUG_TEMPDIR)/all.clist
 	$(plug-create-jargs)
 
@@ -193,25 +132,11 @@
 
 import-binary-plug-jmf-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/jmf.clist
 	$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/jmf.clist)
-import-binary-plug-sound-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/sound.clist
-	$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/sound.clist)
 
 # Import all classes from the jar file
 
 import-binary-plug-jar: \
-	     import-binary-plug-jmf-classes \
-	     import-binary-plug-sound-classes
-
-# Import native libraries
-
-$(LIB_LOCATION)/$(PLUG_JSOUND_LIBRARY): \
-    $(PLUG_IMPORT_DIR)/$(PLUG_LOCATION_SUBDIR)/$(PLUG_JSOUND_LIBRARY)
-	$(import-binary-plug-file)
-
-# Rules only used by lower level makefiles
-
-import-binary-plug-jsound-library: \
-    $(LIB_LOCATION)/$(PLUG_JSOUND_LIBRARY)
+	     import-binary-plug-jmf-classes
 
 # Binary plug start/complete messages
 
@@ -241,9 +166,7 @@
 	import-binary-plugs-libs \
 	import-binary-plugs \
 	import-binary-plug-jar \
-        import-binary-plug-jmf-classes \
-        import-binary-plug-sound-classes \
-        import-binary-plug-jsound-library
+	import-binary-plug-jmf-classes
 
 else # !OPENJDK
 
@@ -280,12 +203,6 @@
 	@$(java-vm-cleanup)
 export-binary-plugs-jar: $(PLUG_EXPORT_JARFILE)
 
-# Export native libraries
-
-$(PLUG_EXPORT_DIR)/$(PLUG_LOCATION_SUBDIR)/$(PLUG_JSOUND_LIBRARY): \
-    $(LIB_LOCATION)/$(PLUG_JSOUND_LIBRARY)
-	$(export-binary-plug-file)
-
 # Export binary plug start/complete messages
 
 export-binary-plugs-started:
--- a/jdk/make/common/internal/Resources.gmk	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/common/internal/Resources.gmk	Wed Jul 05 16:46:22 2017 +0200
@@ -44,12 +44,8 @@
 #
 #   NEW_RESOURCE_BUNDLES_JAVA        - new resource bundles implemented in
 #                                      Java, not localized
-#   NEW_RESOURCE_BUNDLES_PROPERTIES  - new resource bundles implemented as
-#                                      properties files, not localized
 #   RESOURCE_BUNDLES_JAVA            - resource bundles implemented in
 #                                      Java, localized
-#   RESOURCE_BUNDLES_PROPERTIES      - new resource bundles implemented as
-#                                      properties files, localized
 #
 # The following variable is now used for most .properties files in the JDK. 
 # These properties files are converted into java and compiled with javac.
@@ -61,6 +57,13 @@
 #                                          properties files, localized
 #   NEW_RESOURCE_BUNDLES_COMPILED_PROPERTIES - same as above, not localized
 #
+# For non-compiled properties files, use the following variables:
+#
+#   NEW_RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES  - new resource bundles implemented as
+#                                      properties files, not localized
+#   RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES      - resource bundles implemented as
+#                                      properties files, localized
+#
 # Other properties files to be installed are identified using the variable:
 #
 #   OTHER_PROPERTIES
@@ -109,11 +112,12 @@
 FILES_java += $(COMPILED_PROPERTIES:%.properties=%.java)
 
 # Non-compiled files
-PROPERTIES_FILES += $(NEW_RESOURCE_BUNDLES_PROPERTIES)
-PROPERTIES_FILES += $(RESOURCE_BUNDLES_PROPERTIES) \
-    $(foreach file,$(RESOURCE_BUNDLES_PROPERTIES), \
+PROPERTIES_FILES += $(NEW_RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES)
+PROPERTIES_FILES += $(RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES) \
+    $(foreach file,$(RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES), \
        $(foreach locale,$(LOCALE_SUFFIXES), \
 	  $(basename $(file))_$(locale)$(suffix $(file))))
+# other properties
 PROPERTIES_FILES += $(OTHER_PROPERTIES)
 
 #
--- a/jdk/make/javax/sound/Makefile	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/javax/sound/Makefile	Wed Jul 05 16:46:22 2017 +0200
@@ -54,18 +54,6 @@
 AUTO_FILES_JAVA_DIRS = javax/sound com/sun/media/sound
 
 #
-# Specific to OpenJDK building
-#
-ifdef OPENJDK
-
-# copy closed .class files
-build: import-binary-plug-sound-classes 
-
-include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
-
-endif # OPENJDK
-
-#
 # Files that just need cp.
 #
 SERVICEDIR = $(CLASSBINDIR)/META-INF/services
@@ -79,13 +67,11 @@
 	$(SERVICEDIR)/javax.sound.sampled.spi.AudioFileReader \
 	$(SERVICEDIR)/javax.sound.sampled.spi.FormatConversionProvider \
 	$(SERVICEDIR)/javax.sound.sampled.spi.MixerProvider \
-	$(LIBDIR)/audio/soundbank.gm \
 	$(LIBDIR)/sound.properties
 
 FILES_mkdirs = \
 	$(CLASSBINDIR)/META-INF \
-	$(CLASSBINDIR)/META-INF/services \
-	$(LIBDIR)/audio
+	$(CLASSBINDIR)/META-INF/services
 
 FILES_copydirs = \
 	$(CLASSBINDIR) \
@@ -96,11 +82,6 @@
 
 
 #
-# add "closed" library
-#
-SUBDIRS += jsoundhs
-
-#
 # system dependent flags
 #
 ifeq ($(PLATFORM), windows)
--- a/jdk/make/javax/sound/jsoundhs/FILES.gmk	Thu Jan 29 13:21:02 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#
-# Copyright 2007 Sun Microsystems, 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.  Sun designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-#
-
-FILES_c = \
-	Utilities.c \
-	MixerThread.c \
-	HeadspaceMixer.c \
-	MixerClip.c \
-	MixerSourceLine.c \
-	SimpleInputDevice.c \
-	SimpleInputDeviceProvider.c \
-	HeadspaceSoundbank.c \
-	MixerMidiChannel.c \
-	AbstractPlayer.c \
-	MixerSequencer.c \
-	MixerSynth.c
-
-FILES_engine = \
-	DriverTools.c \
-	GenAudioCaptureStreams.c \
-	GenAudioStreams.c \
-	GenOutput.c \
-	GenPatch.c \
-	GenReverb.c \
-	GenSample.c \
-	GenSeq.c \
-	GenSetup.c \
-	GenSong.c \
-	GenSynth.c \
-	GenSynthFilters.c \
-	GenSynthInterp2.c \
-	GenSynthResample.c \
-	NewNewLZSS.c \
-	SampleTools.c \
-	SMOD_Volume_Scaler.c \
-	X_API.c \
-	X_Decompress.c \
-	X_IMA.c \
-	GenFiltersReverb.c \
-	GenInterp2Reverb.c \
-	GenSoundFiles.c \
-	SincResample.c
-
-FILES_solaris = \
-	HAE_API_SolarisOS.c \
-	HAE_API_SolarisOS_Capture.c
-
-FILES_linux = \
-	HAE_API_LinuxOS.c \
-	HAE_API_LinuxOS_Capture.c
-
-FILES_windows = \
-	HAE_API_WinOS.c \
-	HAE_API_WinOS_Capture.c \
-	HAE_API_WinOS_Synth.c
-
-FILES_export = \
-	com/sun/media/sound/AbstractPlayer.java \
-	com/sun/media/sound/HeadspaceMixer.java \
-	com/sun/media/sound/HeadspaceSoundbank.java \
-	com/sun/media/sound/MixerClip.java \
-	com/sun/media/sound/MixerMidiChannel.java \
-	com/sun/media/sound/MixerSequencer.java \
-	com/sun/media/sound/MixerSourceLine.java \
-	com/sun/media/sound/MixerSynth.java \
-	com/sun/media/sound/MixerThread.java \
-	com/sun/media/sound/SimpleInputDevice.java \
-	com/sun/media/sound/SimpleInputDeviceProvider.java
-
--- a/jdk/make/javax/sound/jsoundhs/Makefile	Thu Jan 29 13:21:02 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-#
-# Copyright 2007 Sun Microsystems, 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.  Sun designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-#
-
-BUILDDIR = ../../..
-PACKAGE = javax.sound
-LIBRARY = jsoundhs
-PRODUCT = sun
-CPLUSPLUSLIBRARY = true
-include $(BUILDDIR)/common/Defs.gmk
-
-# this Makefile compiles "closed" JavaSound library
-
-ifdef OPENJDK
-
-# precompiled lib will be copied by the rules in Library.gmk instead of compiling.
-USE_BINARY_PLUG_LIBRARY=true
-
-build: import-binary-plug-jsound-library
-
-include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
-
-else # OPENJDK
-
-# include defines for sound
-include ../SoundDefs.gmk
-
-#
-# Add use of mapfile
-#
-FILES_m = mapfile-vers
-include $(BUILDDIR)/common/Mapfile-vers.gmk
-
-#
-# Files
-#
-include FILES.gmk
-
-FILES_c += $(FILES_engine) $(FILES_$(PLATFORM))
-
-#
-# Extra cc/linker flags.
-#
-# flags needed for all platforms
-CPPFLAGS += \
-	-DJAVA_SOUND -DJAVA_THREAD \
-	-I$(CLOSED_SHARE_SRC)/native/com/sun/media/sound \
-	-I$(CLOSED_SHARE_SRC)/native/com/sun/media/sound/engine
-
-# system dependent flags
-ifeq ($(PLATFORM), windows)
-  CPPFLAGS += 	-DUSE_DIRECTSOUND=0 \
-		-DUSE_EXTERNAL_SYNTH=TRUE
-  LDLIBS += winmm.lib
-endif # PLATFORM windows
-
-ifeq ($(PLATFORM), linux)
-endif # PLATFORM linux
-
-ifeq ($(PLATFORM), solaris)
-endif # PLATFORM solaris
-
-
-#
-# Add to the ambient VPATH.
-#
-vpath %.c $(CLOSED_SHARE_SRC)/native/com/sun/media/sound
-vpath %.c $(CLOSED_SHARE_SRC)/native/com/sun/media/sound/engine
-vpath %.c $(CLOSED_PLATFORM_SRC)/native/com/sun/media/sound/engine
-
-
-endif # OPENJDK
-
-
-#
-# Include rules
-#
-include $(BUILDDIR)/common/Library.gmk
-
--- a/jdk/make/javax/sound/jsoundhs/mapfile-vers	Thu Jan 29 13:21:02 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-#
-# Copyright 2007 Sun Microsystems, 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.  Sun designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-#
-
-# Define library interface.
-
-SUNWprivate_1.1 {
-	global:
-            Java_com_sun_media_sound_AbstractPlayer_nAddReceiver;
-            Java_com_sun_media_sound_AbstractPlayer_nClose;
-            Java_com_sun_media_sound_AbstractPlayer_nLoadInstrument;
-            Java_com_sun_media_sound_AbstractPlayer_nRemapInstrument;
-            Java_com_sun_media_sound_AbstractPlayer_nRemoveReceiver;
-            Java_com_sun_media_sound_AbstractPlayer_nUnloadInstrument;
-            Java_com_sun_media_sound_HeadspaceMixer_nAllocateVoices;
-            Java_com_sun_media_sound_HeadspaceMixer_nCloseMixer;
-            Java_com_sun_media_sound_HeadspaceMixer_nCreateLinkedStreams;
-            Java_com_sun_media_sound_HeadspaceMixer_nDrain;
-            Java_com_sun_media_sound_HeadspaceMixer_nFlush;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetCpuLoad;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetDefaultBufferSize;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetLevel;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetPosition;
-            Java_com_sun_media_sound_HeadspaceMixer_nGetTotalVoices;
-            Java_com_sun_media_sound_HeadspaceMixer_nOpenMixer;
-            Java_com_sun_media_sound_HeadspaceMixer_nPause;
-            Java_com_sun_media_sound_HeadspaceMixer_nResume;
-            Java_com_sun_media_sound_HeadspaceMixer_nSetInterpolation;
-            Java_com_sun_media_sound_HeadspaceMixer_nSetMixerFormat;
-            Java_com_sun_media_sound_HeadspaceMixer_nSetMixLevel;
-            Java_com_sun_media_sound_HeadspaceMixer_nSetReverb;
-            Java_com_sun_media_sound_HeadspaceMixer_nStartLinkedStreams;
-            Java_com_sun_media_sound_HeadspaceMixer_nStopLinkedStreams;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nCloseResource;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetInstruments;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetName;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetSamples;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetVersionMajor;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetVersionMinor;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nGetVersionSubMinor;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResource;
-            Java_com_sun_media_sound_HeadspaceSoundbank_nOpenResourceFromByteArray;
-            Java_com_sun_media_sound_MixerClip_nClose;
-            Java_com_sun_media_sound_MixerClip_nDrain;
-            Java_com_sun_media_sound_MixerClip_nFlush;
-            Java_com_sun_media_sound_MixerClip_nGetPosition;
-            Java_com_sun_media_sound_MixerClip_nOpen;
-            Java_com_sun_media_sound_MixerClip_nSetLinearGain;
-            Java_com_sun_media_sound_MixerClip_nSetPan;
-            Java_com_sun_media_sound_MixerClip_nSetSampleRate;
-            Java_com_sun_media_sound_MixerClip_nSetup;
-            Java_com_sun_media_sound_MixerClip_nStart;
-            Java_com_sun_media_sound_MixerClip_nStop;
-            Java_com_sun_media_sound_MixerMidiChannel_nAllNotesOff;
-            Java_com_sun_media_sound_MixerMidiChannel_nControlChange;
-            Java_com_sun_media_sound_MixerMidiChannel_nGetController;
-            Java_com_sun_media_sound_MixerMidiChannel_nGetPitchBend;
-            Java_com_sun_media_sound_MixerMidiChannel_nGetSolo;
-            Java_com_sun_media_sound_MixerMidiChannel_nNoteOff;
-            Java_com_sun_media_sound_MixerMidiChannel_nNoteOn;
-            Java_com_sun_media_sound_MixerMidiChannel_nProgramChange__JIIIJ;
-            Java_com_sun_media_sound_MixerMidiChannel_nProgramChange__JIIJ;
-            Java_com_sun_media_sound_MixerMidiChannel_nResetAllControllers;
-            Java_com_sun_media_sound_MixerMidiChannel_nSetMute;
-            Java_com_sun_media_sound_MixerMidiChannel_nSetPitchBend;
-            Java_com_sun_media_sound_MixerMidiChannel_nSetSolo;
-            Java_com_sun_media_sound_MixerSequencer_nAddControllerEventCallback;
-            Java_com_sun_media_sound_MixerSequencer_nGetMasterTempo;
-            Java_com_sun_media_sound_MixerSequencer_nGetSequenceMicrosecondLength;
-            Java_com_sun_media_sound_MixerSequencer_nGetSequencerMicrosecondPosition;
-            Java_com_sun_media_sound_MixerSequencer_nGetSequencerTickPosition;
-            Java_com_sun_media_sound_MixerSequencer_nGetSequenceTickLength;
-            Java_com_sun_media_sound_MixerSequencer_nGetTempoInBPM;
-            Java_com_sun_media_sound_MixerSequencer_nGetTempoInMPQ;
-            Java_com_sun_media_sound_MixerSequencer_nGetTrackMute;
-            Java_com_sun_media_sound_MixerSequencer_nGetTrackSolo;
-            Java_com_sun_media_sound_MixerSequencer_nOpenMidiSequencer;
-            Java_com_sun_media_sound_MixerSequencer_nOpenRmfSequencer;
-            Java_com_sun_media_sound_MixerSequencer_nPauseSequencer;
-            Java_com_sun_media_sound_MixerSequencer_nResumeSequencer;
-            Java_com_sun_media_sound_MixerSequencer_nSetMasterTempo;
-            Java_com_sun_media_sound_MixerSequencer_nSetSequencerMicrosecondPosition;
-            Java_com_sun_media_sound_MixerSequencer_nSetSequencerTickPosition;
-            Java_com_sun_media_sound_MixerSequencer_nSetTempoInBPM;
-            Java_com_sun_media_sound_MixerSequencer_nSetTempoInMPQ;
-            Java_com_sun_media_sound_MixerSequencer_nSetTrackMute;
-            Java_com_sun_media_sound_MixerSequencer_nSetTrackSolo;
-            Java_com_sun_media_sound_MixerSequencer_nStartSequencer;
-            Java_com_sun_media_sound_MixerSourceLine_nClose;
-            Java_com_sun_media_sound_MixerSourceLine_nDrain;
-            Java_com_sun_media_sound_MixerSourceLine_nFlush;
-            Java_com_sun_media_sound_MixerSourceLine_nGetLevel;
-            Java_com_sun_media_sound_MixerSourceLine_nGetPosition;
-            Java_com_sun_media_sound_MixerSourceLine_nOpen;
-            Java_com_sun_media_sound_MixerSourceLine_nPause;
-            Java_com_sun_media_sound_MixerSourceLine_nResume;
-            Java_com_sun_media_sound_MixerSourceLine_nSetLinearGain;
-            Java_com_sun_media_sound_MixerSourceLine_nSetPan;
-            Java_com_sun_media_sound_MixerSourceLine_nSetSampleRate;
-            Java_com_sun_media_sound_MixerSourceLine_nStart;
-            Java_com_sun_media_sound_MixerSynth_nCreateSynthesizer;
-            Java_com_sun_media_sound_MixerSynth_nDestroySynthesizer;
-            Java_com_sun_media_sound_MixerSynth_nGetLatency;
-            Java_com_sun_media_sound_MixerSynth_nLoadInstrument;
-            Java_com_sun_media_sound_MixerSynth_nRemapInstrument;
-            Java_com_sun_media_sound_MixerSynth_nStartSynthesizer;
-            Java_com_sun_media_sound_MixerSynth_nUnloadInstrument;
-            Java_com_sun_media_sound_MixerThread_runNative;
-            Java_com_sun_media_sound_SimpleInputDevice_nClose;
-            Java_com_sun_media_sound_SimpleInputDevice_nDrain;
-            Java_com_sun_media_sound_SimpleInputDevice_nFlush;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetBufferSizeInFrames;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetFormats;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetNumPorts;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetPortName;
-            Java_com_sun_media_sound_SimpleInputDevice_nGetPosition;
-            Java_com_sun_media_sound_SimpleInputDevice_nOpen;
-            Java_com_sun_media_sound_SimpleInputDevice_nPause;
-            Java_com_sun_media_sound_SimpleInputDevice_nResume;
-            Java_com_sun_media_sound_SimpleInputDevice_nStart;
-            Java_com_sun_media_sound_SimpleInputDevice_nStop;
-            Java_com_sun_media_sound_SimpleInputDevice_nSupportsChannels;
-            Java_com_sun_media_sound_SimpleInputDevice_nSupportsSampleRate;
-            Java_com_sun_media_sound_SimpleInputDevice_nSupportsSampleSizeInBits;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetDescription;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetName;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetNumDevices;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetVendor;
-            Java_com_sun_media_sound_SimpleInputDeviceProvider_nGetVersion;
-	local:
-	    *;
-};
--- a/jdk/make/sun/javazic/tzdata/VERSION	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/VERSION	Wed Jul 05 16:46:22 2017 +0200
@@ -21,4 +21,4 @@
 # CA 95054 USA or visit www.sun.com if you need additional information or
 # have any questions.
 #
-tzdata2008e
+tzdata2009a
--- a/jdk/make/sun/javazic/tzdata/africa	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/africa	Wed Jul 05 16:46:22 2017 +0200
@@ -458,11 +458,36 @@
 # http://www.worldtimezone.com/dst_news/dst_news_mauritius02.html
 # </a>
 
+# From Riad M. Hossen Ally (2008-08-03):
+# The Government of Mauritius weblink
+# <a href="http://www.gov.mu/portal/site/pmosite/menuitem.4ca0efdee47462e7440a600248a521ca/?content_id=3D4728ca68b2a5b110VgnVCM1000000a04a8c0RCRD">
+# http://www.gov.mu/portal/site/pmosite/menuitem.4ca0efdee47462e7440a600248a521ca/?content_id=3D4728ca68b2a5b110VgnVCM1000000a04a8c0RCRD
+# </a>
+# Cabinet Decision of July 18th, 2008 states as follows:
+#
+# 4. ...Cabinet has agreed to the introduction into the National Assembly
+# of the Time Bill which provides for the introduction of summer time in
+# Mauritius. The summer time period which will be of one hour ahead of
+# the standard time, will be aligned with that in Europe and the United
+# States of America. It will start at two o'clock in the morning on the
+# last Sunday of October and will end at two o'clock in the morning on
+# the last Sunday of March the following year. The summer time for the
+# year 2008 - 2009 will, therefore, be effective as from 26 October 2008
+# and end on 29 March 2009.
+
+# From Ed Maste (2008-10-07):
+# THE TIME BILL (No. XXVII of 2008) Explanatory Memorandum states the
+# beginning / ending of summer time is 2 o'clock standard time in the
+# morning of the last Sunday of October / last Sunday of March.
+# <a href="http://www.gov.mu/portal/goc/assemblysite/file/bill2708.pdf">
+# http://www.gov.mu/portal/goc/assemblysite/file/bill2708.pdf
+# </a>
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule Mauritius	1982	only	-	Oct	10	0:00	1:00	S
 Rule Mauritius	1983	only	-	Mar	21	0:00	0	-
-Rule Mauritius	2008	only	-	Oct	26	2:00s	1:00	S
-Rule Mauritius	2009	only	-	Mar	27	2:00s	0	-
+Rule Mauritius	2008	max	-	Oct	lastSun	2:00s	1:00	S
+Rule Mauritius	2009	max	-	Mar	lastSun	2:00s	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Indian/Mauritius	3:50:00 -	LMT	1907		# Port Louis
 			4:00 Mauritius	MU%sT	# Mauritius Time
@@ -547,7 +572,22 @@
 # From Arthur David Olson (2008-05-09):
 # XXX--guess that it is only Morocco for now; guess only 2008 for now.
 
+# From Steffen Thorsen (2008-08-27):
+# Morocco will change the clocks back on the midnight between August 31 
+# and September 1. They originally planned to observe DST to near the end 
+# of September:
+#
+# One article about it (in French):
+# <a href="http://www.menara.ma/fr/Actualites/Maroc/Societe/ci.retour_a_l_heure_gmt_a_partir_du_dimanche_31_aout_a_minuit_officiel_.default">
+# http://www.menara.ma/fr/Actualites/Maroc/Societe/ci.retour_a_l_heure_gmt_a_partir_du_dimanche_31_aout_a_minuit_officiel_.default
+# </a>
+#
+# We have some further details posted here:
+# <a href="http://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html">
+# http://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html
+# </a>
 # RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+
 Rule	Morocco	1939	only	-	Sep	12	 0:00	1:00	S
 Rule	Morocco	1939	only	-	Nov	19	 0:00	0	-
 Rule	Morocco	1940	only	-	Feb	25	 0:00	1:00	S
@@ -564,7 +604,7 @@
 Rule	Morocco	1978	only	-	Jun	 1	 0:00	1:00	S
 Rule	Morocco	1978	only	-	Aug	 4	 0:00	0	-
 Rule	Morocco	2008	only	-	Jun	 1	 0:00	1:00	S
-Rule	Morocco	2008	only	-	Sep	28	 0:00	0	-
+Rule	Morocco	2008	only	-	Sep	 1	 0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Casablanca	-0:30:20 -	LMT	1913 Oct 26
 			 0:00	Morocco	WE%sT	1984 Mar 16
--- a/jdk/make/sun/javazic/tzdata/asia	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/asia	Wed Jul 05 16:46:22 2017 +0200
@@ -1496,7 +1496,7 @@
 
 # Nepal
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Katmandu	5:41:16 -	LMT	1920
+Zone	Asia/Kathmandu	5:41:16 -	LMT	1920
 			5:30	-	IST	1986
 			5:45	-	NPT	# Nepal Time
 
@@ -1563,11 +1563,24 @@
 # From Arthur David Olson (2008-05-19):
 # XXX--midnight transitions is a guess; 2008 only is a guess.
 
+# From Alexander Krivenyshev (2008-08-28):
+# Pakistan government has decided to keep the watches one-hour advanced
+# for another 2 months--plan to return to Standard Time on October 31
+# instead of August 31.
+#
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan02.html">
+# http://www.worldtimezone.com/dst_news/dst_news_pakistan02.html
+# </a>
+# OR
+# <a href="http://dailymailnews.com/200808/28/news/dmbrn03.html">
+# http://dailymailnews.com/200808/28/news/dmbrn03.html
+# </a>
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule Pakistan	2002	only	-	Apr	Sun>=2	0:01	1:00	S
 Rule Pakistan	2002	only	-	Oct	Sun>=2	0:01	0	-
 Rule Pakistan	2008	only	-	Jun	1	0:00	1:00	S
-Rule Pakistan	2008	only	-	Sep	1	0:00	0	-
+Rule Pakistan	2008	only	-	Nov	1	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Karachi	4:28:12 -	LMT	1907
 			5:30	-	IST	1942 Sep
@@ -1687,6 +1700,23 @@
 # For lack of better information, predict that future changes will be
 # the 2nd Thursday of September at 02:00.
 
+# From Alexander Krivenyshev (2008-08-28):
+# Here is an article, that Mideast running on different clocks at Ramadan.
+#
+# Gaza Strip (as Egypt) ended DST at midnight Thursday (Aug 28, 2008), while
+# the West Bank will end Daylight Saving Time at midnight Sunday (Aug 31, 2008).
+#
+# <a href="http://www.guardian.co.uk/world/feedarticle/7759001">
+# http://www.guardian.co.uk/world/feedarticle/7759001
+# </a>
+# <a href="http://www.abcnews.go.com/International/wireStory?id=5676087">
+# http://www.abcnews.go.com/International/wireStory?id=5676087
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_gazastrip01.html">
+# http://www.worldtimezone.com/dst_news/dst_news_gazastrip01.html
+# </a>
+
 # The rules for Egypt are stolen from the `africa' file.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
@@ -1702,7 +1732,8 @@
 Rule Palestine	2005	only	-	Oct	 4	2:00	0	-
 Rule Palestine	2006	max	-	Apr	 1	0:00	1:00	S
 Rule Palestine	2006	only	-	Sep	22	0:00	0	-
-Rule Palestine	2007	max	-	Sep	Thu>=8	2:00	0	-
+Rule Palestine	2007	only	-	Sep	Thu>=8	2:00	0	-
+Rule Palestine	2008	max	-	Aug	lastThu	2:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
@@ -1948,8 +1979,20 @@
 # compilers can't handle  or having multiple Rules (a la Israel).
 # For now, use "Apr Fri>=1", and go with IATA on a uniform Sep 30 end.
 
+# From Steffen Thorsen (2008-10-07):
+# Syria has now officially decided to end DST on 2008-11-01 this year,
+# according to the following article in the Syrian Arab News Agency (SANA).
+#
+# The article is in Arabic, and seems to tell that they will go back to
+# winter time on 2008-11-01 at 00:00 local daylight time (delaying/setting
+# clocks back 60 minutes).
+#
+# <a href="http://sana.sy/ara/2/2008/10/07/195459.htm">
+# http://sana.sy/ara/2/2008/10/07/195459.htm
+# </a>
+
 Rule	Syria	2008	max	-	Apr	Fri>=1	0:00	1:00	S
-Rule	Syria	2008	max	-	Oct	1	0:00	0	-
+Rule	Syria	2008	max	-	Nov	1	0:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Damascus	2:25:12 -	LMT	1920	# Dimashq
--- a/jdk/make/sun/javazic/tzdata/backward	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/backward	Wed Jul 05 16:46:22 2017 +0200
@@ -46,6 +46,7 @@
 Link	Asia/Ashgabat		Asia/Ashkhabad
 Link	Asia/Chongqing		Asia/Chungking
 Link	Asia/Dhaka		Asia/Dacca
+Link	Asia/Kathmandu		Asia/Katmandu
 Link	Asia/Kolkata		Asia/Calcutta
 Link	Asia/Macau		Asia/Macao
 Link	Asia/Jerusalem		Asia/Tel_Aviv
--- a/jdk/make/sun/javazic/tzdata/europe	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/europe	Wed Jul 05 16:46:22 2017 +0200
@@ -2335,11 +2335,64 @@
 # mean time in preference to apparent time -- Geneva from 1780 ....
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 # From Whitman (who writes ``Midnight?''):
-Rule	Swiss	1940	only	-	Nov	 2	0:00	1:00	S
-Rule	Swiss	1940	only	-	Dec	31	0:00	0	-
+# Rule	Swiss	1940	only	-	Nov	 2	0:00	1:00	S
+# Rule	Swiss	1940	only	-	Dec	31	0:00	0	-
 # From Shanks & Pottenger:
-Rule	Swiss	1941	1942	-	May	Sun>=1	2:00	1:00	S
-Rule	Swiss	1941	1942	-	Oct	Sun>=1	0:00	0	-
+# Rule	Swiss	1941	1942	-	May	Sun>=1	2:00	1:00	S
+# Rule	Swiss	1941	1942	-	Oct	Sun>=1	0:00	0	-
+
+# From Alois Treindl (2008-12-17):
+# I have researched the DST usage in Switzerland during the 1940ies.
+#
+# As I wrote in an earlier message, I suspected the current tzdata values
+# to be wrong. This is now verified.
+#
+# I have found copies of the original ruling by the Swiss Federal
+# government, in 'Eidgen[o]ssische Gesetzessammlung 1941 and 1942' (Swiss
+# federal law collection)...
+#
+# DST began on Monday 5 May 1941, 1:00 am by shifting the clocks to 2:00 am
+# DST ended on Monday 6 Oct 1941, 2:00 am by shifting the clocks to 1:00 am.
+#
+# DST began on Monday, 4 May 1942 at 01:00 am
+# DST ended on Monday, 5 Oct 1942 at 02:00 am
+#
+# There was no DST in 1940, I have checked the law collection carefully.
+# It is also indicated by the fact that the 1942 entry in the law
+# collection points back to 1941 as a reference, but no reference to any
+# other years are made.
+#
+# Newspaper articles I have read in the archives on 6 May 1941 reported
+# about the introduction of DST (Sommerzeit in German) during the previous
+# night as an absolute novelty, because this was the first time that such
+# a thing had happened in Switzerland.
+#
+# I have also checked 1916, because one book source (Gabriel, Traite de
+# l'heure dans le monde) claims that Switzerland had DST in 1916. This is
+# false, no official document could be found. Probably Gabriel got misled
+# by references to Germany, which introduced DST in 1916 for the first time.
+#
+# The tzdata rules for Switzerland must be changed to:
+# Rule  Swiss   1941    1942    -       May     Mon>=1  1:00    1:00    S
+# Rule  Swiss   1941    1942    -       Oct     Mon>=1  2:00    0       -
+#
+# The 1940 rules must be deleted.
+#
+# One further detail for Switzerland, which is probably out of scope for
+# most users of tzdata:
+# The zone file
+# Zone    Europe/Zurich   0:34:08 -       LMT     1848 Sep 12
+#                          0:29:44 -       BMT     1894 Jun #Bern Mean Time
+#                          1:00    Swiss   CE%sT   1981
+#                          1:00    EU      CE%sT
+# describes all of Switzerland correctly, with the exception of
+# the Cantone Geneve (Geneva, Genf). Between 1848 and 1894 Geneve did not
+# follow Bern Mean Time but kept its own local mean time.
+# To represent this, an extra zone would be needed.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Swiss	1941	1942	-	May	Mon>=1	1:00	1:00	S
+Rule	Swiss	1941	1942	-	Oct	Mon>=1	2:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Europe/Zurich	0:34:08 -	LMT	1848 Sep 12
 			0:29:44	-	BMT	1894 Jun # Bern Mean Time
@@ -2375,6 +2428,27 @@
 # (on a non-government server though) describing dates between 2002 and 2006:
 # http://www.alomaliye.com/bkk_2002_3769.htm
 
+# From Sue Williams (2008-08-11):
+# I spotted this news article about a potential change in Turkey.
+#
+# <a href="http://www.hurriyet.com.tr/english/domestic/9626174.asp?scr=1">
+# http://www.hurriyet.com.tr/english/domestic/9626174.asp?scr=1
+# </a>
+
+# From Sue Williams (2008-08-20):
+# This article says that around the end of March 2011, Turkey wants to
+# adjust the clocks forward by 1/2 hour and stay that way permanently.
+# The article indicates that this is a change in timezone offset in addition
+# to stopping observance of DST.
+# This proposal has not yet been approved.
+#
+# Read more here...
+#
+# Turkey to abandon daylight saving time in 2011
+# <a href="http://www.turkishdailynews.com.tr/article.php?enewsid=112989">
+# http://www.turkishdailynews.com.tr/article.php?enewsid=112989
+# </a>
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Turkey	1916	only	-	May	 1	0:00	1:00	S
 Rule	Turkey	1916	only	-	Oct	 1	0:00	0	-
--- a/jdk/make/sun/javazic/tzdata/northamerica	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/northamerica	Wed Jul 05 16:46:22 2017 +0200
@@ -1764,9 +1764,13 @@
 # The individual that answered the phone confirmed that the clocks did not
 # move at the end of daylight saving on October 29/2006.  He also told me that
 # the clocks did not move this past weekend (March 11/2007)....
-#
-# America/Resolute should use the "Canada" Rule up to October 29/2006.
-# After that it should be fixed on Eastern Standard Time until further notice.
+
+# From Chris Walton (2008-11-13):
+# ...the residents of Resolute believe that they are changing "time zones"
+# twice a year.  In winter months, local time is qualified with "Eastern
+# Time" which is really "Eastern Standard Time (UTC-5)".  In summer
+# months, local time is qualified with "Central Time" which is really
+# "Central Daylight Time (UTC-5)"...
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	NT_YK	1918	only	-	Apr	14	2:00	1:00	D
@@ -1794,11 +1798,14 @@
 			-6:00	Canada	C%sT	2000 Oct 29 2:00
 			-5:00	Canada	E%sT
 # aka Qausuittuq
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Resolute 2006	max	-	Nov	Sun>=1	2:00	0	ES
+Rule	Resolute 2007	max	-	Mar	Sun>=8	2:00	0	CD
 Zone America/Resolute	0	-	zzz	1947 Aug 31 # Resolute founded
 			-6:00	NT_YK	C%sT	2000 Oct 29 2:00
 			-5:00	-	EST	2001 Apr  1 3:00
 			-6:00	Canada	C%sT	2006 Oct 29 2:00
-			-5:00	-	EST
+			-5:00	Resolute	%sT
 # aka Kangiqiniq
 Zone America/Rankin_Inlet 0	-	zzz	1957 # Rankin Inlet founded
 			-6:00	NT_YK	C%sT	2000 Oct 29 2:00
@@ -2302,7 +2309,7 @@
 Rule	Cuba	1997	only	-	Oct	12	0:00s	0	S
 Rule	Cuba	1998	1999	-	Mar	lastSun	0:00s	1:00	D
 Rule	Cuba	1998	2003	-	Oct	lastSun	0:00s	0	S
-Rule	Cuba	2000	2006	-	Apr	Sun>=1	0:00s	1:00	D
+Rule	Cuba	2000	2004	-	Apr	Sun>=1	0:00s	1:00	D
 Rule	Cuba	2006	max	-	Oct	lastSun	0:00s	0	S
 Rule	Cuba	2007	only	-	Mar	Sun>=8	0:00s	1:00	D
 Rule	Cuba	2008	max	-	Mar	Sun>=15	0:00s	1:00	D
--- a/jdk/make/sun/javazic/tzdata/southamerica	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/southamerica	Wed Jul 05 16:46:22 2017 +0200
@@ -186,9 +186,58 @@
 # From Paul Eggert (2007-12-22):
 # For dates after mid-2008, the following rules are my guesses and
 # are quite possibly wrong, but are more likely than no DST at all.
+
+# From Alexander Krivenyshev (2008-09-05):
+# As per message from Carlos Alberto Fonseca Arauz (Nicaragua),
+# Argentina will start DST on Sunday October 19, 2008.
+#
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_argentina03.html">
+# http://www.worldtimezone.com/dst_news/dst_news_argentina03.html
+# </a>
+# OR
+# <a href="http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish)">
+# http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish)
+# </a>
+
+# From Rodrigo Severo (2008-10-06):
+# Here is some info available at a Gentoo bug related to TZ on Argentina's DST:
+# ...
+# ------- Comment #1 from [jmdocile]  2008-10-06 16:28 0000 -------
+# Hi, there is a problem with timezone-data-2008e and maybe with
+# timezone-data-2008f
+# Argentinian law [Number] 25.155 is no longer valid.
+# <a href="http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm">
+# http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm
+# </a>
+# The new one is law [Number] 26.350
+# <a href="http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm">
+# http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm
+# </a>
+# So there is no summer time in Argentina for now.
+
+# From Mariano Absatz (2008-10-20):
+# Decree 1693/2008 applies Law 26.350 for the summer 2008/2009 establishing DST in Argentina
+# From 2008-10-19 until 2009-03-15
+# <a href="http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=16102008&pi=3&pf=4&s=0&sec=01">
+# http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=16102008&pi=3&pf=4&s=0&sec=01
+# </a>
+#
+# Decree 1705/2008 excepting 12 Provinces from applying DST in the summer 2008/2009:
+# Catamarca, La Rioja, Mendoza, Salta, San Juan, San Luis, La Pampa, Neuquen, Rio Negro, Chubut, Santa Cruz
+# and Tierra del Fuego
+# <a href="http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=17102008&pi=1&pf=1&s=0&sec=01">
+# http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=17102008&pi=1&pf=1&s=0&sec=01
+# </a>
+#
+# Press release 235 dated Saturday October 18th, from the Government of the Province of Jujuy saying
+# it will not apply DST either (even when it was not included in Decree 1705/2008)
+# <a href="http://www.jujuy.gov.ar/index2/partes_prensa/18_10_08/235-181008.doc">
+# http://www.jujuy.gov.ar/index2/partes_prensa/18_10_08/235-181008.doc
+# </a>
+
 Rule	Arg	2007	only	-	Dec	30	0:00	1:00	S
 Rule	Arg	2008	max	-	Mar	Sun>=15	0:00	0	-
-Rule	Arg	2008	max	-	Oct	Sun>=1	0:00	1:00	S
+Rule	Arg	2008	max	-	Oct	Sun>=15	0:00	1:00	S
  
 # From Mariano Absatz (2004-05-21):
 # Today it was officially published that the Province of Mendoza is changing
@@ -336,9 +385,8 @@
 			-4:00	Arg	AR%sT	2000 Mar  3
 			-3:00	Arg	AR%sT
 #
-# Santa Fe (SF), Entre Rios (ER), Corrientes (CN), Misiones (MN), Chaco (CC),
-# Formosa (FM), Salta (SA), Santiago del Estero (SE), Cordoba (CB),
-# La Pampa (LP), Neuquen (NQ), Rio Negro (RN)
+# Cordoba (CB), Santa Fe (SF), Entre Rios (ER), Corrientes (CN), Misiones (MN),
+# Chaco (CC), Formosa (FM), Santiago del Estero (SE)
 #
 # Shanks & Pottenger also make the following claims, which we haven't verified:
 # - Formosa switched to -3:00 on 1991-01-07.
@@ -357,6 +405,18 @@
 			-4:00	Arg	AR%sT	2000 Mar  3
 			-3:00	Arg	AR%sT
 #
+# Salta (SA), La Pampa (LP), Neuquen (NQ), Rio Negro (RN)
+Zone America/Argentina/Salta -4:21:40 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  3
+			-4:00	-	WART	1991 Oct 20
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
+#
 # Tucuman (TM)
 Zone America/Argentina/Tucuman -4:20:52 - LMT	1894 Oct 31
 			-4:16:48 -	CMT	1920 May
@@ -381,7 +441,8 @@
 			-4:00	Arg	AR%sT	2000 Mar  3
 			-3:00	-	ART	2004 Jun  1
 			-4:00	-	WART	2004 Jun 20
-			-3:00	Arg	AR%sT
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
 #
 # San Juan (SJ)
 Zone America/Argentina/San_Juan -4:34:04 - LMT	1894 Oct 31
@@ -394,7 +455,8 @@
 			-4:00	Arg	AR%sT	2000 Mar  3
 			-3:00	-	ART	2004 May 31
 			-4:00	-	WART	2004 Jul 25
-			-3:00	Arg	AR%sT
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
 #
 # Jujuy (JY)
 Zone America/Argentina/Jujuy -4:21:12 -	LMT	1894 Oct 31
@@ -408,7 +470,8 @@
 			-3:00	1:00	ARST	1992
 			-3:00	Arg	AR%sT	1999 Oct  3
 			-4:00	Arg	AR%sT	2000 Mar  3
-			-3:00	Arg	AR%sT
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
 #
 # Catamarca (CT), Chubut (CH)
 Zone America/Argentina/Catamarca -4:23:08 - LMT	1894 Oct 31
@@ -421,7 +484,8 @@
 			-4:00	Arg	AR%sT	2000 Mar  3
 			-3:00	-	ART	2004 Jun  1
 			-4:00	-	WART	2004 Jun 20
-			-3:00	Arg	AR%sT
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
 #
 # Mendoza (MZ)
 Zone America/Argentina/Mendoza -4:35:16 - LMT	1894 Oct 31
@@ -438,7 +502,8 @@
 			-4:00	Arg	AR%sT	2000 Mar  3
 			-3:00	-	ART	2004 May 23
 			-4:00	-	WART	2004 Sep 26
-			-3:00	Arg	AR%sT
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
 #
 # San Luis (SL)
 Zone America/Argentina/San_Luis -4:25:24 - LMT	1894 Oct 31
@@ -466,7 +531,8 @@
 			-4:00	Arg	AR%sT	2000 Mar  3
 			-3:00	-	ART	2004 Jun  1
 			-4:00	-	WART	2004 Jun 20
-			-3:00	Arg	AR%sT
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
 #
 # Tierra del Fuego, Antartida e Islas del Atlantico Sur (TF)
 Zone America/Argentina/Ushuaia -4:33:12 - LMT 1894 Oct 31
@@ -477,7 +543,8 @@
 			-4:00	Arg	AR%sT	2000 Mar  3
 			-3:00	-	ART	2004 May 30
 			-4:00	-	WART	2004 Jun 20
-			-3:00	Arg	AR%sT
+			-3:00	Arg	AR%sT	2008 Oct 18
+			-3:00	-	ART
 
 # Aruba
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -613,6 +680,36 @@
 # Decretos sobre o Horario de Verao no Brasil
 # </a>.
 
+# From Steffen Thorsen (2008-08-29):
+# As announced by the government and many newspapers in Brazil late
+# yesterday, Brazil will start DST on 2008-10-19 (need to change rule) and
+# it will end on 2009-02-15 (current rule for Brazil is fine). Based on
+# past years experience with the elections, there was a good chance that
+# the start was postponed to November, but it did not happen this year.
+#
+# It has not yet been posted to http://pcdsh01.on.br/DecHV.html
+#
+# An official page about it:
+# <a href="http://www.mme.gov.br/site/news/detail.do?newsId=16722">
+# http://www.mme.gov.br/site/news/detail.do?newsId=16722
+# </a>
+# Note that this link does not always work directly, but must be accessed
+# by going to
+# <a href="http://www.mme.gov.br/first">
+# http://www.mme.gov.br/first
+# </a>
+#
+# One example link that works directly:
+# <a href="http://jornale.com.br/index.php?option=com_content&task=view&id=13530&Itemid=54">
+# http://jornale.com.br/index.php?option=com_content&task=view&id=13530&Itemid=54
+# (Portuguese)
+# </a>
+#
+# We have a written a short article about it as well:
+# <a href="http://www.timeanddate.com/news/time/brazil-dst-2008-2009.html">
+# http://www.timeanddate.com/news/time/brazil-dst-2008-2009.html
+# </a>
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 # Decree <a href="http://pcdsh01.on.br/HV20466.htm">20,466</a> (1931-10-01)
 # Decree <a href="http://pcdsh01.on.br/HV21896.htm">21,896</a> (1932-01-10)
@@ -746,12 +843,34 @@
 Rule	Brazil	2007	only	-	Feb	25	 0:00	0	-
 # Decree <a href="http://pcdsh01.on.br/DecHV6212.gif">6,212</a> (2007-09-26),
 # adopted by the same states as before.
-Rule	Brazil	2007	max	-	Oct	Sun>=8	 0:00	1:00	S
-Rule	Brazil	2008	max	-	Feb	Sun>=15	 0:00	0	-
+Rule	Brazil	2007	only	-	Oct	Sun>=8	 0:00	1:00	S
+# From Frederico A. C. Neves (2008-09-10):
+# Acording to this decree
+# <a href="http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm">
+# http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm
+# </a>
+# [t]he DST period in Brazil now on will be from the 3rd Oct Sunday to the
+# 3rd Feb Sunday. There is an exception on the return date when this is
+# the Carnival Sunday then the return date will be the next Sunday...
+Rule	Brazil	2008	max	-	Oct	Sun>=15	0:00	1:00	S
+Rule	Brazil	2008	2011	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2012	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2013	2014	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2015	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2016	2022	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2023	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2024	2025	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2026	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2027	2033	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2034	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2035	2036	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2037	only	-	Feb	Sun>=22	0:00	0	-
+# From Arthur David Olson (2008-09-29):
+# The next is wrong in some years but is better than nothing.
+Rule	Brazil	2038	max	-	Feb	Sun>=15	0:00	0	-
+
 # The latest ruleset listed above says that the following states observe DST:
 # DF, ES, GO, MG, MS, MT, PR, RJ, RS, SC, SP.
-# For dates after mid-2008, the above rules with TO="max" are guesses
-# and are quite possibly wrong, but are more likely than no DST at all.
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #
--- a/jdk/make/sun/javazic/tzdata/zone.tab	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/zone.tab	Wed Jul 05 16:46:22 2017 +0200
@@ -64,14 +64,15 @@
 AQ	-6640+14001	Antarctica/DumontDUrville	Dumont-d'Urville Station, Terre Adelie
 AQ	-690022+0393524	Antarctica/Syowa	Syowa Station, E Ongul I
 AR	-3436-05827	America/Argentina/Buenos_Aires	Buenos Aires (BA, CF)
-AR	-3124-06411	America/Argentina/Cordoba	most locations (CB, CC, CN, ER, FM, LP, MN, NQ, RN, SA, SE, SF)
-AR	-3319-06621	America/Argentina/San_Luis	San Luis (SL)
+AR	-3124-06411	America/Argentina/Cordoba	most locations (CB, CC, CN, ER, FM, MN, SE, SF)
+AR	-2447-06525	America/Argentina/Salta	(SA, LP, NQ, RN)
 AR	-2411-06518	America/Argentina/Jujuy	Jujuy (JY)
 AR	-2649-06513	America/Argentina/Tucuman	Tucuman (TM)
 AR	-2828-06547	America/Argentina/Catamarca	Catamarca (CT), Chubut (CH)
 AR	-2926-06651	America/Argentina/La_Rioja	La Rioja (LR)
 AR	-3132-06831	America/Argentina/San_Juan	San Juan (SJ)
 AR	-3253-06849	America/Argentina/Mendoza	Mendoza (MZ)
+AR	-3319-06621	America/Argentina/San_Luis	San Luis (SL)
 AR	-5138-06913	America/Argentina/Rio_Gallegos	Santa Cruz (SC)
 AR	-5448-06818	America/Argentina/Ushuaia	Tierra del Fuego (TF)
 AS	-1416-17042	Pacific/Pago_Pago
@@ -137,7 +138,7 @@
 CA	+4823-08915	America/Thunder_Bay	Eastern Time - Thunder Bay, Ontario
 CA	+6344-06828	America/Iqaluit	Eastern Time - east Nunavut - most locations
 CA	+6608-06544	America/Pangnirtung	Eastern Time - Pangnirtung, Nunavut
-CA	+744144-0944945	America/Resolute	Eastern Time - Resolute, Nunavut
+CA	+744144-0944945	America/Resolute	Eastern Standard Time - Resolute, Nunavut
 CA	+484531-0913718	America/Atikokan	Eastern Standard Time - Atikokan, Ontario and Southampton I, Nunavut
 CA	+624900-0920459	America/Rankin_Inlet	Central Time - central Nunavut
 CA	+4953-09709	America/Winnipeg	Central Time - Manitoba & west Ontario
@@ -313,9 +314,9 @@
 NI	+1209-08617	America/Managua
 NL	+5222+00454	Europe/Amsterdam
 NO	+5955+01045	Europe/Oslo
-NP	+2743+08519	Asia/Katmandu
+NP	+2743+08519	Asia/Kathmandu
 NR	-0031+16655	Pacific/Nauru
-NU	-1901+16955	Pacific/Niue
+NU	-1901-16955	Pacific/Niue
 NZ	-3652+17446	Pacific/Auckland	most locations
 NZ	-4357-17633	Pacific/Chatham	Chatham Islands
 OM	+2336+05835	Asia/Muscat
@@ -406,13 +407,13 @@
 US	+364947-0845057	America/Kentucky/Monticello	Eastern Time - Kentucky - Wayne County
 US	+394606-0860929	America/Indiana/Indianapolis	Eastern Time - Indiana - most locations
 US	+384038-0873143	America/Indiana/Vincennes	Eastern Time - Indiana - Daviess, Dubois, Knox & Martin Counties
-US	+411745-0863730	America/Indiana/Knox	Eastern Time - Indiana - Starke County
 US	+410305-0863611	America/Indiana/Winamac	Eastern Time - Indiana - Pulaski County
 US	+382232-0862041	America/Indiana/Marengo	Eastern Time - Indiana - Crawford County
+US	+382931-0871643	America/Indiana/Petersburg	Eastern Time - Indiana - Pike County
 US	+384452-0850402	America/Indiana/Vevay	Eastern Time - Indiana - Switzerland County
 US	+415100-0873900	America/Chicago	Central Time
 US	+375711-0864541	America/Indiana/Tell_City	Central Time - Indiana - Perry County
-US	+382931-0871643	America/Indiana/Petersburg	Central Time - Indiana - Pike County
+US	+411745-0863730	America/Indiana/Knox	Central Time - Indiana - Starke County
 US	+450628-0873651	America/Menominee	Central Time - Michigan - Dickinson, Gogebic, Iron & Menominee Counties
 US	+470659-1011757	America/North_Dakota/Center	Central Time - North Dakota - Oliver County
 US	+465042-1012439	America/North_Dakota/New_Salem	Central Time - North Dakota - Morton County (except Mandan area)
--- a/jdk/make/sun/launcher/Makefile	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/launcher/Makefile	Wed Jul 05 16:46:22 2017 +0200
@@ -37,7 +37,7 @@
 # Resources
 #
 LOCALE_SET_DEFINITION = jre
-NEW_RESOURCE_BUNDLES_PROPERTIES = $(PKGDIR)/resources/launcher.properties
+NEW_RESOURCE_BUNDLES_COMPILED_PROPERTIES = $(PKGDIR)/resources/launcher.properties
 
 #
 # Rules
--- a/jdk/make/sun/rmi/oldtools/Makefile	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/rmi/oldtools/Makefile	Wed Jul 05 16:46:22 2017 +0200
@@ -41,7 +41,7 @@
 # Resources
 #
 LOCALE_SET_DEFINITION = j2sdk
-RESOURCE_BUNDLES_PROPERTIES = sun/tools/javac/resources/javac.properties
+RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES = sun/tools/javac/resources/javac.properties
 
 #
 # Rules
--- a/jdk/make/sun/rmi/registry/Makefile	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/rmi/registry/Makefile	Wed Jul 05 16:46:22 2017 +0200
@@ -41,7 +41,7 @@
 # Resources
 #
 LOCALE_SET_DEFINITION = jre
-RESOURCE_BUNDLES_PROPERTIES = $(PKGDIR)/resources/rmiregistry.properties
+RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES = $(PKGDIR)/resources/rmiregistry.properties
 
 #
 # Rules
--- a/jdk/make/sun/rmi/rmic/Makefile	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/rmi/rmic/Makefile	Wed Jul 05 16:46:22 2017 +0200
@@ -43,7 +43,7 @@
 # Resources
 #
 LOCALE_SET_DEFINITION = jdk
-RESOURCE_BUNDLES_PROPERTIES = $(PKGDIR)/resources/rmic.properties
+RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES = $(PKGDIR)/resources/rmic.properties
 
 #
 # Rules
--- a/jdk/make/sun/rmi/rmid/Makefile	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/rmi/rmid/Makefile	Wed Jul 05 16:46:22 2017 +0200
@@ -39,7 +39,7 @@
 # Resources
 #
 LOCALE_SET_DEFINITION = jre
-RESOURCE_BUNDLES_PROPERTIES = sun/rmi/server/resources/rmid.properties
+RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES = sun/rmi/server/resources/rmid.properties
 
 #
 # Extra dependencies.
--- a/jdk/make/sun/serialver/Makefile	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/make/sun/serialver/Makefile	Wed Jul 05 16:46:22 2017 +0200
@@ -41,7 +41,7 @@
 # Resources
 #
 LOCALE_SET_DEFINITION = jdk
-RESOURCE_BUNDLES_PROPERTIES = $(PKGDIR)/resources/serialver.properties 
+RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES = $(PKGDIR)/resources/serialver.properties 
 
 #
 # Rules
--- a/jdk/src/share/classes/com/sun/beans/ObjectHandler.java	Thu Jan 29 13:21:02 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,479 +0,0 @@
-/*
- * Copyright 2003-2006 Sun Microsystems, 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.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package com.sun.beans;
-
-import com.sun.beans.finder.ClassFinder;
-
-import java.beans.*;
-import java.util.*;
-
-import org.xml.sax.*;
-
-import static java.util.Locale.ENGLISH;
-
-/**
- * <b>WARNING</b>: This class is an implementation detail and only meant
- * for use within the core platform. You should NOT depend upon it! This
- * API may change drastically between dot dot release, and it may even be
- * removed.
- *
- * @see java.beans.XMLEncoder
- * @see java.io.ObjectInputStream
- *
- * @since 1.4
- *
- * @author Philip Milne
- */
-public class ObjectHandler extends HandlerBase {
-
-    public static Class typeNameToClass(String typeName) {
-        typeName = typeName.intern();
-        if (typeName == "boolean") return Boolean.class;
-        if (typeName == "byte") return Byte.class;
-        if (typeName == "char") return Character.class;
-        if (typeName == "short") return Short.class;
-        if (typeName == "int") return Integer.class;
-        if (typeName == "long") return Long.class;
-        if (typeName == "float") return Float.class;
-        if (typeName == "double") return Double.class;
-        if (typeName == "void") return Void.class;
-        return null;
-    }
-
-    public static Class typeNameToPrimitiveClass(String typeName) {
-        typeName = typeName.intern();
-        if (typeName == "boolean") return boolean.class;
-        if (typeName == "byte") return byte.class;
-        if (typeName == "char") return char.class;
-        if (typeName == "short") return short.class;
-        if (typeName == "int") return int.class;
-        if (typeName == "long") return long.class;
-        if (typeName == "float") return float.class;
-        if (typeName == "double") return double.class;
-        if (typeName == "void") return void.class;
-        return null;
-    }
-
-    /**
-     * Returns the <code>Class</code> object associated with
-     * the class or interface with the given string name,
-     * using the default class loader.
-     *
-     * @param name  fully qualified name of the desired class
-     * @param cl    class loader from which the class must be loaded
-     * @return class object representing the desired class
-     *
-     * @exception ClassNotFoundException  if the class cannot be located
-     *                                    by the specified class loader
-     *
-     * @deprecated As of JDK version 7, replaced by
-     *             {@link ClassFinder#resolveClass(String)}.
-     */
-    @Deprecated
-    public static Class classForName(String name) throws ClassNotFoundException {
-        return ClassFinder.resolveClass(name);
-    }
-
-    /**
-     * Returns the <code>Class</code> object associated with
-     * the class or interface with the given string name,
-     * using the given class loader.
-     *
-     * @param name  fully qualified name of the desired class
-     * @param cl    class loader from which the class must be loaded
-     * @return class object representing the desired class
-     *
-     * @exception ClassNotFoundException  if the class cannot be located
-     *                                    by the specified class loader
-     *
-     * @deprecated As of JDK version 7, replaced by
-     *             {@link ClassFinder#resolveClass(String,ClassLoader)}.
-     */
-    @Deprecated
-    public static Class classForName(String name, ClassLoader cl)
-        throws ClassNotFoundException {
-        return ClassFinder.resolveClass(name, cl);
-    }
-
-    private Hashtable environment;
-    private Vector expStack;
-    private StringBuffer chars;
-    private XMLDecoder is;
-    private ClassLoader ldr;
-    private int itemsRead = 0;
-    private boolean isString;
-
-    public ObjectHandler() {
-        environment = new Hashtable();
-        expStack = new Vector();
-        chars = new StringBuffer();
-    }
-
-    public ObjectHandler(XMLDecoder is) {
-        this();
-        this.is = is;
-    }
-
-    /* loader can be null */
-    public ObjectHandler(XMLDecoder is, ClassLoader loader) {
-        this(is);
-        this.ldr = loader;
-    }
-
-
-    public void reset() {
-        expStack.clear();
-        chars.setLength(0);
-        MutableExpression e = new MutableExpression();
-        e.setTarget(classForName2("java.lang.Object"));
-        e.setMethodName("null");
-        expStack.add(e);
-    }
-
-    private Object getValue(Expression exp) {
-        try {
-            return exp.getValue();
-        }
-        catch (Exception e) {
-            if (is != null) {
-                is.getExceptionListener().exceptionThrown(e);
-            }
-            return null;
-        }
-    }
-
-    private void addArg(Object arg) {
-        lastExp().addArg(arg);
-    }
-
-    private Object pop(Vector v) {
-        int last = v.size()-1;
-        Object result = v.get(last);
-        v.remove(last);
-        return result;
-    }
-
-    private Object eval() {
-        return getValue(lastExp());
-    }
-
-    private MutableExpression lastExp() {
-        return (MutableExpression)expStack.lastElement();
-    }
-
-    public Object dequeueResult() {
-        Object[] results = lastExp().getArguments();
-        return results[itemsRead++];
-    }
-
-    private boolean isPrimitive(String name) {
-        return name != "void" && typeNameToClass(name) != null;
-    }
-
-    private void simulateException(String message) {
-        Exception e = new Exception(message);
-        e.fillInStackTrace();
-        if (is != null) {
-            is.getExceptionListener().exceptionThrown(e);
-        }
-    }
-
-    private Class classForName2(String name) {
-        try {
-            return ClassFinder.resolveClass(name, this.ldr);
-        }
-        catch (ClassNotFoundException e) {
-            if (is != null) {
-                is.getExceptionListener().exceptionThrown(e);
-            }
-        }
-        return null;
-    }
-
-    private HashMap getAttributes(AttributeList attrs) {
-        HashMap attributes = new HashMap();
-        if (attrs != null && attrs.getLength() > 0) {
-            for(int i = 0; i < attrs.getLength(); i++) {
-                attributes.put(attrs.getName(i), attrs.getValue(i));
-            }
-        }
-        return attributes;
-    }
-
-    public void startElement(String name, AttributeList attrs) throws SAXException {
-        name = name.intern(); // Xerces parser does not supply unique tag names.
-        if (this.isString) {
-            parseCharCode(name, getAttributes(attrs));
-            return;
-        }
-        chars.setLength(0);
-
-        HashMap attributes = getAttributes(attrs);
-        MutableExpression e = new MutableExpression();
-
-        // Target
-        String className = (String)attributes.get("class");
-        if (className != null) {
-            e.setTarget(classForName2(className));
-        }
-
-        // Property
-        Object property = attributes.get("property");
-        String index = (String)attributes.get("index");
-        if (index != null) {
-            property = new Integer(index);
-            e.addArg(property);
-        }
-        e.setProperty(property);
-
-        // Method
-        String methodName = (String)attributes.get("method");
-        if (methodName == null && property == null) {
-            methodName = "new";
-        }
-        e.setMethodName(methodName);
-
-        // Tags
-        if (name == "string") {
-            e.setTarget(String.class);
-            e.setMethodName("new");
-            this.isString = true;
-        }
-        else if (isPrimitive(name)){
-            Class wrapper = typeNameToClass(name);
-            e.setTarget(wrapper);
-            e.setMethodName("new");
-            parseCharCode(name, attributes);
-        }
-        else if (name == "class") {
-            e.setTarget(Class.class);
-            e.setMethodName("forName");
-        }
-        else if (name == "null") {
-            // Create an arbitrary expression that has a value of null - for
-            // consistency.
-            e.setTarget(Object.class);
-            e.setMethodName("getSuperclass");
-            e.setValue(null);
-        }
-        else if (name == "void") {
-            if (e.getTarget() == null) { // this check is for "void class="foo" method= ..."
-                e.setTarget(eval());
-            }
-        }
-        else if (name == "array") {
-            // The class attribute means sub-type for arrays.
-            String subtypeName = (String)attributes.get("class");
-            Class subtype = (subtypeName == null) ? Object.class : classForName2(subtypeName);
-            String length = (String)attributes.get("length");
-            if (length != null) {
-                e.setTarget(java.lang.reflect.Array.class);
-                e.addArg(subtype);
-                e.addArg(new Integer(length));
-            }
-            else {
-                Class arrayClass = java.lang.reflect.Array.newInstance(subtype, 0).getClass();
-                e.setTarget(arrayClass);
-            }
-        }
-        else if (name == "java") {
-            e.setValue(is); // The outermost scope is the stream itself.
-        }
-        else if (name == "object") {
-        }
-        else {
-            simulateException("Unrecognized opening tag: " + name + " " + attrsToString(attrs));
-            return;
-        }
-
-        // ids
-        String idName = (String)attributes.get("id");
-        if (idName != null) {
-            environment.put(idName, e);
-        }
-
-        // idrefs
-        String idrefName = (String)attributes.get("idref");
-        if (idrefName != null) {
-            e.setValue(lookup(idrefName));
-        }
-
-        // fields
-        String fieldName = (String)attributes.get("field");
-        if (fieldName != null) {
-            e.setValue(getFieldValue(e.getTarget(), fieldName));
-        }
-        expStack.add(e);
-    }
-
-    private Object getFieldValue(Object target, String fieldName) {
-        try {
-            Class type = target.getClass();
-            if (type == Class.class) {
-                type = (Class)target;
-            }
-            java.lang.reflect.Field f = sun.reflect.misc.FieldUtil.getField(type, fieldName);
-            return f.get(target);
-        }
-        catch (Exception e) {
-            if (is != null) {
-                is.getExceptionListener().exceptionThrown(e);
-            }
-            return null;
-        }
-    }
-
-    private String attrsToString(AttributeList attrs) {
-        StringBuffer b = new StringBuffer();
-        for (int i = 0; i < attrs.getLength (); i++) {
-            b.append(attrs.getName(i)+"=\""+attrs.getValue(i)+"\" ");
-        }
-        return b.toString();
-    }
-
-    public void characters(char buf [], int offset, int len) throws SAXException {
-        chars.append(new String(buf, offset, len));
-    }
-
-    private void parseCharCode(String name, Map map) {
-        if (name == "char") {
-            String value = (String) map.get("code");
-            if (value != null) {
-                int code = Integer.decode(value);
-                for (char ch : Character.toChars(code)) {
-                    this.chars.append(ch);
-                }
-            }
-        }
-    }
-
-    public Object lookup(String s) {
-        Expression e = (Expression)environment.get(s);
-        if (e == null) {
-            simulateException("Unbound variable: " + s);
-        }
-        return getValue(e);
-    }
-
-    public void register(String id, Object value) {
-        Expression e = new MutableExpression();
-        e.setValue(value);
-        environment.put(id, e);
-    }
-
-    public void endElement(String name) throws SAXException {
-        name = name.intern(); // Xerces parser does not supply unique tag names.
-        if (name == "string") {
-            this.isString = false;
-        } else if (this.isString) {
-            return;
-        }
-        if (name == "java") {
-            return;
-        }
-        if (isPrimitive(name) || name == "string" || name == "class") {
-            addArg(chars.toString());
-        }
-        if (name == "object" || name == "array" || name == "void" ||
-                isPrimitive(name) || name == "string" || name == "class" ||
-                name == "null") {
-            Expression e = (Expression)pop(expStack);
-            Object value = getValue(e);
-            if (name != "void") {
-                addArg(value);
-            }
-        }
-        else {
-            simulateException("Unrecognized closing tag: " + name);
-        }
-    }
-}
-
-
-class MutableExpression extends Expression {
-    private Object target;
-    private String methodName;
-
-    private Object property;
-    private Vector argV = new Vector();
-
-    private String capitalize(String propertyName) {
-        if (propertyName.length() == 0) {
-            return propertyName;
-        }
-        return propertyName.substring(0, 1).toUpperCase(ENGLISH) + propertyName.substring(1);
-    }
-
-    public MutableExpression() {
-        super(null, null, null);
-    }
-
-    public Object[] getArguments() {
-        return argV.toArray();
-    }
-
-    public String getMethodName() {
-        if (property == null) {
-            return methodName;
-        }
-        int setterArgs = (property instanceof String) ? 1 : 2;
-        String methodName = (argV.size() == setterArgs) ? "set" : "get";
-        if (property instanceof String) {
-            return methodName + capitalize((String)property);
-        }
-        else {
-            return methodName;
-        }
-    }
-
-    public void addArg(Object arg) {
-        argV.add(arg);
-    }
-
-    public void setTarget(Object target) {
-        this.target = target;
-    }
-
-    public Object getTarget() {
-        return target;
-    }
-
-    public void setMethodName(String methodName) {
-        this.methodName = methodName;
-    }
-
-    public void setProperty(Object property) {
-        this.property = property;
-    }
-
-    public void setValue(Object value) {
-        super.setValue(value);
-    }
-
-    public Object getValue() throws Exception {
-        return super.getValue();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/AccessorElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This is base class that simplifies access to entities (fields or properties).
+ * The {@code name} attribute specifies the name of the accessible entity.
+ * The element defines getter if it contains no argument
+ * or setter if it contains one argument.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+abstract class AccessorElementHandler extends ElementHandler {
+    private String name;
+    private ValueObject value;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>name
+     * <dd>the name of the accessible entity
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("name")) { // NON-NLS: the attribute name
+            this.name = value;
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Adds the argument that is used to set the value of this element.
+     *
+     * @param argument  the value of the element that contained in this one
+     */
+    @Override
+    protected final void addArgument(Object argument) {
+        if (this.value != null) {
+            throw new IllegalStateException("Could not add argument to evaluated element");
+        }
+        setValue(this.name, argument);
+        this.value = ValueObjectImpl.VOID;
+    }
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    @Override
+    protected final ValueObject getValueObject() {
+        if (this.value == null) {
+            this.value = ValueObjectImpl.create(getValue(this.name));
+        }
+        return this.value;
+    }
+
+    /**
+     * Returns the value of the entity with specified {@code name}.
+     *
+     * @param name  the name of the accessible entity
+     * @return the value of the specified entity
+     */
+    protected abstract Object getValue(String name);
+
+    /**
+     * Sets the new value for the entity with specified {@code name}.
+     *
+     * @param name   the name of the accessible entity
+     * @param value  the new value for the specified entity
+     */
+    protected abstract void setValue(String name, Object value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/ArrayElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import java.lang.reflect.Array;
+
+/**
+ * This class is intended to handle &lt;array&gt; element,
+ * that is used to array creation.
+ * The {@code length} attribute specifies the length of the array.
+ * The {@code class} attribute specifies the elements type.
+ * The {@link Object} type is used by default.
+ * For example:<pre>
+ * &lt;array length="10"/&gt;</pre>
+ * is equivalent to {@code new Component[10]} in Java code.
+ * The {@code set} and {@code get} methods,
+ * as defined in the {@link java.util.List} interface,
+ * can be used as if they could be applied to array instances.
+ * The {@code index} attribute can thus be used with arrays.
+ * For example:<pre>
+ * &lt;array length="3" class="java.lang.String"&gt;
+ *     &lt;void index="1"&gt;
+ *         &lt;string&gt;Hello, world&lt;/string&gt;
+ *     &lt;/void&gt;
+ * &lt;/array&gt;</pre>
+ * is equivalent to the following Java code:<pre>
+ * String[] s = new String[3];
+ * s[1] = "Hello, world";</pre>
+ * It is possible to omit the {@code length} attribute and
+ * specify the values directly, without using {@code void} tags.
+ * The length of the array is equal to the number of values specified.
+ * For example:<pre>
+ * &lt;array id="array" class="int"&gt;
+ *     &lt;int&gt;123&lt;/int&gt;
+ *     &lt;int&gt;456&lt;/int&gt;
+ * &lt;/array&gt;</pre>
+ * is equivalent to {@code int[] array = {123, 456}} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>length
+ * <dd>the array length
+ * <dt>class
+ * <dd>the type of object for instantiation
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class ArrayElementHandler extends NewElementHandler {
+    private Integer length;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>length
+     * <dd>the array length
+     * <dt>class
+     * <dd>the type of object for instantiation
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("length")) { // NON-NLS: the attribute name
+            this.length = Integer.valueOf(value);
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Calculates the value of this element
+     * if the lentgh attribute is set.
+     */
+    @Override
+    public void startElement() {
+        if (this.length != null) {
+            getValueObject();
+        }
+    }
+
+    /**
+     * Creates an instance of the array.
+     *
+     * @param type  the base class
+     * @param args  the array of arguments
+     * @return the value of this element
+     */
+    @Override
+    protected ValueObject getValueObject(Class<?> type, Object[] args) {
+        if (type == null) {
+            type = Object.class;
+        }
+        if (this.length != null) {
+            return ValueObjectImpl.create(Array.newInstance(type, this.length));
+        }
+        Object array = Array.newInstance(type, args.length);
+        for (int i = 0; i < args.length; i++) {
+            Array.set(array, i, args[i]);
+        }
+        return ValueObjectImpl.create(array);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/BooleanElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;boolean&gt; element.
+ * This element specifies {@code boolean} values.
+ * The class {@link Boolean} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;boolean&gt;true&lt;/boolean&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="valueOf" class="java.lang.Boolean"&gt;
+ *     &lt;string&gt;true&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Boolean.valueOf("true")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class BooleanElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code boolean} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code boolean} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        if (Boolean.TRUE.toString().equalsIgnoreCase(argument)) {
+            return Boolean.TRUE;
+        }
+        if (Boolean.FALSE.toString().equalsIgnoreCase(argument)) {
+            return Boolean.FALSE;
+        }
+        throw new IllegalArgumentException("Unsupported boolean argument: " + argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/ByteElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;byte&gt; element.
+ * This element specifies {@code byte} values.
+ * The class {@link Byte} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;byte&gt;127&lt;/byte&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="decode" class="java.lang.Byte"&gt;
+ *     &lt;string&gt;127&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Byte.decode("127")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class ByteElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code byte} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code byte} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return Byte.decode(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/CharElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;char&gt; element.
+ * This element specifies {@code char} values.
+ * The class {@link Character} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;char&gt;X&lt;/char&gt;</pre>
+ * which is equivalent to {@code Character.valueOf('X')} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>code
+ * <dd>this attribute specifies character code
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ * The {@code code} attribute can be used for characters
+ * that are illegal in XML document, for example:<pre>
+ * &lt;char code="0"/&gt;</pre>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class CharElementHandler extends StringElementHandler {
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>code
+     * <dd>this attribute specifies character code
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("code")) { // NON-NLS: the attribute name
+            int code = Integer.decode(value);
+            for (char ch : Character.toChars(code)) {
+                addCharacter(ch);
+            }
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Creates {@code char} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code char} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        if (argument.length() != 1) {
+            throw new IllegalArgumentException("Wrong characters count");
+        }
+        return Character.valueOf(argument.charAt(0));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/ClassElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;class&gt; element.
+ * This element specifies {@link Class} values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;class&gt;java.lang.Class&lt;/class&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="forName" class="java.lang.Class"&gt;
+ *     &lt;string&gt;java.lang.Class&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Class.forName("java.lang.Class")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class ClassElementHandler extends StringElementHandler {
+
+    /**
+     * Creates class by the name from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code Class} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return getOwner().findClass(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/DocumentHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import com.sun.beans.finder.ClassFinder;
+
+import java.beans.ExceptionListener;
+
+import java.io.IOException;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * The main class to parse JavaBeans XML archive.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ *
+ * @see ElementHandler
+ */
+public final class DocumentHandler extends DefaultHandler {
+    private final Map<String, Class<? extends ElementHandler>> handlers = new HashMap<String, Class<? extends ElementHandler>>();
+
+    private final Map<String, Object> environment = new HashMap<String, Object>();
+
+    private final List<Object> objects = new ArrayList<Object>();
+
+    private Reference<ClassLoader> loader;
+    private ExceptionListener listener;
+    private Object owner;
+
+    private ElementHandler handler;
+
+    /**
+     * Creates new instance of document handler.
+     */
+    public DocumentHandler() {
+        setElementHandler("java", JavaElementHandler.class); // NON-NLS: the element name
+        setElementHandler("null", NullElementHandler.class); // NON-NLS: the element name
+        setElementHandler("array", ArrayElementHandler.class); // NON-NLS: the element name
+        setElementHandler("class", ClassElementHandler.class); // NON-NLS: the element name
+        setElementHandler("string", StringElementHandler.class); // NON-NLS: the element name
+        setElementHandler("object", ObjectElementHandler.class); // NON-NLS: the element name
+
+        setElementHandler("void", VoidElementHandler.class); // NON-NLS: the element name
+        setElementHandler("char", CharElementHandler.class); // NON-NLS: the element name
+        setElementHandler("byte", ByteElementHandler.class); // NON-NLS: the element name
+        setElementHandler("short", ShortElementHandler.class); // NON-NLS: the element name
+        setElementHandler("int", IntElementHandler.class); // NON-NLS: the element name
+        setElementHandler("long", LongElementHandler.class); // NON-NLS: the element name
+        setElementHandler("float", FloatElementHandler.class); // NON-NLS: the element name
+        setElementHandler("double", DoubleElementHandler.class); // NON-NLS: the element name
+        setElementHandler("boolean", BooleanElementHandler.class); // NON-NLS: the element name
+
+        // some handlers for new elements
+        setElementHandler("new", NewElementHandler.class); // NON-NLS: the element name
+        setElementHandler("var", VarElementHandler.class); // NON-NLS: the element name
+        setElementHandler("true", TrueElementHandler.class); // NON-NLS: the element name
+        setElementHandler("false", FalseElementHandler.class); // NON-NLS: the element name
+        setElementHandler("field", FieldElementHandler.class); // NON-NLS: the element name
+        setElementHandler("method", MethodElementHandler.class); // NON-NLS: the element name
+        setElementHandler("property", PropertyElementHandler.class); // NON-NLS: the element name
+    }
+
+    /**
+     * Returns the class loader used to instantiate objects.
+     * If the class loader has not been explicitly set
+     * then {@code null} is returned.
+     *
+     * @return the class loader used to instantiate objects
+     */
+    public ClassLoader getClassLoader() {
+        return (this.loader != null)
+                ? this.loader.get()
+                : null;
+    }
+
+    /**
+     * Sets the class loader used to instantiate objects.
+     * If the class loader is not set
+     * then default class loader will be used.
+     *
+     * @param loader  a classloader to use
+     */
+    public void setClassLoader(ClassLoader loader) {
+        this.loader = new WeakReference<ClassLoader>(loader);
+    }
+
+    /**
+     * Returns the exception listener for parsing.
+     * The exception listener is notified
+     * when handler catches recoverable exceptions.
+     * If the exception listener has not been explicitly set
+     * then default exception listener is returned.
+     *
+     * @return the exception listener for parsing
+     */
+    public ExceptionListener getExceptionListener() {
+        return this.listener;
+    }
+
+    /**
+     * Sets the exception listener for parsing.
+     * The exception listener is notified
+     * when handler catches recoverable exceptions.
+     *
+     * @param listener  the exception listener for parsing
+     */
+    public void setExceptionListener(ExceptionListener listener) {
+        this.listener = listener;
+    }
+
+    /**
+     * Returns the owner of this document handler.
+     *
+     * @return the owner of this document handler
+     */
+    public Object getOwner() {
+        return this.owner;
+    }
+
+    /**
+     * Sets the owner of this document handler.
+     *
+     * @param owner  the owner of this document handler
+     */
+    public void setOwner(Object owner) {
+        this.owner = owner;
+    }
+
+    /**
+     * Returns the handler for the element with specified name.
+     *
+     * @param name  the name of the element
+     * @return the corresponding element handler
+     */
+    public Class<? extends ElementHandler> getElementHandler(String name) {
+        Class<? extends ElementHandler> type = this.handlers.get(name);
+        if (type == null) {
+            throw new IllegalArgumentException("Unsupported element: " + name);
+        }
+        return type;
+    }
+
+    /**
+     * Sets the handler for the element with specified name.
+     *
+     * @param name     the name of the element
+     * @param handler  the corresponding element handler
+     */
+    public void setElementHandler(String name, Class<? extends ElementHandler> handler) {
+        this.handlers.put(name, handler);
+    }
+
+    /**
+     * Indicates whether the variable with specified identifier is defined.
+     *
+     * @param id  the identifier
+     * @return @{code true} if the variable is defined;
+     *         @{code false} otherwise
+     */
+    public boolean hasVariable(String id) {
+        return this.environment.containsKey(id);
+    }
+
+    /**
+     * Returns the value of the variable with specified identifier.
+     *
+     * @param id  the identifier
+     * @return the value of the variable
+     */
+    public Object getVariable(String id) {
+        if (!this.environment.containsKey(id)) {
+            throw new IllegalArgumentException("Unbound variable: " + id);
+        }
+        return this.environment.get(id);
+    }
+
+    /**
+     * Sets new value of the variable with specified identifier.
+     *
+     * @param id     the identifier
+     * @param value  new value of the variable
+     */
+    public void setVariable(String id, Object value) {
+        this.environment.put(id, value);
+    }
+
+    /**
+     * Returns the array of readed objects.
+     *
+     * @return the array of readed objects
+     */
+    public Object[] getObjects() {
+        return this.objects.toArray();
+    }
+
+    /**
+     * Adds the object to the list of readed objects.
+     *
+     * @param object  the object that is readed from XML document
+     */
+    void addObject(Object object) {
+        this.objects.add(object);
+    }
+
+    /**
+     * Prepares this handler to read objects from XML document.
+     */
+    @Override
+    public void startDocument() {
+        this.objects.clear();
+        this.handler = null;
+    }
+
+    /**
+     * Parses opening tag of XML element
+     * using corresponding element handler.
+     *
+     * @param uri         the namespace URI, or the empty string
+     *                    if the element has no namespace URI or
+     *                    if namespace processing is not being performed
+     * @param localName   the local name (without prefix), or the empty string
+     *                    if namespace processing is not being performed
+     * @param qName       the qualified name (with prefix), or the empty string
+     *                    if qualified names are not available
+     * @param attributes  the attributes attached to the element
+     */
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+        ElementHandler parent = this.handler;
+        try {
+            this.handler = getElementHandler(qName).newInstance();
+            this.handler.setOwner(this);
+            this.handler.setParent(parent);
+        }
+        catch (Exception exception) {
+            throw new SAXException(exception);
+        }
+        for (int i = 0; i < attributes.getLength(); i++)
+            try {
+                String name = attributes.getQName(i);
+                String value = attributes.getValue(i);
+                this.handler.addAttribute(name, value);
+            }
+            catch (RuntimeException exception) {
+                handleException(exception);
+            }
+
+        this.handler.startElement();
+    }
+
+    /**
+     * Parses closing tag of XML element
+     * using corresponding element handler.
+     *
+     * @param uri        the namespace URI, or the empty string
+     *                   if the element has no namespace URI or
+     *                   if namespace processing is not being performed
+     * @param localName  the local name (without prefix), or the empty string
+     *                   if namespace processing is not being performed
+     * @param qName      the qualified name (with prefix), or the empty string
+     *                   if qualified names are not available
+     */
+    @Override
+    public void endElement(String uri, String localName, String qName) {
+        try {
+            this.handler.endElement();
+        }
+        catch (RuntimeException exception) {
+            handleException(exception);
+        }
+        finally {
+            this.handler = this.handler.getParent();
+        }
+    }
+
+    /**
+     * Parses character data inside XML element.
+     *
+     * @param chars   the array of characters
+     * @param start   the start position in the character array
+     * @param length  the number of characters to use
+     */
+    @Override
+    public void characters(char[] chars, int start, int length) {
+        if (this.handler != null) {
+            try {
+                while (0 < length--) {
+                    this.handler.addCharacter(chars[start++]);
+                }
+            }
+            catch (RuntimeException exception) {
+                handleException(exception);
+            }
+        }
+    }
+
+    /**
+     * Handles an exception using current exception listener.
+     *
+     * @param exception  an exception to handle
+     * @see #setExceptionListener
+     */
+    public void handleException(Exception exception) {
+        if (this.listener == null) {
+            throw new IllegalStateException(exception);
+        }
+        this.listener.exceptionThrown(exception);
+    }
+
+    /**
+     * Starts parsing of the specified input source.
+     *
+     * @param input  the input source to parse
+     */
+    public void parse(InputSource input) {
+        try {
+            SAXParserFactory.newInstance().newSAXParser().parse(input, this);
+        }
+        catch (ParserConfigurationException exception) {
+            handleException(exception);
+        }
+        catch (SAXException wrapper) {
+            Exception exception = wrapper.getException();
+            if (exception == null) {
+                exception = wrapper;
+            }
+            handleException(exception);
+        }
+        catch (IOException exception) {
+            handleException(exception);
+        }
+    }
+
+    /**
+     * Resolves class by name using current class loader.
+     * This method handles exception using current exception listener.
+     *
+     * @param name  the name of the class
+     * @return the object that represents the class
+     */
+    public Class<?> findClass(String name) {
+        try {
+            return ClassFinder.resolveClass(name, getClassLoader());
+        }
+        catch (ClassNotFoundException exception) {
+            handleException(exception);
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/DoubleElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;double&gt; element.
+ * This element specifies {@code double} values.
+ * The class {@link Double} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;double&gt;1.23e45&lt;/double&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="valueOf" class="java.lang.Double"&gt;
+ *     &lt;string&gt;1.23e45&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Double.valueOf("1.23e45")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class DoubleElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code double} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code double} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return Double.valueOf(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/ElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * The base class for element handlers.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ *
+ * @see DocumentHandler
+ */
+public abstract class ElementHandler {
+    private DocumentHandler owner;
+    private ElementHandler parent;
+
+    private String id;
+
+    /**
+     * Returns the document handler that creates this element handler.
+     *
+     * @return the owner document handler
+     */
+    public final DocumentHandler getOwner() {
+        return this.owner;
+    }
+
+    /**
+     * Sets the document handler that creates this element handler.
+     * The owner document handler should be set after instantiation.
+     * Such approach is used to simplify the extensibility.
+     *
+     * @param owner  the owner document handler
+     * @see DocumentHandler#startElement
+     */
+    final void setOwner(DocumentHandler owner) {
+        if (owner == null) {
+            throw new IllegalArgumentException("Every element should have owner");
+        }
+        this.owner = owner;
+    }
+
+    /**
+     * Returns the element handler that contains this one.
+     *
+     * @return the parent element handler
+     */
+    public final ElementHandler getParent() {
+        return this.parent;
+    }
+
+    /**
+     * Sets the element handler that contains this one.
+     * The parent element handler should be set after instantiation.
+     * Such approach is used to simplify the extensibility.
+     *
+     * @param parent  the parent element handler
+     * @see DocumentHandler#startElement
+     */
+    final void setParent(ElementHandler parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Returns the value of the variable with specified identifier.
+     *
+     * @param id  the identifier
+     * @return the value of the variable
+     */
+    protected final Object getVariable(String id) {
+        if (id.equals(this.id)) {
+            ValueObject value = getValueObject();
+            if (value.isVoid()) {
+                throw new IllegalStateException("The element does not return value");
+            }
+            return value.getValue();
+        }
+        return (this.parent != null)
+                ? this.parent.getVariable(id)
+                : this.owner.getVariable(id);
+    }
+
+    /**
+     * Returns the value of the parent element.
+     *
+     * @return the value of the parent element
+     */
+    protected Object getContextBean() {
+        if (this.parent != null) {
+            ValueObject value = this.parent.getValueObject();
+            if (!value.isVoid()) {
+                return value.getValue();
+            }
+            throw new IllegalStateException("The outer element does not return value");
+        } else {
+            Object value = this.owner.getOwner();
+            if (value != null) {
+                return value;
+            }
+            throw new IllegalStateException("The topmost element does not have context");
+        }
+    }
+
+    /**
+     * Parses attributes of the element.
+     * By default, the following atribute is supported:
+     * <dl>
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    public void addAttribute(String name, String value) {
+        if (name.equals("id")) { // NON-NLS: the attribute name
+            this.id = value;
+        } else {
+            throw new IllegalArgumentException("Unsupported attribute: " + name);
+        }
+    }
+
+    /**
+     * This method is called before parsing of the element's body.
+     * All attributes are parsed at this point.
+     * By default, do nothing.
+     */
+    public void startElement() {
+    }
+
+    /**
+     * This method is called after parsing of the element's body.
+     * By default, it calculates the value of this element.
+     * The following tasks are executing for any non-void value:
+     * <ol>
+     * <li>If the {@code id} attribute is set
+     * the value of the variable with the specified identifier
+     * is set to the value of this element.</li>
+     * <li>This element is used as an argument of parent element if it is possible.</li>
+     * </ol>
+     *
+     * @see #isArgument
+     */
+    public void endElement() {
+        // do nothing if no value returned
+        ValueObject value = getValueObject();
+        if (!value.isVoid()) {
+            if (this.id != null) {
+                this.owner.setVariable(this.id, value.getValue());
+            }
+            if (isArgument()) {
+                if (this.parent != null) {
+                    this.parent.addArgument(value.getValue());
+                } else {
+                    this.owner.addObject(value.getValue());
+                }
+            }
+        }
+    }
+
+    /**
+     * Adds the character that contained in this element.
+     * By default, only whitespaces are acceptable.
+     *
+     * @param ch  the character
+     */
+    public void addCharacter(char ch) {
+        if ((ch != ' ') && (ch != '\n') && (ch != '\t') && (ch != '\r')) {
+            throw new IllegalStateException("Illegal character with code " + (int) ch);
+        }
+    }
+
+    /**
+     * Adds the argument that is used to calculate the value of this element.
+     * By default, no arguments are acceptable.
+     *
+     * @param argument  the value of the element that contained in this one
+     */
+    protected void addArgument(Object argument) {
+        throw new IllegalStateException("Could not add argument to simple element");
+    }
+
+    /**
+     * Tests whether the value of this element can be used
+     * as an argument of the element that contained in this one.
+     *
+     * @return {@code true} if the value of this element can be used
+     *         as an argument of the element that contained in this one,
+     *         {@code false} otherwise
+     */
+    protected boolean isArgument() {
+        return this.id == null;
+    }
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    protected abstract ValueObject getValueObject();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/FalseElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;false&gt; element.
+ * This element specifies {@code false} value.
+ * It should not contain body or inner elements.
+ * For example:<pre>
+ * &lt;false/&gt;</pre>
+ * is equivalent to {@code false} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class FalseElementHandler extends NullElementHandler {
+
+    /**
+     * Returns {@code Boolean.FALSE}
+     * as a value of &lt;false&gt; element.
+     *
+     * @return {@code Boolean.FALSE} by default
+     */
+    @Override
+    public Object getValue() {
+        return Boolean.FALSE;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/FieldElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import com.sun.beans.finder.FieldFinder;
+
+import java.lang.reflect.Field;
+
+/**
+ * This class is intended to handle &lt;field&gt; element.
+ * This element simplifies access to the fields.
+ * If the {@code class} attribute is specified
+ * this element accesses static field of specified class.
+ * This element defines getter if it contains no argument.
+ * It returns the value of the field in this case.
+ * For example:<pre>
+ * &lt;field name="TYPE" class="java.lang.Long"/&gt;</pre>
+ * is equivalent to {@code Long.TYPE} in Java code.
+ * This element defines setter if it contains one argument.
+ * It does not return the value of the field in this case.
+ * For example:<pre>
+ * &lt;field name="id"&gt;&lt;int&gt;0&lt;/int&gt;&lt;/field&gt;</pre>
+ * is equivalent to {@code id = 0} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>name
+ * <dd>the field name
+ * <dt>class
+ * <dd>the type is used for static fields only
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class FieldElementHandler extends AccessorElementHandler {
+    private Class<?> type;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>name
+     * <dd>the field name
+     * <dt>class
+     * <dd>the type is used for static fields only
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("class")) { // NON-NLS: the attribute name
+            this.type = getOwner().findClass(value);
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Tests whether the value of this element can be used
+     * as an argument of the element that contained in this one.
+     *
+     * @return {@code true} if the value of this element should be used
+     *         as an argument of the element that contained in this one,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isArgument() {
+        return super.isArgument() && (this.type != null); // only static accessor can be used an argument
+    }
+
+    /**
+     * Returns the context of the field.
+     * The context of the static field is the class object.
+     * The context of the non-static field is the value of the parent element.
+     *
+     * @return the context of the field
+     */
+    @Override
+    protected Object getContextBean() {
+        return (this.type != null)
+                ? this.type
+                : super.getContextBean();
+    }
+
+    /**
+     * Returns the value of the field with specified {@code name}.
+     *
+     * @param name  the name of the field
+     * @return the value of the specified field
+     */
+    @Override
+    protected Object getValue(String name) {
+        try {
+            return getFieldValue(getContextBean(), name);
+        }
+        catch (Exception exception) {
+            getOwner().handleException(exception);
+        }
+        return null;
+    }
+
+    /**
+     * Sets the new value for the field with specified {@code name}.
+     *
+     * @param name   the name of the field
+     * @param value  the new value for the specified field
+     */
+    @Override
+    protected void setValue(String name, Object value) {
+        try {
+            setFieldValue(getContextBean(), name, value);
+        }
+        catch (Exception exception) {
+            getOwner().handleException(exception);
+        }
+    }
+
+    /**
+     * Performs the search of the field with specified {@code name}
+     * in specified context and returns its value.
+     *
+     * @param bean  the context bean that contains field
+     * @param name  the name of the field
+     * @return the value of the field
+     * @throws IllegalAccessException if the field is not accesible
+     * @throws NoSuchFieldException   if the field is not found
+     */
+    static Object getFieldValue(Object bean, String name) throws IllegalAccessException, NoSuchFieldException {
+        return findField(bean, name).get(bean);
+    }
+
+    /**
+     * Performs the search of the field with specified {@code name}
+     * in specified context and updates its value.
+     *
+     * @param bean   the context bean that contains field
+     * @param name   the name of the field
+     * @param value  the new value for the field
+     * @throws IllegalAccessException if the field is not accesible
+     * @throws NoSuchFieldException   if the field is not found
+     */
+    private static void setFieldValue(Object bean, String name, Object value) throws IllegalAccessException, NoSuchFieldException {
+        findField(bean, name).set(bean, value);
+    }
+
+    /**
+     * Performs the search of the field
+     * with specified {@code name} in specified context.
+     *
+     * @param bean  the context bean that contains field
+     * @param name  the name of the field
+     * @return field object that represents found field
+     * @throws NoSuchFieldException if the field is not found
+     */
+    private static Field findField(Object bean, String name) throws NoSuchFieldException {
+        return (bean instanceof Class<?>)
+                ? FieldFinder.findStaticField((Class<?>) bean, name)
+                : FieldFinder.findField(bean.getClass(), name);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/FloatElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;float&gt; element.
+ * This element specifies {@code float} values.
+ * The class {@link Float} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;float&gt;-1.23&lt;/float&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="valueOf" class="java.lang.Float"&gt;
+ *     &lt;string&gt;-1.23&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Float.valueOf("-1.23")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class FloatElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code float} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code float} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return Float.valueOf(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/IntElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;int&gt; element.
+ * This element specifies {@code int} values.
+ * The class {@link Integer} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;int&gt;-1&lt;/int&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="decode" class="java.lang.Integer"&gt;
+ *     &lt;string&gt;-1&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Integer.decode("-1")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class IntElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code int} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code int} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return Integer.decode(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/JavaElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import java.beans.XMLDecoder;
+
+/**
+ * This class is intended to handle &lt;java&gt; element.
+ * Each element that appears in the body of this element
+ * is evaluated in the context of the decoder itself.
+ * Typically this outer context is used to retrieve the owner of the decoder,
+ * which can be set before reading the archive.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>version
+ * <dd>the Java version (not supported)
+ * <dt>class
+ * <dd>the type of preferable parser (not supported)
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @see DocumentHandler#getOwner
+ * @see DocumentHandler#setOwner
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class JavaElementHandler extends ElementHandler {
+    private Class<?> type;
+    private ValueObject value;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>version
+     * <dd>the Java version (not supported)
+     * <dt>class
+     * <dd>the type of preferable parser (not supported)
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("version")) { // NON-NLS: the attribute name
+            // unsupported attribute
+        } else if (name.equals("class")) { // NON-NLS: the attribute name
+            // check class for owner
+            this.type = getOwner().findClass(value);
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Adds the argument to the list of readed objects.
+     *
+     * @param argument  the value of the element that contained in this one
+     */
+    @Override
+    protected void addArgument(Object argument) {
+        getOwner().addObject(argument);
+    }
+
+    /**
+     * Tests whether the value of this element can be used
+     * as an argument of the element that contained in this one.
+     *
+     * @return {@code true} if the value of this element should be used
+     *         as an argument of the element that contained in this one,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isArgument() {
+        return false; // do not use owner as object
+    }
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    @Override
+    protected ValueObject getValueObject() {
+        if (this.value == null) {
+            this.value = ValueObjectImpl.create(getValue());
+        }
+        return this.value;
+    }
+
+    /**
+     * Returns the owner of the owner document handler
+     * as a value of &lt;java&gt; element.
+     *
+     * @return the owner of the owner document handler
+     */
+    private Object getValue() {
+        Object owner = getOwner().getOwner();
+        if ((this.type == null) || isValid(owner)) {
+            return owner;
+        }
+        if (owner instanceof XMLDecoder) {
+            XMLDecoder decoder = (XMLDecoder) owner;
+            owner = decoder.getOwner();
+            if (isValid(owner)) {
+                return owner;
+            }
+        }
+        throw new IllegalStateException("Unexpected owner class: " + owner.getClass().getName());
+    }
+
+    /**
+     * Validates the owner of the &lt;java&gt; element.
+     * The owner is valid if it is {@code null} or an instance
+     * of the class specified by the {@code class} attribute.
+     *
+     * @param owner  the owner of the &lt;java&gt; element
+     * @return {@code true} if the {@code owner} is valid;
+     *         {@code false} otherwise
+     */
+    private boolean isValid(Object owner) {
+        return (owner == null) || this.type.isInstance(owner);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/LongElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;long&gt; element.
+ * This element specifies {@code long} values.
+ * The class {@link Long} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;long&gt;0xFFFF&lt;/long&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="decode" class="java.lang.Long"&gt;
+ *     &lt;string&gt;0xFFFF&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Long.decode("0xFFFF")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class LongElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code long} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code long} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return Long.decode(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/MethodElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import com.sun.beans.finder.MethodFinder;
+
+import java.lang.reflect.Method;
+
+/**
+ * This class is intended to handle &lt;method&gt; element.
+ * It describes invocation of the method.
+ * The {@code name} attribute denotes
+ * the name of the method to invoke.
+ * If the {@code class} attribute is specified
+ * this element invokes static method of specified class.
+ * The inner elements specifies the arguments of the method.
+ * For example:<pre>
+ * &lt;method name="valueOf" class="java.lang.Long"&gt;
+ *     &lt;string&gt;10&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * is equivalent to {@code Long.valueOf("10")} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>name
+ * <dd>the method name
+ * <dt>class
+ * <dd>the type of object for instantiation
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class MethodElementHandler extends NewElementHandler {
+    private String name;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>name
+     * <dd>the method name
+     * <dt>class
+     * <dd>the type of object for instantiation
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("name")) { // NON-NLS: the attribute name
+            this.name = value;
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Returns the result of method execution.
+     *
+     * @param type  the base class
+     * @param args  the array of arguments
+     * @return the value of this element
+     * @throws Exception if calculation is failed
+     */
+    @Override
+    protected ValueObject getValueObject(Class<?> type, Object[] args) throws Exception {
+        Object bean = getContextBean();
+        Class<?>[] types = getArgumentTypes(args);
+        Method method = (type != null)
+                ? MethodFinder.findStaticMethod(type, this.name, types)
+                : MethodFinder.findMethod(bean.getClass(), this.name, types);
+
+        if (method.isVarArgs()) {
+            args = getArguments(args, method.getParameterTypes());
+        }
+        Object value = method.invoke(bean, args);
+        return method.getReturnType().equals(void.class)
+                ? ValueObjectImpl.VOID
+                : ValueObjectImpl.create(value);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/NewElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import com.sun.beans.finder.ConstructorFinder;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class is intended to handle &lt;new&gt; element.
+ * It describes instantiation of the object.
+ * The {@code class} attribute denotes
+ * the name of the class to instantiate.
+ * The inner elements specifies the arguments of the constructor.
+ * For example:<pre>
+ * &lt;new class="java.lang.Long"&gt;
+ *     &lt;string&gt;10&lt;/string&gt;
+ * &lt;/new&gt;</pre>
+ * is equivalent to {@code new Long("10")} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>class
+ * <dd>the type of object for instantiation
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+class NewElementHandler extends ElementHandler {
+    private List<Object> arguments = new ArrayList<Object>();
+    private ValueObject value = ValueObjectImpl.VOID;
+
+    private Class<?> type;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>class
+     * <dd>the type of object for instantiation
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("class")) { // NON-NLS: the attribute name
+            this.type = getOwner().findClass(value);
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Adds the argument to the list of arguments
+     * that is used to calculate the value of this element.
+     *
+     * @param argument  the value of the element that contained in this one
+     */
+    @Override
+    protected final void addArgument(Object argument) {
+        if (this.arguments == null) {
+            throw new IllegalStateException("Could not add argument to evaluated element");
+        }
+        this.arguments.add(argument);
+    }
+
+    /**
+     * Returns the context of the method.
+     * The context of the static method is the class object.
+     * The context of the non-static method is the value of the parent element.
+     *
+     * @return the context of the method
+     */
+    @Override
+    protected final Object getContextBean() {
+        return (this.type != null)
+                ? this.type
+                : super.getContextBean();
+    }
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    @Override
+    protected final ValueObject getValueObject() {
+        if (this.arguments != null) {
+            try {
+                this.value = getValueObject(this.type, this.arguments.toArray());
+            }
+            catch (Exception exception) {
+                getOwner().handleException(exception);
+            }
+            finally {
+                this.arguments = null;
+            }
+        }
+        return this.value;
+    }
+
+    /**
+     * Calculates the value of this element
+     * using the base class and the array of arguments.
+     * By default, it creates an instance of the base class.
+     * This method should be overridden in those handlers
+     * that extend behavior of this element.
+     *
+     * @param type  the base class
+     * @param args  the array of arguments
+     * @return the value of this element
+     * @throws Exception if calculation is failed
+     */
+    ValueObject getValueObject(Class<?> type, Object[] args) throws Exception {
+        if (type == null) {
+            throw new IllegalArgumentException("Class name is not set");
+        }
+        Class<?>[] types = getArgumentTypes(args);
+        Constructor<?> constructor = ConstructorFinder.findConstructor(type, types);
+        if (constructor.isVarArgs()) {
+            args = getArguments(args, constructor.getParameterTypes());
+        }
+        return ValueObjectImpl.create(constructor.newInstance(args));
+    }
+
+    /**
+     * Converts the array of arguments to the array of corresponding classes.
+     * If argument is {@code null} the class is {@code null} too.
+     *
+     * @param arguments  the array of arguments
+     * @return the array of corresponding classes
+     */
+    static Class<?>[] getArgumentTypes(Object[] arguments) {
+        Class<?>[] types = new Class<?>[arguments.length];
+        for (int i = 0; i < arguments.length; i++) {
+            if (arguments[i] != null) {
+                types[i] = arguments[i].getClass();
+            }
+        }
+        return types;
+    }
+
+    /**
+     * Resolves variable arguments.
+     *
+     * @param arguments  the array of arguments
+     * @param types      the array of parameter types
+     * @return the resolved array of arguments
+     */
+    static Object[] getArguments(Object[] arguments, Class<?>[] types) {
+        int index = types.length - 1;
+        if (types.length == arguments.length) {
+            Object argument = arguments[index];
+            if (argument == null) {
+                return arguments;
+            }
+            Class<?> type = types[index];
+            if (type.isAssignableFrom(argument.getClass())) {
+                return arguments;
+            }
+        }
+        int length = arguments.length - index;
+        Class<?> type = types[index].getComponentType();
+        Object array = Array.newInstance(type, length);
+        System.arraycopy(arguments, index, array, 0, length);
+
+        Object[] args = new Object[types.length];
+        System.arraycopy(arguments, 0, args, 0, index);
+        args[index] = array;
+        return args;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/NullElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;null&gt; element.
+ * This element specifies {@code null} value.
+ * It should not contain body or inner elements.
+ * For example:<pre>
+ * &lt;null/&gt;</pre>
+ * is equivalent to {@code null} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+class NullElementHandler extends ElementHandler implements ValueObject {
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    @Override
+    protected final ValueObject getValueObject() {
+        return this;
+    }
+
+    /**
+     * Returns {@code null}
+     * as a value of &lt;null&gt; element.
+     * This method should be overridden in those handlers
+     * that extend behavior of this element.
+     *
+     * @return {@code null} by default
+     */
+    public Object getValue() {
+        return null;
+    }
+
+    /**
+     * Returns {@code void} state of this value object.
+     *
+     * @return {@code false} always
+     */
+    public final boolean isVoid() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/ObjectElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import java.beans.Expression;
+
+import static java.util.Locale.ENGLISH;
+
+/**
+ * This class is intended to handle &lt;object&gt; element.
+ * This element looks like &lt;void&gt; element,
+ * but its value is always used as an argument for element
+ * that contains this one.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>class
+ * <dd>the type is used for static methods and fields
+ * <dt>method
+ * <dd>the method name
+ * <dt>property
+ * <dd>the property name
+ * <dt>index
+ * <dd>the property index
+ * <dt>field
+ * <dd>the field name
+ * <dt>idref
+ * <dd>the identifier to refer to the variable
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+class ObjectElementHandler extends NewElementHandler {
+    private String idref;
+    private String field;
+    private Integer index;
+    private String property;
+    private String method;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>class
+     * <dd>the type is used for static methods and fields
+     * <dt>method
+     * <dd>the method name
+     * <dt>property
+     * <dd>the property name
+     * <dt>index
+     * <dd>the property index
+     * <dt>field
+     * <dd>the field name
+     * <dt>idref
+     * <dd>the identifier to refer to the variable
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public final void addAttribute(String name, String value) {
+        if (name.equals("idref")) { // NON-NLS: the attribute name
+            this.idref = value;
+        } else if (name.equals("field")) { // NON-NLS: the attribute name
+            this.field = value;
+        } else if (name.equals("index")) { // NON-NLS: the attribute name
+            this.index = Integer.valueOf(value);
+            addArgument(this.index); // hack for compatibility
+        } else if (name.equals("property")) { // NON-NLS: the attribute name
+            this.property = value;
+        } else if (name.equals("method")) { // NON-NLS: the attribute name
+            this.method = value;
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Calculates the value of this element
+     * if the field attribute or the idref attribute is set.
+     */
+    @Override
+    public final void startElement() {
+        if ((this.field != null) || (this.idref != null)) {
+            getValueObject();
+        }
+    }
+
+    /**
+     * Tests whether the value of this element can be used
+     * as an argument of the element that contained in this one.
+     *
+     * @return {@code true} if the value of this element can be used
+     *         as an argument of the element that contained in this one,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isArgument() {
+        return true; // hack for compatibility
+    }
+
+    /**
+     * Creates the value of this element.
+     *
+     * @param type  the base class
+     * @param args  the array of arguments
+     * @return the value of this element
+     * @throws Exception if calculation is failed
+     */
+    @Override
+    protected final ValueObject getValueObject(Class<?> type, Object[] args) throws Exception {
+        if (this.field != null) {
+            return ValueObjectImpl.create(FieldElementHandler.getFieldValue(getContextBean(), this.field));
+        }
+        if (this.idref != null) {
+            return ValueObjectImpl.create(getVariable(this.idref));
+        }
+        Object bean = getContextBean();
+        String name;
+        if (this.index != null) {
+            name = (args.length == 2)
+                    ? PropertyElementHandler.SETTER
+                    : PropertyElementHandler.GETTER;
+        } else if (this.property != null) {
+            name = (args.length == 1)
+                    ? PropertyElementHandler.SETTER
+                    : PropertyElementHandler.GETTER;
+
+            if (0 < this.property.length()) {
+                name += this.property.substring(0, 1).toUpperCase(ENGLISH) + this.property.substring(1);
+            }
+        } else {
+            name = (this.method != null) && (0 < this.method.length())
+                    ? this.method
+                    : "new"; // NON-NLS: the constructor marker
+        }
+        Expression expression = new Expression(bean, name, args);
+        return ValueObjectImpl.create(expression.getValue());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/PropertyElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import com.sun.beans.finder.MethodFinder;
+
+import java.beans.IndexedPropertyDescriptor;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * This class is intended to handle &lt;property&gt; element.
+ * This element simplifies access to the properties.
+ * If the {@code index} attribute is specified
+ * this element uses additional {@code int} parameter.
+ * If the {@code name} attribute is not specified
+ * this element uses method "get" as getter
+ * and method "set" as setter.
+ * This element defines getter if it contains no argument.
+ * It returns the value of the property in this case.
+ * For example:<pre>
+ * &lt;property name="object" index="10"/&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="getObject"&gt;
+ *     &lt;int&gt;10&lt;/int&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code getObject(10)} in Java code.
+ * This element defines setter if it contains one argument.
+ * It does not return the value of the property in this case.
+ * For example:<pre>
+ * &lt;property&gt;&lt;int&gt;0&lt;/int&gt;&lt;/property&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="set"&gt;
+ *     &lt;int&gt;0&lt;/int&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code set(0)} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>name
+ * <dd>the property name
+ * <dt>index
+ * <dd>the property index
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class PropertyElementHandler extends AccessorElementHandler {
+    static final String GETTER = "get"; // NON-NLS: the getter prefix
+    static final String SETTER = "set"; // NON-NLS: the setter prefix
+
+    private Integer index;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>name
+     * <dd>the property name
+     * <dt>index
+     * <dd>the property index
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("index")) { // NON-NLS: the attribute name
+            this.index = Integer.valueOf(value);
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Tests whether the value of this element can be used
+     * as an argument of the element that contained in this one.
+     *
+     * @return {@code true} if the value of this element should be used
+     *         as an argument of the element that contained in this one,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isArgument() {
+        return false; // non-static accessor cannot be used an argument
+    }
+
+    /**
+     * Returns the value of the property with specified {@code name}.
+     *
+     * @param name  the name of the property
+     * @return the value of the specified property
+     */
+    @Override
+    protected Object getValue(String name) {
+        try {
+            return getPropertyValue(getContextBean(), name, this.index);
+        }
+        catch (Exception exception) {
+            getOwner().handleException(exception);
+        }
+        return null;
+    }
+
+    /**
+     * Sets the new value for the property with specified {@code name}.
+     *
+     * @param name   the name of the property
+     * @param value  the new value for the specified property
+     */
+    @Override
+    protected void setValue(String name, Object value) {
+        try {
+            setPropertyValue(getContextBean(), name, this.index, value);
+        }
+        catch (Exception exception) {
+            getOwner().handleException(exception);
+        }
+    }
+
+    /**
+     * Performs the search of the getter for the property
+     * with specified {@code name} in specified class
+     * and returns value of the property.
+     *
+     * @param bean   the context bean that contains property
+     * @param name   the name of the property
+     * @param index  the index of the indexed property
+     * @return the value of the property
+     * @throws IllegalAccessException    if the property is not accesible
+     * @throws IntrospectionException    if the bean introspection is failed
+     * @throws InvocationTargetException if the getter cannot be invoked
+     * @throws NoSuchMethodException     if the getter is not found
+     */
+    private static Object getPropertyValue(Object bean, String name, Integer index) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException {
+        Class<?> type = bean.getClass();
+        if (index == null) {
+            return findGetter(type, name).invoke(bean);
+        } else if (type.isArray() && (name == null)) {
+            return Array.get(bean, index);
+        } else {
+            return findGetter(type, name, int.class).invoke(bean, index);
+        }
+    }
+
+    /**
+     * Performs the search of the setter for the property
+     * with specified {@code name} in specified class
+     * and updates value of the property.
+     *
+     * @param bean   the context bean that contains property
+     * @param name   the name of the property
+     * @param index  the index of the indexed property
+     * @param value  the new value for the property
+     * @throws IllegalAccessException    if the property is not accesible
+     * @throws IntrospectionException    if the bean introspection is failed
+     * @throws InvocationTargetException if the setter cannot be invoked
+     * @throws NoSuchMethodException     if the setter is not found
+     */
+    private static void setPropertyValue(Object bean, String name, Integer index, Object value) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException {
+        Class<?> type = bean.getClass();
+        Class<?> param = (value != null)
+                ? value.getClass()
+                : null;
+
+        if (index == null) {
+            findSetter(type, name, param).invoke(bean, value);
+        } else if (type.isArray() && (name == null)) {
+            Array.set(bean, index, value);
+        } else {
+            findSetter(type, name, int.class, param).invoke(bean, index, value);
+        }
+    }
+
+    /**
+     * Performs the search of the getter for the property
+     * with specified {@code name} in specified class.
+     *
+     * @param type  the class that contains method
+     * @param name  the name of the property
+     * @param args  the method arguments
+     * @return method object that represents found getter
+     * @throws IntrospectionException if the bean introspection is failed
+     * @throws NoSuchMethodException  if method is not found
+     */
+    private static Method findGetter(Class<?> type, String name, Class<?>...args) throws IntrospectionException, NoSuchMethodException {
+        if (name == null) {
+            return MethodFinder.findInstanceMethod(type, GETTER, args);
+        }
+        PropertyDescriptor pd = getProperty(type, name);
+        if (args.length == 0) {
+            Method method = pd.getReadMethod();
+            if (method != null) {
+                return method;
+            }
+        } else if (pd instanceof IndexedPropertyDescriptor) {
+            IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
+            Method method = ipd.getIndexedReadMethod();
+            if (method != null) {
+                return method;
+            }
+        }
+        throw new IntrospectionException("Could not find getter for the " + name + " property");
+    }
+
+    /**
+     * Performs the search of the setter for the property
+     * with specified {@code name} in specified class.
+     *
+     * @param type  the class that contains method
+     * @param name  the name of the property
+     * @param args  the method arguments
+     * @return method object that represents found setter
+     * @throws IntrospectionException if the bean introspection is failed
+     * @throws NoSuchMethodException  if method is not found
+     */
+    private static Method findSetter(Class<?> type, String name, Class<?>...args) throws IntrospectionException, NoSuchMethodException {
+        if (name == null) {
+            return MethodFinder.findInstanceMethod(type, SETTER, args);
+        }
+        PropertyDescriptor pd = getProperty(type, name);
+        if (args.length == 1) {
+            Method method = pd.getWriteMethod();
+            if (method != null) {
+                return method;
+            }
+        } else if (pd instanceof IndexedPropertyDescriptor) {
+            IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
+            Method method = ipd.getIndexedWriteMethod();
+            if (method != null) {
+                return method;
+            }
+        }
+        throw new IntrospectionException("Could not find setter for the " + name + " property");
+    }
+
+    /**
+     * Performs the search of the descriptor for the property
+     * with specified {@code name} in specified class.
+     *
+     * @param type  the class to introspect
+     * @param name  the property name
+     * @return descriptor for the named property
+     * @throws IntrospectionException if property descriptor is not found
+     */
+    private static PropertyDescriptor getProperty(Class<?> type, String name) throws IntrospectionException {
+        for (PropertyDescriptor pd : Introspector.getBeanInfo(type).getPropertyDescriptors()) {
+            if (name.equals(pd.getName())) {
+                return pd;
+            }
+        }
+        throw new IntrospectionException("Could not find the " + name + " property descriptor");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/ShortElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;short&gt; element.
+ * This element specifies {@code short} values.
+ * The class {@link Short} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;short&gt;200&lt;/short&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="decode" class="java.lang.Short"&gt;
+ *     &lt;string&gt;200&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Short.decode("200")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class ShortElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code short} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code short} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return Short.decode(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/StringElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;string&gt; element.
+ * This element specifies {@link String} values.
+ * The result value is created from text of the body of this element.
+ * For example:<pre>
+ * &lt;string&gt;description&lt;/string&gt;</pre>
+ * is equivalent to {@code "description"} in Java code.
+ * The value of inner element is calculated
+ * before adding to the string using {@link String#valueOf(Object)}.
+ * Note that all characters are used including whitespaces (' ', '\t', '\n', '\r').
+ * So the value of the element<pre>
+ * &lt;string&gt&lt;true&gt&lt;/string&gt;</pre>
+ * is not equal to the value of the element<pre>
+ * &lt;string&gt;
+ *     &lt;true&gt;
+ * &lt;/string&gt;</pre>
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public class StringElementHandler extends ElementHandler {
+    private StringBuilder sb = new StringBuilder();
+    private ValueObject value = ValueObjectImpl.NULL;
+
+    /**
+     * Adds the character that contained in this element.
+     *
+     * @param ch  the character
+     */
+    @Override
+    public final void addCharacter(char ch) {
+        if (this.sb == null) {
+            throw new IllegalStateException("Could not add chararcter to evaluated string element");
+        }
+        this.sb.append(ch);
+    }
+
+    /**
+     * Adds the string value of the argument to the string value of this element.
+     *
+     * @param argument  the value of the element that contained in this one
+     */
+    @Override
+    protected final void addArgument(Object argument) {
+        if (this.sb == null) {
+            throw new IllegalStateException("Could not add argument to evaluated string element");
+        }
+        this.sb.append(argument);
+    }
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    @Override
+    protected final ValueObject getValueObject() {
+        if (this.sb != null) {
+            try {
+                this.value = ValueObjectImpl.create(getValue(this.sb.toString()));
+            }
+            catch (RuntimeException exception) {
+                getOwner().handleException(exception);
+            }
+            finally {
+                this.sb = null;
+            }
+        }
+        return this.value;
+    }
+
+    /**
+     * Returns the text of the body of this element.
+     * This method evaluates value from text of the body,
+     * and should be overridden in those handlers
+     * that extend behavior of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated value
+     */
+    protected Object getValue(String argument) {
+        return argument;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/TrueElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;true&gt; element.
+ * This element specifies {@code true} value.
+ * It should not contain body or inner elements.
+ * For example:<pre>
+ * &lt;true/&gt;</pre>
+ * is equivalent to {@code true} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class TrueElementHandler extends NullElementHandler {
+
+    /**
+     * Returns {@code Boolean.TRUE}
+     * as a value of &lt;true&gt; element.
+     *
+     * @return {@code Boolean.TRUE} by default
+     */
+    @Override
+    public Object getValue() {
+        return Boolean.TRUE;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/ValueObject.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This interface represents the result of method execution.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public interface ValueObject {
+
+    /**
+     * Returns the result of method execution.
+     *
+     * @return the result of method execution
+     */
+    Object getValue();
+
+    /**
+     * Returns {@code void} state of this value object.
+     *
+     * @return {@code true} if value can be ignored,
+     *         {@code false} otherwise
+     */
+    boolean isVoid();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/ValueObjectImpl.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This utility class provides {@code static} method
+ * to create the object that contains the result of method execution.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class ValueObjectImpl implements ValueObject {
+    static final ValueObject NULL = new ValueObjectImpl(null);
+    static final ValueObject VOID = new ValueObjectImpl();
+
+    /**
+     * Returns the object that describes returning value.
+     *
+     * @param value  the result of method execution
+     * @return the object that describes value
+     */
+    static ValueObject create(Object value) {
+        return (value != null)
+                ? new ValueObjectImpl(value)
+                : NULL;
+    }
+
+    private Object value;
+    private boolean isVoid;
+
+    /**
+     * Creates the object that describes returning void value.
+     */
+    private ValueObjectImpl() {
+        this.isVoid = true;
+    }
+
+    /**
+     * Creates the object that describes returning non-void value.
+     *
+     * @param value  the result of method execution
+     */
+    private ValueObjectImpl(Object value) {
+        this.value = value;
+    }
+
+    /**
+     * Returns the result of method execution.
+     *
+     * @return the result of method execution
+     */
+    public Object getValue() {
+        return this.value;
+    }
+
+    /**
+     * Returns {@code void} state of this value object.
+     *
+     * @return {@code true} if value should be ignored,
+     *         {@code false} otherwise
+     */
+    public boolean isVoid() {
+        return this.isVoid;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/VarElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;var&gt; element.
+ * This element retrieves the value of specified variable.
+ * For example:<pre>
+ * &lt;var id="id1" idref="id2"/&gt;</pre>
+ * is equivalent to {@code id1 = id2} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>idref
+ * <dd>the identifier to refer to the variable
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class VarElementHandler extends ElementHandler {
+    private ValueObject value;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>idref
+     * <dd>the identifier to refer to the variable
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("idref")) { // NON-NLS: the attribute name
+            this.value = ValueObjectImpl.create(getVariable(value));
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    @Override
+    protected ValueObject getValueObject() {
+        if (this.value == null) {
+            throw new IllegalArgumentException("Variable name is not set");
+        }
+        return this.value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/decoder/VoidElementHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;void&gt; element.
+ * This element looks like &lt;object&gt; element,
+ * but its value is not used as an argument for element
+ * that contains this one.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>class
+ * <dd>the type is used for static methods and fields
+ * <dt>method
+ * <dd>the method name
+ * <dt>property
+ * <dd>the property name
+ * <dt>index
+ * <dd>the property index
+ * <dt>field
+ * <dd>the field name
+ * <dt>idref
+ * <dd>the identifier to refer to the variable
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class VoidElementHandler extends ObjectElementHandler {
+
+    /**
+     * Tests whether the value of this element can be used
+     * as an argument of the element that contained in this one.
+     *
+     * @return {@code true} if the value of this element should be used
+     *         as an argument of the element that contained in this one,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isArgument() {
+        return false; // hack for compatibility
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/finder/AbstractFinder.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This abstract class provides functionality
+ * to find a public method or constructor
+ * with specified parameter types.
+ * It supports a variable number of parameters.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+abstract class AbstractFinder<T> {
+    private final Class<?>[] args;
+
+    /**
+     * Creates finder for array of classes of arguments.
+     * If a particular element of array equals {@code null},
+     * than the appropriate pair of classes
+     * does not take into consideration.
+     *
+     * @param args  array of classes of arguments
+     */
+    protected AbstractFinder(Class<?>[] args) {
+        this.args = args;
+    }
+
+    /**
+     * Returns an array of {@code Class} objects
+     * that represent the formal parameter types of the method
+     * Returns an empty array if the method takes no parameters.
+     *
+     * @param method  the object that represents method
+     * @return the parameter types of the method
+     */
+    protected abstract Class<?>[] getParameters(T method);
+
+    /**
+     * Returns {@code true} if and only if the method
+     * was declared to take a variable number of arguments.
+     *
+     * @param method  the object that represents method
+     * @return {@code true} if the method was declared
+     *         to take a variable number of arguments;
+     *         {@code false} otherwise
+     */
+    protected abstract boolean isVarArgs(T method);
+
+    /**
+     * Checks validness of the method.
+     * At least the valid method should be public.
+     *
+     * @param method  the object that represents method
+     * @return {@code true} if the method is valid,
+     *         {@code false} otherwise
+     */
+    protected abstract boolean isValid(T method);
+
+    /**
+     * Performs a search in the {@code methods} array.
+     * The one method is selected from the array of the valid methods.
+     * The list of parameters of the selected method shows
+     * the best correlation with the list of arguments
+     * specified at class initialization.
+     * If more than one method is both accessible and applicable
+     * to a method invocation, it is necessary to choose one
+     * to provide the descriptor for the run-time method dispatch.
+     * The most specific method should be chosen.
+     *
+     * @param methods  the array of methods to search within
+     * @return the object that represents found method
+     * @throws NoSuchMethodException if no method was found or several
+     *                               methods meet the search criteria
+     * @see #isAssignable
+     */
+    final T find(T[] methods) throws NoSuchMethodException {
+        Map<T, Class<?>[]> map = new HashMap<T, Class<?>[]>();
+
+        T oldMethod = null;
+        Class<?>[] oldParams = null;
+        boolean ambiguous = false;
+
+        for (T newMethod : methods) {
+            if (isValid(newMethod)) {
+                Class<?>[] newParams = getParameters(newMethod);
+                if (newParams.length == this.args.length) {
+                    PrimitiveWrapperMap.replacePrimitivesWithWrappers(newParams);
+                    if (isAssignable(newParams, this.args)) {
+                        if (oldMethod == null) {
+                            oldMethod = newMethod;
+                            oldParams = newParams;
+                        } else {
+                            boolean useNew = isAssignable(oldParams, newParams);
+                            boolean useOld = isAssignable(newParams, oldParams);
+
+                            if (useOld == useNew) {
+                                ambiguous = true;
+                            } else if (useNew) {
+                                oldMethod = newMethod;
+                                oldParams = newParams;
+                                ambiguous = false;
+                            }
+                        }
+                    }
+                }
+                if (isVarArgs(newMethod)) {
+                    int length = newParams.length - 1;
+                    if (length <= this.args.length) {
+                        Class<?>[] array = new Class<?>[this.args.length];
+                        System.arraycopy(newParams, 0, array, 0, length);
+                        if (length < this.args.length) {
+                            Class<?> type = newParams[length].getComponentType();
+                            if (type.isPrimitive()) {
+                                type = PrimitiveWrapperMap.getType(type.getName());
+                            }
+                            for (int i = length; i < this.args.length; i++) {
+                                array[i] = type;
+                            }
+                        }
+                        map.put(newMethod, array);
+                    }
+                }
+            }
+        }
+        for (T newMethod : methods) {
+            Class<?>[] newParams = map.get(newMethod);
+            if (newParams != null) {
+                if (isAssignable(newParams, this.args)) {
+                    if (oldMethod == null) {
+                        oldMethod = newMethod;
+                        oldParams = newParams;
+                    } else {
+                        boolean useNew = isAssignable(oldParams, newParams);
+                        boolean useOld = isAssignable(newParams, oldParams);
+
+                        if (useOld == useNew) {
+                            if (oldParams == map.get(oldMethod)) {
+                                ambiguous = true;
+                            }
+                        } else if (useNew) {
+                            oldMethod = newMethod;
+                            oldParams = newParams;
+                            ambiguous = false;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (ambiguous) {
+            throw new NoSuchMethodException("Ambiguous methods are found");
+        }
+        if (oldMethod == null) {
+            throw new NoSuchMethodException("Method is not found");
+        }
+        return oldMethod;
+    }
+
+    /**
+     * Determines if every class in {@code min} array is either the same as,
+     * or is a superclass of, the corresponding class in {@code max} array.
+     * The length of every array must equal the number of arguments.
+     * This comparison is performed in the {@link #find} method
+     * before the first call of the isAssignable method.
+     * If an argument equals {@code null}
+     * the appropriate pair of classes does not take into consideration.
+     *
+     * @param min  the array of classes to be checked
+     * @param max  the array of classes that is used to check
+     * @return {@code true} if all classes in {@code min} array
+     *         are assignable from corresponding classes in {@code max} array,
+     *         {@code false} otherwise
+     *
+     * @see Class#isAssignableFrom
+     */
+    private boolean isAssignable(Class<?>[] min, Class<?>[] max) {
+        for (int i = 0; i < this.args.length; i++) {
+            if (null != this.args[i]) {
+                if (!min[i].isAssignableFrom(max[i])) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+}
--- a/jdk/src/share/classes/com/sun/beans/finder/ClassFinder.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/beans/finder/ClassFinder.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2006-2008 Sun Microsystems, 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
@@ -25,7 +25,7 @@
 package com.sun.beans.finder;
 
 /**
- * This is utility class that provides <code>static</code> methods
+ * This is utility class that provides {@code static} methods
  * to find a class with the specified name using the specified class loader.
  *
  * @since 1.7
@@ -33,137 +33,138 @@
  * @author Sergey A. Malenkov
  */
 public final class ClassFinder {
+
     /**
-     * Returns the <code>Class</code> object associated
+     * Returns the {@code Class} object associated
      * with the class or interface with the given string name,
      * using the default class loader.
      * <p>
-     * The <code>name</code> can denote an array class
+     * The {@code name} can denote an array class
      * (see {@link Class#getName} for details).
      *
      * @param name  fully qualified name of the desired class
      * @return class object representing the desired class
      *
-     * @exception ClassNotFoundException  if the class cannot be located
-     *                                    by the specified class loader
+     * @throws ClassNotFoundException  if the class cannot be located
+     *                                 by the specified class loader
      *
      * @see Class#forName(String)
      * @see Class#forName(String,boolean,ClassLoader)
      * @see ClassLoader#getSystemClassLoader()
      * @see Thread#getContextClassLoader()
      */
-    public static Class findClass( String name ) throws ClassNotFoundException {
+    public static Class<?> findClass(String name) throws ClassNotFoundException {
         try {
             ClassLoader loader = Thread.currentThread().getContextClassLoader();
-            if ( loader == null ) {
+            if (loader == null) {
                 // can be null in IE (see 6204697)
                 loader = ClassLoader.getSystemClassLoader();
             }
-            if ( loader != null ) {
-                return Class.forName( name, false, loader );
+            if (loader != null) {
+                return Class.forName(name, false, loader);
             }
 
-        } catch ( ClassNotFoundException exception ) {
+        } catch (ClassNotFoundException exception) {
             // use current class loader instead
-        } catch ( SecurityException exception ) {
+        } catch (SecurityException exception) {
             // use current class loader instead
         }
-        return Class.forName( name );
+        return Class.forName(name);
     }
 
     /**
-     * Returns the <code>Class</code> object associated with
+     * Returns the {@code Class} object associated with
      * the class or interface with the given string name,
      * using the given class loader.
      * <p>
-     * The <code>name</code> can denote an array class
+     * The {@code name} can denote an array class
      * (see {@link Class#getName} for details).
      * <p>
-     * If the parameter <code>loader</code> is null,
+     * If the parameter {@code loader} is null,
      * the class is loaded through the default class loader.
      *
      * @param name    fully qualified name of the desired class
      * @param loader  class loader from which the class must be loaded
      * @return class object representing the desired class
      *
-     * @exception ClassNotFoundException  if the class cannot be located
-     *                                    by the specified class loader
+     * @throws ClassNotFoundException  if the class cannot be located
+     *                                 by the specified class loader
      *
      * @see #findClass(String,ClassLoader)
      * @see Class#forName(String,boolean,ClassLoader)
      */
-    public static Class findClass( String name, ClassLoader loader ) throws ClassNotFoundException {
-        if ( loader != null ) {
+    public static Class<?> findClass(String name, ClassLoader loader) throws ClassNotFoundException {
+        if (loader != null) {
             try {
-                return Class.forName( name, false, loader );
-            } catch ( ClassNotFoundException exception ) {
+                return Class.forName(name, false, loader);
+            } catch (ClassNotFoundException exception) {
                 // use default class loader instead
-            } catch ( SecurityException exception ) {
+            } catch (SecurityException exception) {
                 // use default class loader instead
             }
         }
-        return findClass( name );
+        return findClass(name);
     }
 
     /**
-     * Returns the <code>Class</code> object associated
+     * Returns the {@code Class} object associated
      * with the class or interface with the given string name,
      * using the default class loader.
      * <p>
-     * The <code>name</code> can denote an array class
+     * The {@code name} can denote an array class
      * (see {@link Class#getName} for details).
      * <p>
      * This method can be used to obtain
-     * any of the <code>Class</code> objects
-     * representing <code>void</code> or primitive Java types:
-     * <code>char</code>, <code>byte</code>, <code>short</code>,
-     * <code>int</code>, <code>long</code>, <code>float</code>,
-     * <code>double</code> and <code>boolean</code>.
+     * any of the {@code Class} objects
+     * representing {@code void} or primitive Java types:
+     * {@code char}, {@code byte}, {@code short},
+     * {@code int}, {@code long}, {@code float},
+     * {@code double} and {@code boolean}.
      *
      * @param name  fully qualified name of the desired class
      * @return class object representing the desired class
      *
-     * @exception ClassNotFoundException  if the class cannot be located
-     *                                    by the specified class loader
+     * @throws ClassNotFoundException  if the class cannot be located
+     *                                 by the specified class loader
      *
      * @see #resolveClass(String,ClassLoader)
      */
-    public static Class resolveClass( String name ) throws ClassNotFoundException {
-        return resolveClass( name, null );
+    public static Class<?> resolveClass(String name) throws ClassNotFoundException {
+        return resolveClass(name, null);
     }
 
     /**
-     * Returns the <code>Class</code> object associated with
+     * Returns the {@code Class} object associated with
      * the class or interface with the given string name,
      * using the given class loader.
      * <p>
-     * The <code>name</code> can denote an array class
+     * The {@code name} can denote an array class
      * (see {@link Class#getName} for details).
      * <p>
-     * If the parameter <code>loader</code> is null,
+     * If the parameter {@code loader} is null,
      * the class is loaded through the default class loader.
      * <p>
      * This method can be used to obtain
-     * any of the <code>Class</code> objects
-     * representing <code>void</code> or primitive Java types:
-     * <code>char</code>, <code>byte</code>, <code>short</code>,
-     * <code>int</code>, <code>long</code>, <code>float</code>,
-     * <code>double</code> and <code>boolean</code>.
+     * any of the {@code Class} objects
+     * representing {@code void} or primitive Java types:
+     * {@code char}, {@code byte}, {@code short},
+     * {@code int}, {@code long}, {@code float},
+     * {@code double} and {@code boolean}.
      *
      * @param name    fully qualified name of the desired class
      * @param loader  class loader from which the class must be loaded
      * @return class object representing the desired class
      *
-     * @exception ClassNotFoundException  if the class cannot be located
-     *                                    by the specified class loader
+     * @throws ClassNotFoundException  if the class cannot be located
+     *                                 by the specified class loader
      *
      * @see #findClass(String,ClassLoader)
      * @see PrimitiveTypeMap#getType(String)
      */
-    public static Class resolveClass( String name, ClassLoader loader ) throws ClassNotFoundException {
-        Class type = PrimitiveTypeMap.getType( name );
-        return ( type == null )
-                ? findClass( name, loader )
+    public static Class<?> resolveClass(String name, ClassLoader loader) throws ClassNotFoundException {
+        Class<?> type = PrimitiveTypeMap.getType(name);
+        return (type == null)
+                ? findClass(name, loader)
                 : type;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/finder/ConstructorFinder.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+import com.sun.beans.WeakCache;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+
+/**
+ * This utility class provides {@code static} methods
+ * to find a public constructor with specified parameter types
+ * in specified class.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public final class ConstructorFinder extends AbstractFinder<Constructor<?>> {
+    private static final WeakCache<Signature, Constructor<?>> CACHE = new WeakCache<Signature, Constructor<?>>();
+
+    /**
+     * Finds public constructor
+     * that is declared in public class.
+     *
+     * @param type  the class that can have constructor
+     * @param args  parameter types that is used to find constructor
+     * @return object that represents found constructor
+     * @throws NoSuchMethodException if constructor could not be found
+     *                               or some constructors are found
+     */
+    public static Constructor<?> findConstructor(Class<?> type, Class<?>...args) throws NoSuchMethodException {
+        if (type.isPrimitive()) {
+            throw new NoSuchMethodException("Primitive wrapper does not contain constructors");
+        }
+        if (type.isInterface()) {
+            throw new NoSuchMethodException("Interface does not contain constructors");
+        }
+        if (Modifier.isAbstract(type.getModifiers())) {
+            throw new NoSuchMethodException("Abstract class cannot be instantiated");
+        }
+        if (!Modifier.isPublic(type.getModifiers())) {
+            throw new NoSuchMethodException("Class is not accessible");
+        }
+        PrimitiveWrapperMap.replacePrimitivesWithWrappers(args);
+        Signature signature = new Signature(type, args);
+
+        Constructor<?> constructor = CACHE.get(signature);
+        if (constructor != null) {
+            return constructor;
+        }
+        constructor = new ConstructorFinder(args).find(type.getConstructors());
+        CACHE.put(signature, constructor);
+        return constructor;
+    }
+
+    /**
+     * Creates constructor finder with specified array of parameter types.
+     *
+     * @param args  the array of parameter types
+     */
+    private ConstructorFinder(Class<?>[] args) {
+        super(args);
+    }
+
+    /**
+     * Returns an array of {@code Class} objects
+     * that represent the formal parameter types of the constructor
+     * Returns an empty array if the constructor takes no parameters.
+     *
+     * @param constructor  the object that represents constructor
+     * @return the parameter types of the constructor
+     */
+    @Override
+    protected Class<?>[] getParameters(Constructor<?> constructor) {
+        return constructor.getParameterTypes();
+    }
+
+    /**
+     * Returns {@code true} if and only if the constructor
+     * was declared to take a variable number of arguments.
+     *
+     * @param constructor  the object that represents constructor
+     * @return {@code true} if the constructor was declared
+     *         to take a variable number of arguments;
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isVarArgs(Constructor<?> constructor) {
+        return constructor.isVarArgs();
+    }
+
+    /**
+     * Checks validness of the constructor.
+     * The valid constructor should be public.
+     *
+     * @param constructor  the object that represents constructor
+     * @return {@code true} if the constructor is valid,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isValid(Constructor<?> constructor) {
+        return Modifier.isPublic(constructor.getModifiers());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/finder/FieldFinder.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * This utility class provides {@code static} methods
+ * to find a public field with specified name
+ * in specified class.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public final class FieldFinder {
+
+    /**
+     * Finds public field (static or non-static)
+     * that is declared in public class.
+     *
+     * @param type  the class that can have field
+     * @param name  the name of field to find
+     * @return object that represents found field
+     * @throws NoSuchFieldException if field is not found
+     * @see Class#getField
+     */
+    public static Field findField(Class<?> type, String name) throws NoSuchFieldException {
+        if (name == null) {
+            throw new IllegalArgumentException("Field name is not set");
+        }
+        Field field = type.getField(name);
+        if (!Modifier.isPublic(field.getModifiers())) {
+            throw new NoSuchFieldException("Field '" + name + "' is not public");
+        }
+        if (!Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
+            throw new NoSuchFieldException("Field '" + name + "' is not accessible");
+        }
+        return field;
+    }
+
+    /**
+     * Finds public non-static field
+     * that is declared in public class.
+     *
+     * @param type  the class that can have field
+     * @param name  the name of field to find
+     * @return object that represents found field
+     * @throws NoSuchFieldException if field is not found
+     * @see Class#getField
+     */
+    public static Field findInstanceField(Class<?> type, String name) throws NoSuchFieldException {
+        Field field = findField(type, name);
+        if (Modifier.isStatic(field.getModifiers())) {
+            throw new NoSuchFieldException("Field '" + name + "' is static");
+        }
+        return field;
+    }
+
+    /**
+     * Finds public static field
+     * that is declared in public class.
+     *
+     * @param type  the class that can have field
+     * @param name  the name of field to find
+     * @return object that represents found field
+     * @throws NoSuchFieldException if field is not found
+     * @see Class#getField
+     */
+    public static Field findStaticField(Class<?> type, String name) throws NoSuchFieldException {
+        Field field = findField(type, name);
+        if (!Modifier.isStatic(field.getModifiers())) {
+            throw new NoSuchFieldException("Field '" + name + "' is not static");
+        }
+        return field;
+    }
+
+    /**
+     * Disable instantiation.
+     */
+    private FieldFinder() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+import com.sun.beans.TypeResolver;
+import com.sun.beans.WeakCache;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+
+/**
+ * This utility class provides {@code static} methods
+ * to find a public method with specified name and parameter types
+ * in specified class.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public final class MethodFinder extends AbstractFinder<Method> {
+    private static final WeakCache<Signature, Method> CACHE = new WeakCache<Signature, Method>();
+
+    /**
+     * Finds public method (static or non-static)
+     * that is accessible from public class.
+     *
+     * @param type  the class that can have method
+     * @param name  the name of method to find
+     * @param args  parameter types that is used to find method
+     * @return object that represents found method
+     * @throws NoSuchMethodException if method could not be found
+     *                               or some methods are found
+     */
+    public static Method findMethod(Class<?> type, String name, Class<?>...args) throws NoSuchMethodException {
+        if (name == null) {
+            throw new IllegalArgumentException("Method name is not set");
+        }
+        PrimitiveWrapperMap.replacePrimitivesWithWrappers(args);
+        Signature signature = new Signature(type, name, args);
+
+        Method method = CACHE.get(signature);
+        if (method != null) {
+            return method;
+        }
+        method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods()));
+        CACHE.put(signature, method);
+        return method;
+    }
+
+    /**
+     * Finds public non-static method
+     * that is accessible from public class.
+     *
+     * @param type  the class that can have method
+     * @param name  the name of method to find
+     * @param args  parameter types that is used to find method
+     * @return object that represents found method
+     * @throws NoSuchMethodException if method could not be found
+     *                               or some methods are found
+     */
+    public static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) throws NoSuchMethodException {
+        Method method = findMethod(type, name, args);
+        if (Modifier.isStatic(method.getModifiers())) {
+            throw new NoSuchMethodException("Method '" + name + "' is static");
+        }
+        return method;
+    }
+
+    /**
+     * Finds public static method
+     * that is accessible from public class.
+     *
+     * @param type  the class that can have method
+     * @param name  the name of method to find
+     * @param args  parameter types that is used to find method
+     * @return object that represents found method
+     * @throws NoSuchMethodException if method could not be found
+     *                               or some methods are found
+     */
+    public static Method findStaticMethod(Class<?> type, String name, Class<?>...args) throws NoSuchMethodException {
+        Method method = findMethod(type, name, args);
+        if (!Modifier.isStatic(method.getModifiers())) {
+            throw new NoSuchMethodException("Method '" + name + "' is not static");
+        }
+        return method;
+    }
+
+    /**
+     * Finds method that is accessible from public class or interface through class hierarchy.
+     *
+     * @param method  object that represents found method
+     * @return object that represents accessible method
+     * @throws NoSuchMethodException if method is not accessible or is not found
+     *                               in specified superclass or interface
+     */
+    private static Method findAccessibleMethod(Method method) throws NoSuchMethodException {
+        Class<?> type = method.getDeclaringClass();
+        if (Modifier.isPublic(type.getModifiers())) {
+            return method;
+        }
+        if (Modifier.isStatic(method.getModifiers())) {
+            throw new NoSuchMethodException("Method '" + method.getName() + "' is not accessible");
+        }
+        for (Type generic : type.getGenericInterfaces()) {
+            try {
+                return findAccessibleMethod(method, generic);
+            }
+            catch (NoSuchMethodException exception) {
+                // try to find in superclass or another interface
+            }
+        }
+        return findAccessibleMethod(method, type.getGenericSuperclass());
+    }
+
+    /**
+     * Finds method that accessible from specified class.
+     *
+     * @param method  object that represents found method
+     * @param generic generic type that is used to find accessible method
+     * @return object that represents accessible method
+     * @throws NoSuchMethodException if method is not accessible or is not found
+     *                               in specified superclass or interface
+     */
+    private static Method findAccessibleMethod(Method method, Type generic) throws NoSuchMethodException {
+        String name = method.getName();
+        Class<?>[] params = method.getParameterTypes();
+        if (generic instanceof Class) {
+            Class<?> type = (Class<?>) generic;
+            return findAccessibleMethod(type.getMethod(name, params));
+        }
+        if (generic instanceof ParameterizedType) {
+            ParameterizedType pt = (ParameterizedType) generic;
+            Class<?> type = (Class<?>) pt.getRawType();
+            for (Method m : type.getMethods()) {
+                if (m.getName().equals(name)) {
+                    Class<?>[] pts = m.getParameterTypes();
+                    if (pts.length == params.length) {
+                        if (Arrays.equals(params, pts)) {
+                            return findAccessibleMethod(m);
+                        }
+                        Type[] gpts = m.getGenericParameterTypes();
+                        if (Arrays.equals(params, TypeResolver.erase(TypeResolver.resolve(pt, gpts)))) {
+                            return findAccessibleMethod(m);
+                        }
+                    }
+                }
+            }
+        }
+        throw new NoSuchMethodException("Method '" + name + "' is not accessible");
+    }
+
+
+    private final String name;
+
+    /**
+     * Creates method finder with specified array of parameter types.
+     *
+     * @param name  the name of method to find
+     * @param args  the array of parameter types
+     */
+    private MethodFinder(String name, Class<?>[] args) {
+        super(args);
+        this.name = name;
+    }
+
+    /**
+     * Returns an array of {@code Class} objects
+     * that represent the formal parameter types of the method
+     * Returns an empty array if the method takes no parameters.
+     *
+     * @param method  the object that represents method
+     * @return the parameter types of the method
+     */
+    @Override
+    protected Class<?>[] getParameters(Method method) {
+        return method.getParameterTypes();
+    }
+
+    /**
+     * Returns {@code true} if and only if the method
+     * was declared to take a variable number of arguments.
+     *
+     * @param method  the object that represents method
+     * @return {@code true} if the method was declared
+     *         to take a variable number of arguments;
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isVarArgs(Method method) {
+        return method.isVarArgs();
+    }
+
+    /**
+     * Checks validness of the method.
+     * The valid method should be public and
+     * should have the specified name.
+     *
+     * @param method  the object that represents method
+     * @return {@code true} if the method is valid,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isValid(Method method) {
+        return Modifier.isPublic(method.getModifiers()) && method.getName().equals(this.name);
+    }
+}
--- a/jdk/src/share/classes/com/sun/beans/finder/PrimitiveTypeMap.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/beans/finder/PrimitiveTypeMap.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2006-2008 Sun Microsystems, 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
@@ -36,29 +36,30 @@
  * @author Sergey A. Malenkov
  */
 final class PrimitiveTypeMap {
+
     /**
      * Returns primitive type class by its name.
      *
      * @param name  the name of primitive type
      * @return found primitive type class,
-     *         or <code>null</code> if not found
+     *         or {@code null} if not found
      */
-    static Class getType( String name ) {
-        return map.get( name );
+    static Class<?> getType(String name) {
+        return map.get(name);
     }
 
-    private static final Map<String, Class> map = new HashMap<String, Class>( 9 );
+    private static final Map<String, Class<?>> map = new HashMap<String, Class<?>>(9);
 
     static {
-        map.put( boolean.class.getName(), boolean.class );
-        map.put( char.class.getName(), char.class );
-        map.put( byte.class.getName(), byte.class );
-        map.put( short.class.getName(), short.class );
-        map.put( int.class.getName(), int.class );
-        map.put( long.class.getName(), long.class );
-        map.put( float.class.getName(), float.class );
-        map.put( double.class.getName(), double.class );
-        map.put( void.class.getName(), void.class );
+        map.put(boolean.class.getName(), boolean.class);
+        map.put(char.class.getName(), char.class);
+        map.put(byte.class.getName(), byte.class);
+        map.put(short.class.getName(), short.class);
+        map.put(int.class.getName(), int.class);
+        map.put(long.class.getName(), long.class);
+        map.put(float.class.getName(), float.class);
+        map.put(double.class.getName(), double.class);
+        map.put(void.class.getName(), void.class);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/finder/PrimitiveWrapperMap.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This utility class associates
+ * name of primitive type with appropriate wrapper.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public final class PrimitiveWrapperMap {
+
+    /**
+     * Replaces all primitive types in specified array with wrappers.
+     *
+     * @param types  array of classes where all primitive types
+     *               will be replaced by appropriate wrappers
+     */
+    static void replacePrimitivesWithWrappers(Class<?>[] types) {
+        for (int i = 0; i < types.length; i++) {
+            if (types[i] != null) {
+                if (types[i].isPrimitive()) {
+                    types[i] = getType(types[i].getName());
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns wrapper for primitive type by its name.
+     *
+     * @param name  the name of primitive type
+     * @return found wrapper for primitive type,
+     *         or {@code null} if not found
+     */
+    public static Class<?> getType(String name) {
+        return map.get(name);
+    }
+
+    private static final Map<String, Class<?>> map = new HashMap<String, Class<?>>(9);
+
+    static {
+        map.put(Boolean.TYPE.getName(), Boolean.class);
+        map.put(Character.TYPE.getName(), Character.class);
+        map.put(Byte.TYPE.getName(), Byte.class);
+        map.put(Short.TYPE.getName(), Short.class);
+        map.put(Integer.TYPE.getName(), Integer.class);
+        map.put(Long.TYPE.getName(), Long.class);
+        map.put(Float.TYPE.getName(), Float.class);
+        map.put(Double.TYPE.getName(), Double.class);
+        map.put(Void.TYPE.getName(), Void.class);
+    }
+
+    /**
+     * Disable instantiation.
+     */
+    private PrimitiveWrapperMap() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/finder/Signature.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+/**
+ * This class is designed to be a key of a cache
+ * of constructors or methods.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class Signature {
+    private final Class<?> type;
+    private final String name;
+    private final Class<?>[] args;
+
+    private volatile int code;
+
+    /**
+     * Constructs signature for constructor.
+     *
+     * @param type  the class that contains constructor
+     * @param args  the types of constructor's parameters
+     */
+    Signature(Class<?> type, Class<?>[] args) {
+        this(type, null, args);
+    }
+
+    /**
+     * Constructs signature for method.
+     *
+     * @param type  the class that contains method
+     * @param name  the name of the method
+     * @param args  the types of method's parameters
+     */
+    Signature(Class<?> type, String name, Class<?>[] args) {
+        this.type = type;
+        this.name = name;
+        this.args = args;
+    }
+
+    /**
+     * Indicates whether some other object is "equal to" this one.
+     *
+     * @param object  the reference object with which to compare
+     * @return {@code true} if this object is the same as the
+     *         {@code object} argument, {@code false} otherwise
+     * @see #hashCode()
+     */
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object instanceof Signature) {
+            Signature signature = (Signature) object;
+            return isEqual(signature.type, this.type)
+                && isEqual(signature.name, this.name)
+                && isEqual(signature.args, this.args);
+        }
+        return false;
+    }
+
+    /**
+     * Indicates whether some object is "equal to" another one.
+     * This method supports {@code null} values.
+     *
+     * @param obj1  the first reference object that will compared
+     * @param obj2  the second reference object that will compared
+     * @return {@code true} if first object is the same as the second object,
+     *         {@code false} otherwise
+     */
+    private static boolean isEqual(Object obj1, Object obj2) {
+        return (obj1 == null)
+                ? obj2 == null
+                : obj1.equals(obj2);
+    }
+
+    /**
+     * Indicates whether some array is "equal to" another one.
+     * This method supports {@code null} values.
+     *
+     * @param args1 the first reference array that will compared
+     * @param args2 the second reference array that will compared
+     * @return {@code true} if first array is the same as the second array,
+     *         {@code false} otherwise
+     */
+    private static boolean isEqual(Class<?>[] args1, Class<?>[] args2) {
+        if ((args1 == null) || (args2 == null)) {
+            return args1 == args2;
+        }
+        if (args1.length != args2.length) {
+            return false;
+        }
+        for (int i = 0; i < args1.length; i++) {
+            if (!isEqual(args1[i], args2[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns a hash code value for the object.
+     * This method is supported for the benefit of hashtables
+     * such as {@link java.util.HashMap} or {@link java.util.HashSet}.
+     * Hash code computed using algorithm
+     * suggested in Effective Java, Item 8.
+     *
+     * @return a hash code value for this object
+     * @see #equals(Object)
+     */
+    @Override
+    public int hashCode() {
+        if (this.code == 0) {
+            int code = 17;
+            code = addHashCode(code, this.type);
+            code = addHashCode(code, this.name);
+
+            if (this.args != null) {
+                for (Class<?> arg : this.args) {
+                    code = addHashCode(code, arg);
+                }
+            }
+            this.code = code;
+        }
+        return this.code;
+    }
+
+    /**
+     * Adds hash code value if specified object.
+     * This is a part of the algorithm
+     * suggested in Effective Java, Item 8.
+     *
+     * @param code    current hash code value
+     * @param object  object that updates hash code value
+     * @return updated hash code value
+     * @see #hashCode()
+     */
+    private static int addHashCode(int code, Object object) {
+        code *= 37;
+        return (object != null)
+                ? code + object.hashCode()
+                : code;
+    }
+}
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKColorChooserPanel.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKColorChooserPanel.java	Wed Jul 05 16:46:22 2017 +0200
@@ -799,9 +799,9 @@
             Graphics g = triangleImage.getGraphics();
             g.setColor(new Color(0, 0, 0, 0));
             g.fillRect(0, 0, a, a);
-            g.translate((int)(a / 2), 0);
+            g.translate(a / 2, 0);
             paintTriangle(g, triangleSize, getColor());
-            g.translate((int)(-a / 2), 0);
+            g.translate(-a / 2, 0);
             g.dispose();
 
             g = wheelImage.getGraphics();
@@ -897,7 +897,7 @@
                 return false;
             }
             // Rotate to origin and and verify x is valid.
-            int triangleSize = (int)innerR * 3 / 2;
+            int triangleSize = innerR * 3 / 2;
             double x1 = Math.cos(angle) * x - Math.sin(angle) * y;
             double y1 = Math.sin(angle) * x + Math.cos(angle) * y;
             if (x1 < -(innerR / 2)) {
@@ -960,7 +960,7 @@
          */
         private void setSaturationAndBrightness(float s, float b) {
             int innerR = getTriangleCircumscribedRadius();
-            int triangleSize = (int)innerR * 3 / 2;
+            int triangleSize = innerR * 3 / 2;
             double x = b * triangleSize;
             double maxY = x * Math.tan(Math.toRadians(30.0));
             double y = 2 * maxY * s - maxY;
@@ -1156,7 +1156,7 @@
          * @param x X location to get color for
          * @param y Y location to get color for
          * @param rad Radius from center of color wheel
-         * @param integer with red, green and blue components
+         * @return integer with red, green and blue components
          */
         private int colorWheelLocationToRGB(int x, int y, double rad) {
             double angle = Math.acos((double)x / rad);
@@ -1165,12 +1165,12 @@
             if (angle < PI_3) {
                 if (y < 0) {
                     // FFFF00 - FF0000
-                    rgb = 0xFF0000 | (int)Math.min(255,
+                    rgb = 0xFF0000 | Math.min(255,
                                            (int)(255 * angle / PI_3)) << 8;
                 }
                 else {
                     // FF0000 - FF00FF
-                    rgb = 0xFF0000 | (int)Math.min(255,
+                    rgb = 0xFF0000 | Math.min(255,
                                            (int)(255 * angle / PI_3));
                 }
             }
@@ -1178,12 +1178,12 @@
                 angle -= PI_3;
                 if (y < 0) {
                     // 00FF00 - FFFF00
-                    rgb = 0x00FF00 | (int)Math.max(0, 255 -
+                    rgb = 0x00FF00 | Math.max(0, 255 -
                                            (int)(255 * angle / PI_3)) << 16;
                 }
                 else {
                     // FF00FF - 0000FF
-                    rgb = 0x0000FF | (int)Math.max(0, 255 -
+                    rgb = 0x0000FF | Math.max(0, 255 -
                                            (int)(255 * angle / PI_3)) << 16;
                 }
             }
@@ -1191,12 +1191,12 @@
                 angle -= 2 * PI_3;
                 if (y < 0) {
                     // 00FFFF - 00FF00
-                    rgb = 0x00FF00 | (int)Math.min(255,
+                    rgb = 0x00FF00 | Math.min(255,
                                            (int)(255 * angle / PI_3));
                 }
                 else {
                     // 0000FF - 00FFFF
-                    rgb = 0x0000FF | (int)Math.min(255,
+                    rgb = 0x0000FF | Math.min(255,
                                            (int)(255 * angle / PI_3)) << 8;
                 }
             }
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKEngine.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKEngine.java	Wed Jul 05 16:46:22 2017 +0200
@@ -112,7 +112,7 @@
     }
 
 
-    private static HashMap regionToWidgetTypeMap;
+    private static HashMap<Region, Object> regionToWidgetTypeMap;
     private ImageCache cache = new ImageCache(CACHE_SIZE);
     private int x0, y0, w0, h0;
     private Graphics graphics;
@@ -178,7 +178,7 @@
         Toolkit.getDefaultToolkit();
 
         // Initialize regionToWidgetTypeMap
-        regionToWidgetTypeMap = new HashMap(50);
+        regionToWidgetTypeMap = new HashMap<Region, Object>(50);
         regionToWidgetTypeMap.put(Region.ARROW_BUTTON, new WidgetType[] {
             WidgetType.SPINNER_ARROW_BUTTON,
             WidgetType.COMBO_BOX_ARROW_BUTTON,
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java	Wed Jul 05 16:46:22 2017 +0200
@@ -148,7 +148,7 @@
             directoryList : fileList;
         Object[] files = list.getSelectedValues();
         int len = files.length;
-        Vector result = new Vector(len + 1);
+        Vector<String> result = new Vector<String>(len + 1);
 
         // we return all selected file names
         for (int i = 0; i < len; i++) {
@@ -263,13 +263,13 @@
         ListSelectionModel sm = directoryList.getSelectionModel();
         if (sm instanceof DefaultListSelectionModel) {
             ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0);
-            ((DefaultListSelectionModel)sm).setAnchorSelectionIndex(0);
+            sm.setAnchorSelectionIndex(0);
         }
         fileList.clearSelection();
         sm = fileList.getSelectionModel();
         if (sm instanceof DefaultListSelectionModel) {
             ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0);
-            ((DefaultListSelectionModel)sm).setAnchorSelectionIndex(0);
+            sm.setAnchorSelectionIndex(0);
         }
 
         File currentDirectory = getFileChooser().getCurrentDirectory();
@@ -425,16 +425,16 @@
                             setDirectorySelected(true);
                             setDirectory(((File)objects[0]));
                         } else {
-                            ArrayList fList = new ArrayList(objects.length);
-                            for (int i = 0; i < objects.length; i++) {
-                                File f = (File)objects[i];
+                            ArrayList<File> fList = new ArrayList<File>(objects.length);
+                            for (Object object : objects) {
+                                File f = (File) object;
                                 if ((chooser.isFileSelectionEnabled() && f.isFile())
                                     || (chooser.isDirectorySelectionEnabled() && f.isDirectory())) {
                                     fList.add(f);
                                 }
                             }
                             if (fList.size() > 0) {
-                                files = (File[])fList.toArray(new File[fList.size()]);
+                                files = fList.toArray(new File[fList.size()]);
                             }
                             setDirectorySelected(false);
                         }
@@ -671,9 +671,9 @@
 
         pathFieldLabel.setLabelFor(fileNameTextField);
 
-        Set forwardTraversalKeys = fileNameTextField.getFocusTraversalKeys(
+        Set<AWTKeyStroke> forwardTraversalKeys = fileNameTextField.getFocusTraversalKeys(
             KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
-        forwardTraversalKeys = new HashSet(forwardTraversalKeys);
+        forwardTraversalKeys = new HashSet<AWTKeyStroke>(forwardTraversalKeys);
         forwardTraversalKeys.remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
         fileNameTextField.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardTraversalKeys);
 
@@ -895,10 +895,9 @@
 
     private class GTKDirectoryModel extends BasicDirectoryModel {
         FileSystemView fsv;
-        private Comparator fileComparator = new Comparator() {
-            public int compare(Object o, Object o1) {
-                return fsv.getSystemDisplayName((File) o).compareTo
-                      (fsv.getSystemDisplayName((File) o1));
+        private Comparator<File> fileComparator = new Comparator<File>() {
+            public int compare(File o, File o1) {
+                return fsv.getSystemDisplayName(o).compareTo(fsv.getSystemDisplayName(o1));
             }
         };
 
@@ -1074,7 +1073,7 @@
      * Data model for a type-face selection combo-box.
      */
     protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel {
-        Vector directories = new Vector();
+        Vector<File> directories = new Vector<File>();
         File selectedDirectory = null;
         JFileChooser chooser = getFileChooser();
         FileSystemView fsv = chooser.getFileSystemView();
@@ -1216,7 +1215,7 @@
                     ListSelectionModel sm = fileList.getSelectionModel();
                     if (sm instanceof DefaultListSelectionModel) {
                         ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0);
-                        ((DefaultListSelectionModel)sm).setAnchorSelectionIndex(0);
+                        sm.setAnchorSelectionIndex(0);
                     }
                     rescanCurrentDirectory(getFileChooser());
                     return;
@@ -1352,8 +1351,8 @@
             FileFilter currentFilter = getFileChooser().getFileFilter();
             boolean found = false;
             if (currentFilter != null) {
-                for (int i = 0; i < filters.length; i++) {
-                    if (filters[i] == currentFilter) {
+                for (FileFilter filter : filters) {
+                    if (filter == currentFilter) {
                         found = true;
                     }
                 }
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1470,7 +1470,7 @@
         aaTextInfo = SwingUtilities2.AATextInfo.getAATextInfo(gtkAAFontSettingsCond);
     }
 
-    static ReferenceQueue queue = new ReferenceQueue();
+    static ReferenceQueue<GTKLookAndFeel> queue = new ReferenceQueue<GTKLookAndFeel>();
 
     private static void flushUnreferenced() {
         WeakPCL pcl;
@@ -1480,12 +1480,12 @@
         }
     }
 
-    static class WeakPCL extends WeakReference implements
+    static class WeakPCL extends WeakReference<GTKLookAndFeel> implements
             PropertyChangeListener {
         private Toolkit kit;
         private String key;
 
-        WeakPCL(Object target, Toolkit kit, String key) {
+        WeakPCL(GTKLookAndFeel target, Toolkit kit, String key) {
             super(target, queue);
             this.kit = kit;
             this.key = key;
@@ -1494,7 +1494,7 @@
         public String getKey() { return key; }
 
         public void propertyChange(final PropertyChangeEvent pce) {
-            final GTKLookAndFeel lnf = (GTKLookAndFeel)get();
+            final GTKLookAndFeel lnf = get();
 
             if (lnf == null || UIManager.getLookAndFeel() != lnf) {
                 // The property was GC'ed, we're no longer interested in
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java	Wed Jul 05 16:46:22 2017 +0200
@@ -299,7 +299,7 @@
             // Paint the default indicator
             GTKStyle style = (GTKStyle)context.getStyle();
             if (defaultCapable && !toolButton) {
-                Insets defaultInsets = (Insets)style.getClassSpecificInsetsValue(
+                Insets defaultInsets = style.getClassSpecificInsetsValue(
                         context, "default-border",
                         GTKStyle.BUTTON_DEFAULT_BORDER_INSETS);
 
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java	Wed Jul 05 16:46:22 2017 +0200
@@ -124,7 +124,7 @@
         }
 
         // Initialize constants
-        variables = new HashMap();
+        variables = new HashMap<String, Integer>();
         NodeList nodes = xmlDoc.getElementsByTagName("constant");
         int n = nodes.getLength();
         for (int i = 0; i < n; i++) {
@@ -144,14 +144,14 @@
         }
 
         // Cache frame geometries
-        frameGeometries = new HashMap();
+        frameGeometries = new HashMap<String, Map<String, Object>>();
         nodes = xmlDoc.getElementsByTagName("frame_geometry");
         n = nodes.getLength();
         for (int i = 0; i < n; i++) {
             Node node = nodes.item(i);
             String name = getStringAttr(node, "name");
             if (name != null) {
-                HashMap<String, Object> gm = new HashMap();
+                HashMap<String, Object> gm = new HashMap<String, Object>();
                 frameGeometries.put(name, gm);
 
                 String parentGM = getStringAttr(node, "parent");
@@ -458,7 +458,7 @@
 
 
 
-    private static class Privileged implements PrivilegedAction {
+    private static class Privileged implements PrivilegedAction<Object> {
         private static int GET_THEME_DIR  = 0;
         private static int GET_USER_THEME = 1;
         private static int GET_IMAGE      = 2;
@@ -598,7 +598,7 @@
         g2.setComposite(oldComp);
     }
 
-    private HashMap<String, Image> images = new HashMap();
+    private HashMap<String, Image> images = new HashMap<String, Image>();
 
     protected Image getImage(String key, Color c) {
         Image image = images.get(key+"-"+c.getRGB());
@@ -1530,8 +1530,8 @@
                 DocumentBuilderFactory.newInstance().newDocumentBuilder();
         }
         InputStream inputStream =
-            (InputStream)AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+            AccessController.doPrivileged(new PrivilegedAction<InputStream>() {
+                public InputStream run() {
                     try {
                         return new BufferedInputStream(xmlFile.openStream());
                     } catch (IOException ex) {
@@ -1551,7 +1551,7 @@
     protected Node[] getNodesByName(Node parent, String name) {
         NodeList nodes = parent.getChildNodes(); // ElementNode
         int n = nodes.getLength();
-        ArrayList<Node> list = new ArrayList();
+        ArrayList<Node> list = new ArrayList<Node>();
         for (int i=0; i < n; i++) {
             Node node = nodes.item(i);
             if (name.equals(node.getNodeName())) {
@@ -1603,7 +1603,7 @@
                             String aValue = attrs[a * 2 + 1];
                             Node attr = nodeAttrs.getNamedItem(aName);
                             if (attr == null ||
-                                aValue != null && !aValue.equals((String)attr.getNodeValue())) {
+                                aValue != null && !aValue.equals(attr.getNodeValue())) {
                                 matches = false;
                                 break;
                             }
@@ -1642,7 +1642,7 @@
 
     protected String getStringAttr(NamedNodeMap attrs, String name) {
         Node item = attrs.getNamedItem(name);
-        return (item != null) ? (String)item.getNodeValue() : null;
+        return (item != null) ? item.getNodeValue() : null;
     }
 
     protected boolean getBooleanAttr(Node node, String name, boolean fallback) {
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java	Wed Jul 05 16:46:22 2017 +0200
@@ -70,7 +70,6 @@
     private JTextField filenameTextField;
     private FilePane filePane;
     private WindowsPlacesBar placesBar;
-    private boolean useShellFolder;
 
     private JButton approveButton;
     private JButton cancelButton;
@@ -210,10 +209,6 @@
         public ListSelectionListener createListSelectionListener() {
             return WindowsFileChooserUI.this.createListSelectionListener(getFileChooser());
         }
-
-        public boolean usesShellFolder() {
-            return useShellFolder;
-        }
     }
 
     public void installComponents(JFileChooser fc) {
@@ -625,15 +620,8 @@
         // Decide whether to use the ShellFolder class to populate shortcut
         // panel and combobox.
         JFileChooser fc = getFileChooser();
-        Boolean prop =
-            (Boolean)fc.getClientProperty("FileChooser.useShellFolder");
-        if (prop != null) {
-            useShellFolder = prop.booleanValue();
-        } else {
-            useShellFolder = fc.getFileSystemView().equals(FileSystemView.getFileSystemView());
-        }
         if (OS_VERSION.compareTo(OSInfo.WINDOWS_ME) >= 0) {
-            if (useShellFolder) {
+            if (FilePane.usesShellFolder(fc)) {
                 if (placesBar == null && !UIManager.getBoolean("FileChooser.noPlacesBar")) {
                     placesBar = new WindowsPlacesBar(fc, XPStyle.getXP() != null);
                     fc.add(placesBar, BorderLayout.BEFORE_LINE_BEGINS);
@@ -1149,6 +1137,8 @@
                 return;
             }
 
+            boolean useShellFolder = FilePane.usesShellFolder(chooser);
+
             directories.clear();
 
             File[] baseFolders;
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1554,10 +1554,10 @@
             "Tree.selectionBackground", SelectionBackgroundColor,
             "Tree.expandedIcon", treeExpandedIcon,
             "Tree.collapsedIcon", treeCollapsedIcon,
-            "Tree.openIcon",   new ActiveWindowsIcon("win.icon.shellIconBPP", "shell32Icon 5",
-                                                     (Icon)table.get("Tree.openIcon")),
-            "Tree.closedIcon", new ActiveWindowsIcon("win.icon.shellIconBPP", "shell32Icon 4",
-                                                     (Icon)table.get("Tree.closedIcon")),
+            "Tree.openIcon",   new ActiveWindowsIcon("win.icon.shellIconBPP",
+                                   "shell32Icon 5", "icons/TreeOpen.gif"),
+            "Tree.closedIcon", new ActiveWindowsIcon("win.icon.shellIconBPP",
+                                   "shell32Icon 4", "icons/TreeClosed.gif"),
             "Tree.focusInputMap",
                new UIDefaults.LazyInputMap(new Object[] {
                                     "ADD", "expand",
@@ -2205,21 +2205,21 @@
      */
     private class ActiveWindowsIcon implements UIDefaults.ActiveValue {
         private Icon icon;
-        private Icon fallback;
         private String nativeImageName;
+        private String fallbackName;
         private DesktopProperty desktopProperty;
 
         ActiveWindowsIcon(String desktopPropertyName,
-                          String nativeImageName, Icon fallback) {
+                            String nativeImageName, String fallbackName) {
             this.nativeImageName = nativeImageName;
-            this.fallback = fallback;
+            this.fallbackName = fallbackName;
 
             if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS &&
                     OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_XP) < 0) {
                 // This desktop property is needed to trigger reloading the icon.
                 // It is kept in member variable to avoid GC.
                 this.desktopProperty = new TriggerDesktopProperty(desktopPropertyName) {
-                    protected void updateUI() {
+                    @Override protected void updateUI() {
                         icon = null;
                         super.updateUI();
                     }
@@ -2227,6 +2227,7 @@
             }
         }
 
+        @Override
         public Object createValue(UIDefaults table) {
             if (icon == null) {
                 Image image = (Image)ShellFolder.get(nativeImageName);
@@ -2234,8 +2235,11 @@
                     icon = new ImageIconUIResource(image);
                 }
             }
-            if (icon == null && fallback != null) {
-                icon = fallback;
+            if (icon == null && fallbackName != null) {
+                UIDefaults.LazyValue fallback = (UIDefaults.LazyValue)
+                        SwingUtilities2.makeIcon(WindowsLookAndFeel.class,
+                            BasicLookAndFeel.class, fallbackName);
+                icon = (Icon) fallback.createValue(table);
             }
             return icon;
         }
--- a/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java	Wed Jul 05 16:46:22 2017 +0200
@@ -75,13 +75,6 @@
     /**
      * This is the device handle returned from native code
      */
-    /*
-     * $$rratta Solaris 64 bit holds pointer must be long
-     *
-     * $$mp 2003-08-07:
-     * 'id' is a really bad name. The variable should
-     * be called nativePointer or something similar.
-     */
     protected long id                   = 0;
 
 
@@ -586,7 +579,6 @@
 
         private ArrayList<Transmitter> transmitters = new ArrayList<Transmitter>();
         private MidiOutDevice.MidiOutReceiver midiOutReceiver;
-        private MixerSynth.SynthReceiver mixerSynthReceiver;
 
         // how many transmitters must be present for optimized
         // handling
@@ -621,22 +613,14 @@
                 if (midiOutReceiver == oldR) {
                     midiOutReceiver = null;
                 }
-                if (mixerSynthReceiver == oldR) {
-                    mixerSynthReceiver = null;
-                }
                 if (newR != null) {
                     if ((newR instanceof MidiOutDevice.MidiOutReceiver)
                         && (midiOutReceiver == null)) {
                         midiOutReceiver = ((MidiOutDevice.MidiOutReceiver) newR);
                     }
-                    if ((newR instanceof MixerSynth.SynthReceiver)
-                        && (mixerSynthReceiver == null)) {
-                        mixerSynthReceiver = ((MixerSynth.SynthReceiver) newR);
-                    }
                 }
                 optimizedReceiverCount =
-                      ((midiOutReceiver!=null)?1:0)
-                    + ((mixerSynthReceiver!=null)?1:0);
+                      ((midiOutReceiver!=null)?1:0);
             }
             // more potential for optimization here
         }
@@ -670,10 +654,6 @@
                             if (TRACE_TRANSMITTER) Printer.println("Sending packed message to MidiOutReceiver");
                             midiOutReceiver.sendPackedMidiMessage(packedMessage, timeStamp);
                         }
-                        if (mixerSynthReceiver != null) {
-                            if (TRACE_TRANSMITTER) Printer.println("Sending packed message to MixerSynthReceiver");
-                            mixerSynthReceiver.sendPackedMidiMessage(packedMessage, timeStamp);
-                        }
                     } else {
                         if (TRACE_TRANSMITTER) Printer.println("Sending packed message to "+size+" transmitter's receivers");
                         for (int i = 0; i < size; i++) {
@@ -682,9 +662,6 @@
                                 if (optimizedReceiverCount > 0) {
                                     if (receiver instanceof MidiOutDevice.MidiOutReceiver) {
                                         ((MidiOutDevice.MidiOutReceiver) receiver).sendPackedMidiMessage(packedMessage, timeStamp);
-                                    }
-                                    else if (receiver instanceof MixerSynth.SynthReceiver) {
-                                        ((MixerSynth.SynthReceiver) receiver).sendPackedMidiMessage(packedMessage, timeStamp);
                                     } else {
                                         receiver.send(new FastShortMessage(packedMessage), timeStamp);
                                     }
@@ -739,10 +716,6 @@
                         if (TRACE_TRANSMITTER) Printer.println("Sending MIDI message to MidiOutReceiver");
                         midiOutReceiver.send(message, timeStamp);
                     }
-                    if (mixerSynthReceiver != null) {
-                        if (TRACE_TRANSMITTER) Printer.println("Sending MIDI message to MixerSynthReceiver");
-                        mixerSynthReceiver.send(message, timeStamp);
-                    }
                 } else {
                     if (TRACE_TRANSMITTER) Printer.println("Sending MIDI message to "+size+" transmitter's receivers");
                     for (int i = 0; i < size; i++) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.spi.SoundbankReader;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+/**
+ * Soundbank reader that uses audio files as soundbanks.
+ *
+ * @author Karl Helgason
+ */
+public class AudioFileSoundbankReader extends SoundbankReader {
+
+    public Soundbank getSoundbank(URL url)
+            throws InvalidMidiDataException, IOException {
+        try {
+            AudioInputStream ais = AudioSystem.getAudioInputStream(url);
+            Soundbank sbk = getSoundbank(ais);
+            ais.close();
+            return sbk;
+        } catch (UnsupportedAudioFileException e) {
+            return null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        stream.mark(512);
+        try {
+            AudioInputStream ais = AudioSystem.getAudioInputStream(stream);
+            Soundbank sbk = getSoundbank(ais);
+            if (sbk != null)
+                return sbk;
+        } catch (UnsupportedAudioFileException e) {
+        } catch (IOException e) {
+        }
+        stream.reset();
+        return null;
+    }
+
+    public Soundbank getSoundbank(AudioInputStream ais)
+            throws InvalidMidiDataException, IOException {
+        try {
+            byte[] buffer;
+            if (ais.getFrameLength() == -1) {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                byte[] buff = new byte[1024
+                        - (1024 % ais.getFormat().getFrameSize())];
+                int ret;
+                while ((ret = ais.read(buff)) != -1) {
+                    baos.write(buff, 0, ret);
+                }
+                ais.close();
+                buffer = baos.toByteArray();
+            } else {
+                buffer = new byte[(int) (ais.getFrameLength()
+                                    * ais.getFormat().getFrameSize())];
+                new DataInputStream(ais).readFully(buffer);
+            }
+            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
+                    new ModelByteBuffer(buffer), ais.getFormat(), -4800);
+            ModelPerformer performer = new ModelPerformer();
+            performer.getOscillators().add(osc);
+
+            SimpleSoundbank sbk = new SimpleSoundbank();
+            SimpleInstrument ins = new SimpleInstrument();
+            ins.add(performer);
+            sbk.addInstrument(ins);
+            return sbk;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(File file)
+            throws InvalidMidiDataException, IOException {
+        try {
+            AudioInputStream ais = AudioSystem.getAudioInputStream(file);
+            ais.close();
+            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
+                    new ModelByteBuffer(file, 0, file.length()), -4800);
+            ModelPerformer performer = new ModelPerformer();
+            performer.getOscillators().add(osc);
+            SimpleSoundbank sbk = new SimpleSoundbank();
+            SimpleInstrument ins = new SimpleInstrument();
+            ins.add(performer);
+            sbk.addInstrument(ins);
+            return sbk;
+        } catch (UnsupportedAudioFileException e1) {
+            return null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioFloatConverter.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,1058 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+/**
+ * This class is used to convert between 8,16,24,32,32+ bit signed/unsigned
+ * big/litle endian fixed/floating point byte buffers and float buffers.
+ *
+ * @author Karl Helgason
+ */
+public abstract class AudioFloatConverter {
+
+    public static final Encoding PCM_FLOAT = new Encoding("PCM_FLOAT");
+
+    /***************************************************************************
+     *
+     * LSB Filter, used filter least significant byte in samples arrays.
+     *
+     * Is used filter out data in lsb byte when SampleSizeInBits is not
+     * dividable by 8.
+     *
+     **************************************************************************/
+
+    private static class AudioFloatLSBFilter extends AudioFloatConverter {
+
+        private AudioFloatConverter converter;
+
+        final private int offset;
+
+        final private int stepsize;
+
+        final private byte mask;
+
+        private byte[] mask_buffer;
+
+        public AudioFloatLSBFilter(AudioFloatConverter converter,
+                AudioFormat format) {
+            int bits = format.getSampleSizeInBits();
+            boolean bigEndian = format.isBigEndian();
+            this.converter = converter;
+            stepsize = (bits + 7) / 8;
+            offset = bigEndian ? (stepsize - 1) : 0;
+            int lsb_bits = bits % 8;
+            if (lsb_bits == 0)
+                mask = (byte) 0x00;
+            else if (lsb_bits == 1)
+                mask = (byte) 0x80;
+            else if (lsb_bits == 2)
+                mask = (byte) 0xC0;
+            else if (lsb_bits == 3)
+                mask = (byte) 0xE0;
+            else if (lsb_bits == 4)
+                mask = (byte) 0xF0;
+            else if (lsb_bits == 5)
+                mask = (byte) 0xF8;
+            else if (lsb_bits == 6)
+                mask = (byte) 0xFC;
+            else if (lsb_bits == 7)
+                mask = (byte) 0xFE;
+            else
+                mask = (byte) 0xFF;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            byte[] ret = converter.toByteArray(in_buff, in_offset, in_len,
+                    out_buff, out_offset);
+
+            int out_offset_end = in_len * stepsize;
+            for (int i = out_offset + offset; i < out_offset_end; i += stepsize) {
+                out_buff[i] = (byte) (out_buff[i] & mask);
+            }
+
+            return ret;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            if (mask_buffer == null || mask_buffer.length < in_buff.length)
+                mask_buffer = new byte[in_buff.length];
+            System.arraycopy(in_buff, 0, mask_buffer, 0, in_buff.length);
+            int in_offset_end = out_len * stepsize;
+            for (int i = in_offset + offset; i < in_offset_end; i += stepsize) {
+                mask_buffer[i] = (byte) (mask_buffer[i] & mask);
+            }
+            float[] ret = converter.toFloatArray(mask_buffer, in_offset,
+                    out_buff, out_offset, out_len);
+            return ret;
+        }
+
+    }
+
+    /***************************************************************************
+     *
+     * 64 bit float, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 64 bit float, little-endian
+    private static class AudioFloatConversion64L extends AudioFloatConverter {
+        ByteBuffer bytebuffer = null;
+
+        DoubleBuffer floatbuffer = null;
+
+        double[] double_buff = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 8;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asDoubleBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            if (double_buff == null
+                    || double_buff.length < out_len + out_offset)
+                double_buff = new double[out_len + out_offset];
+            floatbuffer.get(double_buff, out_offset, out_len);
+            int out_offset_end = out_offset + out_len;
+            for (int i = out_offset; i < out_offset_end; i++) {
+                out_buff[i] = (float) double_buff[i];
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 8;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asDoubleBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            if (double_buff == null || double_buff.length < in_offset + in_len)
+                double_buff = new double[in_offset + in_len];
+            int in_offset_end = in_offset + in_len;
+            for (int i = in_offset; i < in_offset_end; i++) {
+                double_buff[i] = in_buff[i];
+            }
+            floatbuffer.put(double_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    // PCM 64 bit float, big-endian
+    private static class AudioFloatConversion64B extends AudioFloatConverter {
+        ByteBuffer bytebuffer = null;
+
+        DoubleBuffer floatbuffer = null;
+
+        double[] double_buff = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 8;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asDoubleBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            if (double_buff == null
+                    || double_buff.length < out_len + out_offset)
+                double_buff = new double[out_len + out_offset];
+            floatbuffer.get(double_buff, out_offset, out_len);
+            int out_offset_end = out_offset + out_len;
+            for (int i = out_offset; i < out_offset_end; i++) {
+                out_buff[i] = (float) double_buff[i];
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 8;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asDoubleBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            if (double_buff == null || double_buff.length < in_offset + in_len)
+                double_buff = new double[in_offset + in_len];
+            int in_offset_end = in_offset + in_len;
+            for (int i = in_offset; i < in_offset_end; i++) {
+                double_buff[i] = in_buff[i];
+            }
+            floatbuffer.put(double_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 32 bit float, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 32 bit float, little-endian
+    private static class AudioFloatConversion32L extends AudioFloatConverter {
+        ByteBuffer bytebuffer = null;
+
+        FloatBuffer floatbuffer = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            floatbuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            floatbuffer.put(in_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit float, big-endian
+    private static class AudioFloatConversion32B extends AudioFloatConverter {
+        ByteBuffer bytebuffer = null;
+
+        FloatBuffer floatbuffer = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            floatbuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            floatbuffer.put(in_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 8 bit signed/unsigned
+     *
+     **************************************************************************/
+
+    // PCM 8 bit, signed
+    private static class AudioFloatConversion8S extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++)
+                out_buff[ox++] = in_buff[ix++] * (1.0f / 127.0f);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++)
+                out_buff[ox++] = (byte) (in_buff[ix++] * 127.0f);
+            return out_buff;
+        }
+    }
+
+    // PCM 8 bit, unsigned
+    private static class AudioFloatConversion8U extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++)
+                out_buff[ox++] = ((in_buff[ix++] & 0xFF) - 127)
+                        * (1.0f / 127.0f);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++)
+                out_buff[ox++] = (byte) (127 + in_buff[ix++] * 127.0f);
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 16 bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 16 bit, signed, little-endian
+    private static class AudioFloatConversion16SL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int len = out_offset + out_len;
+            for (int ox = out_offset; ox < len; ox++) {
+                out_buff[ox] = ((short) ((in_buff[ix++] & 0xFF) |
+                           (in_buff[ix++] << 8))) * (1.0f / 32767.0f);
+            }
+
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ox = out_offset;
+            int len = in_offset + in_len;
+            for (int ix = in_offset; ix < len; ix++) {
+                int x = (int) (in_buff[ix] * 32767.0);
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 16 bit, signed, big-endian
+    private static class AudioFloatConversion16SB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                out_buff[ox++] = ((short) ((in_buff[ix++] << 8) |
+                        (in_buff[ix++] & 0xFF))) * (1.0f / 32767.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * 32767.0);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 16 bit, unsigned, little-endian
+    private static class AudioFloatConversion16UL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8);
+                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = 32767 + (int) (in_buff[ix++] * 32767.0);
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 16 bit, unsigned, big-endian
+    private static class AudioFloatConversion16UB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = 32767 + (int) (in_buff[ix++] * 32767.0);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 24 bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 24 bit, signed, little-endian
+    private static class AudioFloatConversion24SL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16);
+                if (x > 0x7FFFFF)
+                    x -= 0x1000000;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                if (x < 0)
+                    x += 0x1000000;
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 24 bit, signed, big-endian
+    private static class AudioFloatConversion24SB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                if (x > 0x7FFFFF)
+                    x -= 0x1000000;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                if (x < 0)
+                    x += 0x1000000;
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 24 bit, unsigned, little-endian
+    private static class AudioFloatConversion24UL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16);
+                x -= 0x7FFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                x += 0x7FFFFF;
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 24 bit, unsigned, big-endian
+    private static class AudioFloatConversion24UB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                x -= 0x7FFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                x += 0x7FFFFF;
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 32 bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 32 bit, signed, little-endian
+    private static class AudioFloatConversion32SL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 24);
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit, signed, big-endian
+    private static class AudioFloatConversion32SB extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                out_buff[ox++] = (byte) (x >>> 24);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit, unsigned, little-endian
+    private static class AudioFloatConversion32UL extends AudioFloatConverter {
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 24);
+                x -= 0x7FFFFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                x += 0x7FFFFFFF;
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit, unsigned, big-endian
+    private static class AudioFloatConversion32UB extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                x -= 0x7FFFFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                x += 0x7FFFFFFF;
+                out_buff[ox++] = (byte) (x >>> 24);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+            }
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 32+ bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 32+ bit, signed, little-endian
+    private static class AudioFloatConversion32xSL extends AudioFloatConverter {
+
+        final int xbytes;
+
+        public AudioFloatConversion32xSL(int xbytes) {
+            this.xbytes = xbytes;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                ix += xbytes;
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 24);
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                for (int j = 0; j < xbytes; j++) {
+                    out_buff[ox++] = 0;
+                }
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32+ bit, signed, big-endian
+    private static class AudioFloatConversion32xSB extends AudioFloatConverter {
+
+        final int xbytes;
+
+        public AudioFloatConversion32xSB(int xbytes) {
+            this.xbytes = xbytes;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24)
+                        | ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 8)
+                        | (in_buff[ix++] & 0xFF);
+                ix += xbytes;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                out_buff[ox++] = (byte) (x >>> 24);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+                for (int j = 0; j < xbytes; j++) {
+                    out_buff[ox++] = 0;
+                }
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32+ bit, unsigned, little-endian
+    private static class AudioFloatConversion32xUL extends AudioFloatConverter {
+
+        final int xbytes;
+
+        public AudioFloatConversion32xUL(int xbytes) {
+            this.xbytes = xbytes;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                ix += xbytes;
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 24);
+                x -= 0x7FFFFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
+                x += 0x7FFFFFFF;
+                for (int j = 0; j < xbytes; j++) {
+                    out_buff[ox++] = 0;
+                }
+                out_buff[ox++] = (byte) x;
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32+ bit, unsigned, big-endian
+    private static class AudioFloatConversion32xUB extends AudioFloatConverter {
+
+        final int xbytes;
+
+        public AudioFloatConversion32xUB(int xbytes) {
+            this.xbytes = xbytes;
+        }
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                ix += xbytes;
+                x -= 2147483647;
+                out_buff[ox++] = x * (1.0f / 2147483647.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int) (in_buff[ix++] * 2147483647.0);
+                x += 2147483647;
+                out_buff[ox++] = (byte) (x >>> 24);
+                out_buff[ox++] = (byte) (x >>> 16);
+                out_buff[ox++] = (byte) (x >>> 8);
+                out_buff[ox++] = (byte) x;
+                for (int j = 0; j < xbytes; j++) {
+                    out_buff[ox++] = 0;
+                }
+            }
+            return out_buff;
+        }
+    }
+
+    public static AudioFloatConverter getConverter(AudioFormat format) {
+        AudioFloatConverter conv = null;
+        if (format.getFrameSize() == 0)
+            return null;
+        if (format.getFrameSize() !=
+                ((format.getSampleSizeInBits() + 7) / 8) * format.getChannels()) {
+            return null;
+        }
+        if (format.getEncoding().equals(Encoding.PCM_SIGNED)) {
+            if (format.isBigEndian()) {
+                if (format.getSampleSizeInBits() <= 8) {
+                    conv = new AudioFloatConversion8S();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                      format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16SB();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                      format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24SB();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                      format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32SB();
+                } else if (format.getSampleSizeInBits() > 32) {
+                    conv = new AudioFloatConversion32xSB(((format
+                            .getSampleSizeInBits() + 7) / 8) - 4);
+                }
+            } else {
+                if (format.getSampleSizeInBits() <= 8) {
+                    conv = new AudioFloatConversion8S();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                         format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16SL();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                         format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24SL();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                         format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32SL();
+                } else if (format.getSampleSizeInBits() > 32) {
+                    conv = new AudioFloatConversion32xSL(((format
+                            .getSampleSizeInBits() + 7) / 8) - 4);
+                }
+            }
+        } else if (format.getEncoding().equals(Encoding.PCM_UNSIGNED)) {
+            if (format.isBigEndian()) {
+                if (format.getSampleSizeInBits() <= 8) {
+                    conv = new AudioFloatConversion8U();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                        format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16UB();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                        format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24UB();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                        format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32UB();
+                } else if (format.getSampleSizeInBits() > 32) {
+                    conv = new AudioFloatConversion32xUB(((
+                            format.getSampleSizeInBits() + 7) / 8) - 4);
+                }
+            } else {
+                if (format.getSampleSizeInBits() <= 8) {
+                    conv = new AudioFloatConversion8U();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                        format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16UL();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                        format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24UL();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                        format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32UL();
+                } else if (format.getSampleSizeInBits() > 32) {
+                    conv = new AudioFloatConversion32xUL(((
+                            format.getSampleSizeInBits() + 7) / 8) - 4);
+                }
+            }
+        } else if (format.getEncoding().equals(PCM_FLOAT)) {
+            if (format.getSampleSizeInBits() == 32) {
+                if (format.isBigEndian())
+                    conv = new AudioFloatConversion32B();
+                else
+                    conv = new AudioFloatConversion32L();
+            } else if (format.getSampleSizeInBits() == 64) {
+                if (format.isBigEndian())
+                    conv = new AudioFloatConversion64B();
+                else
+                    conv = new AudioFloatConversion64L();
+            }
+
+        }
+
+        if ((format.getEncoding().equals(Encoding.PCM_SIGNED) ||
+                format.getEncoding().equals(Encoding.PCM_UNSIGNED)) &&
+                (format.getSampleSizeInBits() % 8 != 0)) {
+            conv = new AudioFloatLSBFilter(conv, format);
+        }
+
+        if (conv != null)
+            conv.format = format;
+        return conv;
+    }
+
+    private AudioFormat format;
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public abstract float[] toFloatArray(byte[] in_buff, int in_offset,
+            float[] out_buff, int out_offset, int out_len);
+
+    public float[] toFloatArray(byte[] in_buff, float[] out_buff,
+            int out_offset, int out_len) {
+        return toFloatArray(in_buff, 0, out_buff, out_offset, out_len);
+    }
+
+    public float[] toFloatArray(byte[] in_buff, int in_offset,
+            float[] out_buff, int out_len) {
+        return toFloatArray(in_buff, in_offset, out_buff, 0, out_len);
+    }
+
+    public float[] toFloatArray(byte[] in_buff, float[] out_buff, int out_len) {
+        return toFloatArray(in_buff, 0, out_buff, 0, out_len);
+    }
+
+    public float[] toFloatArray(byte[] in_buff, float[] out_buff) {
+        return toFloatArray(in_buff, 0, out_buff, 0, out_buff.length);
+    }
+
+    public abstract byte[] toByteArray(float[] in_buff, int in_offset,
+            int in_len, byte[] out_buff, int out_offset);
+
+    public byte[] toByteArray(float[] in_buff, int in_len, byte[] out_buff,
+            int out_offset) {
+        return toByteArray(in_buff, 0, in_len, out_buff, out_offset);
+    }
+
+    public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+            byte[] out_buff) {
+        return toByteArray(in_buff, in_offset, in_len, out_buff, 0);
+    }
+
+    public byte[] toByteArray(float[] in_buff, int in_len, byte[] out_buff) {
+        return toByteArray(in_buff, 0, in_len, out_buff, 0);
+    }
+
+    public byte[] toByteArray(float[] in_buff, byte[] out_buff) {
+        return toByteArray(in_buff, 0, in_buff.length, out_buff, 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,617 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.AudioFormat.Encoding;
+import javax.sound.sampled.spi.FormatConversionProvider;
+
+/**
+ * This class is used to convert between 8,16,24,32 bit signed/unsigned
+ * big/litle endian fixed/floating stereo/mono/multi-channel audio streams and
+ * perform sample-rate conversion if needed.
+ *
+ * @author Karl Helgason
+ */
+public class AudioFloatFormatConverter extends FormatConversionProvider {
+
+    private static class AudioFloatFormatConverterInputStream extends
+            InputStream {
+        private AudioFloatConverter converter;
+
+        private AudioFloatInputStream stream;
+
+        private float[] readfloatbuffer;
+
+        private int fsize = 0;
+
+        public AudioFloatFormatConverterInputStream(AudioFormat targetFormat,
+                AudioFloatInputStream stream) {
+            this.stream = stream;
+            converter = AudioFloatConverter.getConverter(targetFormat);
+            fsize = ((targetFormat.getSampleSizeInBits() + 7) / 8);
+        }
+
+        public int read() throws IOException {
+            byte[] b = new byte[1];
+            int ret = read(b);
+            if (ret < 0)
+                return ret;
+            return b[0] & 0xFF;
+        }
+
+        public int read(byte[] b, int off, int len) throws IOException {
+
+            int flen = len / fsize;
+            if (readfloatbuffer == null || readfloatbuffer.length < flen)
+                readfloatbuffer = new float[flen];
+            int ret = stream.read(readfloatbuffer, 0, flen);
+            if (ret < 0)
+                return ret;
+            converter.toByteArray(readfloatbuffer, 0, ret, b, off);
+            return ret * fsize;
+        }
+
+        public int available() throws IOException {
+            int ret = stream.available();
+            if (ret < 0)
+                return ret;
+            return ret * fsize;
+        }
+
+        public void close() throws IOException {
+            stream.close();
+        }
+
+        public synchronized void mark(int readlimit) {
+            stream.mark(readlimit * fsize);
+        }
+
+        public boolean markSupported() {
+            return stream.markSupported();
+        }
+
+        public synchronized void reset() throws IOException {
+            stream.reset();
+        }
+
+        public long skip(long n) throws IOException {
+            long ret = stream.skip(n / fsize);
+            if (ret < 0)
+                return ret;
+            return ret * fsize;
+        }
+
+    }
+
+    private static class AudioFloatInputStreamChannelMixer extends
+            AudioFloatInputStream {
+
+        private int targetChannels;
+
+        private int sourceChannels;
+
+        private AudioFloatInputStream ais;
+
+        private AudioFormat targetFormat;
+
+        private float[] conversion_buffer;
+
+        public AudioFloatInputStreamChannelMixer(AudioFloatInputStream ais,
+                int targetChannels) {
+            this.sourceChannels = ais.getFormat().getChannels();
+            this.targetChannels = targetChannels;
+            this.ais = ais;
+            AudioFormat format = ais.getFormat();
+            targetFormat = new AudioFormat(format.getEncoding(), format
+                    .getSampleRate(), format.getSampleSizeInBits(),
+                    targetChannels, (format.getFrameSize() / sourceChannels)
+                            * targetChannels, format.getFrameRate(), format
+                            .isBigEndian());
+        }
+
+        public int available() throws IOException {
+            return (ais.available() / sourceChannels) * targetChannels;
+        }
+
+        public void close() throws IOException {
+            ais.close();
+        }
+
+        public AudioFormat getFormat() {
+            return targetFormat;
+        }
+
+        public long getFrameLength() {
+            return ais.getFrameLength();
+        }
+
+        public void mark(int readlimit) {
+            ais.mark((readlimit / targetChannels) * sourceChannels);
+        }
+
+        public boolean markSupported() {
+            return ais.markSupported();
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+            int len2 = (len / targetChannels) * sourceChannels;
+            if (conversion_buffer == null || conversion_buffer.length < len2)
+                conversion_buffer = new float[len2];
+            int ret = ais.read(conversion_buffer, 0, len2);
+            if (ret < 0)
+                return ret;
+            if (sourceChannels == 1) {
+                int cs = targetChannels;
+                for (int c = 0; c < targetChannels; c++) {
+                    for (int i = 0, ix = off + c; i < len2; i++, ix += cs) {
+                        b[ix] = conversion_buffer[i];
+                        ;
+                    }
+                }
+            } else if (targetChannels == 1) {
+                int cs = sourceChannels;
+                for (int i = 0, ix = off; i < len2; i += cs, ix++) {
+                    b[ix] = conversion_buffer[i];
+                }
+                for (int c = 1; c < sourceChannels; c++) {
+                    for (int i = c, ix = off; i < len2; i += cs, ix++) {
+                        b[ix] += conversion_buffer[i];
+                        ;
+                    }
+                }
+                float vol = 1f / ((float) sourceChannels);
+                for (int i = 0, ix = off; i < len2; i += cs, ix++) {
+                    b[ix] *= vol;
+                }
+            } else {
+                int minChannels = Math.min(sourceChannels, targetChannels);
+                int off_len = off + len;
+                int ct = targetChannels;
+                int cs = sourceChannels;
+                for (int c = 0; c < minChannels; c++) {
+                    for (int i = off + c, ix = c; i < off_len; i += ct, ix += cs) {
+                        b[i] = conversion_buffer[ix];
+                    }
+                }
+                for (int c = minChannels; c < targetChannels; c++) {
+                    for (int i = off + c; i < off_len; i += ct) {
+                        b[i] = 0;
+                    }
+                }
+            }
+            return (ret / sourceChannels) * targetChannels;
+        }
+
+        public void reset() throws IOException {
+            ais.reset();
+        }
+
+        public long skip(long len) throws IOException {
+            long ret = ais.skip((len / targetChannels) * sourceChannels);
+            if (ret < 0)
+                return ret;
+            return (ret / sourceChannels) * targetChannels;
+        }
+
+    }
+
+    private static class AudioFloatInputStreamResampler extends
+            AudioFloatInputStream {
+
+        private AudioFloatInputStream ais;
+
+        private AudioFormat targetFormat;
+
+        private float[] skipbuffer;
+
+        private SoftAbstractResampler resampler;
+
+        private float[] pitch = new float[1];
+
+        private float[] ibuffer2;
+
+        private float[][] ibuffer;
+
+        private float ibuffer_index = 0;
+
+        private int ibuffer_len = 0;
+
+        private int nrofchannels = 0;
+
+        private float[][] cbuffer;
+
+        private int buffer_len = 512;
+
+        private int pad;
+
+        private int pad2;
+
+        private float[] ix = new float[1];
+
+        private int[] ox = new int[1];
+
+        private float[][] mark_ibuffer = null;
+
+        private float mark_ibuffer_index = 0;
+
+        private int mark_ibuffer_len = 0;
+
+        public AudioFloatInputStreamResampler(AudioFloatInputStream ais,
+                AudioFormat format) {
+            this.ais = ais;
+            AudioFormat sourceFormat = ais.getFormat();
+            targetFormat = new AudioFormat(sourceFormat.getEncoding(), format
+                    .getSampleRate(), sourceFormat.getSampleSizeInBits(),
+                    sourceFormat.getChannels(), sourceFormat.getFrameSize(),
+                    format.getSampleRate(), sourceFormat.isBigEndian());
+            nrofchannels = targetFormat.getChannels();
+            Object interpolation = format.getProperty("interpolation");
+            if (interpolation != null && (interpolation instanceof String)) {
+                String resamplerType = (String) interpolation;
+                if (resamplerType.equalsIgnoreCase("point"))
+                    this.resampler = new SoftPointResampler();
+                if (resamplerType.equalsIgnoreCase("linear"))
+                    this.resampler = new SoftLinearResampler2();
+                if (resamplerType.equalsIgnoreCase("linear1"))
+                    this.resampler = new SoftLinearResampler();
+                if (resamplerType.equalsIgnoreCase("linear2"))
+                    this.resampler = new SoftLinearResampler2();
+                if (resamplerType.equalsIgnoreCase("cubic"))
+                    this.resampler = new SoftCubicResampler();
+                if (resamplerType.equalsIgnoreCase("lanczos"))
+                    this.resampler = new SoftLanczosResampler();
+                if (resamplerType.equalsIgnoreCase("sinc"))
+                    this.resampler = new SoftSincResampler();
+            }
+            if (resampler == null)
+                resampler = new SoftLinearResampler2(); // new
+                                                        // SoftLinearResampler2();
+            pitch[0] = sourceFormat.getSampleRate() / format.getSampleRate();
+            pad = resampler.getPadding();
+            pad2 = pad * 2;
+            ibuffer = new float[nrofchannels][buffer_len + pad2];
+            ibuffer2 = new float[nrofchannels * buffer_len];
+            ibuffer_index = buffer_len + pad;
+            ibuffer_len = buffer_len;
+        }
+
+        public int available() throws IOException {
+            return 0;
+        }
+
+        public void close() throws IOException {
+            ais.close();
+        }
+
+        public AudioFormat getFormat() {
+            return targetFormat;
+        }
+
+        public long getFrameLength() {
+            return AudioSystem.NOT_SPECIFIED; // ais.getFrameLength();
+        }
+
+        public void mark(int readlimit) {
+            ais.mark((int) (readlimit * pitch[0]));
+            mark_ibuffer_index = ibuffer_index;
+            mark_ibuffer_len = ibuffer_len;
+            if (mark_ibuffer == null) {
+                mark_ibuffer = new float[ibuffer.length][ibuffer[0].length];
+            }
+            for (int c = 0; c < ibuffer.length; c++) {
+                float[] from = ibuffer[c];
+                float[] to = mark_ibuffer[c];
+                for (int i = 0; i < to.length; i++) {
+                    to[i] = from[i];
+                }
+            }
+        }
+
+        public boolean markSupported() {
+            return ais.markSupported();
+        }
+
+        private void readNextBuffer() throws IOException {
+
+            if (ibuffer_len == -1)
+                return;
+
+            for (int c = 0; c < nrofchannels; c++) {
+                float[] buff = ibuffer[c];
+                int buffer_len_pad = ibuffer_len + pad2;
+                for (int i = ibuffer_len, ix = 0; i < buffer_len_pad; i++, ix++) {
+                    buff[ix] = buff[i];
+                }
+            }
+
+            ibuffer_index -= (ibuffer_len);
+
+            ibuffer_len = ais.read(ibuffer2);
+            if (ibuffer_len >= 0) {
+                while (ibuffer_len < ibuffer2.length) {
+                    int ret = ais.read(ibuffer2, ibuffer_len, ibuffer2.length
+                            - ibuffer_len);
+                    if (ret == -1)
+                        break;
+                    ibuffer_len += ret;
+                }
+                Arrays.fill(ibuffer2, ibuffer_len, ibuffer2.length, 0);
+                ibuffer_len /= nrofchannels;
+            } else {
+                Arrays.fill(ibuffer2, 0, ibuffer2.length, 0);
+            }
+
+            int ibuffer2_len = ibuffer2.length;
+            for (int c = 0; c < nrofchannels; c++) {
+                float[] buff = ibuffer[c];
+                for (int i = c, ix = pad2; i < ibuffer2_len; i += nrofchannels, ix++) {
+                    buff[ix] = ibuffer2[i];
+                }
+            }
+
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+
+            if (cbuffer == null || cbuffer[0].length < len / nrofchannels) {
+                cbuffer = new float[nrofchannels][len / nrofchannels];
+            }
+            if (ibuffer_len == -1)
+                return -1;
+            if (len < 0)
+                return 0;
+            int remain = len / nrofchannels;
+            int destPos = 0;
+            int in_end = ibuffer_len;
+            while (remain > 0) {
+                if (ibuffer_len >= 0) {
+                    if (ibuffer_index >= (ibuffer_len + pad))
+                        readNextBuffer();
+                    in_end = ibuffer_len + pad;
+                }
+
+                if (ibuffer_len < 0) {
+                    in_end = pad2;
+                    if (ibuffer_index >= in_end)
+                        break;
+                }
+
+                if (ibuffer_index < 0)
+                    break;
+                int preDestPos = destPos;
+                for (int c = 0; c < nrofchannels; c++) {
+                    ix[0] = ibuffer_index;
+                    ox[0] = destPos;
+                    float[] buff = ibuffer[c];
+                    resampler.interpolate(buff, ix, in_end, pitch, 0,
+                            cbuffer[c], ox, len / nrofchannels);
+                }
+                ibuffer_index = ix[0];
+                destPos = ox[0];
+                remain -= destPos - preDestPos;
+            }
+            for (int c = 0; c < nrofchannels; c++) {
+                int ix = 0;
+                float[] buff = cbuffer[c];
+                for (int i = c; i < b.length; i += nrofchannels) {
+                    b[i] = buff[ix++];
+                }
+            }
+            return len - remain * nrofchannels;
+        }
+
+        public void reset() throws IOException {
+            ais.reset();
+            if (mark_ibuffer == null)
+                return;
+            ibuffer_index = mark_ibuffer_index;
+            ibuffer_len = mark_ibuffer_len;
+            for (int c = 0; c < ibuffer.length; c++) {
+                float[] from = mark_ibuffer[c];
+                float[] to = ibuffer[c];
+                for (int i = 0; i < to.length; i++) {
+                    to[i] = from[i];
+                }
+            }
+
+        }
+
+        public long skip(long len) throws IOException {
+            if (len > 0)
+                return 0;
+            if (skipbuffer == null)
+                skipbuffer = new float[1024 * targetFormat.getFrameSize()];
+            float[] l_skipbuffer = skipbuffer;
+            long remain = len;
+            while (remain > 0) {
+                int ret = read(l_skipbuffer, 0, (int) Math.min(remain,
+                        skipbuffer.length));
+                if (ret < 0) {
+                    if (remain == len)
+                        return ret;
+                    break;
+                }
+                remain -= ret;
+            }
+            return len - remain;
+
+        }
+
+    }
+
+    private Encoding[] formats = { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
+            AudioFloatConverter.PCM_FLOAT };
+
+    public AudioInputStream getAudioInputStream(Encoding targetEncoding,
+            AudioInputStream sourceStream) {
+        if (sourceStream.getFormat().getEncoding().equals(targetEncoding))
+            return sourceStream;
+        AudioFormat format = sourceStream.getFormat();
+        int channels = format.getChannels();
+        Encoding encoding = targetEncoding;
+        float samplerate = format.getSampleRate();
+        int bits = format.getSampleSizeInBits();
+        boolean bigendian = format.isBigEndian();
+        if (targetEncoding.equals(AudioFloatConverter.PCM_FLOAT))
+            bits = 32;
+        AudioFormat targetFormat = new AudioFormat(encoding, samplerate, bits,
+                channels, channels * bits / 8, samplerate, bigendian);
+        return getAudioInputStream(targetFormat, sourceStream);
+    }
+
+    public AudioInputStream getAudioInputStream(AudioFormat targetFormat,
+            AudioInputStream sourceStream) {
+        if (!isConversionSupported(targetFormat, sourceStream.getFormat()))
+            throw new IllegalArgumentException("Unsupported conversion: "
+                    + sourceStream.getFormat().toString() + " to "
+                    + targetFormat.toString());
+        return getAudioInputStream(targetFormat, AudioFloatInputStream
+                .getInputStream(sourceStream));
+    }
+
+    public AudioInputStream getAudioInputStream(AudioFormat targetFormat,
+            AudioFloatInputStream sourceStream) {
+
+        if (!isConversionSupported(targetFormat, sourceStream.getFormat()))
+            throw new IllegalArgumentException("Unsupported conversion: "
+                    + sourceStream.getFormat().toString() + " to "
+                    + targetFormat.toString());
+        if (targetFormat.getChannels() != sourceStream.getFormat()
+                .getChannels())
+            sourceStream = new AudioFloatInputStreamChannelMixer(sourceStream,
+                    targetFormat.getChannels());
+        if (Math.abs(targetFormat.getSampleRate()
+                - sourceStream.getFormat().getSampleRate()) > 0.000001)
+            sourceStream = new AudioFloatInputStreamResampler(sourceStream,
+                    targetFormat);
+        return new AudioInputStream(new AudioFloatFormatConverterInputStream(
+                targetFormat, sourceStream), targetFormat, sourceStream
+                .getFrameLength());
+    }
+
+    public Encoding[] getSourceEncodings() {
+        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
+                AudioFloatConverter.PCM_FLOAT };
+    }
+
+    public Encoding[] getTargetEncodings() {
+        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
+                AudioFloatConverter.PCM_FLOAT };
+    }
+
+    public Encoding[] getTargetEncodings(AudioFormat sourceFormat) {
+        if (AudioFloatConverter.getConverter(sourceFormat) == null)
+            return new Encoding[0];
+        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
+                AudioFloatConverter.PCM_FLOAT };
+    }
+
+    public AudioFormat[] getTargetFormats(Encoding targetEncoding,
+            AudioFormat sourceFormat) {
+        if (AudioFloatConverter.getConverter(sourceFormat) == null)
+            return new AudioFormat[0];
+        int channels = sourceFormat.getChannels();
+
+        ArrayList<AudioFormat> formats = new ArrayList<AudioFormat>();
+
+        if (targetEncoding.equals(Encoding.PCM_SIGNED))
+            formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+        if (targetEncoding.equals(Encoding.PCM_UNSIGNED))
+            formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+
+        for (int bits = 16; bits < 32; bits += 8) {
+            if (targetEncoding.equals(Encoding.PCM_SIGNED)) {
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+            }
+            if (targetEncoding.equals(Encoding.PCM_UNSIGNED)) {
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+            }
+        }
+
+        if (targetEncoding.equals(AudioFloatConverter.PCM_FLOAT)) {
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, true));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, true));
+        }
+
+        return formats.toArray(new AudioFormat[formats.size()]);
+    }
+
+    public boolean isConversionSupported(AudioFormat targetFormat,
+            AudioFormat sourceFormat) {
+        if (AudioFloatConverter.getConverter(sourceFormat) == null)
+            return false;
+        if (AudioFloatConverter.getConverter(targetFormat) == null)
+            return false;
+        if (sourceFormat.getChannels() <= 0)
+            return false;
+        if (targetFormat.getChannels() <= 0)
+            return false;
+        return true;
+    }
+
+    public boolean isConversionSupported(Encoding targetEncoding,
+            AudioFormat sourceFormat) {
+        if (AudioFloatConverter.getConverter(sourceFormat) == null)
+            return false;
+        for (int i = 0; i < formats.length; i++) {
+            if (targetEncoding.equals(formats[i]))
+                return true;
+        }
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioFloatInputStream.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,281 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+/**
+ * This class is used to create AudioFloatInputStream from AudioInputStream and
+ * byte buffers.
+ *
+ * @author Karl Helgason
+ */
+public abstract class AudioFloatInputStream {
+
+    private static class BytaArrayAudioFloatInputStream
+            extends AudioFloatInputStream {
+
+        private int pos = 0;
+        private int markpos = 0;
+        private AudioFloatConverter converter;
+        private AudioFormat format;
+        private byte[] buffer;
+        private int buffer_offset;
+        private int buffer_len;
+        private int framesize_pc;
+
+        public BytaArrayAudioFloatInputStream(AudioFloatConverter converter,
+                byte[] buffer, int offset, int len) {
+            this.converter = converter;
+            this.format = converter.getFormat();
+            this.buffer = buffer;
+            this.buffer_offset = offset;
+            framesize_pc = format.getFrameSize() / format.getChannels();
+            this.buffer_len = len / framesize_pc;
+
+        }
+
+        public AudioFormat getFormat() {
+            return format;
+        }
+
+        public long getFrameLength() {
+            return buffer_len;// / format.getFrameSize();
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+            if (b == null)
+                throw new NullPointerException();
+            if (off < 0 || len < 0 || len > b.length - off)
+                throw new IndexOutOfBoundsException();
+            if (pos >= buffer_len)
+                return -1;
+            if (len == 0)
+                return 0;
+            if (pos + len > buffer_len)
+                len = buffer_len - pos;
+            converter.toFloatArray(buffer, buffer_offset + pos * framesize_pc,
+                    b, off, len);
+            pos += len;
+            return len;
+        }
+
+        public long skip(long len) throws IOException {
+            if (pos >= buffer_len)
+                return -1;
+            if (len <= 0)
+                return 0;
+            if (pos + len > buffer_len)
+                len = buffer_len - pos;
+            pos += len;
+            return len;
+        }
+
+        public int available() throws IOException {
+            return buffer_len - pos;
+        }
+
+        public void close() throws IOException {
+        }
+
+        public void mark(int readlimit) {
+            markpos = pos;
+        }
+
+        public boolean markSupported() {
+            return true;
+        }
+
+        public void reset() throws IOException {
+            pos = markpos;
+        }
+    }
+
+    private static class DirectAudioFloatInputStream
+            extends AudioFloatInputStream {
+
+        private AudioInputStream stream;
+        private AudioFloatConverter converter;
+        private int framesize_pc; // framesize / channels
+        private byte[] buffer;
+
+        public DirectAudioFloatInputStream(AudioInputStream stream) {
+            converter = AudioFloatConverter.getConverter(stream.getFormat());
+            if (converter == null) {
+                AudioFormat format = stream.getFormat();
+                AudioFormat newformat;
+
+                AudioFormat[] formats = AudioSystem.getTargetFormats(
+                        AudioFormat.Encoding.PCM_SIGNED, format);
+                if (formats.length != 0) {
+                    newformat = formats[0];
+                } else {
+                    float samplerate = format.getSampleRate();
+                    int samplesizeinbits = format.getSampleSizeInBits();
+                    int framesize = format.getFrameSize();
+                    float framerate = format.getFrameRate();
+                    samplesizeinbits = 16;
+                    framesize = format.getChannels() * (samplesizeinbits / 8);
+                    framerate = samplerate;
+
+                    newformat = new AudioFormat(
+                            AudioFormat.Encoding.PCM_SIGNED, samplerate,
+                            samplesizeinbits, format.getChannels(), framesize,
+                            framerate, false);
+                }
+
+                stream = AudioSystem.getAudioInputStream(newformat, stream);
+                converter = AudioFloatConverter.getConverter(stream.getFormat());
+            }
+            framesize_pc = stream.getFormat().getFrameSize()
+                    / stream.getFormat().getChannels();
+            this.stream = stream;
+        }
+
+        public AudioFormat getFormat() {
+            return stream.getFormat();
+        }
+
+        public long getFrameLength() {
+            return stream.getFrameLength();
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+            int b_len = len * framesize_pc;
+            if (buffer == null || buffer.length < b_len)
+                buffer = new byte[b_len];
+            int ret = stream.read(buffer, 0, b_len);
+            if (ret == -1)
+                return -1;
+            converter.toFloatArray(buffer, b, off, ret / framesize_pc);
+            return ret / framesize_pc;
+        }
+
+        public long skip(long len) throws IOException {
+            long b_len = len * framesize_pc;
+            long ret = stream.skip(b_len);
+            if (ret == -1)
+                return -1;
+            return ret / framesize_pc;
+        }
+
+        public int available() throws IOException {
+            return stream.available() / framesize_pc;
+        }
+
+        public void close() throws IOException {
+            stream.close();
+        }
+
+        public void mark(int readlimit) {
+            stream.mark(readlimit * framesize_pc);
+        }
+
+        public boolean markSupported() {
+            return stream.markSupported();
+        }
+
+        public void reset() throws IOException {
+            stream.reset();
+        }
+    }
+
+    public static AudioFloatInputStream getInputStream(URL url)
+            throws UnsupportedAudioFileException, IOException {
+        return new DirectAudioFloatInputStream(AudioSystem
+                .getAudioInputStream(url));
+    }
+
+    public static AudioFloatInputStream getInputStream(File file)
+            throws UnsupportedAudioFileException, IOException {
+        return new DirectAudioFloatInputStream(AudioSystem
+                .getAudioInputStream(file));
+    }
+
+    public static AudioFloatInputStream getInputStream(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+        return new DirectAudioFloatInputStream(AudioSystem
+                .getAudioInputStream(stream));
+    }
+
+    public static AudioFloatInputStream getInputStream(
+            AudioInputStream stream) {
+        return new DirectAudioFloatInputStream(stream);
+    }
+
+    public static AudioFloatInputStream getInputStream(AudioFormat format,
+            byte[] buffer, int offset, int len) {
+        AudioFloatConverter converter = AudioFloatConverter
+                .getConverter(format);
+        if (converter != null)
+            return new BytaArrayAudioFloatInputStream(converter, buffer,
+                    offset, len);
+
+        InputStream stream = new ByteArrayInputStream(buffer, offset, len);
+        long aLen = format.getFrameSize() == AudioSystem.NOT_SPECIFIED
+                ? AudioSystem.NOT_SPECIFIED : len / format.getFrameSize();
+        AudioInputStream astream = new AudioInputStream(stream, format, aLen);
+        return getInputStream(astream);
+    }
+
+    public abstract AudioFormat getFormat();
+
+    public abstract long getFrameLength();
+
+    public abstract int read(float[] b, int off, int len) throws IOException;
+
+    public int read(float[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    public float read() throws IOException {
+        float[] b = new float[1];
+        int ret = read(b, 0, 1);
+        if (ret == -1 || ret == 0)
+            return 0;
+        return b[0];
+    }
+
+    public abstract long skip(long len) throws IOException;
+
+    public abstract int available() throws IOException;
+
+    public abstract void close() throws IOException;
+
+    public abstract void mark(int readlimit);
+
+    public abstract boolean markSupported();
+
+    public abstract void reset() throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Map;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Synthesizer;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * <code>AudioSynthesizer</code> is a <code>Synthesizer</code>
+ * which renders it's output audio into <code>SourceDataLine</code>
+ * or <code>AudioInputStream</code>.
+ *
+ * @see MidiSystem#getSynthesizer
+ * @see Synthesizer
+ *
+ * @author Karl Helgason
+ */
+public interface AudioSynthesizer extends Synthesizer {
+
+    /**
+     * Obtains the current format (encoding, sample rate, number of channels,
+     * etc.) of the synthesizer audio data.
+     *
+     * <p>If the synthesizer is not open and has never been opened, it returns
+     * the default format.
+     *
+     * @return current audio data format
+     * @see AudioFormat
+     */
+    public AudioFormat getFormat();
+
+    /**
+     * Gets information about the possible properties for the synthesizer.
+     *
+     * @param info a proposed list of tag/value pairs that will be sent on open.
+     * @return an array of <code>AudioSynthesizerPropertyInfo</code> objects
+     * describing possible properties. This array may be an empty array if
+     * no properties are required.
+     */
+    public AudioSynthesizerPropertyInfo[] getPropertyInfo(
+            Map<String, Object> info);
+
+    /**
+     * Opens the synthesizer and starts rendering audio into
+     * <code>SourceDataLine</code>.
+     *
+     * <p>An application opening a synthesizer explicitly with this call
+     * has to close the synthesizer by calling {@link #close}. This is
+     * necessary to release system resources and allow applications to
+     * exit cleanly.
+     *
+     * <p>Note that some synthesizers, once closed, cannot be reopened.
+     * Attempts to reopen such a synthesizer will always result in
+     * a <code>MidiUnavailableException</code>.
+     *
+     * @param line which <code>AudioSynthesizer</code> writes output audio into.
+     * If <code>line</code> is null, then line from system default mixer is used.
+     * @param info a <code>Map<String,Object></code> object containing
+     * properties for additional configuration supported by synthesizer.
+     * If <code>info</code> is null then default settings are used.
+     *
+     * @throws MidiUnavailableException thrown if the synthesizer cannot be
+     * opened due to resource restrictions.
+     * @throws SecurityException thrown if the synthesizer cannot be
+     * opened due to security restrictions.
+     *
+     * @see #close
+     * @see #isOpen
+     */
+    public void open(SourceDataLine line, Map<String, Object> info)
+            throws MidiUnavailableException;
+
+    /**
+     * Opens the synthesizer and renders audio into returned
+     * <code>AudioInputStream</code>.
+     *
+     * <p>An application opening a synthesizer explicitly with this call
+     * has to close the synthesizer by calling {@link #close}. This is
+     * necessary to release system resources and allow applications to
+     * exit cleanly.
+     *
+     * <p>Note that some synthesizers, once closed, cannot be reopened.
+     * Attempts to reopen such a synthesizer will always result in
+     * a <code>MidiUnavailableException<code>.
+     *
+     * @param targetFormat specifies the <code>AudioFormat</code>
+     * used in returned <code>AudioInputStream</code>.
+     * @param info a <code>Map<String,Object></code> object containing
+     * properties for additional configuration supported by synthesizer.
+     * If <code>info</code> is null then default settings are used.
+     *
+     * @throws MidiUnavailableException thrown if the synthesizer cannot be
+     * opened due to resource restrictions.
+     * @throws SecurityException thrown if the synthesizer cannot be
+     * opened due to security restrictions.
+     *
+     * @see #close
+     * @see #isOpen
+     */
+    public AudioInputStream openStream(AudioFormat targetFormat,
+            Map<String, Object> info) throws MidiUnavailableException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Information about property used in  opening <code>AudioSynthesizer</code>.
+ *
+ * @author Karl Helgason
+ */
+public class AudioSynthesizerPropertyInfo {
+
+    /**
+     * Constructs a <code>AudioSynthesizerPropertyInfo</code> object with a given
+     * name and value. The <code>description</code> and <code>choices</code>
+     * are intialized by <code>null</code> values.
+     *
+     * @param name the name of the property
+     * @param value the current value or class used for values.
+     *
+     */
+    public AudioSynthesizerPropertyInfo(String name, Object value) {
+        this.name = name;
+        this.value = value;
+        if (value instanceof Class)
+            valueClass = (Class)value;
+        else if (value != null)
+            valueClass = value.getClass();
+    }
+    /**
+     * The name of the property.
+     */
+    public String name;
+    /**
+     * A brief description of the property, which may be null.
+     */
+    public String description = null;
+    /**
+     * The <code>value</code> field specifies the current value of
+     * the property.
+     */
+    public Object value = null;
+    /**
+     * The <code>valueClass</code> field specifies class
+     * used in <code>value</code> field.
+     */
+    public Class valueClass = null;
+    /**
+     * An array of possible values if the value for the field
+     * <code>AudioSynthesizerPropertyInfo.value</code> may be selected
+     * from a particular set of values; otherwise null.
+     */
+    public Object[] choices = null;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSInfo.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to store information  to describe soundbanks, instruments
+ * and samples. It is stored inside a "INFO" List Chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSInfo {
+
+    /**
+     * (INAM) Title or subject.
+     */
+    public String name = "untitled";
+    /**
+     * (ICRD) Date of creation, the format is: YYYY-MM-DD.
+     *        For example 2007-01-01 for 1. january of year 2007.
+     */
+    public String creationDate = null;
+    /**
+     * (IENG) Name of engineer who created the object.
+     */
+    public String engineers = null;
+    /**
+     * (IPRD) Name of the product which the object is intended for.
+     */
+    public String product = null;
+    /**
+     * (ICOP) Copyright information.
+     */
+    public String copyright = null;
+    /**
+     * (ICMT) General comments. Doesn't contain newline characters.
+     */
+    public String comments = null;
+    /**
+     * (ISFT) Name of software package used to create the file.
+     */
+    public String tools = null;
+    /**
+     * (IARL) Where content is archived.
+     */
+    public String archival_location = null;
+    /**
+     * (IART) Artists of original content.
+     */
+    public String artist = null;
+    /**
+     * (ICMS) Names of persons or orginizations who commissioned the file.
+     */
+    public String commissioned = null;
+    /**
+     * (IGNR) Genre of the work.
+     *        Example: jazz, classical, rock, etc.
+     */
+    public String genre = null;
+    /**
+     * (IKEY) List of keyword that describe the content.
+     *        Examples: FX, bird, piano, etc.
+     */
+    public String keywords = null;
+    /**
+     * (IMED) Describes original medium of the data.
+     *        For example: record, CD, etc.
+     */
+    public String medium = null;
+    /**
+     * (ISBJ) Description of the content.
+     */
+    public String subject = null;
+    /**
+     * (ISRC) Name of person or orginization who supplied
+     *        orginal material for the file.
+     */
+    public String source = null;
+    /**
+     * (ISRF) Source media for sample data is from.
+     *        For example: CD, TV, etc.
+     */
+    public String source_form = null;
+    /**
+     * (ITCH) Technician who sample the file/object.
+     */
+    public String technician = null;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSInstrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,448 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.sound.midi.Patch;
+
+/**
+ * This class is used to store information to describe instrument.
+ * It contains list of regions and modulators.
+ * It is stored inside a "ins " List Chunk inside DLS files.
+ * In the DLS documentation a modulator is called articulator.
+ *
+ * @author Karl Helgason
+ */
+public class DLSInstrument extends ModelInstrument {
+
+    protected int preset = 0;
+    protected int bank = 0;
+    protected boolean druminstrument = false;
+    protected byte[] guid = null;
+    protected DLSInfo info = new DLSInfo();
+    protected List<DLSRegion> regions = new ArrayList<DLSRegion>();
+    protected List<DLSModulator> modulators = new ArrayList<DLSModulator>();
+
+    public DLSInstrument() {
+        super(null, null, null, null);
+    }
+
+    public DLSInstrument(DLSSoundbank soundbank) {
+        super(soundbank, null, null, null);
+    }
+
+    public DLSInfo getInfo() {
+        return info;
+    }
+
+    public String getName() {
+        return info.name;
+    }
+
+    public void setName(String name) {
+        info.name = name;
+    }
+
+    public ModelPatch getPatch() {
+        return new ModelPatch(bank, preset, druminstrument);
+    }
+
+    public void setPatch(Patch patch) {
+        if (patch instanceof ModelPatch && ((ModelPatch)patch).isPercussion()) {
+            druminstrument = true;
+            bank = patch.getBank();
+            preset = patch.getProgram();
+        } else {
+            druminstrument = false;
+            bank = patch.getBank();
+            preset = patch.getProgram();
+        }
+    }
+
+    public Object getData() {
+        return null;
+    }
+
+    public List<DLSRegion> getRegions() {
+        return regions;
+    }
+
+    public List<DLSModulator> getModulators() {
+        return modulators;
+    }
+
+    public String toString() {
+        if (druminstrument)
+            return "Drumkit: " + info.name
+                    + " bank #" + bank + " preset #" + preset;
+        else
+            return "Instrument: " + info.name
+                    + " bank #" + bank + " preset #" + preset;
+    }
+
+    private ModelIdentifier convertToModelDest(int dest) {
+        if (dest == DLSModulator.CONN_DST_NONE)
+            return null;
+        if (dest == DLSModulator.CONN_DST_GAIN)
+            return ModelDestination.DESTINATION_GAIN;
+        if (dest == DLSModulator.CONN_DST_PITCH)
+            return ModelDestination.DESTINATION_PITCH;
+        if (dest == DLSModulator.CONN_DST_PAN)
+            return ModelDestination.DESTINATION_PAN;
+
+        if (dest == DLSModulator.CONN_DST_LFO_FREQUENCY)
+            return ModelDestination.DESTINATION_LFO1_FREQ;
+        if (dest == DLSModulator.CONN_DST_LFO_STARTDELAY)
+            return ModelDestination.DESTINATION_LFO1_DELAY;
+
+        if (dest == DLSModulator.CONN_DST_EG1_ATTACKTIME)
+            return ModelDestination.DESTINATION_EG1_ATTACK;
+        if (dest == DLSModulator.CONN_DST_EG1_DECAYTIME)
+            return ModelDestination.DESTINATION_EG1_DECAY;
+        if (dest == DLSModulator.CONN_DST_EG1_RELEASETIME)
+            return ModelDestination.DESTINATION_EG1_RELEASE;
+        if (dest == DLSModulator.CONN_DST_EG1_SUSTAINLEVEL)
+            return ModelDestination.DESTINATION_EG1_SUSTAIN;
+
+        if (dest == DLSModulator.CONN_DST_EG2_ATTACKTIME)
+            return ModelDestination.DESTINATION_EG2_ATTACK;
+        if (dest == DLSModulator.CONN_DST_EG2_DECAYTIME)
+            return ModelDestination.DESTINATION_EG2_DECAY;
+        if (dest == DLSModulator.CONN_DST_EG2_RELEASETIME)
+            return ModelDestination.DESTINATION_EG2_RELEASE;
+        if (dest == DLSModulator.CONN_DST_EG2_SUSTAINLEVEL)
+            return ModelDestination.DESTINATION_EG2_SUSTAIN;
+
+        // DLS2 Destinations
+        if (dest == DLSModulator.CONN_DST_KEYNUMBER)
+            return ModelDestination.DESTINATION_KEYNUMBER;
+
+        if (dest == DLSModulator.CONN_DST_CHORUS)
+            return ModelDestination.DESTINATION_CHORUS;
+        if (dest == DLSModulator.CONN_DST_REVERB)
+            return ModelDestination.DESTINATION_REVERB;
+
+        if (dest == DLSModulator.CONN_DST_VIB_FREQUENCY)
+            return ModelDestination.DESTINATION_LFO2_FREQ;
+        if (dest == DLSModulator.CONN_DST_VIB_STARTDELAY)
+            return ModelDestination.DESTINATION_LFO2_DELAY;
+
+        if (dest == DLSModulator.CONN_DST_EG1_DELAYTIME)
+            return ModelDestination.DESTINATION_EG1_DELAY;
+        if (dest == DLSModulator.CONN_DST_EG1_HOLDTIME)
+            return ModelDestination.DESTINATION_EG1_HOLD;
+        if (dest == DLSModulator.CONN_DST_EG1_SHUTDOWNTIME)
+            return ModelDestination.DESTINATION_EG1_SHUTDOWN;
+
+        if (dest == DLSModulator.CONN_DST_EG2_DELAYTIME)
+            return ModelDestination.DESTINATION_EG2_DELAY;
+        if (dest == DLSModulator.CONN_DST_EG2_HOLDTIME)
+            return ModelDestination.DESTINATION_EG2_HOLD;
+
+        if (dest == DLSModulator.CONN_DST_FILTER_CUTOFF)
+            return ModelDestination.DESTINATION_FILTER_FREQ;
+        if (dest == DLSModulator.CONN_DST_FILTER_Q)
+            return ModelDestination.DESTINATION_FILTER_Q;
+
+        return null;
+    }
+
+    private ModelIdentifier convertToModelSrc(int src) {
+        if (src == DLSModulator.CONN_SRC_NONE)
+            return null;
+
+        if (src == DLSModulator.CONN_SRC_LFO)
+            return ModelSource.SOURCE_LFO1;
+        if (src == DLSModulator.CONN_SRC_KEYONVELOCITY)
+            return ModelSource.SOURCE_NOTEON_VELOCITY;
+        if (src == DLSModulator.CONN_SRC_KEYNUMBER)
+            return ModelSource.SOURCE_NOTEON_KEYNUMBER;
+        if (src == DLSModulator.CONN_SRC_EG1)
+            return ModelSource.SOURCE_EG1;
+        if (src == DLSModulator.CONN_SRC_EG2)
+            return ModelSource.SOURCE_EG2;
+        if (src == DLSModulator.CONN_SRC_PITCHWHEEL)
+            return ModelSource.SOURCE_MIDI_PITCH;
+        if (src == DLSModulator.CONN_SRC_CC1)
+            return new ModelIdentifier("midi_cc", "1", 0);
+        if (src == DLSModulator.CONN_SRC_CC7)
+            return new ModelIdentifier("midi_cc", "7", 0);
+        if (src == DLSModulator.CONN_SRC_CC10)
+            return new ModelIdentifier("midi_cc", "10", 0);
+        if (src == DLSModulator.CONN_SRC_CC11)
+            return new ModelIdentifier("midi_cc", "11", 0);
+        if (src == DLSModulator.CONN_SRC_RPN0)
+            return new ModelIdentifier("midi_rpn", "0", 0);
+        if (src == DLSModulator.CONN_SRC_RPN1)
+            return new ModelIdentifier("midi_rpn", "1", 0);
+
+        if (src == DLSModulator.CONN_SRC_POLYPRESSURE)
+            return ModelSource.SOURCE_MIDI_POLY_PRESSURE;
+        if (src == DLSModulator.CONN_SRC_CHANNELPRESSURE)
+            return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
+        if (src == DLSModulator.CONN_SRC_VIBRATO)
+            return ModelSource.SOURCE_LFO2;
+        if (src == DLSModulator.CONN_SRC_MONOPRESSURE)
+            return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
+
+        if (src == DLSModulator.CONN_SRC_CC91)
+            return new ModelIdentifier("midi_cc", "91", 0);
+        if (src == DLSModulator.CONN_SRC_CC93)
+            return new ModelIdentifier("midi_cc", "93", 0);
+
+        return null;
+    }
+
+    private ModelConnectionBlock convertToModel(DLSModulator mod) {
+        ModelIdentifier source = convertToModelSrc(mod.getSource());
+        ModelIdentifier control = convertToModelSrc(mod.getControl());
+        ModelIdentifier destination_id =
+                convertToModelDest(mod.getDestination());
+
+        int scale = mod.getScale();
+        double f_scale;
+        if (scale == Integer.MIN_VALUE)
+            f_scale = Double.NEGATIVE_INFINITY;
+        else
+            f_scale = scale / 65536.0;
+
+        if (destination_id != null) {
+            ModelSource src = null;
+            ModelSource ctrl = null;
+            ModelConnectionBlock block = new ModelConnectionBlock();
+            if (control != null) {
+                ModelSource s = new ModelSource();
+                if (control == ModelSource.SOURCE_MIDI_PITCH) {
+                    ((ModelStandardTransform)s.getTransform()).setPolarity(
+                            ModelStandardTransform.POLARITY_BIPOLAR);
+                } else if (control == ModelSource.SOURCE_LFO1
+                        || control == ModelSource.SOURCE_LFO2) {
+                    ((ModelStandardTransform)s.getTransform()).setPolarity(
+                            ModelStandardTransform.POLARITY_BIPOLAR);
+                }
+                s.setIdentifier(control);
+                block.addSource(s);
+                ctrl = s;
+            }
+            if (source != null) {
+                ModelSource s = new ModelSource();
+                if (source == ModelSource.SOURCE_MIDI_PITCH) {
+                    ((ModelStandardTransform)s.getTransform()).setPolarity(
+                            ModelStandardTransform.POLARITY_BIPOLAR);
+                } else if (source == ModelSource.SOURCE_LFO1
+                        || source == ModelSource.SOURCE_LFO2) {
+                    ((ModelStandardTransform)s.getTransform()).setPolarity(
+                            ModelStandardTransform.POLARITY_BIPOLAR);
+                }
+                s.setIdentifier(source);
+                block.addSource(s);
+                src = s;
+            }
+            ModelDestination destination = new ModelDestination();
+            destination.setIdentifier(destination_id);
+            block.setDestination(destination);
+
+            if (mod.getVersion() == 1) {
+                //if (mod.getTransform() ==  DLSModulator.CONN_TRN_CONCAVE) {
+                //    ((ModelStandardTransform)destination.getTransform())
+                //            .setTransform(
+                //            ModelStandardTransform.TRANSFORM_CONCAVE);
+                //}
+                if (mod.getTransform() == DLSModulator.CONN_TRN_CONCAVE) {
+                    if (src != null) {
+                        ((ModelStandardTransform)src.getTransform())
+                                .setTransform(
+                                    ModelStandardTransform.TRANSFORM_CONCAVE);
+                        ((ModelStandardTransform)src.getTransform())
+                                .setDirection(
+                                    ModelStandardTransform.DIRECTION_MAX2MIN);
+                    }
+                    if (ctrl != null) {
+                        ((ModelStandardTransform)ctrl.getTransform())
+                                .setTransform(
+                                    ModelStandardTransform.TRANSFORM_CONCAVE);
+                        ((ModelStandardTransform)ctrl.getTransform())
+                                .setDirection(
+                                    ModelStandardTransform.DIRECTION_MAX2MIN);
+                    }
+                }
+
+            } else if (mod.getVersion() == 2) {
+                int transform = mod.getTransform();
+                int src_transform_invert = (transform >> 15) & 1;
+                int src_transform_bipolar = (transform >> 14) & 1;
+                int src_transform = (transform >> 10) & 8;
+                int ctr_transform_invert = (transform >> 9) & 1;
+                int ctr_transform_bipolar = (transform >> 8) & 1;
+                int ctr_transform = (transform >> 4) & 8;
+
+
+                if (src != null) {
+                    int trans = ModelStandardTransform.TRANSFORM_LINEAR;
+                    if (src_transform == DLSModulator.CONN_TRN_SWITCH)
+                        trans = ModelStandardTransform.TRANSFORM_SWITCH;
+                    if (src_transform == DLSModulator.CONN_TRN_CONCAVE)
+                        trans = ModelStandardTransform.TRANSFORM_CONCAVE;
+                    if (src_transform == DLSModulator.CONN_TRN_CONVEX)
+                        trans = ModelStandardTransform.TRANSFORM_CONVEX;
+                    ((ModelStandardTransform)src.getTransform())
+                            .setTransform(trans);
+                    ((ModelStandardTransform)src.getTransform())
+                            .setPolarity(src_transform_bipolar == 1);
+                    ((ModelStandardTransform)src.getTransform())
+                            .setDirection(src_transform_invert == 1);
+
+                }
+
+                if (ctrl != null) {
+                    int trans = ModelStandardTransform.TRANSFORM_LINEAR;
+                    if (ctr_transform == DLSModulator.CONN_TRN_SWITCH)
+                        trans = ModelStandardTransform.TRANSFORM_SWITCH;
+                    if (ctr_transform == DLSModulator.CONN_TRN_CONCAVE)
+                        trans = ModelStandardTransform.TRANSFORM_CONCAVE;
+                    if (ctr_transform == DLSModulator.CONN_TRN_CONVEX)
+                        trans = ModelStandardTransform.TRANSFORM_CONVEX;
+                    ((ModelStandardTransform)ctrl.getTransform())
+                            .setTransform(trans);
+                    ((ModelStandardTransform)ctrl.getTransform())
+                            .setPolarity(ctr_transform_bipolar == 1);
+                    ((ModelStandardTransform)ctrl.getTransform())
+                            .setDirection(ctr_transform_invert == 1);
+                }
+
+                /* No output transforms are defined the DLS Level 2
+                int out_transform = transform % 8;
+                int trans = ModelStandardTransform.TRANSFORM_LINEAR;
+                if (out_transform == DLSModulator.CONN_TRN_SWITCH)
+                    trans = ModelStandardTransform.TRANSFORM_SWITCH;
+                if (out_transform == DLSModulator.CONN_TRN_CONCAVE)
+                    trans = ModelStandardTransform.TRANSFORM_CONCAVE;
+                if (out_transform == DLSModulator.CONN_TRN_CONVEX)
+                    trans = ModelStandardTransform.TRANSFORM_CONVEX;
+                if (ctrl != null) {
+                    ((ModelStandardTransform)destination.getTransform())
+                            .setTransform(trans);
+                }
+                */
+
+            }
+
+            block.setScale(f_scale);
+
+            return block;
+        }
+
+        return null;
+    }
+
+    public ModelPerformer[] getPerformers() {
+        List<ModelPerformer> performers = new ArrayList<ModelPerformer>();
+
+        Map<String, DLSModulator> modmap = new HashMap<String, DLSModulator>();
+        for (DLSModulator mod: getModulators()) {
+            modmap.put(mod.getSource() + "x" + mod.getControl() + "=" +
+                    mod.getDestination(), mod);
+        }
+
+        Map<String, DLSModulator> insmodmap =
+                new HashMap<String, DLSModulator>();
+
+        for (DLSRegion zone: regions) {
+            ModelPerformer performer = new ModelPerformer();
+            performer.setName(zone.getSample().getName());
+            performer.setSelfNonExclusive((zone.getFusoptions() &
+                    DLSRegion.OPTION_SELFNONEXCLUSIVE) != 0);
+            performer.setExclusiveClass(zone.getExclusiveClass());
+            performer.setKeyFrom(zone.getKeyfrom());
+            performer.setKeyTo(zone.getKeyto());
+            performer.setVelFrom(zone.getVelfrom());
+            performer.setVelTo(zone.getVelto());
+
+            insmodmap.clear();
+            insmodmap.putAll(modmap);
+            for (DLSModulator mod: zone.getModulators()) {
+                insmodmap.put(mod.getSource() + "x" + mod.getControl() + "=" +
+                        mod.getDestination(), mod);
+            }
+
+            List<ModelConnectionBlock> blocks = performer.getConnectionBlocks();
+            for (DLSModulator mod: insmodmap.values()) {
+                ModelConnectionBlock p = convertToModel(mod);
+                if (p != null)
+                    blocks.add(p);
+            }
+
+
+            DLSSample sample = zone.getSample();
+            DLSSampleOptions sampleopt = zone.getSampleoptions();
+            if (sampleopt == null)
+                sampleopt = sample.getSampleoptions();
+
+            ModelByteBuffer buff = sample.getDataBuffer();
+
+            float pitchcorrection = (-sampleopt.unitynote * 100) +
+                    sampleopt.finetune;
+
+            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(buff,
+                    sample.getFormat(), pitchcorrection);
+            osc.setAttenuation(osc.getAttenuation() / 65536f);
+            if (sampleopt.getLoops().size() != 0) {
+                DLSSampleLoop loop = sampleopt.getLoops().get(0);
+                osc.setLoopStart((int)loop.getStart());
+                osc.setLoopLength((int)loop.getLength());
+                if (loop.getType() == DLSSampleLoop.LOOP_TYPE_FORWARD)
+                    osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
+                if (loop.getType() == DLSSampleLoop.LOOP_TYPE_RELEASE)
+                    osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE);
+                else
+                    osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
+            }
+
+            performer.getConnectionBlocks().add(
+                    new ModelConnectionBlock(SoftFilter.FILTERTYPE_LP12,
+                        new ModelDestination(
+                            new ModelIdentifier("filter", "type", 1))));
+
+            performer.getOscillators().add(osc);
+
+            performers.add(performer);
+
+        }
+
+        return performers.toArray(new ModelPerformer[performers.size()]);
+    }
+
+    public byte[] getGuid() {
+        return guid;
+    }
+
+    public void setGuid(byte[] guid) {
+        this.guid = guid;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSModulator.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to store modulator/artiuclation data.
+ * A modulator connects one synthesizer source to
+ * a destination. For example a note on velocity
+ * can be mapped to the gain of the synthesized voice.
+ * It is stored as a "art1" or "art2" chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSModulator {
+
+    // DLS1 Destinations
+    public static final int CONN_DST_NONE = 0x000; // 0
+    public static final int CONN_DST_GAIN = 0x001; // cB
+    public static final int CONN_DST_PITCH = 0x003; // cent
+    public static final int CONN_DST_PAN = 0x004; // 0.1%
+    public static final int CONN_DST_LFO_FREQUENCY = 0x104; // cent (default 5 Hz)
+    public static final int CONN_DST_LFO_STARTDELAY = 0x105; // timecent
+    public static final int CONN_DST_EG1_ATTACKTIME = 0x206; // timecent
+    public static final int CONN_DST_EG1_DECAYTIME = 0x207; // timecent
+    public static final int CONN_DST_EG1_RELEASETIME = 0x209; // timecent
+    public static final int CONN_DST_EG1_SUSTAINLEVEL = 0x20A; // 0.1%
+    public static final int CONN_DST_EG2_ATTACKTIME = 0x30A; // timecent
+    public static final int CONN_DST_EG2_DECAYTIME = 0x30B; // timecent
+    public static final int CONN_DST_EG2_RELEASETIME = 0x30D; // timecent
+    public static final int CONN_DST_EG2_SUSTAINLEVEL = 0x30E; // 0.1%
+    // DLS2 Destinations
+    public static final int CONN_DST_KEYNUMBER = 0x005;
+    public static final int CONN_DST_LEFT = 0x010; // 0.1%
+    public static final int CONN_DST_RIGHT = 0x011; // 0.1%
+    public static final int CONN_DST_CENTER = 0x012; // 0.1%
+    public static final int CONN_DST_LEFTREAR = 0x013; // 0.1%
+    public static final int CONN_DST_RIGHTREAR = 0x014; // 0.1%
+    public static final int CONN_DST_LFE_CHANNEL = 0x015; // 0.1%
+    public static final int CONN_DST_CHORUS = 0x080; // 0.1%
+    public static final int CONN_DST_REVERB = 0x081; // 0.1%
+    public static final int CONN_DST_VIB_FREQUENCY = 0x114; // cent
+    public static final int CONN_DST_VIB_STARTDELAY = 0x115; // dB
+    public static final int CONN_DST_EG1_DELAYTIME = 0x20B; // timecent
+    public static final int CONN_DST_EG1_HOLDTIME = 0x20C; // timecent
+    public static final int CONN_DST_EG1_SHUTDOWNTIME = 0x20D; // timecent
+    public static final int CONN_DST_EG2_DELAYTIME = 0x30F; // timecent
+    public static final int CONN_DST_EG2_HOLDTIME = 0x310; // timecent
+    public static final int CONN_DST_FILTER_CUTOFF = 0x500; // cent
+    public static final int CONN_DST_FILTER_Q = 0x501; // dB
+
+    // DLS1 Sources
+    public static final int CONN_SRC_NONE = 0x000; // 1
+    public static final int CONN_SRC_LFO = 0x001; // linear (sine wave)
+    public static final int CONN_SRC_KEYONVELOCITY = 0x002; // ??db or velocity??
+    public static final int CONN_SRC_KEYNUMBER = 0x003; // ??cent or keynumber??
+    public static final int CONN_SRC_EG1 = 0x004; // linear direct from eg
+    public static final int CONN_SRC_EG2 = 0x005; // linear direct from eg
+    public static final int CONN_SRC_PITCHWHEEL = 0x006; // linear -1..1
+    public static final int CONN_SRC_CC1 = 0x081; // linear 0..1
+    public static final int CONN_SRC_CC7 = 0x087; // linear 0..1
+    public static final int CONN_SRC_CC10 = 0x08A; // linear 0..1
+    public static final int CONN_SRC_CC11 = 0x08B; // linear 0..1
+    public static final int CONN_SRC_RPN0 = 0x100; // ?? // Pitch Bend Range
+    public static final int CONN_SRC_RPN1 = 0x101; // ?? // Fine Tune
+    public static final int CONN_SRC_RPN2 = 0x102; // ?? // Course Tune
+    // DLS2 Sources
+    public static final int CONN_SRC_POLYPRESSURE = 0x007; // linear 0..1
+    public static final int CONN_SRC_CHANNELPRESSURE = 0x008; // linear 0..1
+    public static final int CONN_SRC_VIBRATO = 0x009; // linear 0..1
+    public static final int CONN_SRC_MONOPRESSURE = 0x00A; // linear 0..1
+    public static final int CONN_SRC_CC91 = 0x0DB; // linear 0..1
+    public static final int CONN_SRC_CC93 = 0x0DD; // linear 0..1
+    // DLS1 Transforms
+    public static final int CONN_TRN_NONE = 0x000;
+    public static final int CONN_TRN_CONCAVE = 0x001;
+    // DLS2 Transforms
+    public static final int CONN_TRN_CONVEX = 0x002;
+    public static final int CONN_TRN_SWITCH = 0x003;
+    public static final int DST_FORMAT_CB = 1;
+    public static final int DST_FORMAT_CENT = 1;
+    public static final int DST_FORMAT_TIMECENT = 2;
+    public static final int DST_FORMAT_PERCENT = 3;
+    protected int source;
+    protected int control;
+    protected int destination;
+    protected int transform;
+    protected int scale;
+    protected int version = 1;
+
+    public int getControl() {
+        return control;
+    }
+
+    public void setControl(int control) {
+        this.control = control;
+    }
+
+    public static int getDestinationFormat(int destination) {
+
+        if (destination == CONN_DST_GAIN)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_PITCH)
+            return DST_FORMAT_CENT;
+        if (destination == CONN_DST_PAN)
+            return DST_FORMAT_PERCENT;
+
+        if (destination == CONN_DST_LFO_FREQUENCY)
+            return DST_FORMAT_CENT;
+        if (destination == CONN_DST_LFO_STARTDELAY)
+            return DST_FORMAT_TIMECENT;
+
+        if (destination == CONN_DST_EG1_ATTACKTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_DECAYTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_RELEASETIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_SUSTAINLEVEL)
+            return DST_FORMAT_PERCENT;
+
+        if (destination == CONN_DST_EG2_ATTACKTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG2_DECAYTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG2_RELEASETIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG2_SUSTAINLEVEL)
+            return DST_FORMAT_PERCENT;
+
+        if (destination == CONN_DST_KEYNUMBER)
+            return DST_FORMAT_CENT; // NOT SURE WITHOUT DLS 2 SPEC
+        if (destination == CONN_DST_LEFT)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_RIGHT)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_CENTER)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_LEFTREAR)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_RIGHTREAR)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_LFE_CHANNEL)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_CHORUS)
+            return DST_FORMAT_PERCENT;
+        if (destination == CONN_DST_REVERB)
+            return DST_FORMAT_PERCENT;
+
+        if (destination == CONN_DST_VIB_FREQUENCY)
+            return DST_FORMAT_CENT;
+        if (destination == CONN_DST_VIB_STARTDELAY)
+            return DST_FORMAT_TIMECENT;
+
+        if (destination == CONN_DST_EG1_DELAYTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_HOLDTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_SHUTDOWNTIME)
+            return DST_FORMAT_TIMECENT;
+
+        if (destination == CONN_DST_EG2_DELAYTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG2_HOLDTIME)
+            return DST_FORMAT_TIMECENT;
+
+        if (destination == CONN_DST_FILTER_CUTOFF)
+            return DST_FORMAT_CENT;
+        if (destination == CONN_DST_FILTER_Q)
+            return DST_FORMAT_CB;
+
+        return -1;
+    }
+
+    public static String getDestinationName(int destination) {
+
+        if (destination == CONN_DST_GAIN)
+            return "gain";
+        if (destination == CONN_DST_PITCH)
+            return "pitch";
+        if (destination == CONN_DST_PAN)
+            return "pan";
+
+        if (destination == CONN_DST_LFO_FREQUENCY)
+            return "lfo1.freq";
+        if (destination == CONN_DST_LFO_STARTDELAY)
+            return "lfo1.delay";
+
+        if (destination == CONN_DST_EG1_ATTACKTIME)
+            return "eg1.attack";
+        if (destination == CONN_DST_EG1_DECAYTIME)
+            return "eg1.decay";
+        if (destination == CONN_DST_EG1_RELEASETIME)
+            return "eg1.release";
+        if (destination == CONN_DST_EG1_SUSTAINLEVEL)
+            return "eg1.sustain";
+
+        if (destination == CONN_DST_EG2_ATTACKTIME)
+            return "eg2.attack";
+        if (destination == CONN_DST_EG2_DECAYTIME)
+            return "eg2.decay";
+        if (destination == CONN_DST_EG2_RELEASETIME)
+            return "eg2.release";
+        if (destination == CONN_DST_EG2_SUSTAINLEVEL)
+            return "eg2.sustain";
+
+        if (destination == CONN_DST_KEYNUMBER)
+            return "keynumber";
+        if (destination == CONN_DST_LEFT)
+            return "left";
+        if (destination == CONN_DST_RIGHT)
+            return "right";
+        if (destination == CONN_DST_CENTER)
+            return "center";
+        if (destination == CONN_DST_LEFTREAR)
+            return "leftrear";
+        if (destination == CONN_DST_RIGHTREAR)
+            return "rightrear";
+        if (destination == CONN_DST_LFE_CHANNEL)
+            return "lfe_channel";
+        if (destination == CONN_DST_CHORUS)
+            return "chorus";
+        if (destination == CONN_DST_REVERB)
+            return "reverb";
+
+        if (destination == CONN_DST_VIB_FREQUENCY)
+            return "vib.freq";
+        if (destination == CONN_DST_VIB_STARTDELAY)
+            return "vib.delay";
+
+        if (destination == CONN_DST_EG1_DELAYTIME)
+            return "eg1.delay";
+        if (destination == CONN_DST_EG1_HOLDTIME)
+            return "eg1.hold";
+        if (destination == CONN_DST_EG1_SHUTDOWNTIME)
+            return "eg1.shutdown";
+
+        if (destination == CONN_DST_EG2_DELAYTIME)
+            return "eg2.delay";
+        if (destination == CONN_DST_EG2_HOLDTIME)
+            return "eg.2hold";
+
+        if (destination == CONN_DST_FILTER_CUTOFF)
+            return "filter.cutoff"; // NOT SURE WITHOUT DLS 2 SPEC
+        if (destination == CONN_DST_FILTER_Q)
+            return "filter.q"; // NOT SURE WITHOUT DLS 2 SPEC
+
+        return null;
+    }
+
+    public static String getSourceName(int source) {
+
+        if (source == CONN_SRC_NONE)
+            return "none";
+        if (source == CONN_SRC_LFO)
+            return "lfo";
+        if (source == CONN_SRC_KEYONVELOCITY)
+            return "keyonvelocity";
+        if (source == CONN_SRC_KEYNUMBER)
+            return "keynumber";
+        if (source == CONN_SRC_EG1)
+            return "eg1";
+        if (source == CONN_SRC_EG2)
+            return "eg2";
+        if (source == CONN_SRC_PITCHWHEEL)
+            return "pitchweel";
+        if (source == CONN_SRC_CC1)
+            return "cc1";
+        if (source == CONN_SRC_CC7)
+            return "cc7";
+        if (source == CONN_SRC_CC10)
+            return "c10";
+        if (source == CONN_SRC_CC11)
+            return "cc11";
+
+        if (source == CONN_SRC_POLYPRESSURE)
+            return "polypressure";
+        if (source == CONN_SRC_CHANNELPRESSURE)
+            return "channelpressure";
+        if (source == CONN_SRC_VIBRATO)
+            return "vibrato";
+        if (source == CONN_SRC_MONOPRESSURE)
+            return "monopressure";
+        if (source == CONN_SRC_CC91)
+            return "cc91";
+        if (source == CONN_SRC_CC93)
+            return "cc93";
+        return null;
+    }
+
+    public int getDestination() {
+        return destination;
+    }
+
+    public void setDestination(int destination) {
+        this.destination = destination;
+    }
+
+    public int getScale() {
+        return scale;
+    }
+
+    public void setScale(int scale) {
+        this.scale = scale;
+    }
+
+    public int getSource() {
+        return source;
+    }
+
+    public void setSource(int source) {
+        this.source = source;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+
+    public int getTransform() {
+        return transform;
+    }
+
+    public void setTransform(int transform) {
+        this.transform = transform;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSRegion.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class is used to store region parts for instrument.
+ * A region has a velocity and key range which it response to.
+ * And it has a list of modulators/articulators which
+ * is used how to synthesize a single voice.
+ * It is stored inside a "rgn " List Chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSRegion {
+
+    public final static int OPTION_SELFNONEXCLUSIVE = 0x0001;
+    protected List<DLSModulator> modulators = new ArrayList<DLSModulator>();
+    protected int keyfrom;
+    protected int keyto;
+    protected int velfrom;
+    protected int velto;
+    protected int options;
+    protected int exclusiveClass;
+    protected int fusoptions;
+    protected int phasegroup;
+    protected long channel;
+    protected DLSSample sample = null;
+    protected DLSSampleOptions sampleoptions;
+
+    public List<DLSModulator> getModulators() {
+        return modulators;
+    }
+
+    public long getChannel() {
+        return channel;
+    }
+
+    public void setChannel(long channel) {
+        this.channel = channel;
+    }
+
+    public int getExclusiveClass() {
+        return exclusiveClass;
+    }
+
+    public void setExclusiveClass(int exclusiveClass) {
+        this.exclusiveClass = exclusiveClass;
+    }
+
+    public int getFusoptions() {
+        return fusoptions;
+    }
+
+    public void setFusoptions(int fusoptions) {
+        this.fusoptions = fusoptions;
+    }
+
+    public int getKeyfrom() {
+        return keyfrom;
+    }
+
+    public void setKeyfrom(int keyfrom) {
+        this.keyfrom = keyfrom;
+    }
+
+    public int getKeyto() {
+        return keyto;
+    }
+
+    public void setKeyto(int keyto) {
+        this.keyto = keyto;
+    }
+
+    public int getOptions() {
+        return options;
+    }
+
+    public void setOptions(int options) {
+        this.options = options;
+    }
+
+    public int getPhasegroup() {
+        return phasegroup;
+    }
+
+    public void setPhasegroup(int phasegroup) {
+        this.phasegroup = phasegroup;
+    }
+
+    public DLSSample getSample() {
+        return sample;
+    }
+
+    public void setSample(DLSSample sample) {
+        this.sample = sample;
+    }
+
+    public int getVelfrom() {
+        return velfrom;
+    }
+
+    public void setVelfrom(int velfrom) {
+        this.velfrom = velfrom;
+    }
+
+    public int getVelto() {
+        return velto;
+    }
+
+    public void setVelto(int velto) {
+        this.velto = velto;
+    }
+
+    public void setModulators(List<DLSModulator> modulators) {
+        this.modulators = modulators;
+    }
+
+    public DLSSampleOptions getSampleoptions() {
+        return sampleoptions;
+    }
+
+    public void setSampleoptions(DLSSampleOptions sampleOptions) {
+        this.sampleoptions = sampleOptions;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSSample.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.InputStream;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+
+/**
+ * This class is used to store the sample data itself.
+ * A sample is encoded as PCM audio stream
+ * and in DLS Level 1 files it is always a mono 8/16 bit stream.
+ * They are stored just like RIFF WAVE files are stored.
+ * It is stored inside a "wave" List Chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSSample extends SoundbankResource {
+
+    protected byte[] guid = null;
+    protected DLSInfo info = new DLSInfo();
+    protected DLSSampleOptions sampleoptions;
+    protected ModelByteBuffer data;
+    protected AudioFormat format;
+
+    public DLSSample(Soundbank soundBank) {
+        super(soundBank, null, AudioInputStream.class);
+    }
+
+    public DLSSample() {
+        super(null, null, AudioInputStream.class);
+    }
+
+    public DLSInfo getInfo() {
+        return info;
+    }
+
+    public Object getData() {
+        AudioFormat format = getFormat();
+
+        InputStream is = data.getInputStream();
+        if (is == null)
+            return null;
+        return new AudioInputStream(is, format, data.capacity());
+    }
+
+    public ModelByteBuffer getDataBuffer() {
+        return data;
+    }
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public void setFormat(AudioFormat format) {
+        this.format = format;
+    }
+
+    public void setData(ModelByteBuffer data) {
+        this.data = data;
+    }
+
+    public void setData(byte[] data) {
+        this.data = new ModelByteBuffer(data);
+    }
+
+    public void setData(byte[] data, int offset, int length) {
+        this.data = new ModelByteBuffer(data, offset, length);
+    }
+
+    public String getName() {
+        return info.name;
+    }
+
+    public void setName(String name) {
+        info.name = name;
+    }
+
+    public DLSSampleOptions getSampleoptions() {
+        return sampleoptions;
+    }
+
+    public void setSampleoptions(DLSSampleOptions sampleOptions) {
+        this.sampleoptions = sampleOptions;
+    }
+
+    public String toString() {
+        return "Sample: " + info.name;
+    }
+
+    public byte[] getGuid() {
+        return guid;
+    }
+
+    public void setGuid(byte[] guid) {
+        this.guid = guid;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSSampleLoop.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to store loop points inside DLSSampleOptions class.
+ *
+ * @author Karl Helgason
+ */
+public class DLSSampleLoop {
+
+    public final static int LOOP_TYPE_FORWARD = 0;
+    public final static int LOOP_TYPE_RELEASE = 1;
+    protected long type;
+    protected long start;
+    protected long length;
+
+    public long getLength() {
+        return length;
+    }
+
+    public void setLength(long length) {
+        this.length = length;
+    }
+
+    public long getStart() {
+        return start;
+    }
+
+    public void setStart(long start) {
+        this.start = start;
+    }
+
+    public long getType() {
+        return type;
+    }
+
+    public void setType(long type) {
+        this.type = type;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSSampleOptions.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class stores options how to playback sampled data like pitch/tuning,
+ * attenuation and loops.
+ * It is stored as a "wsmp" chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSSampleOptions {
+
+    protected int unitynote;
+    protected short finetune;
+    protected int attenuation;
+    protected long options;
+    protected List<DLSSampleLoop> loops = new ArrayList<DLSSampleLoop>();
+
+    public int getAttenuation() {
+        return attenuation;
+    }
+
+    public void setAttenuation(int attenuation) {
+        this.attenuation = attenuation;
+    }
+
+    public short getFinetune() {
+        return finetune;
+    }
+
+    public void setFinetune(short finetune) {
+        this.finetune = finetune;
+    }
+
+    public List<DLSSampleLoop> getLoops() {
+        return loops;
+    }
+
+    public long getOptions() {
+        return options;
+    }
+
+    public void setOptions(long options) {
+        this.options = options;
+    }
+
+    public int getUnitynote() {
+        return unitynote;
+    }
+
+    public void setUnitynote(int unitynote) {
+        this.unitynote = unitynote;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSSoundbank.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,1287 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+/**
+ * A DLS Level 1 and Level 2 soundbank reader (from files/url/streams).
+ *
+ * @author Karl Helgason
+ */
+public class DLSSoundbank implements Soundbank {
+
+    static private class DLSID {
+        long i1;
+        int s1;
+        int s2;
+        int x1;
+        int x2;
+        int x3;
+        int x4;
+        int x5;
+        int x6;
+        int x7;
+        int x8;
+
+        private DLSID() {
+        }
+
+        public DLSID(long i1, int s1, int s2, int x1, int x2, int x3, int x4,
+                int x5, int x6, int x7, int x8) {
+            this.i1 = i1;
+            this.s1 = s1;
+            this.s2 = s2;
+            this.x1 = x1;
+            this.x2 = x2;
+            this.x3 = x3;
+            this.x4 = x4;
+            this.x5 = x5;
+            this.x6 = x6;
+            this.x7 = x7;
+            this.x8 = x8;
+        }
+
+        public static DLSID read(RIFFReader riff) throws IOException {
+            DLSID d = new DLSID();
+            d.i1 = riff.readUnsignedInt();
+            d.s1 = riff.readUnsignedShort();
+            d.s2 = riff.readUnsignedShort();
+            d.x1 = riff.readUnsignedByte();
+            d.x2 = riff.readUnsignedByte();
+            d.x3 = riff.readUnsignedByte();
+            d.x4 = riff.readUnsignedByte();
+            d.x5 = riff.readUnsignedByte();
+            d.x6 = riff.readUnsignedByte();
+            d.x7 = riff.readUnsignedByte();
+            d.x8 = riff.readUnsignedByte();
+            return d;
+        }
+
+        public int hashCode() {
+            return (int)i1;
+        }
+
+        public boolean equals(Object obj) {
+            if (!(obj instanceof DLSID)) {
+                return false;
+            }
+            DLSID t = (DLSID) obj;
+            return i1 == t.i1 && s1 == t.s1 && s2 == t.s2
+                && x1 == t.x1 && x2 == t.x2 && x3 == t.x3 && x4 == t.x4
+                && x5 == t.x5 && x6 == t.x6 && x7 == t.x7 && x8 == t.x8;
+        }
+    }
+
+    /** X = X & Y */
+    private static final int DLS_CDL_AND = 0x0001;
+    /** X = X | Y */
+    private static final int DLS_CDL_OR = 0x0002;
+    /** X = X ^ Y */
+    private static final int DLS_CDL_XOR = 0x0003;
+    /** X = X + Y */
+    private static final int DLS_CDL_ADD = 0x0004;
+    /** X = X - Y */
+    private static final int DLS_CDL_SUBTRACT = 0x0005;
+    /** X = X * Y */
+    private static final int DLS_CDL_MULTIPLY = 0x0006;
+    /** X = X / Y */
+    private static final int DLS_CDL_DIVIDE = 0x0007;
+    /** X = X && Y */
+    private static final int DLS_CDL_LOGICAL_AND = 0x0008;
+    /** X = X || Y */
+    private static final int DLS_CDL_LOGICAL_OR = 0x0009;
+    /** X = (X < Y) */
+    private static final int DLS_CDL_LT = 0x000A;
+    /** X = (X <= Y) */
+    private static final int DLS_CDL_LE = 0x000B;
+    /** X = (X > Y) */
+    private static final int DLS_CDL_GT = 0x000C;
+    /** X = (X >= Y) */
+    private static final int DLS_CDL_GE = 0x000D;
+    /** X = (X == Y) */
+    private static final int DLS_CDL_EQ = 0x000E;
+    /** X = !X */
+    private static final int DLS_CDL_NOT = 0x000F;
+    /** 32-bit constant */
+    private static final int DLS_CDL_CONST = 0x0010;
+    /** 32-bit value returned from query */
+    private static final int DLS_CDL_QUERY = 0x0011;
+    /** 32-bit value returned from query */
+    private static final int DLS_CDL_QUERYSUPPORTED = 0x0012;
+
+    private static final DLSID DLSID_GMInHardware = new DLSID(0x178f2f24,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_GSInHardware = new DLSID(0x178f2f25,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_XGInHardware = new DLSID(0x178f2f26,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_SupportsDLS1 = new DLSID(0x178f2f27,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_SupportsDLS2 = new DLSID(0xf14599e5,
+            0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);
+    private static final DLSID DLSID_SampleMemorySize = new DLSID(0x178f2f28,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_ManufacturersID = new DLSID(0xb03e1181,
+            0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+    private static final DLSID DLSID_ProductID = new DLSID(0xb03e1182,
+            0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+    private static final DLSID DLSID_SamplePlaybackRate = new DLSID(0x2a91f713,
+            0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+
+    private long major = -1;
+    private long minor = -1;
+
+    private DLSInfo info = new DLSInfo();
+
+    private List<DLSInstrument> instruments = new ArrayList<DLSInstrument>();
+    private List<DLSSample> samples = new ArrayList<DLSSample>();
+
+    private boolean largeFormat = false;
+    private File sampleFile;
+
+    public DLSSoundbank() {
+    }
+
+    public DLSSoundbank(URL url) throws IOException {
+        InputStream is = url.openStream();
+        try {
+            readSoundbank(is);
+        } finally {
+            is.close();
+        }
+    }
+
+    public DLSSoundbank(File file) throws IOException {
+        largeFormat = true;
+        sampleFile = file;
+        InputStream is = new FileInputStream(file);
+        try {
+            readSoundbank(is);
+        } finally {
+            is.close();
+        }
+    }
+
+    public DLSSoundbank(InputStream inputstream) throws IOException {
+        readSoundbank(inputstream);
+    }
+
+    private void readSoundbank(InputStream inputstream) throws IOException {
+        RIFFReader riff = new RIFFReader(inputstream);
+        if (!riff.getFormat().equals("RIFF")) {
+            throw new RIFFInvalidFormatException(
+                    "Input stream is not a valid RIFF stream!");
+        }
+        if (!riff.getType().equals("DLS ")) {
+            throw new RIFFInvalidFormatException(
+                    "Input stream is not a valid DLS soundbank!");
+        }
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("LIST")) {
+                if (chunk.getType().equals("INFO"))
+                    readInfoChunk(chunk);
+                if (chunk.getType().equals("lins"))
+                    readLinsChunk(chunk);
+                if (chunk.getType().equals("wvpl"))
+                    readWvplChunk(chunk);
+            } else {
+                if (chunk.getFormat().equals("cdl ")) {
+                    if (!readCdlChunk(chunk)) {
+                        throw new RIFFInvalidFormatException(
+                                "DLS file isn't supported!");
+                    }
+                }
+                if (chunk.getFormat().equals("colh")) {
+                    // skipped because we will load the entire bank into memory
+                    // long instrumentcount = chunk.readUnsignedInt();
+                    // System.out.println("instrumentcount = "+ instrumentcount);
+                }
+                if (chunk.getFormat().equals("ptbl")) {
+                    // Pool Table Chunk
+                    // skipped because we will load the entire bank into memory
+                }
+                if (chunk.getFormat().equals("vers")) {
+                    major = chunk.readUnsignedInt();
+                    minor = chunk.readUnsignedInt();
+                }
+            }
+        }
+
+        for (Map.Entry<DLSRegion, Long> entry : temp_rgnassign.entrySet()) {
+            entry.getKey().sample = samples.get((int)entry.getValue().longValue());
+        }
+
+        temp_rgnassign = null;
+    }
+
+    private boolean cdlIsQuerySupported(DLSID uuid) {
+        return uuid.equals(DLSID_GMInHardware)
+            || uuid.equals(DLSID_GSInHardware)
+            || uuid.equals(DLSID_XGInHardware)
+            || uuid.equals(DLSID_SupportsDLS1)
+            || uuid.equals(DLSID_SupportsDLS2)
+            || uuid.equals(DLSID_SampleMemorySize)
+            || uuid.equals(DLSID_ManufacturersID)
+            || uuid.equals(DLSID_ProductID)
+            || uuid.equals(DLSID_SamplePlaybackRate);
+    }
+
+    private long cdlQuery(DLSID uuid) {
+        if (uuid.equals(DLSID_GMInHardware))
+            return 1;
+        if (uuid.equals(DLSID_GSInHardware))
+            return 0;
+        if (uuid.equals(DLSID_XGInHardware))
+            return 0;
+        if (uuid.equals(DLSID_SupportsDLS1))
+            return 1;
+        if (uuid.equals(DLSID_SupportsDLS2))
+            return 1;
+        if (uuid.equals(DLSID_SampleMemorySize))
+            return Runtime.getRuntime().totalMemory();
+        if (uuid.equals(DLSID_ManufacturersID))
+            return 0;
+        if (uuid.equals(DLSID_ProductID))
+            return 0;
+        if (uuid.equals(DLSID_SamplePlaybackRate))
+            return 44100;
+        return 0;
+    }
+
+
+    // Reading cdl-ck Chunk
+    // "cdl " chunk can only appear inside : DLS,lart,lar2,rgn,rgn2
+    private boolean readCdlChunk(RIFFReader riff) throws IOException {
+
+        DLSID uuid;
+        long x;
+        long y;
+        Stack<Long> stack = new Stack<Long>();
+
+        while (riff.available() != 0) {
+            int opcode = riff.readUnsignedShort();
+            switch (opcode) {
+            case DLS_CDL_AND:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(((x != 0) && (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_OR:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(((x != 0) || (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_XOR:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(((x != 0) ^ (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_ADD:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(x + y));
+                break;
+            case DLS_CDL_SUBTRACT:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(x - y));
+                break;
+            case DLS_CDL_MULTIPLY:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(x * y));
+                break;
+            case DLS_CDL_DIVIDE:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(x / y));
+                break;
+            case DLS_CDL_LOGICAL_AND:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(((x != 0) && (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_LOGICAL_OR:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf(((x != 0) || (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_LT:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf((x < y) ? 1 : 0));
+                break;
+            case DLS_CDL_LE:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf((x <= y) ? 1 : 0));
+                break;
+            case DLS_CDL_GT:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf((x > y) ? 1 : 0));
+                break;
+            case DLS_CDL_GE:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf((x >= y) ? 1 : 0));
+                break;
+            case DLS_CDL_EQ:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf((x == y) ? 1 : 0));
+                break;
+            case DLS_CDL_NOT:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(Long.valueOf((x == 0) ? 1 : 0));
+                break;
+            case DLS_CDL_CONST:
+                stack.push(Long.valueOf(riff.readUnsignedInt()));
+                break;
+            case DLS_CDL_QUERY:
+                uuid = DLSID.read(riff);
+                stack.push(cdlQuery(uuid));
+                break;
+            case DLS_CDL_QUERYSUPPORTED:
+                uuid = DLSID.read(riff);
+                stack.push(Long.valueOf(cdlIsQuerySupported(uuid) ? 1 : 0));
+                break;
+            default:
+                break;
+            }
+        }
+        if (stack.isEmpty())
+            return false;
+
+        return stack.pop() == 1;
+    }
+
+    private void readInfoChunk(RIFFReader riff) throws IOException {
+        info.name = null;
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("INAM"))
+                info.name = chunk.readString(chunk.available());
+            else if (format.equals("ICRD"))
+                info.creationDate = chunk.readString(chunk.available());
+            else if (format.equals("IENG"))
+                info.engineers = chunk.readString(chunk.available());
+            else if (format.equals("IPRD"))
+                info.product = chunk.readString(chunk.available());
+            else if (format.equals("ICOP"))
+                info.copyright = chunk.readString(chunk.available());
+            else if (format.equals("ICMT"))
+                info.comments = chunk.readString(chunk.available());
+            else if (format.equals("ISFT"))
+                info.tools = chunk.readString(chunk.available());
+            else if (format.equals("IARL"))
+                info.archival_location = chunk.readString(chunk.available());
+            else if (format.equals("IART"))
+                info.artist = chunk.readString(chunk.available());
+            else if (format.equals("ICMS"))
+                info.commissioned = chunk.readString(chunk.available());
+            else if (format.equals("IGNR"))
+                info.genre = chunk.readString(chunk.available());
+            else if (format.equals("IKEY"))
+                info.keywords = chunk.readString(chunk.available());
+            else if (format.equals("IMED"))
+                info.medium = chunk.readString(chunk.available());
+            else if (format.equals("ISBJ"))
+                info.subject = chunk.readString(chunk.available());
+            else if (format.equals("ISRC"))
+                info.source = chunk.readString(chunk.available());
+            else if (format.equals("ISRF"))
+                info.source_form = chunk.readString(chunk.available());
+            else if (format.equals("ITCH"))
+                info.technician = chunk.readString(chunk.available());
+        }
+    }
+
+    private void readLinsChunk(RIFFReader riff) throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("LIST")) {
+                if (chunk.getType().equals("ins "))
+                    readInsChunk(chunk);
+            }
+        }
+    }
+
+    private void readInsChunk(RIFFReader riff) throws IOException {
+        DLSInstrument instrument = new DLSInstrument(this);
+
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("LIST")) {
+                if (chunk.getType().equals("INFO")) {
+                    readInsInfoChunk(instrument, chunk);
+                }
+                if (chunk.getType().equals("lrgn")) {
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (subchunk.getFormat().equals("LIST")) {
+                            if (subchunk.getType().equals("rgn ")) {
+                                DLSRegion split = new DLSRegion();
+                                if (readRgnChunk(split, subchunk))
+                                    instrument.getRegions().add(split);
+                            }
+                            if (subchunk.getType().equals("rgn2")) {
+                                // support for DLS level 2 regions
+                                DLSRegion split = new DLSRegion();
+                                if (readRgnChunk(split, subchunk))
+                                    instrument.getRegions().add(split);
+                            }
+                        }
+                    }
+                }
+                if (chunk.getType().equals("lart")) {
+                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (chunk.getFormat().equals("cdl ")) {
+                            if (!readCdlChunk(chunk)) {
+                                modlist.clear();
+                                break;
+                            }
+                        }
+                        if (subchunk.getFormat().equals("art1"))
+                            readArt1Chunk(modlist, subchunk);
+                    }
+                    instrument.getModulators().addAll(modlist);
+                }
+                if (chunk.getType().equals("lar2")) {
+                    // support for DLS level 2 ART
+                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (chunk.getFormat().equals("cdl ")) {
+                            if (!readCdlChunk(chunk)) {
+                                modlist.clear();
+                                break;
+                            }
+                        }
+                        if (subchunk.getFormat().equals("art2"))
+                            readArt2Chunk(modlist, subchunk);
+                    }
+                    instrument.getModulators().addAll(modlist);
+                }
+            } else {
+                if (format.equals("dlid")) {
+                    instrument.guid = new byte[16];
+                    chunk.readFully(instrument.guid);
+                }
+                if (format.equals("insh")) {
+                    chunk.readUnsignedInt(); // Read Region Count - ignored
+
+                    int bank = chunk.read();             // LSB
+                    bank += (chunk.read() & 127) << 7;   // MSB
+                    chunk.read(); // Read Reserved byte
+                    int drumins = chunk.read();          // Drum Instrument
+
+                    int id = chunk.read() & 127; // Read only first 7 bits
+                    chunk.read(); // Read Reserved byte
+                    chunk.read(); // Read Reserved byte
+                    chunk.read(); // Read Reserved byte
+
+                    instrument.bank = bank;
+                    instrument.preset = (int) id;
+                    instrument.druminstrument = (drumins & 128) > 0;
+                    //System.out.println("bank="+bank+" drumkit="+drumkit
+                    //        +" id="+id);
+                }
+
+            }
+        }
+        instruments.add(instrument);
+    }
+
+    private void readArt1Chunk(List<DLSModulator> modulators, RIFFReader riff)
+            throws IOException {
+        long size = riff.readUnsignedInt();
+        long count = riff.readUnsignedInt();
+
+        if (size - 8 != 0)
+            riff.skipBytes(size - 8);
+
+        for (int i = 0; i < count; i++) {
+            DLSModulator modulator = new DLSModulator();
+            modulator.version = 1;
+            modulator.source = riff.readUnsignedShort();
+            modulator.control = riff.readUnsignedShort();
+            modulator.destination = riff.readUnsignedShort();
+            modulator.transform = riff.readUnsignedShort();
+            modulator.scale = riff.readInt();
+            modulators.add(modulator);
+        }
+    }
+
+    private void readArt2Chunk(List<DLSModulator> modulators, RIFFReader riff)
+            throws IOException {
+        long size = riff.readUnsignedInt();
+        long count = riff.readUnsignedInt();
+
+        if (size - 8 != 0)
+            riff.skipBytes(size - 8);
+
+        for (int i = 0; i < count; i++) {
+            DLSModulator modulator = new DLSModulator();
+            modulator.version = 2;
+            modulator.source = riff.readUnsignedShort();
+            modulator.control = riff.readUnsignedShort();
+            modulator.destination = riff.readUnsignedShort();
+            modulator.transform = riff.readUnsignedShort();
+            modulator.scale = riff.readInt();
+            modulators.add(modulator);
+        }
+    }
+
+    private Map<DLSRegion, Long> temp_rgnassign = new HashMap<DLSRegion, Long>();
+
+    private boolean readRgnChunk(DLSRegion split, RIFFReader riff)
+            throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("LIST")) {
+                if (chunk.getType().equals("lart")) {
+                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (chunk.getFormat().equals("cdl ")) {
+                            if (!readCdlChunk(chunk)) {
+                                modlist.clear();
+                                break;
+                            }
+                        }
+                        if (subchunk.getFormat().equals("art1"))
+                            readArt1Chunk(modlist, subchunk);
+                    }
+                    split.getModulators().addAll(modlist);
+                }
+                if (chunk.getType().equals("lar2")) {
+                    // support for DLS level 2 ART
+                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (chunk.getFormat().equals("cdl ")) {
+                            if (!readCdlChunk(chunk)) {
+                                modlist.clear();
+                                break;
+                            }
+                        }
+                        if (subchunk.getFormat().equals("art2"))
+                            readArt2Chunk(modlist, subchunk);
+                    }
+                    split.getModulators().addAll(modlist);
+                }
+            } else {
+
+                if (format.equals("cdl ")) {
+                    if (!readCdlChunk(chunk))
+                        return false;
+                }
+                if (format.equals("rgnh")) {
+                    split.keyfrom = chunk.readUnsignedShort();
+                    split.keyto = chunk.readUnsignedShort();
+                    split.velfrom = chunk.readUnsignedShort();
+                    split.velto = chunk.readUnsignedShort();
+                    split.options = chunk.readUnsignedShort();
+                    split.exclusiveClass = chunk.readUnsignedShort();
+                }
+                if (format.equals("wlnk")) {
+                    split.fusoptions = chunk.readUnsignedShort();
+                    split.phasegroup = chunk.readUnsignedShort();
+                    split.channel = chunk.readUnsignedInt();
+                    long sampleid = chunk.readUnsignedInt();
+                    temp_rgnassign.put(split, sampleid);
+                }
+                if (format.equals("wsmp")) {
+                    split.sampleoptions = new DLSSampleOptions();
+                    readWsmpChunk(split.sampleoptions, chunk);
+                }
+            }
+        }
+        return true;
+    }
+
+    private void readWsmpChunk(DLSSampleOptions sampleOptions, RIFFReader riff)
+            throws IOException {
+        long size = riff.readUnsignedInt();
+        sampleOptions.unitynote = riff.readUnsignedShort();
+        sampleOptions.finetune = riff.readShort();
+        sampleOptions.attenuation = riff.readInt();
+        sampleOptions.options = riff.readUnsignedInt();
+        long loops = riff.readInt();
+
+        if (size > 20)
+            riff.skipBytes(size - 20);
+
+        for (int i = 0; i < loops; i++) {
+            DLSSampleLoop loop = new DLSSampleLoop();
+            long size2 = riff.readUnsignedInt();
+            loop.type = riff.readUnsignedInt();
+            loop.start = riff.readUnsignedInt();
+            loop.length = riff.readUnsignedInt();
+            sampleOptions.loops.add(loop);
+            if (size2 > 16)
+                riff.skipBytes(size2 - 16);
+        }
+    }
+
+    private void readInsInfoChunk(DLSInstrument dlsinstrument, RIFFReader riff)
+            throws IOException {
+        dlsinstrument.info.name = null;
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("INAM")) {
+                dlsinstrument.info.name = chunk.readString(chunk.available());
+            } else if (format.equals("ICRD")) {
+                dlsinstrument.info.creationDate =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IENG")) {
+                dlsinstrument.info.engineers =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IPRD")) {
+                dlsinstrument.info.product = chunk.readString(chunk.available());
+            } else if (format.equals("ICOP")) {
+                dlsinstrument.info.copyright =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("ICMT")) {
+                dlsinstrument.info.comments =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("ISFT")) {
+                dlsinstrument.info.tools = chunk.readString(chunk.available());
+            } else if (format.equals("IARL")) {
+                dlsinstrument.info.archival_location =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IART")) {
+                dlsinstrument.info.artist = chunk.readString(chunk.available());
+            } else if (format.equals("ICMS")) {
+                dlsinstrument.info.commissioned =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IGNR")) {
+                dlsinstrument.info.genre = chunk.readString(chunk.available());
+            } else if (format.equals("IKEY")) {
+                dlsinstrument.info.keywords =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IMED")) {
+                dlsinstrument.info.medium = chunk.readString(chunk.available());
+            } else if (format.equals("ISBJ")) {
+                dlsinstrument.info.subject = chunk.readString(chunk.available());
+            } else if (format.equals("ISRC")) {
+                dlsinstrument.info.source = chunk.readString(chunk.available());
+            } else if (format.equals("ISRF")) {
+                dlsinstrument.info.source_form =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("ITCH")) {
+                dlsinstrument.info.technician =
+                        chunk.readString(chunk.available());
+            }
+        }
+    }
+
+    private void readWvplChunk(RIFFReader riff) throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("LIST")) {
+                if (chunk.getType().equals("wave"))
+                    readWaveChunk(chunk);
+            }
+        }
+    }
+
+    private void readWaveChunk(RIFFReader riff) throws IOException {
+        DLSSample sample = new DLSSample(this);
+
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("LIST")) {
+                if (chunk.getType().equals("INFO")) {
+                    readWaveInfoChunk(sample, chunk);
+                }
+            } else {
+                if (format.equals("dlid")) {
+                    sample.guid = new byte[16];
+                    chunk.readFully(sample.guid);
+                }
+
+                if (format.equals("fmt ")) {
+                    int sampleformat = chunk.readUnsignedShort();
+                    if (sampleformat != 1 && sampleformat != 3) {
+                        throw new RIFFInvalidDataException(
+                                "Only PCM samples are supported!");
+                    }
+                    int channels = chunk.readUnsignedShort();
+                    long samplerate = chunk.readUnsignedInt();
+                    // bytes per sec
+                    /* long framerate = */ chunk.readUnsignedInt();
+                    // block align, framesize
+                    int framesize = chunk.readUnsignedShort();
+                    int bits = chunk.readUnsignedShort();
+                    AudioFormat audioformat = null;
+                    if (sampleformat == 1) {
+                        if (bits == 8) {
+                            audioformat = new AudioFormat(
+                                    Encoding.PCM_UNSIGNED, samplerate, bits,
+                                    channels, framesize, samplerate, false);
+                        } else {
+                            audioformat = new AudioFormat(
+                                    Encoding.PCM_SIGNED, samplerate, bits,
+                                    channels, framesize, samplerate, false);
+                        }
+                    }
+                    if (sampleformat == 3) {
+                        audioformat = new AudioFormat(
+                                AudioFloatConverter.PCM_FLOAT, samplerate, bits,
+                                channels, framesize, samplerate, false);
+                    }
+
+                    sample.format = audioformat;
+                }
+
+                if (format.equals("data")) {
+                    if (largeFormat) {
+                        sample.setData(new ModelByteBuffer(sampleFile,
+                                chunk.getFilePointer(), chunk.available()));
+                    } else {
+                        byte[] buffer = new byte[chunk.available()];
+                        //  chunk.read(buffer);
+                        sample.setData(buffer);
+
+                        int read = 0;
+                        int avail = chunk.available();
+                        while (read != avail) {
+                            if (avail - read > 65536) {
+                                chunk.readFully(buffer, read, 65536);
+                                read += 65536;
+                            } else {
+                                chunk.readFully(buffer, read, avail - read);
+                                read = avail;
+                            }
+                        }
+                    }
+                }
+
+                if (format.equals("wsmp")) {
+                    sample.sampleoptions = new DLSSampleOptions();
+                    readWsmpChunk(sample.sampleoptions, chunk);
+                }
+            }
+        }
+
+        samples.add(sample);
+
+    }
+
+    private void readWaveInfoChunk(DLSSample dlssample, RIFFReader riff)
+            throws IOException {
+        dlssample.info.name = null;
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("INAM")) {
+                dlssample.info.name = chunk.readString(chunk.available());
+            } else if (format.equals("ICRD")) {
+                dlssample.info.creationDate =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IENG")) {
+                dlssample.info.engineers = chunk.readString(chunk.available());
+            } else if (format.equals("IPRD")) {
+                dlssample.info.product = chunk.readString(chunk.available());
+            } else if (format.equals("ICOP")) {
+                dlssample.info.copyright = chunk.readString(chunk.available());
+            } else if (format.equals("ICMT")) {
+                dlssample.info.comments = chunk.readString(chunk.available());
+            } else if (format.equals("ISFT")) {
+                dlssample.info.tools = chunk.readString(chunk.available());
+            } else if (format.equals("IARL")) {
+                dlssample.info.archival_location =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IART")) {
+                dlssample.info.artist = chunk.readString(chunk.available());
+            } else if (format.equals("ICMS")) {
+                dlssample.info.commissioned =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IGNR")) {
+                dlssample.info.genre = chunk.readString(chunk.available());
+            } else if (format.equals("IKEY")) {
+                dlssample.info.keywords = chunk.readString(chunk.available());
+            } else if (format.equals("IMED")) {
+                dlssample.info.medium = chunk.readString(chunk.available());
+            } else if (format.equals("ISBJ")) {
+                dlssample.info.subject = chunk.readString(chunk.available());
+            } else if (format.equals("ISRC")) {
+                dlssample.info.source = chunk.readString(chunk.available());
+            } else if (format.equals("ISRF")) {
+                dlssample.info.source_form = chunk.readString(chunk.available());
+            } else if (format.equals("ITCH")) {
+                dlssample.info.technician = chunk.readString(chunk.available());
+            }
+        }
+    }
+
+    public void save(String name) throws IOException {
+        writeSoundbank(new RIFFWriter(name, "DLS "));
+    }
+
+    public void save(File file) throws IOException {
+        writeSoundbank(new RIFFWriter(file, "DLS "));
+    }
+
+    public void save(OutputStream out) throws IOException {
+        writeSoundbank(new RIFFWriter(out, "DLS "));
+    }
+
+    private void writeSoundbank(RIFFWriter writer) throws IOException {
+        RIFFWriter colh_chunk = writer.writeChunk("colh");
+        colh_chunk.writeUnsignedInt(instruments.size());
+
+        if (major != -1 && minor != -1) {
+            RIFFWriter vers_chunk = writer.writeChunk("vers");
+            vers_chunk.writeUnsignedInt(major);
+            vers_chunk.writeUnsignedInt(minor);
+        }
+
+        writeInstruments(writer.writeList("lins"));
+
+        RIFFWriter ptbl = writer.writeChunk("ptbl");
+        ptbl.writeUnsignedInt(8);
+        ptbl.writeUnsignedInt(samples.size());
+        long ptbl_offset = writer.getFilePointer();
+        for (int i = 0; i < samples.size(); i++)
+            ptbl.writeUnsignedInt(0);
+
+        RIFFWriter wvpl = writer.writeList("wvpl");
+        long off = wvpl.getFilePointer();
+        List<Long> offsettable = new ArrayList<Long>();
+        for (DLSSample sample : samples) {
+            offsettable.add(Long.valueOf(wvpl.getFilePointer() - off));
+            writeSample(wvpl.writeList("wave"), sample);
+        }
+
+        // small cheat, we are going to rewrite data back in wvpl
+        long bak = writer.getFilePointer();
+        writer.seek(ptbl_offset);
+        writer.setWriteOverride(true);
+        for (Long offset : offsettable)
+            writer.writeUnsignedInt(offset.longValue());
+        writer.setWriteOverride(false);
+        writer.seek(bak);
+
+        writeInfo(writer.writeList("INFO"), info);
+
+        writer.close();
+    }
+
+    private void writeSample(RIFFWriter writer, DLSSample sample)
+            throws IOException {
+
+        AudioFormat audioformat = sample.getFormat();
+
+        Encoding encoding = audioformat.getEncoding();
+        float sampleRate = audioformat.getSampleRate();
+        int sampleSizeInBits = audioformat.getSampleSizeInBits();
+        int channels = audioformat.getChannels();
+        int frameSize = audioformat.getFrameSize();
+        float frameRate = audioformat.getFrameRate();
+        boolean bigEndian = audioformat.isBigEndian();
+
+        boolean convert_needed = false;
+
+        if (audioformat.getSampleSizeInBits() == 8) {
+            if (!encoding.equals(Encoding.PCM_UNSIGNED)) {
+                encoding = Encoding.PCM_UNSIGNED;
+                convert_needed = true;
+            }
+        } else {
+            if (!encoding.equals(Encoding.PCM_SIGNED)) {
+                encoding = Encoding.PCM_SIGNED;
+                convert_needed = true;
+            }
+            if (bigEndian) {
+                bigEndian = false;
+                convert_needed = true;
+            }
+        }
+
+        if (convert_needed) {
+            audioformat = new AudioFormat(encoding, sampleRate,
+                    sampleSizeInBits, channels, frameSize, frameRate, bigEndian);
+        }
+
+        // fmt
+        RIFFWriter fmt_chunk = writer.writeChunk("fmt ");
+        int sampleformat = 0;
+        if (audioformat.getEncoding().equals(Encoding.PCM_UNSIGNED))
+            sampleformat = 1;
+        else if (audioformat.getEncoding().equals(Encoding.PCM_SIGNED))
+            sampleformat = 1;
+        else if (audioformat.getEncoding().equals(AudioFloatConverter.PCM_FLOAT))
+            sampleformat = 3;
+
+        fmt_chunk.writeUnsignedShort(sampleformat);
+        fmt_chunk.writeUnsignedShort(audioformat.getChannels());
+        fmt_chunk.writeUnsignedInt((long) audioformat.getSampleRate());
+        long srate = ((long)audioformat.getFrameRate())*audioformat.getFrameSize();
+        fmt_chunk.writeUnsignedInt(srate);
+        fmt_chunk.writeUnsignedShort(audioformat.getFrameSize());
+        fmt_chunk.writeUnsignedShort(audioformat.getSampleSizeInBits());
+        fmt_chunk.write(0);
+        fmt_chunk.write(0);
+
+        writeSampleOptions(writer.writeChunk("wsmp"), sample.sampleoptions);
+
+        if (convert_needed) {
+            RIFFWriter data_chunk = writer.writeChunk("data");
+            AudioInputStream stream = AudioSystem.getAudioInputStream(
+                    audioformat, (AudioInputStream)sample.getData());
+            byte[] buff = new byte[1024];
+            int ret;
+            while ((ret = stream.read(buff)) != -1) {
+                data_chunk.write(buff, 0, ret);
+            }
+        } else {
+            RIFFWriter data_chunk = writer.writeChunk("data");
+            ModelByteBuffer databuff = sample.getDataBuffer();
+            databuff.writeTo(data_chunk);
+            /*
+            data_chunk.write(databuff.array(),
+            databuff.arrayOffset(),
+            databuff.capacity());
+             */
+        }
+
+        writeInfo(writer.writeList("INFO"), sample.info);
+    }
+
+    private void writeInstruments(RIFFWriter writer) throws IOException {
+        for (DLSInstrument instrument : instruments) {
+            writeInstrument(writer.writeList("ins "), instrument);
+        }
+    }
+
+    private void writeInstrument(RIFFWriter writer, DLSInstrument instrument)
+            throws IOException {
+
+        int art1_count = 0;
+        int art2_count = 0;
+        for (DLSModulator modulator : instrument.getModulators()) {
+            if (modulator.version == 1)
+                art1_count++;
+            if (modulator.version == 2)
+                art2_count++;
+        }
+        for (DLSRegion region : instrument.regions) {
+            for (DLSModulator modulator : region.getModulators()) {
+                if (modulator.version == 1)
+                    art1_count++;
+                if (modulator.version == 2)
+                    art2_count++;
+            }
+        }
+
+        int version = 1;
+        if (art2_count > 0)
+            version = 2;
+
+        RIFFWriter insh_chunk = writer.writeChunk("insh");
+        insh_chunk.writeUnsignedInt(instrument.getRegions().size());
+        insh_chunk.writeUnsignedInt(instrument.bank +
+                (instrument.druminstrument ? 2147483648L : 0));
+        insh_chunk.writeUnsignedInt(instrument.preset);
+
+        RIFFWriter lrgn = writer.writeList("lrgn");
+        for (DLSRegion region: instrument.regions)
+            writeRegion(lrgn, region, version);
+
+        writeArticulators(writer, instrument.getModulators());
+
+        writeInfo(writer.writeList("INFO"), instrument.info);
+
+    }
+
+    private void writeArticulators(RIFFWriter writer,
+            List<DLSModulator> modulators) throws IOException {
+        int art1_count = 0;
+        int art2_count = 0;
+        for (DLSModulator modulator : modulators) {
+            if (modulator.version == 1)
+                art1_count++;
+            if (modulator.version == 2)
+                art2_count++;
+        }
+        if (art1_count > 0) {
+            RIFFWriter lar1 = writer.writeList("lart");
+            RIFFWriter art1 = lar1.writeChunk("art1");
+            art1.writeUnsignedInt(8);
+            art1.writeUnsignedInt(art1_count);
+            for (DLSModulator modulator : modulators) {
+                if (modulator.version == 1) {
+                    art1.writeUnsignedShort(modulator.source);
+                    art1.writeUnsignedShort(modulator.control);
+                    art1.writeUnsignedShort(modulator.destination);
+                    art1.writeUnsignedShort(modulator.transform);
+                    art1.writeInt(modulator.scale);
+                }
+            }
+        }
+        if (art2_count > 0) {
+            RIFFWriter lar2 = writer.writeList("lar2");
+            RIFFWriter art2 = lar2.writeChunk("art2");
+            art2.writeUnsignedInt(8);
+            art2.writeUnsignedInt(art2_count);
+            for (DLSModulator modulator : modulators) {
+                if (modulator.version == 2) {
+                    art2.writeUnsignedShort(modulator.source);
+                    art2.writeUnsignedShort(modulator.control);
+                    art2.writeUnsignedShort(modulator.destination);
+                    art2.writeUnsignedShort(modulator.transform);
+                    art2.writeInt(modulator.scale);
+                }
+            }
+        }
+    }
+
+    private void writeRegion(RIFFWriter writer, DLSRegion region, int version)
+            throws IOException {
+        RIFFWriter rgns = null;
+        if (version == 1)
+            rgns = writer.writeList("rgn ");
+        if (version == 2)
+            rgns = writer.writeList("rgn2");
+        if (rgns == null)
+            return;
+
+        RIFFWriter rgnh = rgns.writeChunk("rgnh");
+        rgnh.writeUnsignedShort(region.keyfrom);
+        rgnh.writeUnsignedShort(region.keyto);
+        rgnh.writeUnsignedShort(region.velfrom);
+        rgnh.writeUnsignedShort(region.velto);
+        rgnh.writeUnsignedShort(region.options);
+        rgnh.writeUnsignedShort(region.exclusiveClass);
+
+        if (region.sampleoptions != null)
+            writeSampleOptions(rgns.writeChunk("wsmp"), region.sampleoptions);
+
+        if (region.sample != null) {
+            if (samples.indexOf(region.sample) != -1) {
+                RIFFWriter wlnk = rgns.writeChunk("wlnk");
+                wlnk.writeUnsignedShort(region.fusoptions);
+                wlnk.writeUnsignedShort(region.phasegroup);
+                wlnk.writeUnsignedInt(region.channel);
+                wlnk.writeUnsignedInt(samples.indexOf(region.sample));
+            }
+        }
+        writeArticulators(rgns, region.getModulators());
+        rgns.close();
+    }
+
+    private void writeSampleOptions(RIFFWriter wsmp,
+            DLSSampleOptions sampleoptions) throws IOException {
+        wsmp.writeUnsignedInt(20);
+        wsmp.writeUnsignedShort(sampleoptions.unitynote);
+        wsmp.writeShort(sampleoptions.finetune);
+        wsmp.writeInt(sampleoptions.attenuation);
+        wsmp.writeUnsignedInt(sampleoptions.options);
+        wsmp.writeInt(sampleoptions.loops.size());
+
+        for (DLSSampleLoop loop : sampleoptions.loops) {
+            wsmp.writeUnsignedInt(16);
+            wsmp.writeUnsignedInt(loop.type);
+            wsmp.writeUnsignedInt(loop.start);
+            wsmp.writeUnsignedInt(loop.length);
+        }
+    }
+
+    private void writeInfoStringChunk(RIFFWriter writer,
+            String name, String value) throws IOException {
+        if (value == null)
+            return;
+        RIFFWriter chunk = writer.writeChunk(name);
+        chunk.writeString(value);
+        int len = value.getBytes("ascii").length;
+        chunk.write(0);
+        len++;
+        if (len % 2 != 0)
+            chunk.write(0);
+    }
+
+    private void writeInfo(RIFFWriter writer, DLSInfo info) throws IOException {
+        writeInfoStringChunk(writer, "INAM", info.name);
+        writeInfoStringChunk(writer, "ICRD", info.creationDate);
+        writeInfoStringChunk(writer, "IENG", info.engineers);
+        writeInfoStringChunk(writer, "IPRD", info.product);
+        writeInfoStringChunk(writer, "ICOP", info.copyright);
+        writeInfoStringChunk(writer, "ICMT", info.comments);
+        writeInfoStringChunk(writer, "ISFT", info.tools);
+        writeInfoStringChunk(writer, "IARL", info.archival_location);
+        writeInfoStringChunk(writer, "IART", info.artist);
+        writeInfoStringChunk(writer, "ICMS", info.commissioned);
+        writeInfoStringChunk(writer, "IGNR", info.genre);
+        writeInfoStringChunk(writer, "IKEY", info.keywords);
+        writeInfoStringChunk(writer, "IMED", info.medium);
+        writeInfoStringChunk(writer, "ISBJ", info.subject);
+        writeInfoStringChunk(writer, "ISRC", info.source);
+        writeInfoStringChunk(writer, "ISRF", info.source_form);
+        writeInfoStringChunk(writer, "ITCH", info.technician);
+    }
+
+    public DLSInfo getInfo() {
+        return info;
+    }
+
+    public String getName() {
+        return info.name;
+    }
+
+    public String getVersion() {
+        return major + "." + minor;
+    }
+
+    public String getVendor() {
+        return info.engineers;
+    }
+
+    public String getDescription() {
+        return info.comments;
+    }
+
+    public void setName(String s) {
+        info.name = s;
+    }
+
+    public void setVendor(String s) {
+        info.engineers = s;
+    }
+
+    public void setDescription(String s) {
+        info.comments = s;
+    }
+
+    public SoundbankResource[] getResources() {
+        SoundbankResource[] resources = new SoundbankResource[samples.size()];
+        int j = 0;
+        for (int i = 0; i < samples.size(); i++)
+            resources[j++] = samples.get(i);
+        return resources;
+    }
+
+    public DLSInstrument[] getInstruments() {
+        DLSInstrument[] inslist_array =
+                instruments.toArray(new DLSInstrument[instruments.size()]);
+        Arrays.sort(inslist_array, new ModelInstrumentComparator());
+        return inslist_array;
+    }
+
+    public DLSSample[] getSamples() {
+        return samples.toArray(new DLSSample[samples.size()]);
+    }
+
+    public Instrument getInstrument(Patch patch) {
+        int program = patch.getProgram();
+        int bank = patch.getBank();
+        boolean percussion = false;
+        if (patch instanceof ModelPatch)
+            percussion = ((ModelPatch) patch).isPercussion();
+        for (Instrument instrument : instruments) {
+            Patch patch2 = instrument.getPatch();
+            int program2 = patch2.getProgram();
+            int bank2 = patch2.getBank();
+            if (program == program2 && bank == bank2) {
+                boolean percussion2 = false;
+                if (patch2 instanceof ModelPatch)
+                    percussion2 = ((ModelPatch) patch2).isPercussion();
+                if (percussion == percussion2)
+                    return instrument;
+            }
+        }
+        return null;
+    }
+
+    public void addResource(SoundbankResource resource) {
+        if (resource instanceof DLSInstrument)
+            instruments.add((DLSInstrument) resource);
+        if (resource instanceof DLSSample)
+            samples.add((DLSSample) resource);
+    }
+
+    public void removeResource(SoundbankResource resource) {
+        if (resource instanceof DLSInstrument)
+            instruments.remove((DLSInstrument) resource);
+        if (resource instanceof DLSSample)
+            samples.remove((DLSSample) resource);
+    }
+
+    public void addInstrument(DLSInstrument resource) {
+        instruments.add(resource);
+    }
+
+    public void removeInstrument(DLSInstrument resource) {
+        instruments.remove(resource);
+    }
+
+    public long getMajor() {
+        return major;
+    }
+
+    public void setMajor(long major) {
+        this.major = major;
+    }
+
+    public long getMinor() {
+        return minor;
+    }
+
+    public void setMinor(long minor) {
+        this.minor = minor;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSSoundbankReader.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.spi.SoundbankReader;
+
+/**
+ * This class is used to connect the DLSSoundBank class
+ * to the SoundbankReader SPI interface.
+ *
+ * @author Karl Helgason
+ */
+public class DLSSoundbankReader extends SoundbankReader {
+
+    public Soundbank getSoundbank(URL url)
+            throws InvalidMidiDataException, IOException {
+        try {
+            return new DLSSoundbank(url);
+        } catch (RIFFInvalidFormatException e) {
+            return null;
+        } catch(IOException ioe) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        try {
+            stream.mark(512);
+            return new DLSSoundbank(stream);
+        } catch (RIFFInvalidFormatException e) {
+            stream.reset();
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(File file)
+            throws InvalidMidiDataException, IOException {
+        try {
+            return new DLSSoundbank(file);
+        } catch (RIFFInvalidFormatException e) {
+            return null;
+        }
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/DirectAudioDevice.java	Wed Jul 05 16:46:22 2017 +0200
@@ -394,7 +394,12 @@
         private float leftGain, rightGain;
         protected volatile boolean noService = false; // do not run the nService method
 
+        // Guards all native calls.
         protected Object lockNative = new Object();
+        // Guards the lastOpened static variable in implOpen and implClose.
+        protected static Object lockLast = new Object();
+        // Keeps track of last opened line, see implOpen "trick".
+        protected static DirectDL lastOpened;
 
         // CONSTRUCTOR
         protected DirectDL(DataLine.Info info,
@@ -496,20 +501,50 @@
             // align buffer to full frames
             bufferSize = ((int) bufferSize / format.getFrameSize()) * format.getFrameSize();
 
-            id = nOpen(mixerIndex, deviceID, isSource,
-                       encoding,
-                       hardwareFormat.getSampleRate(),
-                       hardwareFormat.getSampleSizeInBits(),
-                       hardwareFormat.getFrameSize(),
-                       hardwareFormat.getChannels(),
-                       hardwareFormat.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED),
-                       hardwareFormat.isBigEndian(),
-                       bufferSize);
+            synchronized(lockLast) {
+                id = nOpen(mixerIndex, deviceID, isSource,
+                        encoding,
+                        hardwareFormat.getSampleRate(),
+                        hardwareFormat.getSampleSizeInBits(),
+                        hardwareFormat.getFrameSize(),
+                        hardwareFormat.getChannels(),
+                        hardwareFormat.getEncoding().equals(
+                            AudioFormat.Encoding.PCM_SIGNED),
+                        hardwareFormat.isBigEndian(),
+                        bufferSize);
 
-            if (id == 0) {
-                // TODO: nicer error messages...
-                throw new LineUnavailableException("line with format "+format+" not supported.");
+                if (id == 0) {
+                    // Bah... Dirty trick. The most likely cause is an application
+                    // already having a line open for this particular hardware
+                    // format and forgetting about it. If so, silently close that
+                    // implementation and try again. Unfortuantely we can only
+                    // open one line per hardware format currently.
+                    if (lastOpened != null
+                            && hardwareFormat.matches(lastOpened.hardwareFormat)) {
+                        lastOpened.implClose();
+                        lastOpened = null;
+
+                        id = nOpen(mixerIndex, deviceID, isSource,
+                                encoding,
+                                hardwareFormat.getSampleRate(),
+                                hardwareFormat.getSampleSizeInBits(),
+                                hardwareFormat.getFrameSize(),
+                                hardwareFormat.getChannels(),
+                                hardwareFormat.getEncoding().equals(
+                                    AudioFormat.Encoding.PCM_SIGNED),
+                                hardwareFormat.isBigEndian(),
+                                bufferSize);
+                    }
+
+                    if (id == 0) {
+                        // TODO: nicer error messages...
+                        throw new LineUnavailableException(
+                            "line with format "+format+" not supported.");
+                    }
+                }
+                lastOpened = this;
             }
+
             this.bufferSize = nGetBufferSize(id, isSource);
             if (this.bufferSize < 1) {
                 // this is an error!
@@ -580,12 +615,12 @@
             }
             synchronized (lockNative) {
                 nStop(id, isSource);
+
+                // need to set doIO to false before notifying the
+                // read/write thread, that's why isStartedRunning()
+                // cannot be used
+                doIO = false;
             }
-
-            // need to set doIO to false before notifying the
-            // read/write thread, that's why isStartedRunning()
-            // cannot be used
-            doIO = false;
             // wake up any waiting threads
             synchronized(lock) {
                 lock.notifyAll();
@@ -614,8 +649,12 @@
             doIO = false;
             long oldID = id;
             id = 0;
-            synchronized (lockNative) {
-                nClose(oldID, isSource);
+            synchronized (lockLast) {
+                synchronized (lockNative) {
+                    nClose(oldID, isSource);
+                    if (lastOpened == this)
+                      lastOpened = null;
+                }
             }
             bytePosition = 0;
             softwareConversionSize = 0;
@@ -630,7 +669,8 @@
             }
             int a = 0;
             synchronized (lockNative) {
-                a = nAvailable(id, isSource);
+                if (doIO)
+                    a = nAvailable(id, isSource);
             }
             return a;
         }
@@ -644,9 +684,9 @@
             int counter = 0;
             long startPos = getLongFramePosition();
             boolean posChanged = false;
-            while (!drained && doIO) {
+            while (!drained) {
                 synchronized (lockNative) {
-                    if ((id == 0) || !nIsStillDraining(id, isSource))
+                    if ((id == 0) || (!doIO) || !nIsStillDraining(id, isSource))
                         break;
                 }
                 // check every now and then for a new position
@@ -686,7 +726,7 @@
                     lock.notifyAll();
                 }
                 synchronized (lockNative) {
-                    if (id != 0) {
+                    if (id != 0 && doIO) {
                         // then flush native buffers
                         nFlush(id, isSource);
                     }
@@ -697,9 +737,10 @@
 
         // replacement for getFramePosition (see AbstractDataLine)
         public long getLongFramePosition() {
-            long pos;
+            long pos = 0;
             synchronized (lockNative) {
-                pos = nGetBytePosition(id, isSource, bytePosition);
+                if (doIO)
+                    pos = nGetBytePosition(id, isSource, bytePosition);
             }
             // hack because ALSA sometimes reports wrong framepos
             if (pos < 0) {
@@ -745,11 +786,12 @@
             }
             int written = 0;
             while (!flushing) {
-                int thisWritten;
+                int thisWritten = 0;
                 synchronized (lockNative) {
-                    thisWritten = nWrite(id, b, off, len,
-                            softwareConversionSize,
-                            leftGain, rightGain);
+                    if (doIO)
+                        thisWritten = nWrite(id, b, off, len,
+                                softwareConversionSize,
+                                leftGain, rightGain);
                     if (thisWritten < 0) {
                         // error in native layer
                         break;
@@ -972,9 +1014,10 @@
             }
             int read = 0;
             while (doIO && !flushing) {
-                int thisRead;
+                int thisRead = 0;
                 synchronized (lockNative) {
-                    thisRead = nRead(id, b, off, len, softwareConversionSize);
+                    if (doIO)
+                        thisRead = nRead(id, b, off, len, softwareConversionSize);
                     if (thisRead < 0) {
                         // error in native layer
                         break;
@@ -1209,7 +1252,8 @@
             // set new native position (if necessary)
             // this must come after the flush!
             synchronized (lockNative) {
-                nSetBytePosition(id, isSource, frames * frameSize);
+                if (doIO)
+                    nSetBytePosition(id, isSource, frames * frameSize);
             }
 
             if (Printer.debug) Printer.debug("  DirectClip.setFramePosition: "
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/EmergencySoundbank.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,2695 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Random;
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * Emergency Soundbank generator.
+ * Used when no other default soundbank can be found.
+ *
+ * @author Karl Helgason
+ */
+public class EmergencySoundbank {
+
+    private final static String[] general_midi_instruments = {
+        "Acoustic Grand Piano",
+        "Bright Acoustic Piano",
+        "Electric Grand Piano",
+        "Honky-tonk Piano",
+        "Electric Piano 1",
+        "Electric Piano 2",
+        "Harpsichord",
+        "Clavi",
+        "Celesta",
+        "Glockenspiel",
+        "Music Box",
+        "Vibraphone",
+        "Marimba",
+        "Xylophone",
+        "Tubular Bells",
+        "Dulcimer",
+        "Drawbar Organ",
+        "Percussive Organ",
+        "Rock Organ",
+        "Church Organ",
+        "Reed Organ",
+        "Accordion",
+        "Harmonica",
+        "Tango Accordion",
+        "Acoustic Guitar (nylon)",
+        "Acoustic Guitar (steel)",
+        "Electric Guitar (jazz)",
+        "Electric Guitar (clean)",
+        "Electric Guitar (muted)",
+        "Overdriven Guitar",
+        "Distortion Guitar",
+        "Guitar harmonics",
+        "Acoustic Bass",
+        "Electric Bass (finger)",
+        "Electric Bass (pick)",
+        "Fretless Bass",
+        "Slap Bass 1",
+        "Slap Bass 2",
+        "Synth Bass 1",
+        "Synth Bass 2",
+        "Violin",
+        "Viola",
+        "Cello",
+        "Contrabass",
+        "Tremolo Strings",
+        "Pizzicato Strings",
+        "Orchestral Harp",
+        "Timpani",
+        "String Ensemble 1",
+        "String Ensemble 2",
+        "SynthStrings 1",
+        "SynthStrings 2",
+        "Choir Aahs",
+        "Voice Oohs",
+        "Synth Voice",
+        "Orchestra Hit",
+        "Trumpet",
+        "Trombone",
+        "Tuba",
+        "Muted Trumpet",
+        "French Horn",
+        "Brass Section",
+        "SynthBrass 1",
+        "SynthBrass 2",
+        "Soprano Sax",
+        "Alto Sax",
+        "Tenor Sax",
+        "Baritone Sax",
+        "Oboe",
+        "English Horn",
+        "Bassoon",
+        "Clarinet",
+        "Piccolo",
+        "Flute",
+        "Recorder",
+        "Pan Flute",
+        "Blown Bottle",
+        "Shakuhachi",
+        "Whistle",
+        "Ocarina",
+        "Lead 1 (square)",
+        "Lead 2 (sawtooth)",
+        "Lead 3 (calliope)",
+        "Lead 4 (chiff)",
+        "Lead 5 (charang)",
+        "Lead 6 (voice)",
+        "Lead 7 (fifths)",
+        "Lead 8 (bass + lead)",
+        "Pad 1 (new age)",
+        "Pad 2 (warm)",
+        "Pad 3 (polysynth)",
+        "Pad 4 (choir)",
+        "Pad 5 (bowed)",
+        "Pad 6 (metallic)",
+        "Pad 7 (halo)",
+        "Pad 8 (sweep)",
+        "FX 1 (rain)",
+        "FX 2 (soundtrack)",
+        "FX 3 (crystal)",
+        "FX 4 (atmosphere)",
+        "FX 5 (brightness)",
+        "FX 6 (goblins)",
+        "FX 7 (echoes)",
+        "FX 8 (sci-fi)",
+        "Sitar",
+        "Banjo",
+        "Shamisen",
+        "Koto",
+        "Kalimba",
+        "Bag pipe",
+        "Fiddle",
+        "Shanai",
+        "Tinkle Bell",
+        "Agogo",
+        "Steel Drums",
+        "Woodblock",
+        "Taiko Drum",
+        "Melodic Tom",
+        "Synth Drum",
+        "Reverse Cymbal",
+        "Guitar Fret Noise",
+        "Breath Noise",
+        "Seashore",
+        "Bird Tweet",
+        "Telephone Ring",
+        "Helicopter",
+        "Applause",
+        "Gunshot"
+    };
+
+    public static SF2Soundbank createSoundbank() throws Exception {
+        SF2Soundbank sf2 = new SF2Soundbank();
+        sf2.setName("Emergency GM sound set");
+        sf2.setVendor("Generated");
+        sf2.setDescription("Emergency generated soundbank");
+
+        /*
+         *  percussion instruments
+         */
+
+        SF2Layer bass_drum = new_bass_drum(sf2);
+        SF2Layer snare_drum = new_snare_drum(sf2);
+        SF2Layer tom = new_tom(sf2);
+        SF2Layer open_hihat = new_open_hihat(sf2);
+        SF2Layer closed_hihat = new_closed_hihat(sf2);
+        SF2Layer crash_cymbal = new_crash_cymbal(sf2);
+        SF2Layer side_stick = new_side_stick(sf2);
+
+        SF2Layer[] drums = new SF2Layer[128];
+        drums[35] = bass_drum;
+        drums[36] = bass_drum;
+        drums[38] = snare_drum;
+        drums[40] = snare_drum;
+        drums[41] = tom;
+        drums[43] = tom;
+        drums[45] = tom;
+        drums[47] = tom;
+        drums[48] = tom;
+        drums[50] = tom;
+        drums[42] = closed_hihat;
+        drums[44] = closed_hihat;
+        drums[46] = open_hihat;
+        drums[49] = crash_cymbal;
+        drums[51] = crash_cymbal;
+        drums[52] = crash_cymbal;
+        drums[55] = crash_cymbal;
+        drums[57] = crash_cymbal;
+        drums[59] = crash_cymbal;
+
+        // Use side_stick for missing drums:
+        drums[37] = side_stick;
+        drums[39] = side_stick;
+        drums[53] = side_stick;
+        drums[54] = side_stick;
+        drums[56] = side_stick;
+        drums[58] = side_stick;
+        drums[69] = side_stick;
+        drums[70] = side_stick;
+        drums[75] = side_stick;
+        drums[60] = side_stick;
+        drums[61] = side_stick;
+        drums[62] = side_stick;
+        drums[63] = side_stick;
+        drums[64] = side_stick;
+        drums[65] = side_stick;
+        drums[66] = side_stick;
+        drums[67] = side_stick;
+        drums[68] = side_stick;
+        drums[71] = side_stick;
+        drums[72] = side_stick;
+        drums[73] = side_stick;
+        drums[74] = side_stick;
+        drums[76] = side_stick;
+        drums[77] = side_stick;
+        drums[78] = side_stick;
+        drums[79] = side_stick;
+        drums[80] = side_stick;
+        drums[81] = side_stick;
+
+
+        SF2Instrument drum_instrument = new SF2Instrument(sf2);
+        drum_instrument.setName("Standard Kit");
+        drum_instrument.setPatch(new ModelPatch(0, 0, true));
+        sf2.addInstrument(drum_instrument);
+        for (int i = 0; i < drums.length; i++) {
+            if (drums[i] != null) {
+                SF2InstrumentRegion region = new SF2InstrumentRegion();
+                region.setLayer(drums[i]);
+                region.putBytes(SF2InstrumentRegion.GENERATOR_KEYRANGE,
+                        new byte[]{(byte) i, (byte) i});
+                drum_instrument.getRegions().add(region);
+            }
+        }
+
+
+        /*
+         *  melodic instruments
+         */
+
+        SF2Layer gpiano = new_gpiano(sf2);
+        SF2Layer gpiano2 = new_gpiano2(sf2);
+        SF2Layer gpiano_hammer = new_piano_hammer(sf2);
+        SF2Layer piano1 = new_piano1(sf2);
+        SF2Layer epiano1 = new_epiano1(sf2);
+        SF2Layer epiano2 = new_epiano2(sf2);
+
+        SF2Layer guitar = new_guitar1(sf2);
+        SF2Layer guitar_pick = new_guitar_pick(sf2);
+        SF2Layer guitar_dist = new_guitar_dist(sf2);
+        SF2Layer bass1 = new_bass1(sf2);
+        SF2Layer bass2 = new_bass2(sf2);
+        SF2Layer synthbass = new_synthbass(sf2);
+        SF2Layer string2 = new_string2(sf2);
+        SF2Layer orchhit = new_orchhit(sf2);
+        SF2Layer choir = new_choir(sf2);
+        SF2Layer solostring = new_solostring(sf2);
+        SF2Layer organ = new_organ(sf2);
+        SF2Layer ch_organ = new_ch_organ(sf2);
+        SF2Layer bell = new_bell(sf2);
+        SF2Layer flute = new_flute(sf2);
+
+        SF2Layer timpani = new_timpani(sf2);
+        SF2Layer melodic_toms = new_melodic_toms(sf2);
+        SF2Layer trumpet = new_trumpet(sf2);
+        SF2Layer trombone = new_trombone(sf2);
+        SF2Layer brass_section = new_brass_section(sf2);
+        SF2Layer horn = new_horn(sf2);
+        SF2Layer sax = new_sax(sf2);
+        SF2Layer oboe = new_oboe(sf2);
+        SF2Layer bassoon = new_bassoon(sf2);
+        SF2Layer clarinet = new_clarinet(sf2);
+        SF2Layer reverse_cymbal = new_reverse_cymbal(sf2);
+
+        SF2Layer defaultsound = piano1;
+
+        newInstrument(sf2, "Piano", new Patch(0, 0), gpiano, gpiano_hammer);
+        newInstrument(sf2, "Piano", new Patch(0, 1), gpiano2, gpiano_hammer);
+        newInstrument(sf2, "Piano", new Patch(0, 2), piano1);
+        {
+            SF2Instrument ins = newInstrument(sf2, "Honky-tonk Piano",
+                    new Patch(0, 3), piano1, piano1);
+            SF2InstrumentRegion region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 80);
+            region.putInteger(SF2Region.GENERATOR_FINETUNE, 30);
+            region = ins.getRegions().get(1);
+            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 30);
+        }
+        newInstrument(sf2, "Rhodes", new Patch(0, 4), epiano2);
+        newInstrument(sf2, "Rhodes", new Patch(0, 5), epiano2);
+        newInstrument(sf2, "Clavinet", new Patch(0, 6), epiano1);
+        newInstrument(sf2, "Clavinet", new Patch(0, 7), epiano1);
+        newInstrument(sf2, "Rhodes", new Patch(0, 8), epiano2);
+        newInstrument(sf2, "Bell", new Patch(0, 9), bell);
+        newInstrument(sf2, "Bell", new Patch(0, 10), bell);
+        newInstrument(sf2, "Vibraphone", new Patch(0, 11), bell);
+        newInstrument(sf2, "Marimba", new Patch(0, 12), bell);
+        newInstrument(sf2, "Marimba", new Patch(0, 13), bell);
+        newInstrument(sf2, "Bell", new Patch(0, 14), bell);
+        newInstrument(sf2, "Rock Organ", new Patch(0, 15), organ);
+        newInstrument(sf2, "Rock Organ", new Patch(0, 16), organ);
+        newInstrument(sf2, "Perc Organ", new Patch(0, 17), organ);
+        newInstrument(sf2, "Rock Organ", new Patch(0, 18), organ);
+        newInstrument(sf2, "Church Organ", new Patch(0, 19), ch_organ);
+        newInstrument(sf2, "Accordion", new Patch(0, 20), organ);
+        newInstrument(sf2, "Accordion", new Patch(0, 21), organ);
+        newInstrument(sf2, "Accordion", new Patch(0, 22), organ);
+        newInstrument(sf2, "Accordion", new Patch(0, 23), organ);
+        newInstrument(sf2, "Guitar", new Patch(0, 24), guitar, guitar_pick);
+        newInstrument(sf2, "Guitar", new Patch(0, 25), guitar, guitar_pick);
+        newInstrument(sf2, "Guitar", new Patch(0, 26), guitar, guitar_pick);
+        newInstrument(sf2, "Guitar", new Patch(0, 27), guitar, guitar_pick);
+        newInstrument(sf2, "Guitar", new Patch(0, 28), guitar, guitar_pick);
+        newInstrument(sf2, "Distorted Guitar", new Patch(0, 29), guitar_dist);
+        newInstrument(sf2, "Distorted Guitar", new Patch(0, 30), guitar_dist);
+        newInstrument(sf2, "Guitar", new Patch(0, 31), guitar, guitar_pick);
+        newInstrument(sf2, "Finger Bass", new Patch(0, 32), bass1);
+        newInstrument(sf2, "Finger Bass", new Patch(0, 33), bass1);
+        newInstrument(sf2, "Finger Bass", new Patch(0, 34), bass1);
+        newInstrument(sf2, "Frettless Bass", new Patch(0, 35), bass2);
+        newInstrument(sf2, "Frettless Bass", new Patch(0, 36), bass2);
+        newInstrument(sf2, "Frettless Bass", new Patch(0, 37), bass2);
+        newInstrument(sf2, "Synth Bass1", new Patch(0, 38), synthbass);
+        newInstrument(sf2, "Synth Bass2", new Patch(0, 39), synthbass);
+        newInstrument(sf2, "Solo String", new Patch(0, 40), string2, solostring);
+        newInstrument(sf2, "Solo String", new Patch(0, 41), string2, solostring);
+        newInstrument(sf2, "Solo String", new Patch(0, 42), string2, solostring);
+        newInstrument(sf2, "Solo String", new Patch(0, 43), string2, solostring);
+        newInstrument(sf2, "Solo String", new Patch(0, 44), string2, solostring);
+        newInstrument(sf2, "Def", new Patch(0, 45), defaultsound);
+        newInstrument(sf2, "Harp", new Patch(0, 46), bell);
+        newInstrument(sf2, "Timpani", new Patch(0, 47), timpani);
+        newInstrument(sf2, "Strings", new Patch(0, 48), string2);
+        SF2Instrument slow_strings =
+                newInstrument(sf2, "Slow Strings", new Patch(0, 49), string2);
+        SF2InstrumentRegion region = slow_strings.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, 2500);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 2000);
+        newInstrument(sf2, "Synth Strings", new Patch(0, 50), string2);
+        newInstrument(sf2, "Synth Strings", new Patch(0, 51), string2);
+
+
+        newInstrument(sf2, "Choir", new Patch(0, 52), choir);
+        newInstrument(sf2, "Choir", new Patch(0, 53), choir);
+        newInstrument(sf2, "Choir", new Patch(0, 54), choir);
+        {
+            SF2Instrument ins = newInstrument(sf2, "Orch Hit",
+                    new Patch(0, 55), orchhit, orchhit, timpani);
+            region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_COARSETUNE, -12);
+            region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        }
+        newInstrument(sf2, "Trumpet", new Patch(0, 56), trumpet);
+        newInstrument(sf2, "Trombone", new Patch(0, 57), trombone);
+        newInstrument(sf2, "Trombone", new Patch(0, 58), trombone);
+        newInstrument(sf2, "Trumpet", new Patch(0, 59), trumpet);
+        newInstrument(sf2, "Horn", new Patch(0, 60), horn);
+        newInstrument(sf2, "Brass Section", new Patch(0, 61), brass_section);
+        newInstrument(sf2, "Brass Section", new Patch(0, 62), brass_section);
+        newInstrument(sf2, "Brass Section", new Patch(0, 63), brass_section);
+        newInstrument(sf2, "Sax", new Patch(0, 64), sax);
+        newInstrument(sf2, "Sax", new Patch(0, 65), sax);
+        newInstrument(sf2, "Sax", new Patch(0, 66), sax);
+        newInstrument(sf2, "Sax", new Patch(0, 67), sax);
+        newInstrument(sf2, "Oboe", new Patch(0, 68), oboe);
+        newInstrument(sf2, "Horn", new Patch(0, 69), horn);
+        newInstrument(sf2, "Bassoon", new Patch(0, 70), bassoon);
+        newInstrument(sf2, "Clarinet", new Patch(0, 71), clarinet);
+        newInstrument(sf2, "Flute", new Patch(0, 72), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 73), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 74), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 75), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 76), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 77), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 78), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 79), flute);
+        newInstrument(sf2, "Organ", new Patch(0, 80), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 81), organ);
+        newInstrument(sf2, "Flute", new Patch(0, 82), flute);
+        newInstrument(sf2, "Organ", new Patch(0, 83), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 84), organ);
+        newInstrument(sf2, "Choir", new Patch(0, 85), choir);
+        newInstrument(sf2, "Organ", new Patch(0, 86), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 87), organ);
+        newInstrument(sf2, "Synth Strings", new Patch(0, 88), string2);
+        newInstrument(sf2, "Organ", new Patch(0, 89), organ);
+        newInstrument(sf2, "Def", new Patch(0, 90), defaultsound);
+        newInstrument(sf2, "Choir", new Patch(0, 91), choir);
+        newInstrument(sf2, "Organ", new Patch(0, 92), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 93), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 94), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 95), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 96), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 97), organ);
+        newInstrument(sf2, "Bell", new Patch(0, 98), bell);
+        newInstrument(sf2, "Organ", new Patch(0, 99), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 100), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 101), organ);
+        newInstrument(sf2, "Def", new Patch(0, 102), defaultsound);
+        newInstrument(sf2, "Synth Strings", new Patch(0, 103), string2);
+        newInstrument(sf2, "Def", new Patch(0, 104), defaultsound);
+        newInstrument(sf2, "Def", new Patch(0, 105), defaultsound);
+        newInstrument(sf2, "Def", new Patch(0, 106), defaultsound);
+        newInstrument(sf2, "Def", new Patch(0, 107), defaultsound);
+        newInstrument(sf2, "Marimba", new Patch(0, 108), bell);
+        newInstrument(sf2, "Sax", new Patch(0, 109), sax);
+        newInstrument(sf2, "Solo String", new Patch(0, 110), string2, solostring);
+        newInstrument(sf2, "Oboe", new Patch(0, 111), oboe);
+        newInstrument(sf2, "Bell", new Patch(0, 112), bell);
+        newInstrument(sf2, "Melodic Toms", new Patch(0, 113), melodic_toms);
+        newInstrument(sf2, "Marimba", new Patch(0, 114), bell);
+        newInstrument(sf2, "Melodic Toms", new Patch(0, 115), melodic_toms);
+        newInstrument(sf2, "Melodic Toms", new Patch(0, 116), melodic_toms);
+        newInstrument(sf2, "Melodic Toms", new Patch(0, 117), melodic_toms);
+        newInstrument(sf2, "Reverse Cymbal", new Patch(0, 118), reverse_cymbal);
+        newInstrument(sf2, "Reverse Cymbal", new Patch(0, 119), reverse_cymbal);
+        newInstrument(sf2, "Guitar", new Patch(0, 120), guitar);
+        newInstrument(sf2, "Def", new Patch(0, 121), defaultsound);
+        {
+            SF2Instrument ins = newInstrument(sf2, "Seashore/Reverse Cymbal",
+                    new Patch(0, 122), reverse_cymbal);
+            region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+            region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 18500);
+            region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 4500);
+            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, -4500);
+        }
+        {
+            SF2Instrument ins = newInstrument(sf2, "Bird/Flute",
+                    new Patch(0, 123), flute);
+            region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_COARSETUNE, 24);
+            region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, -3000);
+            region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        }
+        newInstrument(sf2, "Def", new Patch(0, 124), side_stick);
+        {
+            SF2Instrument ins = newInstrument(sf2, "Seashore/Reverse Cymbal",
+                    new Patch(0, 125), reverse_cymbal);
+            region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+            region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 18500);
+            region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 4500);
+            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, -4500);
+        }
+        newInstrument(sf2, "Applause/crash_cymbal",
+                new Patch(0, 126), crash_cymbal);
+        newInstrument(sf2, "Gunshot/side_stick", new Patch(0, 127), side_stick);
+
+        for (SF2Instrument instrument : sf2.getInstruments()) {
+            Patch patch = instrument.getPatch();
+            if (patch instanceof ModelPatch) {
+                if (((ModelPatch) patch).isPercussion())
+                    continue;
+            }
+            instrument.setName(general_midi_instruments[patch.getProgram()]);
+        }
+
+        return sf2;
+
+    }
+
+    public static SF2Layer new_bell(SF2Soundbank sf2) {
+        Random random = new Random(102030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.01;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.00001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double detune = 1 + (random.nextDouble() * 2 - 1) * 0.01;
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1) * detune, w, a);
+            a *= a_step;
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base);
+        SF2Layer layer = newLayer(sf2, "EPiano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 1200);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        return layer;
+    }
+
+    public static SF2Layer new_guitar1(SF2Soundbank sf2) {
+
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.01;
+        double end_w = 0.01;
+        double start_a = 2;
+        double end_a = 0.01;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+
+        double[] aa = new double[40];
+        for (int i = 0; i < 40; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] = 2;
+        aa[1] = 0.5;
+        aa[2] = 0.45;
+        aa[3] = 0.2;
+        aa[4] = 1;
+        aa[5] = 0.5;
+        aa[6] = 2;
+        aa[7] = 1;
+        aa[8] = 0.5;
+        aa[9] = 1;
+        aa[9] = 0.5;
+        aa[10] = 0.2;
+        aa[11] = 1;
+        aa[12] = 0.7;
+        aa[13] = 0.5;
+        aa[14] = 1;
+
+        for (int i = 0; i < 40; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Guitar", data, base);
+        SF2Layer layer = newLayer(sf2, "Guitar", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 2400);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -100);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -6000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -20);
+        return layer;
+    }
+
+    public static SF2Layer new_guitar_dist(SF2Soundbank sf2) {
+
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.01;
+        double end_w = 0.01;
+        double start_a = 2;
+        double end_a = 0.01;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+
+        double[] aa = new double[40];
+        for (int i = 0; i < 40; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] = 5;
+        aa[1] = 2;
+        aa[2] = 0.45;
+        aa[3] = 0.2;
+        aa[4] = 1;
+        aa[5] = 0.5;
+        aa[6] = 2;
+        aa[7] = 1;
+        aa[8] = 0.5;
+        aa[9] = 1;
+        aa[9] = 0.5;
+        aa[10] = 0.2;
+        aa[11] = 1;
+        aa[12] = 0.7;
+        aa[13] = 0.5;
+        aa[14] = 1;
+
+        for (int i = 0; i < 40; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+
+        SF2Sample sample = newSimpleFFTSample_dist(sf2, "Distorted Guitar",
+                data, base, 10000.0);
+
+
+        SF2Layer layer = newLayer(sf2, "Distorted Guitar", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        //region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 2400);
+        //region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 200);
+
+        //region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -100);
+        //region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -1000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 8000);
+        //region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -20);
+        return layer;
+    }
+
+    public static SF2Layer new_guitar_pick(SF2Soundbank sf2) {
+
+        double datab[];
+
+        // Make treble part
+        {
+            int m = 2;
+            int fftlen = 4096 * m;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 2048 * m; i++) {
+                data[i] *= Math.exp(-Math.abs((i - 23) / ((double) m)) * 1.2)
+                        + Math.exp(-Math.abs((i - 40) / ((double) m)) * 0.9);
+            }
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.8);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9994;
+            }
+            datab = data;
+
+            fadeUp(data, 80);
+        }
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Guitar Noise", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Guitar Noise");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+//        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+/*
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 0);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINMODENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -11000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 12000);
+         */
+
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_gpiano(SF2Soundbank sf2) {
+        //Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 15.0);
+
+        double[] aa = new double[30];
+        for (int i = 0; i < 30; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 2;
+        //aa[2] *= 0.1;
+        aa[4] *= 2;
+
+
+        aa[12] *= 0.9;
+        aa[13] *= 0.7;
+        for (int i = 14; i < 30; i++) {
+            aa[i] *= 0.5;
+        }
+
+
+        for (int i = 0; i < 30; i++) {
+            //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001;
+            double w = 0.2;
+            double ai = aa[i];
+            if (i > 10) {
+                w = 5;
+                ai *= 10;
+            }
+            int adjust = 0;
+            if (i > 5) {
+                adjust = (i - 5) * 7;
+            }
+            complexGaussianDist(data, base * (i + 1) + adjust, w, ai);
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Grand Piano", data, base, 200);
+        SF2Layer layer = newLayer(sf2, "Grand Piano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -7000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 18000);
+        return layer;
+    }
+
+    public static SF2Layer new_gpiano2(SF2Soundbank sf2) {
+        //Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 20.0);
+
+        double[] aa = new double[30];
+        for (int i = 0; i < 30; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 1;
+        //aa[2] *= 0.1;
+        aa[4] *= 2;
+
+
+        aa[12] *= 0.9;
+        aa[13] *= 0.7;
+        for (int i = 14; i < 30; i++) {
+            aa[i] *= 0.5;
+        }
+
+
+        for (int i = 0; i < 30; i++) {
+            //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001;
+            double w = 0.2;
+            double ai = aa[i];
+            if (i > 10) {
+                w = 5;
+                ai *= 10;
+            }
+            int adjust = 0;
+            if (i > 5) {
+                adjust = (i - 5) * 7;
+            }
+            complexGaussianDist(data, base * (i + 1) + adjust, w, ai);
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Grand Piano", data, base, 200);
+        SF2Layer layer = newLayer(sf2, "Grand Piano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -7000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 18000);
+        return layer;
+    }
+
+    public static SF2Layer new_piano_hammer(SF2Soundbank sf2) {
+
+        double datab[];
+
+        // Make treble part
+        {
+            int m = 2;
+            int fftlen = 4096 * m;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 2048 * m; i++)
+                data[i] *= Math.exp(-Math.abs((i - 37) / ((double) m)) * 0.05);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.6);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9997;
+            }
+            datab = data;
+
+            fadeUp(data, 80);
+        }
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Piano Hammer", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Piano Hammer");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+/*
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 0);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINMODENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -11000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 12000);
+         */
+
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_piano1(SF2Soundbank sf2) {
+        //Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_a = 0.2;
+        double end_a = 0.0001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+
+        double[] aa = new double[30];
+        for (int i = 0; i < 30; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 5;
+        aa[2] *= 0.1;
+        aa[7] *= 5;
+
+
+        for (int i = 0; i < 30; i++) {
+            //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001;
+            double w = 0.2;
+            double ai = aa[i];
+            if (i > 12) {
+                w = 5;
+                ai *= 10;
+            }
+            int adjust = 0;
+            if (i > 5) {
+                adjust = (i - 5) * 7;
+            }
+            complexGaussianDist(data, base * (i + 1) + adjust, w, ai);
+        }
+
+        complexGaussianDist(data, base * (15.5), 1, 0.1);
+        complexGaussianDist(data, base * (17.5), 1, 0.01);
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base, 200);
+        SF2Layer layer = newLayer(sf2, "EPiano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -1200);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        return layer;
+    }
+
+    public static SF2Layer new_epiano1(SF2Soundbank sf2) {
+        Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.05;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.0001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double detune = 1 + (random.nextDouble() * 2 - 1) * 0.0001;
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1) * detune, w, a);
+            a *= a_step;
+        }
+
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base);
+        SF2Layer layer = newLayer(sf2, "EPiano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 1200);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        return layer;
+    }
+
+    public static SF2Layer new_epiano2(SF2Soundbank sf2) {
+        Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.01;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.00001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double detune = 1 + (random.nextDouble() * 2 - 1) * 0.0001;
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1) * detune, w, a);
+            a *= a_step;
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base);
+        SF2Layer layer = newLayer(sf2, "EPiano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 8000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 2400);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        return layer;
+    }
+
+    public static SF2Layer new_bass1(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.05;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.02;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 25.0);
+
+        double[] aa = new double[25];
+        for (int i = 0; i < 25; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 8;
+        aa[1] *= 4;
+        aa[3] *= 8;
+        aa[5] *= 8;
+
+        for (int i = 0; i < 25; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Bass", data, base);
+        SF2Layer layer = newLayer(sf2, "Bass", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 11000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        return layer;
+    }
+
+    public static SF2Layer new_synthbass(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.05;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.02;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 25.0);
+
+        double[] aa = new double[25];
+        for (int i = 0; i < 25; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 16;
+        aa[1] *= 4;
+        aa[3] *= 16;
+        aa[5] *= 8;
+
+        for (int i = 0; i < 25; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Bass", data, base);
+        SF2Layer layer = newLayer(sf2, "Bass", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -3000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 8000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        return layer;
+    }
+
+    public static SF2Layer new_bass2(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.05;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.002;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 25.0);
+
+        double[] aa = new double[25];
+        for (int i = 0; i < 25; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 8;
+        aa[1] *= 4;
+        aa[3] *= 8;
+        aa[5] *= 8;
+
+        for (int i = 0; i < 25; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Bass2", data, base);
+        SF2Layer layer = newLayer(sf2, "Bass2", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -8000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        return layer;
+    }
+
+    public static SF2Layer new_solostring(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 2;
+        double end_w = 2;
+        double start_a = 0.2;
+        double end_a = 0.01;
+
+        double[] aa = new double[18];
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < aa.length; i++) {
+            a *= a_step;
+            aa[i] = a;
+        }
+
+        aa[0] *= 5;
+        aa[1] *= 5;
+        aa[2] *= 5;
+        aa[3] *= 4;
+        aa[4] *= 4;
+        aa[5] *= 3;
+        aa[6] *= 3;
+        aa[7] *= 2;
+
+        for (int i = 0; i < aa.length; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, a);
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base);
+        SF2Layer layer = newLayer(sf2, "Strings", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        region.putInteger(SF2Region.GENERATOR_FREQVIBLFO, -1000);
+        region.putInteger(SF2Region.GENERATOR_VIBLFOTOPITCH, 15);
+        return layer;
+
+    }
+
+    public static SF2Layer new_orchhit(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 2;
+        double end_w = 80;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, a);
+            a *= a_step;
+        }
+        complexGaussianDist(data, base * 4, 300, 1);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Och Strings", data, base);
+        SF2Layer layer = newLayer(sf2, "Och Strings", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 200);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 200);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_string2(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 2;
+        double end_w = 80;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, a);
+            a *= a_step;
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base);
+        SF2Layer layer = newLayer(sf2, "Strings", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_choir(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 2;
+        double end_w = 80;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        double[] aa = new double[40];
+        for (int i = 0; i < aa.length; i++) {
+            a *= a_step;
+            aa[i] = a;
+        }
+
+        aa[5] *= 0.1;
+        aa[6] *= 0.01;
+        aa[7] *= 0.1;
+        aa[8] *= 0.1;
+
+        for (int i = 0; i < aa.length; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base);
+        SF2Layer layer = newLayer(sf2, "Strings", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_organ(SF2Soundbank sf2) {
+        Random random = new Random(102030201);
+        int x = 1;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+        double start_w = 0.01;
+        double end_w = 0.01;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+
+        for (int i = 0; i < 12; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w,
+                    a * (0.5 + 3 * (random.nextDouble())));
+            a *= a_step;
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Organ", data, base);
+        SF2Layer layer = newLayer(sf2, "Organ", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_ch_organ(SF2Soundbank sf2) {
+        int x = 1;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+        double start_w = 0.01;
+        double end_w = 0.01;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 60.0);
+
+        double[] aa = new double[60];
+        for (int i = 0; i < aa.length; i++) {
+            a *= a_step;
+            aa[i] = a;
+        }
+
+        aa[0] *= 5;
+        aa[1] *= 2;
+        aa[2] = 0;
+        aa[4] = 0;
+        aa[5] = 0;
+        aa[7] *= 7;
+        aa[9] = 0;
+        aa[10] = 0;
+        aa[12] = 0;
+        aa[15] *= 7;
+        aa[18] = 0;
+        aa[20] = 0;
+        aa[24] = 0;
+        aa[27] *= 5;
+        aa[29] = 0;
+        aa[30] = 0;
+        aa[33] = 0;
+        aa[36] *= 4;
+        aa[37] = 0;
+        aa[39] = 0;
+        aa[42] = 0;
+        aa[43] = 0;
+        aa[47] = 0;
+        aa[50] *= 4;
+        aa[52] = 0;
+        aa[55] = 0;
+        aa[57] = 0;
+
+
+        aa[10] *= 0.1;
+        aa[11] *= 0.1;
+        aa[12] *= 0.1;
+        aa[13] *= 0.1;
+
+        aa[17] *= 0.1;
+        aa[18] *= 0.1;
+        aa[19] *= 0.1;
+        aa[20] *= 0.1;
+
+        for (int i = 0; i < 60; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+            a *= a_step;
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Organ", data, base);
+        SF2Layer layer = newLayer(sf2, "Organ", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -10000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        return layer;
+
+    }
+
+    public static SF2Layer new_flute(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        complexGaussianDist(data, base * 1, 0.001, 0.5);
+        complexGaussianDist(data, base * 2, 0.001, 0.5);
+        complexGaussianDist(data, base * 3, 0.001, 0.5);
+        complexGaussianDist(data, base * 4, 0.01, 0.5);
+
+        complexGaussianDist(data, base * 4, 100, 120);
+        complexGaussianDist(data, base * 6, 100, 40);
+        complexGaussianDist(data, base * 8, 100, 80);
+
+        complexGaussianDist(data, base * 5, 0.001, 0.05);
+        complexGaussianDist(data, base * 6, 0.001, 0.06);
+        complexGaussianDist(data, base * 7, 0.001, 0.04);
+        complexGaussianDist(data, base * 8, 0.005, 0.06);
+        complexGaussianDist(data, base * 9, 0.005, 0.06);
+        complexGaussianDist(data, base * 10, 0.01, 0.1);
+        complexGaussianDist(data, base * 11, 0.08, 0.7);
+        complexGaussianDist(data, base * 12, 0.08, 0.6);
+        complexGaussianDist(data, base * 13, 0.08, 0.6);
+        complexGaussianDist(data, base * 14, 0.08, 0.6);
+        complexGaussianDist(data, base * 15, 0.08, 0.5);
+        complexGaussianDist(data, base * 16, 0.08, 0.5);
+        complexGaussianDist(data, base * 17, 0.08, 0.2);
+
+
+        complexGaussianDist(data, base * 1, 10, 8);
+        complexGaussianDist(data, base * 2, 10, 8);
+        complexGaussianDist(data, base * 3, 10, 8);
+        complexGaussianDist(data, base * 4, 10, 8);
+        complexGaussianDist(data, base * 5, 10, 8);
+        complexGaussianDist(data, base * 6, 20, 9);
+        complexGaussianDist(data, base * 7, 20, 9);
+        complexGaussianDist(data, base * 8, 20, 9);
+        complexGaussianDist(data, base * 9, 20, 8);
+        complexGaussianDist(data, base * 10, 30, 8);
+        complexGaussianDist(data, base * 11, 30, 9);
+        complexGaussianDist(data, base * 12, 30, 9);
+        complexGaussianDist(data, base * 13, 30, 8);
+        complexGaussianDist(data, base * 14, 30, 8);
+        complexGaussianDist(data, base * 15, 30, 7);
+        complexGaussianDist(data, base * 16, 30, 7);
+        complexGaussianDist(data, base * 17, 30, 6);
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Flute", data, base);
+        SF2Layer layer = newLayer(sf2, "Flute", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_horn(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.00000000001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            if (i == 0)
+                complexGaussianDist(data, base * (i + 1), 0.1, a * 0.2);
+            else
+                complexGaussianDist(data, base * (i + 1), 0.1, a);
+            a *= a_step;
+        }
+
+        complexGaussianDist(data, base * 2, 100, 1);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Horn", data, base);
+        SF2Layer layer = newLayer(sf2, "Horn", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -500);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_trumpet(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.00001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 80.0);
+        double[] aa = new double[80];
+        for (int i = 0; i < 80; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 0.05;
+        aa[1] *= 0.2;
+        aa[2] *= 0.5;
+        aa[3] *= 0.85;
+
+        for (int i = 0; i < 80; i++) {
+            complexGaussianDist(data, base * (i + 1), 0.1, aa[i]);
+        }
+
+        complexGaussianDist(data, base * 5, 300, 3);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Trumpet", data, base);
+        SF2Layer layer = newLayer(sf2, "Trumpet", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -10000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -4000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, -2500);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 10);
+        return layer;
+
+    }
+
+    public static SF2Layer new_brass_section(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.005;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 30.0);
+        double[] aa = new double[30];
+        for (int i = 0; i < 30; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 0.8;
+        aa[1] *= 0.9;
+
+        double w = 5;
+        for (int i = 0; i < 30; i++) {
+            complexGaussianDist(data, base * (i + 1), 0.1 * w, aa[i] * w);
+            w += 6; //*= w_step;
+        }
+
+        complexGaussianDist(data, base * 6, 300, 2);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Brass Section", data, base);
+        SF2Layer layer = newLayer(sf2, "Brass Section", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -9200);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_trombone(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 80.0);
+        double[] aa = new double[80];
+        for (int i = 0; i < 80; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 0.3;
+        aa[1] *= 0.7;
+
+        for (int i = 0; i < 80; i++) {
+            complexGaussianDist(data, base * (i + 1), 0.1, aa[i]);
+        }
+
+        complexGaussianDist(data, base * 6, 300, 2);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Trombone", data, base);
+        SF2Layer layer = newLayer(sf2, "Trombone", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -8000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -2000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 10);
+        return layer;
+
+    }
+
+    public static SF2Layer new_sax(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.01;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            if (i == 0 || i == 2)
+                complexGaussianDist(data, base * (i + 1), 0.1, a * 4);
+            else
+                complexGaussianDist(data, base * (i + 1), 0.1, a);
+            a *= a_step;
+        }
+
+        complexGaussianDist(data, base * 4, 200, 1);
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Sax", data, base);
+        SF2Layer layer = newLayer(sf2, "Sax", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_oboe(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        complexGaussianDist(data, base * 5, 100, 80);
+
+
+        complexGaussianDist(data, base * 1, 0.01, 0.53);
+        complexGaussianDist(data, base * 2, 0.01, 0.51);
+        complexGaussianDist(data, base * 3, 0.01, 0.48);
+        complexGaussianDist(data, base * 4, 0.01, 0.49);
+        complexGaussianDist(data, base * 5, 0.01, 5);
+        complexGaussianDist(data, base * 6, 0.01, 0.51);
+        complexGaussianDist(data, base * 7, 0.01, 0.50);
+        complexGaussianDist(data, base * 8, 0.01, 0.59);
+        complexGaussianDist(data, base * 9, 0.01, 0.61);
+        complexGaussianDist(data, base * 10, 0.01, 0.52);
+        complexGaussianDist(data, base * 11, 0.01, 0.49);
+        complexGaussianDist(data, base * 12, 0.01, 0.51);
+        complexGaussianDist(data, base * 13, 0.01, 0.48);
+        complexGaussianDist(data, base * 14, 0.01, 0.51);
+        complexGaussianDist(data, base * 15, 0.01, 0.46);
+        complexGaussianDist(data, base * 16, 0.01, 0.35);
+        complexGaussianDist(data, base * 17, 0.01, 0.20);
+        complexGaussianDist(data, base * 18, 0.01, 0.10);
+        complexGaussianDist(data, base * 19, 0.01, 0.5);
+        complexGaussianDist(data, base * 20, 0.01, 0.1);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Oboe", data, base);
+        SF2Layer layer = newLayer(sf2, "Oboe", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_bassoon(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        complexGaussianDist(data, base * 2, 100, 40);
+        complexGaussianDist(data, base * 4, 100, 20);
+
+        complexGaussianDist(data, base * 1, 0.01, 0.53);
+        complexGaussianDist(data, base * 2, 0.01, 5);
+        complexGaussianDist(data, base * 3, 0.01, 0.51);
+        complexGaussianDist(data, base * 4, 0.01, 0.48);
+        complexGaussianDist(data, base * 5, 0.01, 1.49);
+        complexGaussianDist(data, base * 6, 0.01, 0.51);
+        complexGaussianDist(data, base * 7, 0.01, 0.50);
+        complexGaussianDist(data, base * 8, 0.01, 0.59);
+        complexGaussianDist(data, base * 9, 0.01, 0.61);
+        complexGaussianDist(data, base * 10, 0.01, 0.52);
+        complexGaussianDist(data, base * 11, 0.01, 0.49);
+        complexGaussianDist(data, base * 12, 0.01, 0.51);
+        complexGaussianDist(data, base * 13, 0.01, 0.48);
+        complexGaussianDist(data, base * 14, 0.01, 0.51);
+        complexGaussianDist(data, base * 15, 0.01, 0.46);
+        complexGaussianDist(data, base * 16, 0.01, 0.35);
+        complexGaussianDist(data, base * 17, 0.01, 0.20);
+        complexGaussianDist(data, base * 18, 0.01, 0.10);
+        complexGaussianDist(data, base * 19, 0.01, 0.5);
+        complexGaussianDist(data, base * 20, 0.01, 0.1);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Flute", data, base);
+        SF2Layer layer = newLayer(sf2, "Flute", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_clarinet(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        complexGaussianDist(data, base * 1, 0.001, 0.5);
+        complexGaussianDist(data, base * 2, 0.001, 0.02);
+        complexGaussianDist(data, base * 3, 0.001, 0.2);
+        complexGaussianDist(data, base * 4, 0.01, 0.1);
+
+        complexGaussianDist(data, base * 4, 100, 60);
+        complexGaussianDist(data, base * 6, 100, 20);
+        complexGaussianDist(data, base * 8, 100, 20);
+
+        complexGaussianDist(data, base * 5, 0.001, 0.1);
+        complexGaussianDist(data, base * 6, 0.001, 0.09);
+        complexGaussianDist(data, base * 7, 0.001, 0.02);
+        complexGaussianDist(data, base * 8, 0.005, 0.16);
+        complexGaussianDist(data, base * 9, 0.005, 0.96);
+        complexGaussianDist(data, base * 10, 0.01, 0.9);
+        complexGaussianDist(data, base * 11, 0.08, 1.2);
+        complexGaussianDist(data, base * 12, 0.08, 1.8);
+        complexGaussianDist(data, base * 13, 0.08, 1.6);
+        complexGaussianDist(data, base * 14, 0.08, 1.2);
+        complexGaussianDist(data, base * 15, 0.08, 0.9);
+        complexGaussianDist(data, base * 16, 0.08, 0.5);
+        complexGaussianDist(data, base * 17, 0.08, 0.2);
+
+
+        complexGaussianDist(data, base * 1, 10, 8);
+        complexGaussianDist(data, base * 2, 10, 8);
+        complexGaussianDist(data, base * 3, 10, 8);
+        complexGaussianDist(data, base * 4, 10, 8);
+        complexGaussianDist(data, base * 5, 10, 8);
+        complexGaussianDist(data, base * 6, 20, 9);
+        complexGaussianDist(data, base * 7, 20, 9);
+        complexGaussianDist(data, base * 8, 20, 9);
+        complexGaussianDist(data, base * 9, 20, 8);
+        complexGaussianDist(data, base * 10, 30, 8);
+        complexGaussianDist(data, base * 11, 30, 9);
+        complexGaussianDist(data, base * 12, 30, 9);
+        complexGaussianDist(data, base * 13, 30, 8);
+        complexGaussianDist(data, base * 14, 30, 8);
+        complexGaussianDist(data, base * 15, 30, 7);
+        complexGaussianDist(data, base * 16, 30, 7);
+        complexGaussianDist(data, base * 17, 30, 6);
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Clarinet", data, base);
+        SF2Layer layer = newLayer(sf2, "Clarinet", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_timpani(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 8;
+            double[] data = new double[2 * fftlen];
+            double base = 48;
+            complexGaussianDist(data, base * 2, 0.2, 1);
+            complexGaussianDist(data, base * 3, 0.2, 0.7);
+            complexGaussianDist(data, base * 5, 10, 1);
+            complexGaussianDist(data, base * 6, 9, 1);
+            complexGaussianDist(data, base * 8, 15, 1);
+            complexGaussianDist(data, base * 9, 18, 0.8);
+            complexGaussianDist(data, base * 11, 21, 0.5);
+            complexGaussianDist(data, base * 13, 28, 0.3);
+            complexGaussianDist(data, base * 14, 22, 0.1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.5);
+            data = realPart(data);
+
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++) {
+                double g = (1.0 - (i / d_len));
+                data[i] *= g * g;
+            }
+            fadeUp(data, 40);
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2) {
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            }
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 300; i++) {
+                double g = (1.0 - (i / 300.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 24; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9998;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i] * 0.02;
+
+        normalize(datab, 0.9);
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Timpani", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Timpani");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_melodic_toms(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            complexGaussianDist(data, 30, 0.5, 1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.8);
+            data = realPart(data);
+
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++)
+                data[i] *= (1.0 - (i / d_len));
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 200; i++) {
+                double g = (1.0 - (i / 200.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 30; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9996;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i] * 0.5;
+        for (int i = 0; i < 5; i++)
+            datab[i] *= i / 5.0;
+
+        normalize(datab, 0.99);
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Melodic Toms", datab);
+        sample.setOriginalPitch(63);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Melodic Toms");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_reverse_cymbal(SF2Soundbank sf2) {
+        double datah[];
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 100; i++)
+                data[i] = 0;
+
+            for (int i = 0; i < 512 * 2; i++) {
+                double gain = (i / (512.0 * 2.0));
+                data[i] = 1 - gain;
+            }
+            datah = data;
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Reverse Cymbal",
+                datah, 100, 20);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Reverse Cymbal");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -200);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_snare_drum(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            complexGaussianDist(data, 24, 0.5, 1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.5);
+            data = realPart(data);
+
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++)
+                data[i] *= (1.0 - (i / d_len));
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 300; i++) {
+                double g = (1.0 - (i / 300.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 24; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9998;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i];
+        for (int i = 0; i < 5; i++)
+            datab[i] *= i / 5.0;
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Snare Drum", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Snare Drum");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_bass_drum(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            complexGaussianDist(data, 1.8 * 5 + 1, 2, 1);
+            complexGaussianDist(data, 1.8 * 9 + 1, 2, 1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++)
+                data[i] *= (1.0 - (i / d_len));
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024; i < 2048; i++)
+                data[i] = 1.0 - (i - 1024) / 1024.0;
+            for (int i = 0; i < 512; i++)
+                data[i] = 10 * i / 512.0;
+            for (int i = 0; i < 10; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.999;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i] * 0.5;
+        for (int i = 0; i < 5; i++)
+            datab[i] *= i / 5.0;
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Bass Drum", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Bass Drum");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_tom(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            complexGaussianDist(data, 30, 0.5, 1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.8);
+            data = realPart(data);
+
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++)
+                data[i] *= (1.0 - (i / d_len));
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 200; i++) {
+                double g = (1.0 - (i / 200.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 30; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9996;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i] * 0.5;
+        for (int i = 0; i < 5; i++)
+            datab[i] *= i / 5.0;
+
+        normalize(datab, 0.99);
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Tom", datab);
+        sample.setOriginalPitch(50);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Tom");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_closed_hihat(SF2Soundbank sf2) {
+        double datah[];
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 2048; i++)
+                data[i] = 0.2 + 0.8 * (i / 2048.0);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9996;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < 5; i++)
+            datah[i] *= i / 5.0;
+        SF2Sample sample = newSimpleDrumSample(sf2, "Closed Hi-Hat", datah);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Closed Hi-Hat");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_EXCLUSIVECLASS, 1);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_open_hihat(SF2Soundbank sf2) {
+        double datah[];
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 200; i++)
+                data[i] = 0;
+            for (int i = 0; i < 2048 * 4; i++) {
+                double gain = (i / (2048.0 * 4.0));
+                data[i] = gain;
+            }
+            datah = data;
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Open Hi-Hat", datah, 1000, 5);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Open Hi-Hat");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 1500);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1500);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_EXCLUSIVECLASS, 1);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_crash_cymbal(SF2Soundbank sf2) {
+        double datah[];
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 100; i++)
+                data[i] = 0;
+            for (int i = 0; i < 512 * 2; i++) {
+                double gain = (i / (512.0 * 2.0));
+                data[i] = gain;
+            }
+            datah = data;
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Crash Cymbal", datah, 1000, 5);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Crash Cymbal");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 1800);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1800);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_side_stick(SF2Soundbank sf2) {
+        double datab[];
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 200; i++) {
+                double g = (1.0 - (i / 200.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 30; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9996;
+            }
+            datab = data;
+        }
+
+        for (int i = 0; i < 10; i++)
+            datab[i] *= i / 10.0;
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Side Stick", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Side Stick");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -50);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+
+    }
+
+    public static SF2Sample newSimpleFFTSample(SF2Soundbank sf2, String name,
+            double[] data, double base) {
+        return newSimpleFFTSample(sf2, name, data, base, 10);
+    }
+
+    public static SF2Sample newSimpleFFTSample(SF2Soundbank sf2, String name,
+            double[] data, double base, int fadeuptime) {
+
+        int fftsize = data.length / 2;
+        AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+        double basefreq = (base / fftsize) * format.getSampleRate() * 0.5;
+
+        randomPhase(data);
+        ifft(data);
+        data = realPart(data);
+        normalize(data, 0.9);
+        float[] fdata = toFloat(data);
+        fdata = loopExtend(fdata, fdata.length + 512);
+        fadeUp(fdata, fadeuptime);
+        byte[] bdata = toBytes(fdata, format);
+
+        /*
+         * Create SoundFont2 sample.
+         */
+        SF2Sample sample = new SF2Sample(sf2);
+        sample.setName(name);
+        sample.setData(bdata);
+        sample.setStartLoop(256);
+        sample.setEndLoop(fftsize + 256);
+        sample.setSampleRate((long) format.getSampleRate());
+        double orgnote = (69 + 12)
+                + (12 * Math.log(basefreq / 440.0) / Math.log(2));
+        sample.setOriginalPitch((int) orgnote);
+        sample.setPitchCorrection((byte) (-(orgnote - (int) orgnote) * 100.0));
+        sf2.addResource(sample);
+
+        return sample;
+    }
+
+    public static SF2Sample newSimpleFFTSample_dist(SF2Soundbank sf2,
+            String name, double[] data, double base, double preamp) {
+
+        int fftsize = data.length / 2;
+        AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+        double basefreq = (base / fftsize) * format.getSampleRate() * 0.5;
+
+        randomPhase(data);
+        ifft(data);
+        data = realPart(data);
+
+        for (int i = 0; i < data.length; i++) {
+            data[i] = (1 - Math.exp(-Math.abs(data[i] * preamp)))
+                    * Math.signum(data[i]);
+        }
+
+        normalize(data, 0.9);
+        float[] fdata = toFloat(data);
+        fdata = loopExtend(fdata, fdata.length + 512);
+        fadeUp(fdata, 80);
+        byte[] bdata = toBytes(fdata, format);
+
+        /*
+         * Create SoundFont2 sample.
+         */
+        SF2Sample sample = new SF2Sample(sf2);
+        sample.setName(name);
+        sample.setData(bdata);
+        sample.setStartLoop(256);
+        sample.setEndLoop(fftsize + 256);
+        sample.setSampleRate((long) format.getSampleRate());
+        double orgnote = (69 + 12)
+                + (12 * Math.log(basefreq / 440.0) / Math.log(2));
+        sample.setOriginalPitch((int) orgnote);
+        sample.setPitchCorrection((byte) (-(orgnote - (int) orgnote) * 100.0));
+        sf2.addResource(sample);
+
+        return sample;
+    }
+
+    public static SF2Sample newSimpleDrumSample(SF2Soundbank sf2, String name,
+            double[] data) {
+
+        int fftsize = data.length;
+        AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+        byte[] bdata = toBytes(toFloat(realPart(data)), format);
+
+        /*
+         * Create SoundFont2 sample.
+         */
+        SF2Sample sample = new SF2Sample(sf2);
+        sample.setName(name);
+        sample.setData(bdata);
+        sample.setStartLoop(256);
+        sample.setEndLoop(fftsize + 256);
+        sample.setSampleRate((long) format.getSampleRate());
+        sample.setOriginalPitch(60);
+        sf2.addResource(sample);
+
+        return sample;
+    }
+
+    public static SF2Layer newLayer(SF2Soundbank sf2, String name, SF2Sample sample) {
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.setSample(sample);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName(name);
+        layer.getRegions().add(region);
+        sf2.addResource(layer);
+
+        return layer;
+    }
+
+    public static SF2Instrument newInstrument(SF2Soundbank sf2, String name,
+            Patch patch, SF2Layer... layers) {
+
+        /*
+         * Create SoundFont2 instrument.
+         */
+        SF2Instrument ins = new SF2Instrument(sf2);
+        ins.setPatch(patch);
+        ins.setName(name);
+        sf2.addInstrument(ins);
+
+        /*
+         * Create region for instrument.
+         */
+        for (int i = 0; i < layers.length; i++) {
+            SF2InstrumentRegion insregion = new SF2InstrumentRegion();
+            insregion.setLayer(layers[i]);
+            ins.getRegions().add(insregion);
+        }
+
+        return ins;
+    }
+
+    static public void ifft(double[] data) {
+        new FFT(data.length / 2, 1).transform(data);
+    }
+
+    static public void fft(double[] data) {
+        new FFT(data.length / 2, -1).transform(data);
+    }
+
+    public static void complexGaussianDist(double[] cdata, double m,
+            double s, double v) {
+        for (int x = 0; x < cdata.length / 4; x++) {
+            cdata[x * 2] += v * (1.0 / (s * Math.sqrt(2 * Math.PI))
+                    * Math.exp((-1.0 / 2.0) * Math.pow((x - m) / s, 2.0)));
+        }
+    }
+
+    static public void randomPhase(double[] data) {
+        for (int i = 0; i < data.length; i += 2) {
+            double phase = Math.random() * 2 * Math.PI;
+            double d = data[i];
+            data[i] = Math.sin(phase) * d;
+            data[i + 1] = Math.cos(phase) * d;
+        }
+    }
+
+    static public void randomPhase(double[] data, Random random) {
+        for (int i = 0; i < data.length; i += 2) {
+            double phase = random.nextDouble() * 2 * Math.PI;
+            double d = data[i];
+            data[i] = Math.sin(phase) * d;
+            data[i + 1] = Math.cos(phase) * d;
+        }
+    }
+
+    static public void normalize(double[] data, double target) {
+        double maxvalue = 0;
+        for (int i = 0; i < data.length; i++) {
+            if (data[i] > maxvalue)
+                maxvalue = data[i];
+            if (-data[i] > maxvalue)
+                maxvalue = -data[i];
+        }
+        if (maxvalue == 0)
+            return;
+        double gain = target / maxvalue;
+        for (int i = 0; i < data.length; i++)
+            data[i] *= gain;
+    }
+
+    static public void normalize(float[] data, double target) {
+        double maxvalue = 0.5;
+        for (int i = 0; i < data.length; i++) {
+            if (data[i * 2] > maxvalue)
+                maxvalue = data[i * 2];
+            if (-data[i * 2] > maxvalue)
+                maxvalue = -data[i * 2];
+        }
+        double gain = target / maxvalue;
+        for (int i = 0; i < data.length; i++)
+            data[i * 2] *= gain;
+    }
+
+    static public double[] realPart(double[] in) {
+        double[] out = new double[in.length / 2];
+        for (int i = 0; i < out.length; i++) {
+            out[i] = in[i * 2];
+        }
+        return out;
+    }
+
+    static public double[] imgPart(double[] in) {
+        double[] out = new double[in.length / 2];
+        for (int i = 0; i < out.length; i++) {
+            out[i] = in[i * 2];
+        }
+        return out;
+    }
+
+    static public float[] toFloat(double[] in) {
+        float[] out = new float[in.length];
+        for (int i = 0; i < out.length; i++) {
+            out[i] = (float) in[i];
+        }
+        return out;
+    }
+
+    static public byte[] toBytes(float[] in, AudioFormat format) {
+        byte[] out = new byte[in.length * format.getFrameSize()];
+        return AudioFloatConverter.getConverter(format).toByteArray(in, out);
+    }
+
+    static public void fadeUp(double[] data, int samples) {
+        double dsamples = samples;
+        for (int i = 0; i < samples; i++)
+            data[i] *= i / dsamples;
+    }
+
+    static public void fadeUp(float[] data, int samples) {
+        double dsamples = samples;
+        for (int i = 0; i < samples; i++)
+            data[i] *= i / dsamples;
+    }
+
+    static public double[] loopExtend(double[] data, int newsize) {
+        double[] outdata = new double[newsize];
+        int p_len = data.length;
+        int p_ps = 0;
+        for (int i = 0; i < outdata.length; i++) {
+            outdata[i] = data[p_ps];
+            p_ps++;
+            if (p_ps == p_len)
+                p_ps = 0;
+        }
+        return outdata;
+    }
+
+    static public float[] loopExtend(float[] data, int newsize) {
+        float[] outdata = new float[newsize];
+        int p_len = data.length;
+        int p_ps = 0;
+        for (int i = 0; i < outdata.length; i++) {
+            outdata[i] = data[p_ps];
+            p_ps++;
+            if (p_ps == p_len)
+                p_ps = 0;
+        }
+        return outdata;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/FFT.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,748 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Fast Fourier Transformer.
+ *
+ * @author Karl Helgason
+ */
+public final class FFT {
+
+    private double[] w;
+    private int fftFrameSize;
+    private int sign;
+    private int[] bitm_array;
+    private int fftFrameSize2;
+
+    // Sign = -1 is FFT, 1 is IFFT (inverse FFT)
+    // Data = Interlaced double array to be transformed.
+    // The order is: real (sin), complex (cos)
+    // Framesize must be power of 2
+    public FFT(int fftFrameSize, int sign) {
+        w = computeTwiddleFactors(fftFrameSize, sign);
+
+        this.fftFrameSize = fftFrameSize;
+        this.sign = sign;
+        fftFrameSize2 = fftFrameSize << 1;
+
+        // Pre-process Bit-Reversal
+        bitm_array = new int[fftFrameSize2];
+        for (int i = 2; i < fftFrameSize2; i += 2) {
+            int j;
+            int bitm;
+            for (bitm = 2, j = 0; bitm < fftFrameSize2; bitm <<= 1) {
+                if ((i & bitm) != 0)
+                    j++;
+                j <<= 1;
+            }
+            bitm_array[i] = j;
+        }
+
+    }
+
+    public void transform(double[] data) {
+        bitreversal(data);
+        calc(fftFrameSize, data, sign, w);
+    }
+
+    private final static double[] computeTwiddleFactors(int fftFrameSize,
+            int sign) {
+
+        int imax = (int) (Math.log(fftFrameSize) / Math.log(2.));
+
+        double[] warray = new double[(fftFrameSize - 1) * 4];
+        int w_index = 0;
+
+        for (int i = 0,  nstep = 2; i < imax; i++) {
+            int jmax = nstep;
+            nstep <<= 1;
+
+            double wr = 1.0;
+            double wi = 0.0;
+
+            double arg = Math.PI / (jmax >> 1);
+            double wfr = Math.cos(arg);
+            double wfi = sign * Math.sin(arg);
+
+            for (int j = 0; j < jmax; j += 2) {
+                warray[w_index++] = wr;
+                warray[w_index++] = wi;
+
+                double tempr = wr;
+                wr = tempr * wfr - wi * wfi;
+                wi = tempr * wfi + wi * wfr;
+            }
+        }
+
+        // PRECOMPUTATION of wwr1, wwi1 for factor 4 Decomposition (3 * complex
+        // operators and 8 +/- complex operators)
+        {
+            w_index = 0;
+            int w_index2 = warray.length >> 1;
+            for (int i = 0,  nstep = 2; i < (imax - 1); i++) {
+                int jmax = nstep;
+                nstep *= 2;
+
+                int ii = w_index + jmax;
+                for (int j = 0; j < jmax; j += 2) {
+                    double wr = warray[w_index++];
+                    double wi = warray[w_index++];
+                    double wr1 = warray[ii++];
+                    double wi1 = warray[ii++];
+                    warray[w_index2++] = wr * wr1 - wi * wi1;
+                    warray[w_index2++] = wr * wi1 + wi * wr1;
+                }
+            }
+
+        }
+
+        return warray;
+    }
+
+    private final static void calc(int fftFrameSize, double[] data, int sign,
+            double[] w) {
+
+        final int fftFrameSize2 = fftFrameSize << 1;
+
+        int nstep = 2;
+
+        if (nstep >= fftFrameSize2)
+            return;
+        int i = nstep - 2;
+        if (sign == -1)
+            calcF4F(fftFrameSize, data, i, nstep, w);
+        else
+            calcF4I(fftFrameSize, data, i, nstep, w);
+
+    }
+
+    private final static void calcF2E(int fftFrameSize, double[] data, int i,
+            int nstep, double[] w) {
+        int jmax = nstep;
+        for (int n = 0; n < jmax; n += 2) {
+            double wr = w[i++];
+            double wi = w[i++];
+            int m = n + jmax;
+            double datam_r = data[m];
+            double datam_i = data[m + 1];
+            double datan_r = data[n];
+            double datan_i = data[n + 1];
+            double tempr = datam_r * wr - datam_i * wi;
+            double tempi = datam_r * wi + datam_i * wr;
+            data[m] = datan_r - tempr;
+            data[m + 1] = datan_i - tempi;
+            data[n] = datan_r + tempr;
+            data[n + 1] = datan_i + tempi;
+        }
+        return;
+
+    }
+
+    // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
+    // complex operators
+    private final static void calcF4F(int fftFrameSize, double[] data, int i,
+            int nstep, double[] w) {
+        final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
+        // Factor-4 Decomposition
+
+        int w_len = w.length >> 1;
+        while (nstep < fftFrameSize2) {
+
+            if (nstep << 2 == fftFrameSize2) {
+                // Goto Factor-4 Final Decomposition
+                // calcF4E(data, i, nstep, -1, w);
+                calcF4FE(fftFrameSize, data, i, nstep, w);
+                return;
+            }
+            int jmax = nstep;
+            int nnstep = nstep << 1;
+            if (nnstep == fftFrameSize2) {
+                // Factor-4 Decomposition not possible
+                calcF2E(fftFrameSize, data, i, nstep, w);
+                return;
+            }
+            nstep <<= 2;
+            int ii = i + jmax;
+            int iii = i + w_len;
+
+            {
+                i += 2;
+                ii += 2;
+                iii += 2;
+
+                for (int n = 0; n < fftFrameSize2; n += nstep) {
+                    int m = n + jmax;
+
+                    double datam1_r = data[m];
+                    double datam1_i = data[m + 1];
+                    double datan1_r = data[n];
+                    double datan1_i = data[n + 1];
+
+                    n += nnstep;
+                    m += nnstep;
+                    double datam2_r = data[m];
+                    double datam2_i = data[m + 1];
+                    double datan2_r = data[n];
+                    double datan2_i = data[n + 1];
+
+                    double tempr = datam1_r;
+                    double tempi = datam1_i;
+
+                    datam1_r = datan1_r - tempr;
+                    datam1_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    double n2w1r = datan2_r;
+                    double n2w1i = datan2_i;
+                    double m2ww1r = datam2_r;
+                    double m2ww1i = datam2_i;
+
+                    tempr = m2ww1r - n2w1r;
+                    tempi = m2ww1i - n2w1i;
+
+                    datam2_r = datam1_r + tempi;
+                    datam2_i = datam1_i - tempr;
+                    datam1_r = datam1_r - tempi;
+                    datam1_i = datam1_i + tempr;
+
+                    tempr = n2w1r + m2ww1r;
+                    tempi = n2w1i + m2ww1i;
+
+                    datan2_r = datan1_r - tempr;
+                    datan2_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    data[m] = datam2_r;
+                    data[m + 1] = datam2_i;
+                    data[n] = datan2_r;
+                    data[n + 1] = datan2_i;
+
+                    n -= nnstep;
+                    m -= nnstep;
+                    data[m] = datam1_r;
+                    data[m + 1] = datam1_i;
+                    data[n] = datan1_r;
+                    data[n + 1] = datan1_i;
+
+                }
+            }
+
+            for (int j = 2; j < jmax; j += 2) {
+                double wr = w[i++];
+                double wi = w[i++];
+                double wr1 = w[ii++];
+                double wi1 = w[ii++];
+                double wwr1 = w[iii++];
+                double wwi1 = w[iii++];
+                // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be
+                // precomputed!!!
+                // double wwi1 = wr * wi1 + wi * wr1;
+
+                for (int n = j; n < fftFrameSize2; n += nstep) {
+                    int m = n + jmax;
+
+                    double datam1_r = data[m];
+                    double datam1_i = data[m + 1];
+                    double datan1_r = data[n];
+                    double datan1_i = data[n + 1];
+
+                    n += nnstep;
+                    m += nnstep;
+                    double datam2_r = data[m];
+                    double datam2_i = data[m + 1];
+                    double datan2_r = data[n];
+                    double datan2_i = data[n + 1];
+
+                    double tempr = datam1_r * wr - datam1_i * wi;
+                    double tempi = datam1_r * wi + datam1_i * wr;
+
+                    datam1_r = datan1_r - tempr;
+                    datam1_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    double n2w1r = datan2_r * wr1 - datan2_i * wi1;
+                    double n2w1i = datan2_r * wi1 + datan2_i * wr1;
+                    double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;
+                    double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;
+
+                    tempr = m2ww1r - n2w1r;
+                    tempi = m2ww1i - n2w1i;
+
+                    datam2_r = datam1_r + tempi;
+                    datam2_i = datam1_i - tempr;
+                    datam1_r = datam1_r - tempi;
+                    datam1_i = datam1_i + tempr;
+
+                    tempr = n2w1r + m2ww1r;
+                    tempi = n2w1i + m2ww1i;
+
+                    datan2_r = datan1_r - tempr;
+                    datan2_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    data[m] = datam2_r;
+                    data[m + 1] = datam2_i;
+                    data[n] = datan2_r;
+                    data[n + 1] = datan2_i;
+
+                    n -= nnstep;
+                    m -= nnstep;
+                    data[m] = datam1_r;
+                    data[m + 1] = datam1_i;
+                    data[n] = datan1_r;
+                    data[n + 1] = datan1_i;
+                }
+            }
+
+            i += jmax << 1;
+
+        }
+
+        calcF2E(fftFrameSize, data, i, nstep, w);
+
+    }
+
+    // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
+    // complex operators
+    private final static void calcF4I(int fftFrameSize, double[] data, int i,
+            int nstep, double[] w) {
+        final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
+        // Factor-4 Decomposition
+
+        int w_len = w.length >> 1;
+        while (nstep < fftFrameSize2) {
+
+            if (nstep << 2 == fftFrameSize2) {
+                // Goto Factor-4 Final Decomposition
+                // calcF4E(data, i, nstep, 1, w);
+                calcF4IE(fftFrameSize, data, i, nstep, w);
+                return;
+            }
+            int jmax = nstep;
+            int nnstep = nstep << 1;
+            if (nnstep == fftFrameSize2) {
+                // Factor-4 Decomposition not possible
+                calcF2E(fftFrameSize, data, i, nstep, w);
+                return;
+            }
+            nstep <<= 2;
+            int ii = i + jmax;
+            int iii = i + w_len;
+            {
+                i += 2;
+                ii += 2;
+                iii += 2;
+
+                for (int n = 0; n < fftFrameSize2; n += nstep) {
+                    int m = n + jmax;
+
+                    double datam1_r = data[m];
+                    double datam1_i = data[m + 1];
+                    double datan1_r = data[n];
+                    double datan1_i = data[n + 1];
+
+                    n += nnstep;
+                    m += nnstep;
+                    double datam2_r = data[m];
+                    double datam2_i = data[m + 1];
+                    double datan2_r = data[n];
+                    double datan2_i = data[n + 1];
+
+                    double tempr = datam1_r;
+                    double tempi = datam1_i;
+
+                    datam1_r = datan1_r - tempr;
+                    datam1_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    double n2w1r = datan2_r;
+                    double n2w1i = datan2_i;
+                    double m2ww1r = datam2_r;
+                    double m2ww1i = datam2_i;
+
+                    tempr = n2w1r - m2ww1r;
+                    tempi = n2w1i - m2ww1i;
+
+                    datam2_r = datam1_r + tempi;
+                    datam2_i = datam1_i - tempr;
+                    datam1_r = datam1_r - tempi;
+                    datam1_i = datam1_i + tempr;
+
+                    tempr = n2w1r + m2ww1r;
+                    tempi = n2w1i + m2ww1i;
+
+                    datan2_r = datan1_r - tempr;
+                    datan2_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    data[m] = datam2_r;
+                    data[m + 1] = datam2_i;
+                    data[n] = datan2_r;
+                    data[n + 1] = datan2_i;
+
+                    n -= nnstep;
+                    m -= nnstep;
+                    data[m] = datam1_r;
+                    data[m + 1] = datam1_i;
+                    data[n] = datan1_r;
+                    data[n + 1] = datan1_i;
+
+                }
+
+            }
+            for (int j = 2; j < jmax; j += 2) {
+                double wr = w[i++];
+                double wi = w[i++];
+                double wr1 = w[ii++];
+                double wi1 = w[ii++];
+                double wwr1 = w[iii++];
+                double wwi1 = w[iii++];
+                // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be
+                // precomputed!!!
+                // double wwi1 = wr * wi1 + wi * wr1;
+
+                for (int n = j; n < fftFrameSize2; n += nstep) {
+                    int m = n + jmax;
+
+                    double datam1_r = data[m];
+                    double datam1_i = data[m + 1];
+                    double datan1_r = data[n];
+                    double datan1_i = data[n + 1];
+
+                    n += nnstep;
+                    m += nnstep;
+                    double datam2_r = data[m];
+                    double datam2_i = data[m + 1];
+                    double datan2_r = data[n];
+                    double datan2_i = data[n + 1];
+
+                    double tempr = datam1_r * wr - datam1_i * wi;
+                    double tempi = datam1_r * wi + datam1_i * wr;
+
+                    datam1_r = datan1_r - tempr;
+                    datam1_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    double n2w1r = datan2_r * wr1 - datan2_i * wi1;
+                    double n2w1i = datan2_r * wi1 + datan2_i * wr1;
+                    double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;
+                    double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;
+
+                    tempr = n2w1r - m2ww1r;
+                    tempi = n2w1i - m2ww1i;
+
+                    datam2_r = datam1_r + tempi;
+                    datam2_i = datam1_i - tempr;
+                    datam1_r = datam1_r - tempi;
+                    datam1_i = datam1_i + tempr;
+
+                    tempr = n2w1r + m2ww1r;
+                    tempi = n2w1i + m2ww1i;
+
+                    datan2_r = datan1_r - tempr;
+                    datan2_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    data[m] = datam2_r;
+                    data[m + 1] = datam2_i;
+                    data[n] = datan2_r;
+                    data[n + 1] = datan2_i;
+
+                    n -= nnstep;
+                    m -= nnstep;
+                    data[m] = datam1_r;
+                    data[m + 1] = datam1_i;
+                    data[n] = datan1_r;
+                    data[n + 1] = datan1_i;
+
+                }
+            }
+
+            i += jmax << 1;
+
+        }
+
+        calcF2E(fftFrameSize, data, i, nstep, w);
+
+    }
+
+    // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
+    // complex operators
+    private final static void calcF4FE(int fftFrameSize, double[] data, int i,
+            int nstep, double[] w) {
+        final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
+        // Factor-4 Decomposition
+
+        int w_len = w.length >> 1;
+        while (nstep < fftFrameSize2) {
+
+            int jmax = nstep;
+            int nnstep = nstep << 1;
+            if (nnstep == fftFrameSize2) {
+                // Factor-4 Decomposition not possible
+                calcF2E(fftFrameSize, data, i, nstep, w);
+                return;
+            }
+            nstep <<= 2;
+            int ii = i + jmax;
+            int iii = i + w_len;
+            for (int n = 0; n < jmax; n += 2) {
+                double wr = w[i++];
+                double wi = w[i++];
+                double wr1 = w[ii++];
+                double wi1 = w[ii++];
+                double wwr1 = w[iii++];
+                double wwi1 = w[iii++];
+                // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be
+                // precomputed!!!
+                // double wwi1 = wr * wi1 + wi * wr1;
+
+                int m = n + jmax;
+
+                double datam1_r = data[m];
+                double datam1_i = data[m + 1];
+                double datan1_r = data[n];
+                double datan1_i = data[n + 1];
+
+                n += nnstep;
+                m += nnstep;
+                double datam2_r = data[m];
+                double datam2_i = data[m + 1];
+                double datan2_r = data[n];
+                double datan2_i = data[n + 1];
+
+                double tempr = datam1_r * wr - datam1_i * wi;
+                double tempi = datam1_r * wi + datam1_i * wr;
+
+                datam1_r = datan1_r - tempr;
+                datam1_i = datan1_i - tempi;
+                datan1_r = datan1_r + tempr;
+                datan1_i = datan1_i + tempi;
+
+                double n2w1r = datan2_r * wr1 - datan2_i * wi1;
+                double n2w1i = datan2_r * wi1 + datan2_i * wr1;
+                double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;
+                double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;
+
+                tempr = m2ww1r - n2w1r;
+                tempi = m2ww1i - n2w1i;
+
+                datam2_r = datam1_r + tempi;
+                datam2_i = datam1_i - tempr;
+                datam1_r = datam1_r - tempi;
+                datam1_i = datam1_i + tempr;
+
+                tempr = n2w1r + m2ww1r;
+                tempi = n2w1i + m2ww1i;
+
+                datan2_r = datan1_r - tempr;
+                datan2_i = datan1_i - tempi;
+                datan1_r = datan1_r + tempr;
+                datan1_i = datan1_i + tempi;
+
+                data[m] = datam2_r;
+                data[m + 1] = datam2_i;
+                data[n] = datan2_r;
+                data[n + 1] = datan2_i;
+
+                n -= nnstep;
+                m -= nnstep;
+                data[m] = datam1_r;
+                data[m + 1] = datam1_i;
+                data[n] = datan1_r;
+                data[n + 1] = datan1_i;
+
+            }
+
+            i += jmax << 1;
+
+        }
+
+    }
+
+    // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
+    // complex operators
+    private final static void calcF4IE(int fftFrameSize, double[] data, int i,
+            int nstep, double[] w) {
+        final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
+        // Factor-4 Decomposition
+
+        int w_len = w.length >> 1;
+        while (nstep < fftFrameSize2) {
+
+            int jmax = nstep;
+            int nnstep = nstep << 1;
+            if (nnstep == fftFrameSize2) {
+                // Factor-4 Decomposition not possible
+                calcF2E(fftFrameSize, data, i, nstep, w);
+                return;
+            }
+            nstep <<= 2;
+            int ii = i + jmax;
+            int iii = i + w_len;
+            for (int n = 0; n < jmax; n += 2) {
+                double wr = w[i++];
+                double wi = w[i++];
+                double wr1 = w[ii++];
+                double wi1 = w[ii++];
+                double wwr1 = w[iii++];
+                double wwi1 = w[iii++];
+                // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be
+                // precomputed!!!
+                // double wwi1 = wr * wi1 + wi * wr1;
+
+                int m = n + jmax;
+
+                double datam1_r = data[m];
+                double datam1_i = data[m + 1];
+                double datan1_r = data[n];
+                double datan1_i = data[n + 1];
+
+                n += nnstep;
+                m += nnstep;
+                double datam2_r = data[m];
+                double datam2_i = data[m + 1];
+                double datan2_r = data[n];
+                double datan2_i = data[n + 1];
+
+                double tempr = datam1_r * wr - datam1_i * wi;
+                double tempi = datam1_r * wi + datam1_i * wr;
+
+                datam1_r = datan1_r - tempr;
+                datam1_i = datan1_i - tempi;
+                datan1_r = datan1_r + tempr;
+                datan1_i = datan1_i + tempi;
+
+                double n2w1r = datan2_r * wr1 - datan2_i * wi1;
+                double n2w1i = datan2_r * wi1 + datan2_i * wr1;
+                double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;
+                double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;
+
+                tempr = n2w1r - m2ww1r;
+                tempi = n2w1i - m2ww1i;
+
+                datam2_r = datam1_r + tempi;
+                datam2_i = datam1_i - tempr;
+                datam1_r = datam1_r - tempi;
+                datam1_i = datam1_i + tempr;
+
+                tempr = n2w1r + m2ww1r;
+                tempi = n2w1i + m2ww1i;
+
+                datan2_r = datan1_r - tempr;
+                datan2_i = datan1_i - tempi;
+                datan1_r = datan1_r + tempr;
+                datan1_i = datan1_i + tempi;
+
+                data[m] = datam2_r;
+                data[m + 1] = datam2_i;
+                data[n] = datan2_r;
+                data[n + 1] = datan2_i;
+
+                n -= nnstep;
+                m -= nnstep;
+                data[m] = datam1_r;
+                data[m + 1] = datam1_i;
+                data[n] = datan1_r;
+                data[n + 1] = datan1_i;
+
+            }
+
+            i += jmax << 1;
+
+        }
+
+    }
+
+    private final void bitreversal(double[] data) {
+        if (fftFrameSize < 4)
+            return;
+
+        int inverse = fftFrameSize2 - 2;
+        for (int i = 0; i < fftFrameSize; i += 4) {
+            int j = bitm_array[i];
+
+            // Performing Bit-Reversal, even v.s. even, O(2N)
+            if (i < j) {
+
+                int n = i;
+                int m = j;
+
+                // COMPLEX: SWAP(data[n], data[m])
+                // Real Part
+                double tempr = data[n];
+                data[n] = data[m];
+                data[m] = tempr;
+                // Imagery Part
+                n++;
+                m++;
+                double tempi = data[n];
+                data[n] = data[m];
+                data[m] = tempi;
+
+                n = inverse - i;
+                m = inverse - j;
+
+                // COMPLEX: SWAP(data[n], data[m])
+                // Real Part
+                tempr = data[n];
+                data[n] = data[m];
+                data[m] = tempr;
+                // Imagery Part
+                n++;
+                m++;
+                tempi = data[n];
+                data[n] = data[m];
+                data[m] = tempi;
+            }
+
+            // Performing Bit-Reversal, odd v.s. even, O(N)
+
+            int m = j + fftFrameSize; // bitm_array[i+2];
+            // COMPLEX: SWAP(data[n], data[m])
+            // Real Part
+            int n = i + 2;
+            double tempr = data[n];
+            data[n] = data[m];
+            data[m] = tempr;
+            // Imagery Part
+            n++;
+            m++;
+            double tempi = data[n];
+            data[n] = data[m];
+            data[m] = tempi;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/InvalidDataException.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+
+/**
+ * This exception is used when a file contains illegal or unexpected data.
+ *
+ * @author Karl Helgason
+ */
+public class InvalidDataException extends IOException {
+
+    private static final long serialVersionUID = 1L;
+
+    public InvalidDataException() {
+        super("Invalid Data!");
+    }
+
+    public InvalidDataException(String s) {
+        super(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/InvalidFormatException.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This exception is used when a reader is used to read file of a format
+ * it doesn't unterstand or support.
+ *
+ * @author Karl Helgason
+ */
+public class InvalidFormatException extends InvalidDataException {
+
+    private static final long serialVersionUID = 1L;
+
+    public InvalidFormatException() {
+        super("Invalid format!");
+    }
+
+    public InvalidFormatException(String s) {
+        super(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/JARSoundbankReader.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.spi.SoundbankReader;
+
+/**
+ * JarSoundbankReader is used to read sounbank object from jar files.
+ *
+ * @author Karl Helgason
+ */
+public class JARSoundbankReader extends SoundbankReader {
+
+    public boolean isZIP(URL url) {
+        boolean ok = false;
+        try {
+            InputStream stream = url.openStream();
+            try {
+                byte[] buff = new byte[4];
+                ok = stream.read(buff) == 4;
+                if (ok) {
+                    ok =  (buff[0] == 0x50
+                        && buff[1] == 0x4b
+                        && buff[2] == 0x03
+                        && buff[3] == 0x04);
+                }
+            } finally {
+                stream.close();
+            }
+        } catch (IOException e) {
+        }
+        return ok;
+    }
+
+    public Soundbank getSoundbank(URL url)
+            throws InvalidMidiDataException, IOException {
+        if (!isZIP(url))
+            return null;
+        ArrayList<Soundbank> soundbanks = new ArrayList<Soundbank>();
+        URLClassLoader ucl = URLClassLoader.newInstance(new URL[]{url});
+        InputStream stream = ucl.getResourceAsStream(
+                "META-INF/services/javax.sound.midi.Soundbank");
+        if (stream == null)
+            return null;
+        try
+        {
+            BufferedReader r = new BufferedReader(new InputStreamReader(stream));
+            String line = r.readLine();
+            while (line != null) {
+                if (!line.startsWith("#")) {
+                    try {
+                        Class c = Class.forName(line.trim(), true, ucl);
+                        Object o = c.newInstance();
+                        if (o instanceof Soundbank) {
+                            soundbanks.add((Soundbank) o);
+                        }
+                    } catch (ClassNotFoundException  e) {
+                    } catch (InstantiationException  e) {
+                    } catch (IllegalAccessException  e) {
+                    }
+                }
+                line = r.readLine();
+            }
+        }
+        finally
+        {
+            stream.close();
+        }
+        if (soundbanks.size() == 0)
+            return null;
+        if (soundbanks.size() == 1)
+            return soundbanks.get(0);
+        SimpleSoundbank sbk = new SimpleSoundbank();
+        for (Soundbank soundbank : soundbanks)
+            sbk.addAllInstruments(soundbank);
+        return sbk;
+    }
+
+    public Soundbank getSoundbank(InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        return null;
+    }
+
+    public Soundbank getSoundbank(File file)
+            throws InvalidMidiDataException, IOException {
+        return getSoundbank(file.toURI().toURL());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelAbstractChannelMixer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * ModelAbstractChannelMixer is ready for use class to implement
+ * ModelChannelMixer interface.
+ *
+ * @author Karl Helgason
+ */
+public abstract class ModelAbstractChannelMixer implements ModelChannelMixer {
+
+    public abstract boolean process(float[][] buffer, int offset, int len);
+
+    public abstract void stop();
+
+    public void allNotesOff() {
+    }
+
+    public void allSoundOff() {
+    }
+
+    public void controlChange(int controller, int value) {
+    }
+
+    public int getChannelPressure() {
+        return 0;
+    }
+
+    public int getController(int controller) {
+        return 0;
+    }
+
+    public boolean getMono() {
+        return false;
+    }
+
+    public boolean getMute() {
+        return false;
+    }
+
+    public boolean getOmni() {
+        return false;
+    }
+
+    public int getPitchBend() {
+        return 0;
+    }
+
+    public int getPolyPressure(int noteNumber) {
+        return 0;
+    }
+
+    public int getProgram() {
+        return 0;
+    }
+
+    public boolean getSolo() {
+        return false;
+    }
+
+    public boolean localControl(boolean on) {
+        return false;
+    }
+
+    public void noteOff(int noteNumber) {
+    }
+
+    public void noteOff(int noteNumber, int velocity) {
+    }
+
+    public void noteOn(int noteNumber, int velocity) {
+    }
+
+    public void programChange(int program) {
+    }
+
+    public void programChange(int bank, int program) {
+    }
+
+    public void resetAllControllers() {
+    }
+
+    public void setChannelPressure(int pressure) {
+    }
+
+    public void setMono(boolean on) {
+    }
+
+    public void setMute(boolean mute) {
+    }
+
+    public void setOmni(boolean on) {
+    }
+
+    public void setPitchBend(int bend) {
+    }
+
+    public void setPolyPressure(int noteNumber, int pressure) {
+    }
+
+    public void setSolo(boolean soloState) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelAbstractOscillator.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.midi.VoiceStatus;
+
+/**
+ * A abstract class used to simplify creating custom ModelOscillator.
+ *
+ * @author Karl Helgason
+ */
+public abstract class ModelAbstractOscillator
+        implements ModelOscillator, ModelOscillatorStream, Soundbank {
+
+    protected float pitch = 6000;
+    protected float samplerate;
+    protected MidiChannel channel;
+    protected VoiceStatus voice;
+    protected int noteNumber;
+    protected int velocity;
+    protected boolean on = false;
+
+    public void init() {
+    }
+
+    public void close() throws IOException {
+    }
+
+    public void noteOff(int velocity) {
+        on = false;
+    }
+
+    public void noteOn(MidiChannel channel, VoiceStatus voice, int noteNumber,
+            int velocity) {
+        this.channel = channel;
+        this.voice = voice;
+        this.noteNumber = noteNumber;
+        this.velocity = velocity;
+        on = true;
+    }
+
+    public int read(float[][] buffer, int offset, int len) throws IOException {
+        return -1;
+    }
+
+    public MidiChannel getChannel() {
+        return channel;
+    }
+
+    public VoiceStatus getVoice() {
+        return voice;
+    }
+
+    public int getNoteNumber() {
+        return noteNumber;
+    }
+
+    public int getVelocity() {
+        return velocity;
+    }
+
+    public boolean isOn() {
+        return on;
+    }
+
+    public void setPitch(float pitch) {
+        this.pitch = pitch;
+    }
+
+    public float getPitch() {
+        return pitch;
+    }
+
+    public void setSampleRate(float samplerate) {
+        this.samplerate = samplerate;
+    }
+
+    public float getSampleRate() {
+        return samplerate;
+    }
+
+    public float getAttenuation() {
+        return 0;
+    }
+
+    public int getChannels() {
+        return 1;
+    }
+
+    public String getName() {
+        return getClass().getName();
+    }
+
+    public Patch getPatch() {
+        return new Patch(0, 0);
+    }
+
+    public ModelOscillatorStream open(float samplerate) {
+        ModelAbstractOscillator oscs;
+        try {
+            oscs = this.getClass().newInstance();
+        } catch (InstantiationException e) {
+            throw new IllegalArgumentException(e);
+        } catch (IllegalAccessException e) {
+            throw new IllegalArgumentException(e);
+        }
+        oscs.setSampleRate(samplerate);
+        oscs.init();
+        return oscs;
+    }
+
+    public ModelPerformer getPerformer() {
+        // Create performer for my custom oscillirator
+        ModelPerformer performer = new ModelPerformer();
+        performer.getOscillators().add(this);
+        return performer;
+
+    }
+
+    public ModelInstrument getInstrument() {
+        // Create Instrument object around my performer
+        SimpleInstrument ins = new SimpleInstrument();
+        ins.setName(getName());
+        ins.add(getPerformer());
+        ins.setPatch(getPatch());
+        return ins;
+
+    }
+
+    public Soundbank getSoundBank() {
+        // Create Soundbank object around the instrument
+        SimpleSoundbank sbk = new SimpleSoundbank();
+        sbk.addInstrument(getInstrument());
+        return sbk;
+    }
+
+    public String getDescription() {
+        return getName();
+    }
+
+    public Instrument getInstrument(Patch patch) {
+        Instrument ins = getInstrument();
+        Patch p = ins.getPatch();
+        if (p.getBank() != patch.getBank())
+            return null;
+        if (p.getProgram() != patch.getProgram())
+            return null;
+        if (p instanceof ModelPatch && patch instanceof ModelPatch) {
+            if (((ModelPatch)p).isPercussion()
+                    != ((ModelPatch)patch).isPercussion()) {
+                return null;
+            }
+        }
+        return ins;
+    }
+
+    public Instrument[] getInstruments() {
+        return new Instrument[]{getInstrument()};
+    }
+
+    public SoundbankResource[] getResources() {
+        return new SoundbankResource[0];
+    }
+
+    public String getVendor() {
+        return null;
+    }
+
+    public String getVersion() {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelByteBuffer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.util.Collection;
+
+/**
+ * This class is a pointer to a binary array either in memory or on disk.
+ *
+ * @author Karl Helgason
+ */
+public class ModelByteBuffer {
+
+    private ModelByteBuffer root = this;
+    private File file;
+    private long fileoffset;
+    private byte[] buffer;
+    private long offset;
+    private final long len;
+
+    private class RandomFileInputStream extends InputStream {
+
+        private RandomAccessFile raf;
+        private long left;
+        private long mark = 0;
+        private long markleft = 0;
+
+        public RandomFileInputStream() throws IOException {
+            raf = new RandomAccessFile(root.file, "r");
+            raf.seek(root.fileoffset + arrayOffset());
+            left = capacity();
+        }
+
+        public int available() throws IOException {
+            if (left > Integer.MAX_VALUE)
+                return Integer.MAX_VALUE;
+            return (int)left;
+        }
+
+        public synchronized void mark(int readlimit) {
+            try {
+                mark = raf.getFilePointer();
+                markleft = left;
+            } catch (IOException e) {
+                //e.printStackTrace();
+            }
+        }
+
+        public boolean markSupported() {
+            return true;
+        }
+
+        public synchronized void reset() throws IOException {
+            raf.seek(mark);
+            left = markleft;
+        }
+
+        public long skip(long n) throws IOException {
+            if( n < 0)
+                return 0;
+            if (n > left)
+                n = left;
+            long p = raf.getFilePointer();
+            raf.seek(p + n);
+            left -= n;
+            return n;
+        }
+
+        public int read(byte b[], int off, int len) throws IOException {
+            if (len > left)
+                len = (int)left;
+            if (left == 0)
+                return -1;
+            len = raf.read(b, off, len);
+            if (len == -1)
+                return -1;
+            left -= len;
+            return len;
+        }
+
+        public int read(byte[] b) throws IOException {
+            int len = b.length;
+            if (len > left)
+                len = (int)left;
+            if (left == 0)
+                return -1;
+            len = raf.read(b, 0, len);
+            if (len == -1)
+                return -1;
+            left -= len;
+            return len;
+        }
+
+        public int read() throws IOException {
+            if (left == 0)
+                return -1;
+            int b = raf.read();
+            if (b == -1)
+                return -1;
+            left--;
+            return b;
+        }
+
+        public void close() throws IOException {
+            raf.close();
+        }
+    }
+
+    private ModelByteBuffer(ModelByteBuffer parent,
+            long beginIndex, long endIndex, boolean independent) {
+        this.root = parent.root;
+        this.offset = 0;
+        long parent_len = parent.len;
+        if (beginIndex < 0)
+            beginIndex = 0;
+        if (beginIndex > parent_len)
+            beginIndex = parent_len;
+        if (endIndex < 0)
+            endIndex = 0;
+        if (endIndex > parent_len)
+            endIndex = parent_len;
+        if (beginIndex > endIndex)
+            beginIndex = endIndex;
+        offset = beginIndex;
+        len = endIndex - beginIndex;
+        if (independent) {
+            buffer = root.buffer;
+            if (root.file != null) {
+                file = root.file;
+                fileoffset = root.fileoffset + arrayOffset();
+                offset = 0;
+            } else
+                offset = arrayOffset();
+            root = this;
+        }
+    }
+
+    public ModelByteBuffer(byte[] buffer) {
+        this.buffer = buffer;
+        this.offset = 0;
+        this.len = buffer.length;
+    }
+
+    public ModelByteBuffer(byte[] buffer, int offset, int len) {
+        this.buffer = buffer;
+        this.offset = offset;
+        this.len = len;
+    }
+
+    public ModelByteBuffer(File file) {
+        this.file = file;
+        this.fileoffset = 0;
+        this.len = file.length();
+    }
+
+    public ModelByteBuffer(File file, long offset, long len) {
+        this.file = file;
+        this.fileoffset = offset;
+        this.len = len;
+    }
+
+    public void writeTo(OutputStream out) throws IOException {
+        if (root.file != null && root.buffer == null) {
+            InputStream is = getInputStream();
+            byte[] buff = new byte[1024];
+            int ret;
+            while ((ret = is.read(buff)) != -1)
+                out.write(buff, 0, ret);
+        } else
+            out.write(array(), (int) arrayOffset(), (int) capacity());
+    }
+
+    public InputStream getInputStream() {
+        if (root.file != null && root.buffer == null) {
+            try {
+                return new RandomFileInputStream();
+            } catch (IOException e) {
+                //e.printStackTrace();
+                return null;
+            }
+        }
+        return new ByteArrayInputStream(array(),
+                (int)arrayOffset(), (int)capacity());
+    }
+
+    public ModelByteBuffer subbuffer(long beginIndex) {
+        return subbuffer(beginIndex, capacity());
+    }
+
+    public ModelByteBuffer subbuffer(long beginIndex, long endIndex) {
+        return subbuffer(beginIndex, endIndex, false);
+    }
+
+    public ModelByteBuffer subbuffer(long beginIndex, long endIndex,
+            boolean independent) {
+        return new ModelByteBuffer(this, beginIndex, endIndex, independent);
+    }
+
+    public byte[] array() {
+        return root.buffer;
+    }
+
+    public long arrayOffset() {
+        if (root != this)
+            return root.arrayOffset() + offset;
+        return offset;
+    }
+
+    public long capacity() {
+        return len;
+    }
+
+    public ModelByteBuffer getRoot() {
+        return root;
+    }
+
+    public File getFile() {
+        return file;
+    }
+
+    public long getFilePointer() {
+        return fileoffset;
+    }
+
+    public static void loadAll(Collection<ModelByteBuffer> col)
+            throws IOException {
+        File selfile = null;
+        RandomAccessFile raf = null;
+        try {
+            for (ModelByteBuffer mbuff : col) {
+                mbuff = mbuff.root;
+                if (mbuff.file == null)
+                    continue;
+                if (mbuff.buffer != null)
+                    continue;
+                if (selfile == null || !selfile.equals(mbuff.file)) {
+                    if (raf != null) {
+                        raf.close();
+                        raf = null;
+                    }
+                    selfile = mbuff.file;
+                    raf = new RandomAccessFile(mbuff.file, "r");
+                }
+                raf.seek(mbuff.fileoffset);
+                byte[] buffer = new byte[(int) mbuff.capacity()];
+
+                int read = 0;
+                int avail = buffer.length;
+                while (read != avail) {
+                    if (avail - read > 65536) {
+                        raf.readFully(buffer, read, 65536);
+                        read += 65536;
+                    } else {
+                        raf.readFully(buffer, read, avail - read);
+                        read = avail;
+                    }
+
+                }
+
+                mbuff.buffer = buffer;
+                mbuff.offset = 0;
+            }
+        } finally {
+            if (raf != null)
+                raf.close();
+        }
+    }
+
+    public void load() throws IOException {
+        if (root != this) {
+            root.load();
+            return;
+        }
+        if (buffer != null)
+            return;
+        if (file == null) {
+            throw new IllegalStateException(
+                    "No file associated with this ByteBuffer!");
+        }
+
+        DataInputStream is = new DataInputStream(getInputStream());
+        buffer = new byte[(int) capacity()];
+        offset = 0;
+        is.readFully(buffer);
+        is.close();
+
+    }
+
+    public void unload() {
+        if (root != this) {
+            root.unload();
+            return;
+        }
+        if (file == null) {
+            throw new IllegalStateException(
+                    "No file associated with this ByteBuffer!");
+        }
+        root.buffer = null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,281 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.io.InputStream;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+/**
+ * Wavetable oscillator for pre-loaded data.
+ *
+ * @author Karl Helgason
+ */
+public class ModelByteBufferWavetable implements ModelWavetable {
+
+    private class Buffer8PlusInputStream extends InputStream {
+
+        private boolean bigendian;
+        private int framesize_pc;
+        int pos = 0;
+        int pos2 = 0;
+        int markpos = 0;
+        int markpos2 = 0;
+
+        public Buffer8PlusInputStream() {
+            framesize_pc = format.getFrameSize() / format.getChannels();
+            bigendian = format.isBigEndian();
+        }
+
+        public int read(byte[] b, int off, int len) throws IOException {
+            int avail = available();
+            if (avail <= 0)
+                return -1;
+            if (len > avail)
+                len = avail;
+            byte[] buff1 = buffer.array();
+            byte[] buff2 = buffer8.array();
+            pos += buffer.arrayOffset();
+            pos2 += buffer8.arrayOffset();
+            if (bigendian) {
+                for (int i = 0; i < len; i += (framesize_pc + 1)) {
+                    System.arraycopy(buff1, pos, b, i, framesize_pc);
+                    System.arraycopy(buff2, pos2, b, i + framesize_pc, 1);
+                    pos += framesize_pc;
+                    pos2 += 1;
+                }
+            } else {
+                for (int i = 0; i < len; i += (framesize_pc + 1)) {
+                    System.arraycopy(buff2, pos2, b, i, 1);
+                    System.arraycopy(buff1, pos, b, i + 1, framesize_pc);
+                    pos += framesize_pc;
+                    pos2 += 1;
+                }
+            }
+            pos -= buffer.arrayOffset();
+            pos2 -= buffer8.arrayOffset();
+            return len;
+        }
+
+        public long skip(long n) throws IOException {
+            int avail = available();
+            if (avail <= 0)
+                return -1;
+            if (n > avail)
+                n = avail;
+            pos += (n / (framesize_pc + 1)) * (framesize_pc);
+            pos2 += n / (framesize_pc + 1);
+            return super.skip(n);
+        }
+
+        public int read(byte[] b) throws IOException {
+            return read(b, 0, b.length);
+        }
+
+        public int read() throws IOException {
+            byte[] b = new byte[1];
+            int ret = read(b, 0, 1);
+            if (ret == -1)
+                return -1;
+            return 0 & 0xFF;
+        }
+
+        public boolean markSupported() {
+            return true;
+        }
+
+        public int available() throws IOException {
+            return (int)buffer.capacity() + (int)buffer8.capacity() - pos - pos2;
+        }
+
+        public synchronized void mark(int readlimit) {
+            markpos = pos;
+            markpos2 = pos2;
+        }
+
+        public synchronized void reset() throws IOException {
+            pos = markpos;
+            pos2 = markpos2;
+
+        }
+    }
+
+    private float loopStart = -1;
+    private float loopLength = -1;
+    private ModelByteBuffer buffer;
+    private ModelByteBuffer buffer8 = null;
+    private AudioFormat format = null;
+    private float pitchcorrection = 0;
+    private float attenuation = 0;
+    private int loopType = LOOP_TYPE_OFF;
+
+    public ModelByteBufferWavetable(ModelByteBuffer buffer) {
+        this.buffer = buffer;
+    }
+
+    public ModelByteBufferWavetable(ModelByteBuffer buffer,
+            float pitchcorrection) {
+        this.buffer = buffer;
+        this.pitchcorrection = pitchcorrection;
+    }
+
+    public ModelByteBufferWavetable(ModelByteBuffer buffer, AudioFormat format) {
+        this.format = format;
+        this.buffer = buffer;
+    }
+
+    public ModelByteBufferWavetable(ModelByteBuffer buffer, AudioFormat format,
+            float pitchcorrection) {
+        this.format = format;
+        this.buffer = buffer;
+        this.pitchcorrection = pitchcorrection;
+    }
+
+    public void set8BitExtensionBuffer(ModelByteBuffer buffer) {
+        buffer8 = buffer;
+    }
+
+    public ModelByteBuffer get8BitExtensionBuffer() {
+        return buffer8;
+    }
+
+    public ModelByteBuffer getBuffer() {
+        return buffer;
+    }
+
+    public AudioFormat getFormat() {
+        if (format == null) {
+            if (buffer == null)
+                return null;
+            InputStream is = buffer.getInputStream();
+            AudioFormat format = null;
+            try {
+                format = AudioSystem.getAudioFileFormat(is).getFormat();
+            } catch (Exception e) {
+                //e.printStackTrace();
+            }
+            try {
+                is.close();
+            } catch (IOException e) {
+                //e.printStackTrace();
+            }
+            return format;
+        }
+        return format;
+    }
+
+    public AudioFloatInputStream openStream() {
+        if (buffer == null)
+            return null;
+        if (format == null) {
+            InputStream is = buffer.getInputStream();
+            AudioInputStream ais = null;
+            try {
+                ais = AudioSystem.getAudioInputStream(is);
+            } catch (Exception e) {
+                //e.printStackTrace();
+                return null;
+            }
+            return AudioFloatInputStream.getInputStream(ais);
+        }
+        if (buffer.array() == null) {
+            return AudioFloatInputStream.getInputStream(new AudioInputStream(
+                    buffer.getInputStream(), format, buffer.capacity()));
+        }
+        if (buffer8 != null) {
+            if (format.getEncoding().equals(Encoding.PCM_SIGNED)
+                    || format.getEncoding().equals(Encoding.PCM_UNSIGNED)) {
+                InputStream is = new Buffer8PlusInputStream();
+                AudioFormat format2 = new AudioFormat(
+                        format.getEncoding(),
+                        format.getSampleRate(),
+                        format.getSampleSizeInBits() + 8,
+                        format.getChannels(),
+                        format.getFrameSize() + (1 * format.getChannels()),
+                        format.getFrameRate(),
+                        format.isBigEndian());
+
+                AudioInputStream ais = new AudioInputStream(is, format2,
+                        buffer.capacity() / format.getFrameSize());
+                return AudioFloatInputStream.getInputStream(ais);
+            }
+        }
+        return AudioFloatInputStream.getInputStream(format, buffer.array(),
+                (int)buffer.arrayOffset(), (int)buffer.capacity());
+    }
+
+    public int getChannels() {
+        return getFormat().getChannels();
+    }
+
+    public ModelOscillatorStream open(float samplerate) {
+        // ModelWavetableOscillator doesn't support ModelOscillatorStream
+        return null;
+    }
+
+    // attenuation is in cB
+    public float getAttenuation() {
+        return attenuation;
+    }
+    // attenuation is in cB
+    public void setAttenuation(float attenuation) {
+        this.attenuation = attenuation;
+    }
+
+    public float getLoopLength() {
+        return loopLength;
+    }
+
+    public void setLoopLength(float loopLength) {
+        this.loopLength = loopLength;
+    }
+
+    public float getLoopStart() {
+        return loopStart;
+    }
+
+    public void setLoopStart(float loopStart) {
+        this.loopStart = loopStart;
+    }
+
+    public void setLoopType(int loopType) {
+        this.loopType = loopType;
+    }
+
+    public int getLoopType() {
+        return loopType;
+    }
+
+    public float getPitchcorrection() {
+        return pitchcorrection;
+    }
+
+    public void setPitchcorrection(float pitchcorrection) {
+        this.pitchcorrection = pitchcorrection;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelChannelMixer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.MidiChannel;
+
+/**
+ * ModelChannelMixer is used to process channel voice mix output before going
+ * to master output.<br>
+ * It can be used to:<br>
+ * <ul>
+ *   <li>Implement non-voice oriented instruments.</li>
+ *   <li>Add insert effect to instruments; for example distortion effect.</li>
+ * </ui>
+ * <p>
+ * <b>Warning! Classes that implements ModelChannelMixer must be thread-safe.</b>
+ *
+ * @author Karl Helgason
+ */
+public interface ModelChannelMixer extends MidiChannel {
+
+    // Used to process input audio from voices mix.
+    public boolean process(float[][] buffer, int offset, int len);
+
+    // Is used to trigger that this mixer is not be used
+    // and it should fade out.
+    public void stop();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelConnectionBlock.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Connection blocks are used to connect source variable
+ * to a destination variable.
+ * For example Note On velocity can be connected to output gain.
+ * In DLS this is called articulator and in SoundFonts (SF2) a modulator.
+ *
+ * @author Karl Helgason
+ */
+public class ModelConnectionBlock {
+
+    //
+    //   source1 * source2 * scale -> destination
+    //
+    private final static ModelSource[] no_sources = new ModelSource[0];
+    private ModelSource[] sources = no_sources;
+    private double scale = 1;
+    private ModelDestination destination;
+
+    public ModelConnectionBlock() {
+    }
+
+    public ModelConnectionBlock(double scale, ModelDestination destination) {
+        this.scale = scale;
+        this.destination = destination;
+    }
+
+    public ModelConnectionBlock(ModelSource source,
+            ModelDestination destination) {
+        if (source != null) {
+            this.sources = new ModelSource[1];
+            this.sources[0] = source;
+        }
+        this.destination = destination;
+    }
+
+    public ModelConnectionBlock(ModelSource source, double scale,
+            ModelDestination destination) {
+        if (source != null) {
+            this.sources = new ModelSource[1];
+            this.sources[0] = source;
+        }
+        this.scale = scale;
+        this.destination = destination;
+    }
+
+    public ModelConnectionBlock(ModelSource source, ModelSource control,
+            ModelDestination destination) {
+        if (source != null) {
+            if (control == null) {
+                this.sources = new ModelSource[1];
+                this.sources[0] = source;
+            } else {
+                this.sources = new ModelSource[2];
+                this.sources[0] = source;
+                this.sources[1] = control;
+            }
+        }
+        this.destination = destination;
+    }
+
+    public ModelConnectionBlock(ModelSource source, ModelSource control,
+            double scale, ModelDestination destination) {
+        if (source != null) {
+            if (control == null) {
+                this.sources = new ModelSource[1];
+                this.sources[0] = source;
+            } else {
+                this.sources = new ModelSource[2];
+                this.sources[0] = source;
+                this.sources[1] = control;
+            }
+        }
+        this.scale = scale;
+        this.destination = destination;
+    }
+
+    public ModelDestination getDestination() {
+        return destination;
+    }
+
+    public void setDestination(ModelDestination destination) {
+        this.destination = destination;
+    }
+
+    public double getScale() {
+        return scale;
+    }
+
+    public void setScale(double scale) {
+        this.scale = scale;
+    }
+
+    public ModelSource[] getSources() {
+        return sources;
+    }
+
+    public void setSources(ModelSource[] source) {
+        this.sources = source;
+    }
+
+    public void addSource(ModelSource source) {
+        ModelSource[] oldsources = sources;
+        sources = new ModelSource[oldsources.length + 1];
+        for (int i = 0; i < oldsources.length; i++) {
+            sources[i] = oldsources[i];
+        }
+        sources[sources.length - 1] = source;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelDestination.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to identify destinations in connection blocks,
+ * see ModelConnectionBlock.
+ *
+ * @author Karl Helgason
+ */
+public class ModelDestination {
+
+    public static final ModelIdentifier DESTINATION_NONE = null;
+    public static final ModelIdentifier DESTINATION_KEYNUMBER
+            = new ModelIdentifier("noteon", "keynumber");
+    public static final ModelIdentifier DESTINATION_VELOCITY
+            = new ModelIdentifier("noteon", "velocity");
+    public static final ModelIdentifier DESTINATION_PITCH
+            = new ModelIdentifier("osc", "pitch");   // cent
+    public static final ModelIdentifier DESTINATION_GAIN
+            = new ModelIdentifier("mixer", "gain");   // cB
+    public static final ModelIdentifier DESTINATION_PAN
+            = new ModelIdentifier("mixer", "pan");   // 0.1 %
+    public static final ModelIdentifier DESTINATION_REVERB
+            = new ModelIdentifier("mixer", "reverb");   // 0.1 %
+    public static final ModelIdentifier DESTINATION_CHORUS
+            = new ModelIdentifier("mixer", "chorus");   // 0.1 %
+    public static final ModelIdentifier DESTINATION_LFO1_DELAY
+            = new ModelIdentifier("lfo", "delay", 0); // timecent
+    public static final ModelIdentifier DESTINATION_LFO1_FREQ
+            = new ModelIdentifier("lfo", "freq", 0); // cent
+    public static final ModelIdentifier DESTINATION_LFO2_DELAY
+            = new ModelIdentifier("lfo", "delay", 1); // timecent
+    public static final ModelIdentifier DESTINATION_LFO2_FREQ
+            = new ModelIdentifier("lfo", "freq", 1); // cent
+    public static final ModelIdentifier DESTINATION_EG1_DELAY
+            = new ModelIdentifier("eg", "delay", 0); // timecent
+    public static final ModelIdentifier DESTINATION_EG1_ATTACK
+            = new ModelIdentifier("eg", "attack", 0); // timecent
+    public static final ModelIdentifier DESTINATION_EG1_HOLD
+            = new ModelIdentifier("eg", "hold", 0); // timecent
+    public static final ModelIdentifier DESTINATION_EG1_DECAY
+            = new ModelIdentifier("eg", "decay", 0); // timecent
+    public static final ModelIdentifier DESTINATION_EG1_SUSTAIN
+            = new ModelIdentifier("eg", "sustain", 0);
+                                        // 0.1 % (I want this to be value not %)
+    public static final ModelIdentifier DESTINATION_EG1_RELEASE
+            = new ModelIdentifier("eg", "release", 0); // timecent
+    public static final ModelIdentifier DESTINATION_EG1_SHUTDOWN
+            = new ModelIdentifier("eg", "shutdown", 0); // timecent
+    public static final ModelIdentifier DESTINATION_EG2_DELAY
+            = new ModelIdentifier("eg", "delay", 1); // timecent
+    public static final ModelIdentifier DESTINATION_EG2_ATTACK
+            = new ModelIdentifier("eg", "attack", 1); // timecent
+    public static final ModelIdentifier DESTINATION_EG2_HOLD
+            = new ModelIdentifier("eg", "hold", 1); // 0.1 %
+    public static final ModelIdentifier DESTINATION_EG2_DECAY
+            = new ModelIdentifier("eg", "decay", 1); // timecent
+    public static final ModelIdentifier DESTINATION_EG2_SUSTAIN
+            = new ModelIdentifier("eg", "sustain", 1);
+                                        // 0.1 % ( I want this to be value not %)
+    public static final ModelIdentifier DESTINATION_EG2_RELEASE
+            = new ModelIdentifier("eg", "release", 1); // timecent
+    public static final ModelIdentifier DESTINATION_EG2_SHUTDOWN
+            = new ModelIdentifier("eg", "shutdown", 1); // timecent
+    public static final ModelIdentifier DESTINATION_FILTER_FREQ
+            = new ModelIdentifier("filter", "freq", 0); // cent
+    public static final ModelIdentifier DESTINATION_FILTER_Q
+            = new ModelIdentifier("filter", "q", 0); // cB
+    private ModelIdentifier destination = DESTINATION_NONE;
+    private ModelTransform transform = new ModelStandardTransform();
+
+    public ModelDestination() {
+    }
+
+    public ModelDestination(ModelIdentifier id) {
+        destination = id;
+    }
+
+    public ModelIdentifier getIdentifier() {
+        return destination;
+    }
+
+    public void setIdentifier(ModelIdentifier destination) {
+        this.destination = destination;
+    }
+
+    public ModelTransform getTransform() {
+        return transform;
+    }
+
+    public void setTransform(ModelTransform transform) {
+        this.transform = transform;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelDirectedPlayer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ *  ModelDirectedPlayer is the one who is directed by ModelDirector
+ *  to play ModelPerformer objects.
+ *
+ * @author Karl Helgason
+ */
+public interface ModelDirectedPlayer {
+
+    public void play(int performerIndex, ModelConnectionBlock[] connectionBlocks);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelDirector.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A director chooses what performers should be  played for each note on
+ * and note off events.
+ *
+ * ModelInstrument can implement custom performer who chooses what performers
+ * to play for example by sustain pedal is off or on.
+ *
+ * The default director (ModelStandardDirector) chooses performers
+ * by there keyfrom,keyto,velfrom,velto properties.
+ *
+ * @author Karl Helgason
+ */
+public interface ModelDirector {
+
+    public void noteOn(int noteNumber, int velocity);
+
+    public void noteOff(int noteNumber, int velocity);
+
+    public void close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelIdentifier.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class stores the identity of source and destinations in connection
+ * blocks, see ModelConnectionBlock.
+ *
+ * @author Karl Helgason
+ */
+public class ModelIdentifier {
+
+    /*
+     *  Object    Variable
+     *  ------    --------
+     *
+     *  // INPUT parameters
+     *  noteon    keynumber                7 bit midi value
+     *            velocity                 7 bit midi vale
+     *            on                       1 or 0
+     *
+     *  midi      pitch                    14 bit midi value
+     *            channel_pressure         7 bit midi value
+     *            poly_pressure            7 bit midi value
+     *
+     *  midi_cc   0 (midi control #0       7 bit midi value
+     *            1 (midi control #1       7 bit midi value
+     *            ...
+     *            127 (midi control #127   7 bit midi value
+     *
+     *  midi_rpn  0 (midi rpn control #0)  14 bit midi value
+     *            1 (midi rpn control #1)  14 bit midi value
+     *            ....
+     *
+     *  // DAHDSR envelope generator
+     *  eg        (null)
+     *            delay                    timecent
+     *            attack                   timecent
+     *            hold                     timecent
+     *            decay                    timecent
+     *            sustain                  0.1 %
+     *            release                  timecent
+     *
+     *  // Low frequency oscillirator (sine wave)
+     *  lfo       (null)
+     *            delay                    timcent
+     *            freq                     cent
+     *
+     *  // Resonance LowPass Filter 6dB slope
+     *  filter    (null) (output/input)
+     *            freq                     cent
+     *            q                        cB
+     *
+     *  // The oscillator with preloaded wavetable data
+     *  osc       (null)
+     *            pitch                    cent
+     *
+     *  // Output mixer pins
+     *  mixer     gain                     cB
+     *            pan                      0.1 %
+     *            reverb                   0.1 %
+     *            chorus                   0.1 %
+     *
+     */
+    private String object = null;
+    private String variable = null;
+    private int instance = 0;
+
+    public ModelIdentifier(String object) {
+        this.object = object;
+    }
+
+    public ModelIdentifier(String object, int instance) {
+        this.object = object;
+        this.instance = instance;
+    }
+
+    public ModelIdentifier(String object, String variable) {
+        this.object = object;
+        this.variable = variable;
+
+    }
+
+    public ModelIdentifier(String object, String variable, int instance) {
+        this.object = object;
+        this.variable = variable;
+        this.instance = instance;
+
+    }
+
+    public int getInstance() {
+        return instance;
+    }
+
+    public void setInstance(int instance) {
+        this.instance = instance;
+    }
+
+    public String getObject() {
+        return object;
+    }
+
+    public void setObject(String object) {
+        this.object = object;
+    }
+
+    public String getVariable() {
+        return variable;
+    }
+
+    public void setVariable(String variable) {
+        this.variable = variable;
+    }
+
+    public int hashCode() {
+        int hashcode = instance;
+        if(object != null) hashcode |= object.hashCode();
+        if(variable != null) hashcode |= variable.hashCode();
+        return  hashcode;
+    }
+
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ModelIdentifier))
+            return false;
+
+        ModelIdentifier mobj = (ModelIdentifier)obj;
+        if ((object == null) != (mobj.object == null))
+            return false;
+        if ((variable == null) != (mobj.variable == null))
+            return false;
+        if (mobj.getInstance() != getInstance())
+            return false;
+        if (!(object == null || object.equals(mobj.object)))
+            return false;
+        if (!(variable == null || variable.equals(mobj.variable)))
+            return false;
+        return true;
+    }
+
+    public String toString() {
+        if (variable == null) {
+            return object + "[" + instance + "]";
+        } else {
+            return object + "[" + instance + "]" + "." + variable;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelInstrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * The model instrument class.
+ *
+ * <p>The main methods to override are:<br>
+ * getPerformer, getDirector, getChannelMixer.
+ *
+ * <p>Performers are used to define what voices which will
+ * playback when using the instrument.<br>
+ *
+ * ChannelMixer is used to add channel-wide processing
+ * on voices output or to define non-voice oriented instruments.<br>
+ *
+ * Director is used to change how the synthesizer
+ * chooses what performers to play on midi events.
+ *
+ * @author Karl Helgason
+ */
+public abstract class ModelInstrument extends Instrument {
+
+    protected ModelInstrument(Soundbank soundbank, Patch patch, String name,
+            Class<?> dataClass) {
+        super(soundbank, patch, name, dataClass);
+    }
+
+    public ModelDirector getDirector(ModelPerformer[] performers,
+            MidiChannel channel, ModelDirectedPlayer player) {
+        return new ModelStandardDirector(performers, player);
+    }
+
+    public ModelPerformer[] getPerformers() {
+        return new ModelPerformer[0];
+    }
+
+    public ModelChannelMixer getChannelMixer(MidiChannel channel,
+            AudioFormat format) {
+        return null;
+    }
+
+    // Get General MIDI 2 Alias patch for this instrument.
+    public Patch getPatchAlias() {
+        Patch patch = getPatch();
+        int program = patch.getProgram();
+        int bank = patch.getBank();
+        if (bank != 0)
+            return patch;
+        boolean percussion = false;
+        if (getPatch() instanceof ModelPatch)
+            percussion = ((ModelPatch)getPatch()).isPercussion();
+        if (percussion)
+            return new Patch(0x78 << 7, program);
+        else
+            return new Patch(0x79 << 7, program);
+    }
+
+    // Return name of all the keys.
+    // This information is generated from ModelPerformer.getName()
+    // returned from getPerformers().
+    public String[] getKeys() {
+        String[] keys = new String[128];
+        for (ModelPerformer performer : getPerformers()) {
+            for (int k = performer.getKeyFrom(); k <= performer.getKeyTo(); k++) {
+                if (k >= 0 && k < 128 && keys[k] == null) {
+                    String name = performer.getName();
+                    if (name == null)
+                        name = "untitled";
+                    keys[k] = name;
+                }
+            }
+        }
+        return keys;
+    }
+
+    // Return what channels this instrument will probably response
+    // on General MIDI synthesizer.
+    public boolean[] getChannels() {
+        boolean percussion = false;
+        if (getPatch() instanceof ModelPatch)
+            percussion = ((ModelPatch)getPatch()).isPercussion();
+
+        // Check if instrument is percussion.
+        if (percussion) {
+            boolean[] ch = new boolean[16];
+            for (int i = 0; i < ch.length; i++)
+                ch[i] = false;
+            ch[9] = true;
+            return ch;
+        }
+
+        // Check if instrument uses General MIDI 2 default banks.
+        int bank = getPatch().getBank();
+        if (bank >> 7 == 0x78 || bank >> 7 == 0x79) {
+            boolean[] ch = new boolean[16];
+            for (int i = 0; i < ch.length; i++)
+                ch[i] = true;
+            return ch;
+        }
+
+        boolean[] ch = new boolean[16];
+        for (int i = 0; i < ch.length; i++)
+            ch[i] = true;
+        ch[9] = false;
+        return ch;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelInstrumentComparator.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Comparator;
+import javax.sound.midi.Instrument;
+import javax.sound.midi.Patch;
+
+/**
+ * Instrument comparator class.
+ * Used to order instrument by program, bank, percussion.
+ *
+ * @author Karl Helgason
+ */
+public class ModelInstrumentComparator implements Comparator<Instrument> {
+
+    public int compare(Instrument arg0, Instrument arg1) {
+        Patch p0 = arg0.getPatch();
+        Patch p1 = arg1.getPatch();
+        int a = p0.getBank() * 128 + p0.getProgram();
+        int b = p1.getBank() * 128 + p1.getProgram();
+        if (p0 instanceof ModelPatch) {
+            a += ((ModelPatch)p0).isPercussion() ? 2097152 : 0;
+        }
+        if (p1 instanceof ModelPatch) {
+            b += ((ModelPatch)p1).isPercussion() ? 2097152 : 0;
+        }
+        return a - b;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelMappedInstrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * This class is used to map instrument to another patch.
+ *
+ * @author Karl Helgason
+ */
+public class ModelMappedInstrument extends ModelInstrument {
+
+    private ModelInstrument ins;
+
+    public ModelMappedInstrument(ModelInstrument ins, Patch patch) {
+        super(ins.getSoundbank(), patch, ins.getName(), ins.getDataClass());
+        this.ins = ins;
+    }
+
+    public Object getData() {
+        return ins.getData();
+    }
+
+    public ModelPerformer[] getPerformers() {
+        return ins.getPerformers();
+    }
+
+    public ModelDirector getDirector(ModelPerformer[] performers,
+            MidiChannel channel, ModelDirectedPlayer player) {
+        return ins.getDirector(performers, channel, player);
+    }
+
+    public ModelChannelMixer getChannelMixer(MidiChannel channel,
+            AudioFormat format) {
+        return ins.getChannelMixer(channel, format);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelOscillator.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This interface is used for oscillators.
+ * See example in ModelDefaultOscillator which is a wavetable oscillator.
+ *
+ * @author Karl Helgason
+ */
+public interface ModelOscillator {
+
+    public int getChannels();
+
+    /**
+     * Attenuation is in cB.
+     * @return
+     */
+    public float getAttenuation();
+
+    public ModelOscillatorStream open(float samplerate);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelOscillatorStream.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.VoiceStatus;
+
+/**
+ * This interface is used for audio streams from ModelOscillator.
+ *
+ * @author Karl Helgason
+ */
+public interface ModelOscillatorStream {
+
+    public void setPitch(float pitch); // Pitch is in cents!
+
+    public void noteOn(MidiChannel channel, VoiceStatus voice, int noteNumber,
+            int velocity);
+
+    public void noteOff(int velocity);
+
+    public int read(float[][] buffer, int offset, int len) throws IOException;
+
+    public void close() throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelPatch.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.Patch;
+
+/**
+ * A extended patch object that has isPercussion function.
+ * Which is necessary to identify percussion instruments
+ * from melodic instruments.
+ *
+ * @author Karl Helgason
+ */
+public class ModelPatch extends Patch {
+
+    private boolean percussion = false;
+
+    public ModelPatch(int bank, int program) {
+        super(bank, program);
+    }
+
+    public ModelPatch(int bank, int program, boolean percussion) {
+        super(bank, program);
+        this.percussion = percussion;
+    }
+
+    public boolean isPercussion() {
+        return percussion;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelPerformer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class is used to define how to synthesize audio in universal maner
+ * for both SF2 and DLS instruments.
+ *
+ * @author Karl Helgason
+ */
+public class ModelPerformer {
+
+    private List<ModelOscillator> oscillators = new ArrayList<ModelOscillator>();
+    private List<ModelConnectionBlock> connectionBlocks
+            = new ArrayList<ModelConnectionBlock>();
+    private int keyFrom = 0;
+    private int keyTo = 127;
+    private int velFrom = 0;
+    private int velTo = 127;
+    private int exclusiveClass = 0;
+    private boolean releaseTrigger = false;
+    private boolean selfNonExclusive = false;
+    private Object userObject = null;
+    private boolean addDefaultConnections = true;
+    private String name = null;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<ModelConnectionBlock> getConnectionBlocks() {
+        return connectionBlocks;
+    }
+
+    public void setConnectionBlocks(List<ModelConnectionBlock> connectionBlocks) {
+        this.connectionBlocks = connectionBlocks;
+    }
+
+    public List<ModelOscillator> getOscillators() {
+        return oscillators;
+    }
+
+    public int getExclusiveClass() {
+        return exclusiveClass;
+    }
+
+    public void setExclusiveClass(int exclusiveClass) {
+        this.exclusiveClass = exclusiveClass;
+    }
+
+    public boolean isSelfNonExclusive() {
+        return selfNonExclusive;
+    }
+
+    public void setSelfNonExclusive(boolean selfNonExclusive) {
+        this.selfNonExclusive = selfNonExclusive;
+    }
+
+    public int getKeyFrom() {
+        return keyFrom;
+    }
+
+    public void setKeyFrom(int keyFrom) {
+        this.keyFrom = keyFrom;
+    }
+
+    public int getKeyTo() {
+        return keyTo;
+    }
+
+    public void setKeyTo(int keyTo) {
+        this.keyTo = keyTo;
+    }
+
+    public int getVelFrom() {
+        return velFrom;
+    }
+
+    public void setVelFrom(int velFrom) {
+        this.velFrom = velFrom;
+    }
+
+    public int getVelTo() {
+        return velTo;
+    }
+
+    public void setVelTo(int velTo) {
+        this.velTo = velTo;
+    }
+
+    public boolean isReleaseTriggered() {
+        return releaseTrigger;
+    }
+
+    public void setReleaseTriggered(boolean value) {
+        this.releaseTrigger = value;
+    }
+
+    public Object getUserObject() {
+        return userObject;
+    }
+
+    public void setUserObject(Object object) {
+        userObject = object;
+    }
+
+    public boolean isDefaultConnectionsEnabled() {
+        return addDefaultConnections;
+    }
+
+    public void setDefaultConnectionsEnabled(boolean addDefaultConnections) {
+        this.addDefaultConnections = addDefaultConnections;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelSource.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to identify sources in connection blocks,
+ * see ModelConnectionBlock.
+ *
+ * @author Karl Helgason
+ */
+public class ModelSource {
+
+    public static final ModelIdentifier SOURCE_NONE = null;
+    public static final ModelIdentifier SOURCE_NOTEON_KEYNUMBER =
+            new ModelIdentifier("noteon", "keynumber");     // midi keynumber
+    public static final ModelIdentifier SOURCE_NOTEON_VELOCITY =
+            new ModelIdentifier("noteon", "velocity");      // midi velocity
+    public static final ModelIdentifier SOURCE_EG1 =
+            new ModelIdentifier("eg", null, 0);
+    public static final ModelIdentifier SOURCE_EG2 =
+            new ModelIdentifier("eg", null, 1);
+    public static final ModelIdentifier SOURCE_LFO1 =
+            new ModelIdentifier("lfo", null, 0);
+    public static final ModelIdentifier SOURCE_LFO2 =
+            new ModelIdentifier("lfo", null, 1);
+    public static final ModelIdentifier SOURCE_MIDI_PITCH =
+            new ModelIdentifier("midi", "pitch", 0);            // (0..16383)
+    public static final ModelIdentifier SOURCE_MIDI_CHANNEL_PRESSURE =
+            new ModelIdentifier("midi", "channel_pressure", 0); // (0..127)
+//    public static final ModelIdentifier SOURCE_MIDI_MONO_PRESSURE =
+//            new ModelIdentifier("midi","mono_pressure",0);    // (0..127)
+    public static final ModelIdentifier SOURCE_MIDI_POLY_PRESSURE =
+            new ModelIdentifier("midi", "poly_pressure", 0);    // (0..127)
+    public static final ModelIdentifier SOURCE_MIDI_CC_0 =
+            new ModelIdentifier("midi_cc", "0", 0);             // (0..127)
+    public static final ModelIdentifier SOURCE_MIDI_RPN_0 =
+            new ModelIdentifier("midi_rpn", "0", 0);            // (0..16383)
+    private ModelIdentifier source = SOURCE_NONE;
+    private ModelTransform transform;
+
+    public ModelSource() {
+        this.transform = new ModelStandardTransform();
+    }
+
+    public ModelSource(ModelIdentifier id) {
+        source = id;
+        this.transform = new ModelStandardTransform();
+    }
+
+    public ModelSource(ModelIdentifier id, boolean direction) {
+        source = id;
+        this.transform = new ModelStandardTransform(direction);
+    }
+
+    public ModelSource(ModelIdentifier id, boolean direction, boolean polarity) {
+        source = id;
+        this.transform = new ModelStandardTransform(direction, polarity);
+    }
+
+    public ModelSource(ModelIdentifier id, boolean direction, boolean polarity,
+            int transform) {
+        source = id;
+        this.transform =
+                new ModelStandardTransform(direction, polarity, transform);
+    }
+
+    public ModelSource(ModelIdentifier id, ModelTransform transform) {
+        source = id;
+        this.transform = transform;
+    }
+
+    public ModelIdentifier getIdentifier() {
+        return source;
+    }
+
+    public void setIdentifier(ModelIdentifier source) {
+        this.source = source;
+    }
+
+    public ModelTransform getTransform() {
+        return transform;
+    }
+
+    public void setTransform(ModelTransform transform) {
+        this.transform = transform;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelStandardDirector.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A standard director who chooses performers
+ * by there keyfrom,keyto,velfrom,velto properties.
+ *
+ * @author Karl Helgason
+ */
+public class ModelStandardDirector implements ModelDirector {
+
+    ModelPerformer[] performers;
+    ModelDirectedPlayer player;
+    boolean noteOnUsed = false;
+    boolean noteOffUsed = false;
+
+    public ModelStandardDirector(ModelPerformer[] performers,
+            ModelDirectedPlayer player) {
+        this.performers = performers;
+        this.player = player;
+        for (int i = 0; i < performers.length; i++) {
+            ModelPerformer p = performers[i];
+            if (p.isReleaseTriggered()) {
+                noteOffUsed = true;
+            } else {
+                noteOnUsed = true;
+            }
+        }
+    }
+
+    public void close() {
+    }
+
+    public void noteOff(int noteNumber, int velocity) {
+        if (!noteOffUsed)
+            return;
+        for (int i = 0; i < performers.length; i++) {
+            ModelPerformer p = performers[i];
+            if (p.getKeyFrom() <= noteNumber && p.getKeyTo() >= noteNumber) {
+                if (p.getVelFrom() <= velocity && p.getVelTo() >= velocity) {
+                    if (p.isReleaseTriggered()) {
+                        player.play(i, null);
+                    }
+                }
+            }
+        }
+    }
+
+    public void noteOn(int noteNumber, int velocity) {
+        if (!noteOnUsed)
+            return;
+        for (int i = 0; i < performers.length; i++) {
+            ModelPerformer p = performers[i];
+            if (p.getKeyFrom() <= noteNumber && p.getKeyTo() >= noteNumber) {
+                if (p.getVelFrom() <= velocity && p.getVelTo() >= velocity) {
+                    if (!p.isReleaseTriggered()) {
+                        player.play(i, null);
+                    }
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelStandardTransform.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A standard transformer used in connection blocks.
+ * It expects input values to be between 0 and 1.
+ *
+ * The result of the transform is
+ *   between 0 and 1 if polarity = unipolar and
+ *   between -1 and 1 if polarity = bipolar.
+ *
+ * These constraints only applies to Concave, Convex and Switch transforms.
+ *
+ * @author Karl Helgason
+ */
+public class ModelStandardTransform implements ModelTransform {
+
+    public static final boolean DIRECTION_MIN2MAX = false;
+    public static final boolean DIRECTION_MAX2MIN = true;
+    public static final boolean POLARITY_UNIPOLAR = false;
+    public static final boolean POLARITY_BIPOLAR = true;
+    public static final int TRANSFORM_LINEAR = 0;
+    // concave: output = (20*log10(127^2/value^2)) / 96
+    public static final int TRANSFORM_CONCAVE = 1;
+    // convex: same as concave except that start and end point are reversed.
+    public static final int TRANSFORM_CONVEX = 2;
+    // switch: if value > avg(max,min) then max else min
+    public static final int TRANSFORM_SWITCH = 3;
+    public static final int TRANSFORM_ABSOLUTE = 4;
+    private boolean direction = DIRECTION_MIN2MAX;
+    private boolean polarity = POLARITY_UNIPOLAR;
+    private int transform = TRANSFORM_LINEAR;
+
+    public ModelStandardTransform() {
+    }
+
+    public ModelStandardTransform(boolean direction) {
+        this.direction = direction;
+    }
+
+    public ModelStandardTransform(boolean direction, boolean polarity) {
+        this.direction = direction;
+        this.polarity = polarity;
+    }
+
+    public ModelStandardTransform(boolean direction, boolean polarity,
+            int transform) {
+        this.direction = direction;
+        this.polarity = polarity;
+        this.transform = transform;
+    }
+
+    public double transform(double value) {
+        double s;
+        double a;
+        if (direction == DIRECTION_MAX2MIN)
+            value = 1.0 - value;
+        if (polarity == POLARITY_BIPOLAR)
+            value = value * 2.0 - 1.0;
+        switch (transform) {
+            case TRANSFORM_CONCAVE:
+                s = Math.signum(value);
+                a = Math.abs(value);
+                a = -((5.0 / 12.0) / Math.log(10)) * Math.log(1.0 - a);
+                if (a < 0)
+                    a = 0;
+                else if (a > 1)
+                    a = 1;
+                return s * a;
+            case TRANSFORM_CONVEX:
+                s = Math.signum(value);
+                a = Math.abs(value);
+                a = 1.0 + ((5.0 / 12.0) / Math.log(10)) * Math.log(a);
+                if (a < 0)
+                    a = 0;
+                else if (a > 1)
+                    a = 1;
+                return s * a;
+            case TRANSFORM_SWITCH:
+                if (polarity == POLARITY_BIPOLAR)
+                    return (value > 0) ? 1 : -1;
+                else
+                    return (value > 0.5) ? 1 : 0;
+            case TRANSFORM_ABSOLUTE:
+                return Math.abs(value);
+            default:
+                break;
+        }
+
+        return value;
+    }
+
+    public boolean getDirection() {
+        return direction;
+    }
+
+    public void setDirection(boolean direction) {
+        this.direction = direction;
+    }
+
+    public boolean getPolarity() {
+        return polarity;
+    }
+
+    public void setPolarity(boolean polarity) {
+        this.polarity = polarity;
+    }
+
+    public int getTransform() {
+        return transform;
+    }
+
+    public void setTransform(int transform) {
+        this.transform = transform;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelTransform.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Model transform interface.
+ *
+ * @author Karl Helgason
+ */
+public interface ModelTransform {
+
+    abstract public double transform(double value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelWavetable.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This is a wavetable oscillator interface.
+ *
+ * @author Karl Helgason
+ */
+public interface ModelWavetable extends ModelOscillator {
+
+    public static final int LOOP_TYPE_OFF = 0;
+    public static final int LOOP_TYPE_FORWARD = 1;
+    public static final int LOOP_TYPE_RELEASE = 2;
+    public static final int LOOP_TYPE_PINGPONG = 4;
+    public static final int LOOP_TYPE_REVERSE = 8;
+
+    public AudioFloatInputStream openStream();
+
+    public float getLoopLength();
+
+    public float getLoopStart();
+
+    public int getLoopType();
+
+    public float getPitchcorrection();
+}
--- a/jdk/src/share/classes/com/sun/media/sound/Platform.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/Platform.java	Wed Jul 05 16:46:22 2017 +0200
@@ -42,8 +42,6 @@
 
     // native library we need to load
     private static final String libNameMain     = "jsound";
-    private static final String libNameMain2    = "jsoundhs";
-
     private static final String libNameALSA     = "jsoundalsa";
     private static final String libNameDSound   = "jsoundds";
 
@@ -158,9 +156,8 @@
         if(Printer.trace)Printer.trace(">>Platform.loadLibraries");
 
         try {
-            // load the main libraries
+            // load the main library
             JSSecurityManager.loadLibrary(libNameMain);
-            JSSecurityManager.loadLibrary(libNameMain2);
             // just for the heck of it...
             loadedLibs |= LIB_MAIN;
         } catch (SecurityException e) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/RIFFInvalidDataException.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This exception is used when a RIFF file contains illegal or unexpected data.
+ *
+ * @author Karl Helgason
+ */
+public class RIFFInvalidDataException extends InvalidDataException {
+
+    private static final long serialVersionUID = 1L;
+
+    public RIFFInvalidDataException() {
+        super("Invalid Data!");
+    }
+
+    public RIFFInvalidDataException(String s) {
+        super(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/RIFFInvalidFormatException.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This exception is used when a reader is used to read RIFF file of a format it
+ * doesn't unterstand or support.
+ *
+ * @author Karl Helgason
+ */
+public class RIFFInvalidFormatException extends InvalidFormatException {
+
+    private static final long serialVersionUID = 1L;
+
+    public RIFFInvalidFormatException() {
+        super("Invalid format!");
+    }
+
+    public RIFFInvalidFormatException(String s) {
+        super(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/RIFFReader.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,332 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Resource Interchange File Format (RIFF) stream decoder.
+ *
+ * @author Karl Helgason
+ */
+public class RIFFReader extends InputStream {
+
+    private RIFFReader root;
+    private long filepointer = 0;
+    private String fourcc;
+    private String riff_type = null;
+    private long ckSize = 0;
+    private InputStream stream;
+    private long avail;
+    private RIFFReader lastiterator = null;
+
+    public RIFFReader(InputStream stream) throws IOException {
+
+        if (stream instanceof RIFFReader)
+            root = ((RIFFReader)stream).root;
+        else
+            root = this;
+
+        this.stream = stream;
+        avail = Integer.MAX_VALUE;
+        ckSize = Integer.MAX_VALUE;
+
+        // Check for RIFF null paddings,
+        int b;
+        while (true) {
+            b = read();
+            if (b == -1) {
+                fourcc = ""; // don't put null value into fourcc,
+                // because it is expected to
+                // always contain a string value
+                riff_type = null;
+                avail = 0;
+                return;
+            }
+            if (b != 0)
+                break;
+        }
+
+        byte[] fourcc = new byte[4];
+        fourcc[0] = (byte) b;
+        readFully(fourcc, 1, 3);
+        this.fourcc = new String(fourcc, "ascii");
+        ckSize = readUnsignedInt();
+
+        avail = this.ckSize;
+
+        if (getFormat().equals("RIFF") || getFormat().equals("LIST")) {
+            byte[] format = new byte[4];
+            readFully(format);
+            this.riff_type = new String(format, "ascii");
+        }
+    }
+
+    public long getFilePointer() throws IOException {
+        return root.filepointer;
+    }
+
+    public boolean hasNextChunk() throws IOException {
+        if (lastiterator != null)
+            lastiterator.finish();
+        return avail != 0;
+    }
+
+    public RIFFReader nextChunk() throws IOException {
+        if (lastiterator != null)
+            lastiterator.finish();
+        if (avail == 0)
+            return null;
+        lastiterator = new RIFFReader(this);
+        return lastiterator;
+    }
+
+    public String getFormat() {
+        return fourcc;
+    }
+
+    public String getType() {
+        return riff_type;
+    }
+
+    public long getSize() {
+        return ckSize;
+    }
+
+    public int read() throws IOException {
+        if (avail == 0)
+            return -1;
+        int b = stream.read();
+        if (b == -1)
+            return -1;
+        avail--;
+        filepointer++;
+        return b;
+    }
+
+    public int read(byte[] b, int offset, int len) throws IOException {
+        if (avail == 0)
+            return -1;
+        if (len > avail) {
+            int rlen = stream.read(b, offset, (int)avail);
+            if (rlen != -1)
+                filepointer += rlen;
+            avail = 0;
+            return rlen;
+        } else {
+            int ret = stream.read(b, offset, len);
+            if (ret == -1)
+                return -1;
+            avail -= ret;
+            filepointer += ret;
+            return ret;
+        }
+    }
+
+    public final void readFully(byte b[]) throws IOException {
+        readFully(b, 0, b.length);
+    }
+
+    public final void readFully(byte b[], int off, int len) throws IOException {
+        if (len < 0)
+            throw new IndexOutOfBoundsException();
+        while (len > 0) {
+            int s = read(b, off, len);
+            if (s < 0)
+                throw new EOFException();
+            if (s == 0)
+                Thread.yield();
+            off += s;
+            len -= s;
+        }
+    }
+
+    public final long skipBytes(long n) throws IOException {
+        if (n < 0)
+            return 0;
+        long skipped = 0;
+        while (skipped != n) {
+            long s = skip(n - skipped);
+            if (s < 0)
+                break;
+            if (s == 0)
+                Thread.yield();
+            skipped += s;
+        }
+        return skipped;
+    }
+
+    public long skip(long n) throws IOException {
+        if (avail == 0)
+            return -1;
+        if (n > avail) {
+            long len = stream.skip(avail);
+            if (len != -1)
+                filepointer += len;
+            avail = 0;
+            return len;
+        } else {
+            long ret = stream.skip(n);
+            if (ret == -1)
+                return -1;
+            avail -= ret;
+            filepointer += ret;
+            return ret;
+        }
+    }
+
+    public int available() {
+        return (int)avail;
+    }
+
+    public void finish() throws IOException {
+        if (avail != 0) {
+            skipBytes(avail);
+        }
+    }
+
+    // Read ASCII chars from stream
+    public String readString(int len) throws IOException {
+        byte[] buff = new byte[len];
+        readFully(buff);
+        for (int i = 0; i < buff.length; i++) {
+            if (buff[i] == 0) {
+                return new String(buff, 0, i, "ascii");
+            }
+        }
+        return new String(buff, "ascii");
+    }
+
+    // Read 8 bit signed integer from stream
+    public byte readByte() throws IOException {
+        int ch = read();
+        if (ch < 0)
+            throw new EOFException();
+        return (byte) ch;
+    }
+
+    // Read 16 bit signed integer from stream
+    public short readShort() throws IOException {
+        int ch1 = read();
+        int ch2 = read();
+        if (ch1 < 0)
+            throw new EOFException();
+        if (ch2 < 0)
+            throw new EOFException();
+        return (short)(ch1 | (ch2 << 8));
+    }
+
+    // Read 32 bit signed integer from stream
+    public int readInt() throws IOException {
+        int ch1 = read();
+        int ch2 = read();
+        int ch3 = read();
+        int ch4 = read();
+        if (ch1 < 0)
+            throw new EOFException();
+        if (ch2 < 0)
+            throw new EOFException();
+        if (ch3 < 0)
+            throw new EOFException();
+        if (ch4 < 0)
+            throw new EOFException();
+        return ch1 + (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
+    }
+
+    // Read 64 bit signed integer from stream
+    public long readLong() throws IOException {
+        long ch1 = read();
+        long ch2 = read();
+        long ch3 = read();
+        long ch4 = read();
+        long ch5 = read();
+        long ch6 = read();
+        long ch7 = read();
+        long ch8 = read();
+        if (ch1 < 0)
+            throw new EOFException();
+        if (ch2 < 0)
+            throw new EOFException();
+        if (ch3 < 0)
+            throw new EOFException();
+        if (ch4 < 0)
+            throw new EOFException();
+        if (ch5 < 0)
+            throw new EOFException();
+        if (ch6 < 0)
+            throw new EOFException();
+        if (ch7 < 0)
+            throw new EOFException();
+        if (ch8 < 0)
+            throw new EOFException();
+        return ch1 | (ch2 << 8) | (ch3 << 16) | (ch4 << 24)
+                | (ch5 << 32) | (ch6 << 40) | (ch7 << 48) | (ch8 << 56);
+    }
+
+    // Read 8 bit unsigned integer from stream
+    public int readUnsignedByte() throws IOException {
+        int ch = read();
+        if (ch < 0)
+            throw new EOFException();
+        return ch;
+    }
+
+    // Read 16 bit unsigned integer from stream
+    public int readUnsignedShort() throws IOException {
+        int ch1 = read();
+        int ch2 = read();
+        if (ch1 < 0)
+            throw new EOFException();
+        if (ch2 < 0)
+            throw new EOFException();
+        return ch1 | (ch2 << 8);
+    }
+
+    // Read 32 bit unsigned integer from stream
+    public long readUnsignedInt() throws IOException {
+        long ch1 = read();
+        long ch2 = read();
+        long ch3 = read();
+        long ch4 = read();
+        if (ch1 < 0)
+            throw new EOFException();
+        if (ch2 < 0)
+            throw new EOFException();
+        if (ch3 < 0)
+            throw new EOFException();
+        if (ch4 < 0)
+            throw new EOFException();
+        return ch1 + (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
+    }
+
+    public void close() throws IOException {
+        finish();
+        if (this == root)
+            stream.close();
+        stream = null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/RIFFWriter.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,365 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+
+/**
+ * Resource Interchange File Format (RIFF) stream encoder.
+ *
+ * @author Karl Helgason
+ */
+public class RIFFWriter extends OutputStream {
+
+    private interface RandomAccessWriter {
+
+        public void seek(long chunksizepointer) throws IOException;
+
+        public long getPointer() throws IOException;
+
+        public void close() throws IOException;
+
+        public void write(int b) throws IOException;
+
+        public void write(byte[] b, int off, int len) throws IOException;
+
+        public void write(byte[] bytes) throws IOException;
+
+        public long length() throws IOException;
+
+        public void setLength(long i) throws IOException;
+    }
+
+    private static class RandomAccessFileWriter implements RandomAccessWriter {
+
+        RandomAccessFile raf;
+
+        public RandomAccessFileWriter(File file) throws FileNotFoundException {
+            this.raf = new RandomAccessFile(file, "rw");
+        }
+
+        public RandomAccessFileWriter(String name) throws FileNotFoundException {
+            this.raf = new RandomAccessFile(name, "rw");
+        }
+
+        public void seek(long chunksizepointer) throws IOException {
+            raf.seek(chunksizepointer);
+        }
+
+        public long getPointer() throws IOException {
+            return raf.getFilePointer();
+        }
+
+        public void close() throws IOException {
+            raf.close();
+        }
+
+        public void write(int b) throws IOException {
+            raf.write(b);
+        }
+
+        public void write(byte[] b, int off, int len) throws IOException {
+            raf.write(b, off, len);
+        }
+
+        public void write(byte[] bytes) throws IOException {
+            raf.write(bytes);
+        }
+
+        public long length() throws IOException {
+            return raf.length();
+        }
+
+        public void setLength(long i) throws IOException {
+            raf.setLength(i);
+        }
+    }
+
+    private static class RandomAccessByteWriter implements RandomAccessWriter {
+
+        byte[] buff = new byte[32];
+        int length = 0;
+        int pos = 0;
+        byte[] s;
+        OutputStream stream;
+
+        public RandomAccessByteWriter(OutputStream stream) {
+            this.stream = stream;
+        }
+
+        public void seek(long chunksizepointer) throws IOException {
+            pos = (int) chunksizepointer;
+        }
+
+        public long getPointer() throws IOException {
+            return pos;
+        }
+
+        public void close() throws IOException {
+            stream.write(buff, 0, length);
+            stream.close();
+        }
+
+        public void write(int b) throws IOException {
+            if (s == null)
+                s = new byte[1];
+            s[0] = (byte)b;
+            write(s, 0, 1);
+        }
+
+        public void write(byte[] b, int off, int len) throws IOException {
+            int newsize = pos + len;
+            if (newsize > length)
+                setLength(newsize);
+            int end = off + len;
+            for (int i = off; i < end; i++) {
+                buff[pos++] = b[i];
+            }
+        }
+
+        public void write(byte[] bytes) throws IOException {
+            write(bytes, 0, bytes.length);
+        }
+
+        public long length() throws IOException {
+            return length;
+        }
+
+        public void setLength(long i) throws IOException {
+            length = (int) i;
+            if (length > buff.length) {
+                int newlen = Math.max(buff.length << 1, length);
+                byte[] newbuff = new byte[newlen];
+                System.arraycopy(buff, 0, newbuff, 0, buff.length);
+                buff = newbuff;
+            }
+        }
+    }
+    private int chunktype = 0; // 0=RIFF, 1=LIST; 2=CHUNK
+    private RandomAccessWriter raf;
+    private long chunksizepointer;
+    private long startpointer;
+    private RIFFWriter childchunk = null;
+    private boolean open = true;
+    private boolean writeoverride = false;
+
+    public RIFFWriter(String name, String format) throws IOException {
+        this(new RandomAccessFileWriter(name), format, 0);
+    }
+
+    public RIFFWriter(File file, String format) throws IOException {
+        this(new RandomAccessFileWriter(file), format, 0);
+    }
+
+    public RIFFWriter(OutputStream stream, String format) throws IOException {
+        this(new RandomAccessByteWriter(stream), format, 0);
+    }
+
+    private RIFFWriter(RandomAccessWriter raf, String format, int chunktype)
+            throws IOException {
+        if (chunktype == 0)
+            if (raf.length() != 0)
+                raf.setLength(0);
+        this.raf = raf;
+        if (raf.getPointer() % 2 != 0)
+            raf.write(0);
+
+        if (chunktype == 0)
+            raf.write("RIFF".getBytes("ascii"));
+        else if (chunktype == 1)
+            raf.write("LIST".getBytes("ascii"));
+        else
+            raf.write((format + "    ").substring(0, 4).getBytes("ascii"));
+
+        chunksizepointer = raf.getPointer();
+        this.chunktype = 2;
+        writeUnsignedInt(0);
+        this.chunktype = chunktype;
+        startpointer = raf.getPointer();
+        if (chunktype != 2)
+            raf.write((format + "    ").substring(0, 4).getBytes("ascii"));
+
+    }
+
+    public void seek(long pos) throws IOException {
+        raf.seek(pos);
+    }
+
+    public long getFilePointer() throws IOException {
+        return raf.getPointer();
+    }
+
+    public void setWriteOverride(boolean writeoverride) {
+        this.writeoverride = writeoverride;
+    }
+
+    public boolean getWriteOverride() {
+        return writeoverride;
+    }
+
+    public void close() throws IOException {
+        if (!open)
+            return;
+        if (childchunk != null) {
+            childchunk.close();
+            childchunk = null;
+        }
+
+        int bakchunktype = chunktype;
+        long fpointer = raf.getPointer();
+        raf.seek(chunksizepointer);
+        chunktype = 2;
+        writeUnsignedInt(fpointer - startpointer);
+
+        if (bakchunktype == 0)
+            raf.close();
+        else
+            raf.seek(fpointer);
+        open = false;
+        raf = null;
+    }
+
+    public void write(int b) throws IOException {
+        if (!writeoverride) {
+            if (chunktype != 2) {
+                throw new IllegalArgumentException(
+                        "Only chunks can write bytes!");
+            }
+            if (childchunk != null) {
+                childchunk.close();
+                childchunk = null;
+            }
+        }
+        raf.write(b);
+    }
+
+    public void write(byte b[], int off, int len) throws IOException {
+        if (!writeoverride) {
+            if (chunktype != 2) {
+                throw new IllegalArgumentException(
+                        "Only chunks can write bytes!");
+            }
+            if (childchunk != null) {
+                childchunk.close();
+                childchunk = null;
+            }
+        }
+        raf.write(b, off, len);
+    }
+
+    public RIFFWriter writeList(String format) throws IOException {
+        if (chunktype == 2) {
+            throw new IllegalArgumentException(
+                    "Only LIST and RIFF can write lists!");
+        }
+        if (childchunk != null) {
+            childchunk.close();
+            childchunk = null;
+        }
+        childchunk = new RIFFWriter(this.raf, format, 1);
+        return childchunk;
+    }
+
+    public RIFFWriter writeChunk(String format) throws IOException {
+        if (chunktype == 2) {
+            throw new IllegalArgumentException(
+                    "Only LIST and RIFF can write chunks!");
+        }
+        if (childchunk != null) {
+            childchunk.close();
+            childchunk = null;
+        }
+        childchunk = new RIFFWriter(this.raf, format, 2);
+        return childchunk;
+    }
+
+    // Write ASCII chars to stream
+    public void writeString(String string) throws IOException {
+        byte[] buff = string.getBytes();
+        write(buff);
+    }
+
+    // Write ASCII chars to stream
+    public void writeString(String string, int len) throws IOException {
+        byte[] buff = string.getBytes();
+        if (buff.length > len)
+            write(buff, 0, len);
+        else {
+            write(buff);
+            for (int i = buff.length; i < len; i++)
+                write(0);
+        }
+    }
+
+    // Write 8 bit signed integer to stream
+    public void writeByte(int b) throws IOException {
+        write(b);
+    }
+
+    // Write 16 bit signed integer to stream
+    public void writeShort(short b) throws IOException {
+        write((b >>> 0) & 0xFF);
+        write((b >>> 8) & 0xFF);
+    }
+
+    // Write 32 bit signed integer to stream
+    public void writeInt(int b) throws IOException {
+        write((b >>> 0) & 0xFF);
+        write((b >>> 8) & 0xFF);
+        write((b >>> 16) & 0xFF);
+        write((b >>> 24) & 0xFF);
+    }
+
+    // Write 64 bit signed integer to stream
+    public void writeLong(long b) throws IOException {
+        write((int) (b >>> 0) & 0xFF);
+        write((int) (b >>> 8) & 0xFF);
+        write((int) (b >>> 16) & 0xFF);
+        write((int) (b >>> 24) & 0xFF);
+        write((int) (b >>> 32) & 0xFF);
+        write((int) (b >>> 40) & 0xFF);
+        write((int) (b >>> 48) & 0xFF);
+        write((int) (b >>> 56) & 0xFF);
+    }
+
+    // Write 8 bit unsigned integer to stream
+    public void writeUnsignedByte(int b) throws IOException {
+        writeByte((byte) b);
+    }
+
+    // Write 16 bit unsigned integer to stream
+    public void writeUnsignedShort(int b) throws IOException {
+        writeShort((short) b);
+    }
+
+    // Write 32 bit unsigned integer to stream
+    public void writeUnsignedInt(long b) throws IOException {
+        writeInt((int) b);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/RealTimeSequencer.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/RealTimeSequencer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -54,10 +54,6 @@
     private final static boolean DEBUG_PUMP = false;
     private final static boolean DEBUG_PUMP_ALL = false;
 
-
-    /** if true, we bridge RMF files over to the old MixerSequencer */
-    private final static boolean RMF = true;
-
     /**
      * Event Dispatcher thread. Should be using a shared event
      * dispatcher instance with a factory in EventDispatcher
@@ -145,9 +141,6 @@
     private ArrayList controllerEventListeners = new ArrayList();
 
 
-    /** for RMF media we need the RMF sequencer */
-    private MixerSequencer seqBridge = null;
-
     /** automatic connection support */
     private boolean autoConnect = false;
 
@@ -220,21 +213,6 @@
                 playThread.setSequence(sequence);
             }
         }
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.close();
-                seqBridge = null;
-            }
-            // if previous file was an RMF, but this file is not RMF,
-            // then need to call implOpen again!
-            if (isOpen() && sequence != null && playThread == null) {
-                try {
-                    implOpen();
-                } catch (MidiUnavailableException mue) {
-                    if (Printer.err) mue.printStackTrace();
-                }
-            }
-        }
 
         if (Printer.trace) Printer.trace("<< RealTimeSequencer: setSequence(" + sequence +") completed");
     }
@@ -249,52 +227,6 @@
             return;
         }
 
-        // need to be able to detect RMF
-        if (RMF) {
-            MidiFileFormat fileFormat = MidiSystem.getMidiFileFormat(stream); // can throw IOException, InvalidMidiDataException
-            int type = fileFormat.getType();
-            int resolution = fileFormat.getResolution();
-            if (Printer.debug) Printer.debug("Got file with type="+type+" and resolution="+resolution);
-            if (resolution == MidiFileFormat.UNKNOWN_LENGTH) {
-                // seems to be RMF
-                if (seqBridge == null) {
-                    try {
-                        seqBridge = new MixerSequencer();
-                        if (isOpen()) {
-                            seqBridge.open();
-                        }
-                    } catch (MidiUnavailableException mue) {
-                        // uhum, strange situation. Need to cast to InvalidMidiDataException
-                        throw new InvalidMidiDataException(mue.getMessage());
-                    }
-                }
-                seqBridge.setSequence(stream);
-                // propagate state
-                seqBridge.setTempoFactor(getTempoFactor());
-
-                // propagate listeners
-                synchronized(metaEventListeners) {
-                    for (int i = 0 ; i < metaEventListeners.size(); i++) {
-                        seqBridge.addMetaEventListener((MetaEventListener) (metaEventListeners.get(i)));
-                    }
-                }
-                synchronized(controllerEventListeners) {
-                    for (int i = 0 ; i < controllerEventListeners.size(); i++) {
-                        ControllerListElement cve = (ControllerListElement) (controllerEventListeners.get(i));
-                        seqBridge.addControllerEventListener(cve.listener, cve.controllers);
-                    }
-                }
-                // disable the current sequence of RealTimeSequencer
-                //setSequence((Sequence) null); -> will remove bridge again!
-                this.sequence = null;
-                return;
-            }
-            if (seqBridge != null) {
-                seqBridge.close();
-                seqBridge = null;
-            }
-        }
-
         Sequence seq = MidiSystem.getSequence(stream); // can throw IOException, InvalidMidiDataException
 
         setSequence(seq);
@@ -305,22 +237,11 @@
 
 
     public Sequence getSequence() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getSequence();
-            }
-        }
         return sequence;
     }
 
 
     public synchronized void start() {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.start();
-                return;
-            }
-        }
         if (Printer.trace) Printer.trace(">> RealTimeSequencer: start()");
 
         // sequencer not open: throw an exception
@@ -346,12 +267,6 @@
 
 
     public synchronized void stop() {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.stop();
-                return;
-            }
-        }
         if (Printer.trace) Printer.trace(">> RealTimeSequencer: stop()");
 
         if (!isOpen()) {
@@ -373,23 +288,11 @@
 
 
     public boolean isRunning() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.isRunning();
-            }
-        }
         return running;
     }
 
 
     public void startRecording() {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.startRecording();
-                return;
-            }
-        }
-
         if (!isOpen()) {
             throw new IllegalStateException("Sequencer not open");
         }
@@ -400,13 +303,6 @@
 
 
     public void stopRecording() {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.stopRecording();
-                return;
-            }
-        }
-
         if (!isOpen()) {
             throw new IllegalStateException("Sequencer not open");
         }
@@ -415,23 +311,11 @@
 
 
     public boolean isRecording() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.isRecording();
-            }
-        }
         return recording;
     }
 
 
     public void recordEnable(Track track, int channel) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.recordEnable(track, channel);
-                return;
-            }
-        }
-
         if (!findTrack(track)) {
             throw new IllegalArgumentException("Track does not exist in the current sequence");
         }
@@ -449,13 +333,6 @@
 
 
     public void recordDisable(Track track) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.recordDisable(track);
-                return;
-            }
-        }
-
         synchronized(recordingTracks) {
             RecordingTrack rc = RecordingTrack.get(recordingTracks, track);
             if (rc != null) {
@@ -482,11 +359,6 @@
 
 
     public float getTempoInBPM() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getTempoInBPM();
-            }
-        }
         if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTempoInBPM() ");
 
         return (float) MidiUtils.convertTempo(getTempoInMPQ());
@@ -494,12 +366,6 @@
 
 
     public void setTempoInBPM(float bpm) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.setTempoInBPM(bpm);
-                return;
-            }
-        }
         if (Printer.trace) Printer.trace(">> RealTimeSequencer: setTempoInBPM() ");
         if (bpm <= 0) {
             // should throw IllegalArgumentException
@@ -511,12 +377,6 @@
 
 
     public float getTempoInMPQ() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getTempoInMPQ();
-            }
-        }
-
         if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTempoInMPQ() ");
 
         if (needCaching()) {
@@ -537,12 +397,6 @@
 
 
     public void setTempoInMPQ(float mpq) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.setTempoInMPQ(mpq);
-                return;
-            }
-        }
         if (mpq <= 0) {
             // should throw IllegalArgumentException
             mpq = 1.0f;
@@ -564,12 +418,6 @@
 
 
     public void setTempoFactor(float factor) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.setTempoFactor(factor);
-                return;
-            }
-        }
         if (factor <= 0) {
             // should throw IllegalArgumentException
             return;
@@ -588,11 +436,6 @@
 
 
     public float getTempoFactor() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getTempoFactor();
-            }
-        }
         if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTempoFactor() ");
 
         if (needCaching()) {
@@ -606,11 +449,6 @@
 
 
     public long getTickLength() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getTickLength();
-            }
-        }
         if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTickLength() ");
 
         if (sequence == null) {
@@ -622,11 +460,6 @@
 
 
     public synchronized long getTickPosition() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getTickPosition();
-            }
-        }
         if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTickPosition() ");
 
         if (getDataPump() == null || sequence == null) {
@@ -638,12 +471,6 @@
 
 
     public synchronized void setTickPosition(long tick) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.setTickPosition(tick);
-                return;
-            }
-        }
         if (tick < 0) {
             // should throw IllegalArgumentException
             return;
@@ -667,12 +494,6 @@
 
 
     public long getMicrosecondLength() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getMicrosecondLength();
-            }
-        }
-
         if (Printer.trace) Printer.trace(">> RealTimeSequencer: getMicrosecondLength() ");
 
         if (sequence == null) {
@@ -684,12 +505,6 @@
 
 
     public long getMicrosecondPosition() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getMicrosecondPosition();
-            }
-        }
-
         if (Printer.trace) Printer.trace(">> RealTimeSequencer: getMicrosecondPosition() ");
 
         if (getDataPump() == null || sequence == null) {
@@ -702,13 +517,6 @@
 
 
     public void setMicrosecondPosition(long microseconds) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.setMicrosecondPosition(microseconds);
-                return;
-            }
-        }
-
         if (microseconds < 0) {
             // should throw IllegalArgumentException
             return;
@@ -734,33 +542,16 @@
 
 
     public void setMasterSyncMode(Sequencer.SyncMode sync) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.setMasterSyncMode(sync);
-                return;
-            }
-        }
         // not supported
     }
 
 
     public Sequencer.SyncMode getMasterSyncMode() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getMasterSyncMode();
-            }
-        }
         return masterSyncMode;
     }
 
 
     public Sequencer.SyncMode[] getMasterSyncModes() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getMasterSyncModes();
-            }
-        }
-
         Sequencer.SyncMode[] returnedModes = new Sequencer.SyncMode[masterSyncModes.length];
         System.arraycopy(masterSyncModes, 0, returnedModes, 0, masterSyncModes.length);
         return returnedModes;
@@ -768,33 +559,16 @@
 
 
     public void setSlaveSyncMode(Sequencer.SyncMode sync) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.setSlaveSyncMode(sync);
-                return;
-            }
-        }
         // not supported
     }
 
 
     public Sequencer.SyncMode getSlaveSyncMode() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getSlaveSyncMode();
-            }
-        }
         return slaveSyncMode;
     }
 
 
     public Sequencer.SyncMode[] getSlaveSyncModes() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getSlaveSyncModes();
-            }
-        }
-
         Sequencer.SyncMode[] returnedModes = new Sequencer.SyncMode[slaveSyncModes.length];
         System.arraycopy(slaveSyncModes, 0, returnedModes, 0, slaveSyncModes.length);
         return returnedModes;
@@ -812,12 +586,6 @@
 
 
     public synchronized void setTrackMute(int track, boolean mute) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.setTrackMute(track, mute);
-                return;
-            }
-        }
         int trackCount = getTrackCount();
         if (track < 0 || track >= getTrackCount()) return;
         trackMuted = ensureBoolArraySize(trackMuted, trackCount);
@@ -829,11 +597,6 @@
 
 
     public synchronized boolean getTrackMute(int track) {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getTrackMute(track);
-            }
-        }
         if (track < 0 || track >= getTrackCount()) return false;
         if (trackMuted == null || trackMuted.length <= track) return false;
         return trackMuted[track];
@@ -841,12 +604,6 @@
 
 
     public synchronized void setTrackSolo(int track, boolean solo) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.setTrackSolo(track, solo);
-                return;
-            }
-        }
         int trackCount = getTrackCount();
         if (track < 0 || track >= getTrackCount()) return;
         trackSolo = ensureBoolArraySize(trackSolo, trackCount);
@@ -858,11 +615,6 @@
 
 
     public synchronized boolean getTrackSolo(int track) {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getTrackSolo(track);
-            }
-        }
         if (track < 0 || track >= getTrackCount()) return false;
         if (trackSolo == null || trackSolo.length <= track) return false;
         return trackSolo[track];
@@ -870,12 +622,6 @@
 
 
     public boolean addMetaEventListener(MetaEventListener listener) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.addMetaEventListener(listener);
-                // do not return here!
-            }
-        }
         synchronized(metaEventListeners) {
             if (! metaEventListeners.contains(listener)) {
 
@@ -887,12 +633,6 @@
 
 
     public void removeMetaEventListener(MetaEventListener listener) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.removeMetaEventListener(listener);
-                // do not return here!
-            }
-        }
         synchronized(metaEventListeners) {
             int index = metaEventListeners.indexOf(listener);
             if (index >= 0) {
@@ -903,13 +643,6 @@
 
 
     public int[] addControllerEventListener(ControllerEventListener listener, int[] controllers) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.addControllerEventListener(listener, controllers);
-                // do not return here!
-            }
-        }
-
         synchronized(controllerEventListeners) {
 
             // first find the listener.  if we have one, add the controllers
@@ -938,12 +671,6 @@
 
 
     public int[] removeControllerEventListener(ControllerEventListener listener, int[] controllers) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.removeControllerEventListener(listener, controllers);
-                // do not return here!
-            }
-        }
         synchronized(controllerEventListeners) {
             ControllerListElement cve = null;
             boolean flag = false;
@@ -973,12 +700,6 @@
     ////////////////// LOOPING (added in 1.5) ///////////////////////
 
     public void setLoopStartPoint(long tick) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.setLoopStartPoint(tick);
-                return;
-            }
-        }
         if ((tick > getTickLength())
             || ((loopEnd != -1) && (tick > loopEnd))
             || (tick < 0)) {
@@ -988,21 +709,10 @@
     }
 
     public long getLoopStartPoint() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getLoopStartPoint();
-            }
-        }
         return loopStart;
     }
 
     public void setLoopEndPoint(long tick) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.setLoopEndPoint(tick);
-                return;
-            }
-        }
         if ((tick > getTickLength())
             || ((loopStart > tick) && (tick != -1))
             || (tick < -1)) {
@@ -1012,21 +722,10 @@
     }
 
     public long getLoopEndPoint() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getLoopEndPoint();
-            }
-        }
         return loopEnd;
     }
 
     public void setLoopCount(int count) {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.setLoopCount(count);
-                return;
-            }
-        }
         if (count != LOOP_CONTINUOUSLY
             && count < 0) {
             throw new IllegalArgumentException("illegal value for loop count: "+count);
@@ -1038,11 +737,6 @@
     }
 
     public int getLoopCount() {
-        if (RMF) {
-            if (seqBridge != null) {
-                return seqBridge.getLoopCount();
-            }
-        }
         return loopCount;
     }
 
@@ -1053,13 +747,6 @@
      */
     protected void implOpen() throws MidiUnavailableException {
         if (Printer.trace) Printer.trace(">> RealTimeSequencer: implOpen()");
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.open();
-                if (Printer.trace) Printer.trace("<< RealTimeSequencer: -> called seqBridge.open");
-                return;
-            }
-        }
 
         //openInternalSynth();
 
@@ -1095,12 +782,6 @@
             synth.open();
             if (synth instanceof ReferenceCountingDevice) {
                 rec = ((ReferenceCountingDevice) synth).getReceiverReferenceCounting();
-                if (synth.getClass().toString().contains("com.sun.media.sound.MixerSynth")
-                    && (synth.getDefaultSoundbank() == null)) {
-                    // don't use this receiver if no soundbank available
-                    rec = null;
-                    synth.close();
-                }
             } else {
                 rec = synth.getReceiver();
             }
@@ -1147,12 +828,6 @@
 
 
     protected synchronized void implClose() {
-        if (RMF) {
-            if (seqBridge != null) {
-                seqBridge.close();
-                // don't return here!
-            }
-        }
         if (Printer.trace) Printer.trace(">> RealTimeSequencer: implClose() ");
 
         if (playThread == null) {
@@ -1302,12 +977,6 @@
     // OVERRIDES OF ABSTRACT MIDI DEVICE METHODS
 
     protected boolean hasReceivers() {
-        if (RMF) {
-            if (seqBridge != null) {
-                //RMF does not allow recording
-                return false;
-            }
-        }
         return true;
     }
 
@@ -1318,12 +987,6 @@
 
 
     protected boolean hasTransmitters() {
-        if (RMF) {
-            if (seqBridge != null) {
-                //RMF does never allow setting own receivers
-                return false;
-            }
-        }
         return true;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2GlobalRegion.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Soundfont global region.
+ *
+ * @author Karl Helgason
+ */
+public class SF2GlobalRegion extends SF2Region {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2Instrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,911 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.sound.midi.Patch;
+
+/**
+ * Soundfont instrument.
+ *
+ * @author Karl Helgason
+ */
+public class SF2Instrument extends ModelInstrument {
+
+    protected String name = "";
+    protected int preset = 0;
+    protected int bank = 0;
+    protected long library = 0;
+    protected long genre = 0;
+    protected long morphology = 0;
+    protected SF2GlobalRegion globalregion = null;
+    protected List<SF2InstrumentRegion> regions
+            = new ArrayList<SF2InstrumentRegion>();
+
+    public SF2Instrument() {
+        super(null, null, null, null);
+    }
+
+    public SF2Instrument(SF2Soundbank soundbank) {
+        super(soundbank, null, null, null);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Patch getPatch() {
+        if (bank == 128)
+            return new ModelPatch(0, preset, true);
+        else
+            return new ModelPatch(bank << 7, preset, false);
+    }
+
+    public void setPatch(Patch patch) {
+        if (patch instanceof ModelPatch && ((ModelPatch) patch).isPercussion()) {
+            bank = 128;
+            preset = patch.getProgram();
+        } else {
+            bank = patch.getBank() >> 7;
+            preset = patch.getProgram();
+        }
+    }
+
+    public Object getData() {
+        return null;
+    }
+
+    public long getGenre() {
+        return genre;
+    }
+
+    public void setGenre(long genre) {
+        this.genre = genre;
+    }
+
+    public long getLibrary() {
+        return library;
+    }
+
+    public void setLibrary(long library) {
+        this.library = library;
+    }
+
+    public long getMorphology() {
+        return morphology;
+    }
+
+    public void setMorphology(long morphology) {
+        this.morphology = morphology;
+    }
+
+    public List<SF2InstrumentRegion> getRegions() {
+        return regions;
+    }
+
+    public SF2GlobalRegion getGlobalRegion() {
+        return globalregion;
+    }
+
+    public void setGlobalZone(SF2GlobalRegion zone) {
+        globalregion = zone;
+    }
+
+    public String toString() {
+        if (bank == 128)
+            return "Drumkit: " + name + " preset #" + preset;
+        else
+            return "Instrument: " + name + " bank #" + bank
+                    + " preset #" + preset;
+    }
+
+    public ModelPerformer[] getPerformers() {
+        int performercount = 0;
+        for (SF2InstrumentRegion presetzone : regions)
+            performercount += presetzone.getLayer().getRegions().size();
+        ModelPerformer[] performers = new ModelPerformer[performercount];
+        int pi = 0;
+
+        SF2GlobalRegion presetglobal = globalregion;
+        for (SF2InstrumentRegion presetzone : regions) {
+            Map<Integer, Short> pgenerators = new HashMap<Integer, Short>();
+            pgenerators.putAll(presetzone.getGenerators());
+            if (presetglobal != null)
+                pgenerators.putAll(presetglobal.getGenerators());
+
+            SF2Layer layer = presetzone.getLayer();
+            SF2GlobalRegion layerglobal = layer.getGlobalRegion();
+            for (SF2LayerRegion layerzone : layer.getRegions()) {
+                ModelPerformer performer = new ModelPerformer();
+                if (layerzone.getSample() != null)
+                    performer.setName(layerzone.getSample().getName());
+                else
+                    performer.setName(layer.getName());
+
+                performers[pi++] = performer;
+
+                int keyfrom = 0;
+                int keyto = 127;
+                int velfrom = 0;
+                int velto = 127;
+
+                if (layerzone.contains(SF2Region.GENERATOR_EXCLUSIVECLASS)) {
+                    performer.setExclusiveClass(layerzone.getInteger(
+                            SF2Region.GENERATOR_EXCLUSIVECLASS));
+                }
+                if (layerzone.contains(SF2Region.GENERATOR_KEYRANGE)) {
+                    byte[] bytes = layerzone.getBytes(
+                            SF2Region.GENERATOR_KEYRANGE);
+                    if (bytes[0] >= 0)
+                        if (bytes[0] > keyfrom)
+                            keyfrom = bytes[0];
+                    if (bytes[1] >= 0)
+                        if (bytes[1] < keyto)
+                            keyto = bytes[1];
+                }
+                if (layerzone.contains(SF2Region.GENERATOR_VELRANGE)) {
+                    byte[] bytes = layerzone.getBytes(
+                            SF2Region.GENERATOR_VELRANGE);
+                    if (bytes[0] >= 0)
+                        if (bytes[0] > velfrom)
+                            velfrom = bytes[0];
+                    if (bytes[1] >= 0)
+                        if (bytes[1] < velto)
+                            velto = bytes[1];
+                }
+                if (presetzone.contains(SF2Region.GENERATOR_KEYRANGE)) {
+                    byte[] bytes = presetzone.getBytes(
+                            SF2Region.GENERATOR_KEYRANGE);
+                    if (bytes[0] > keyfrom)
+                        keyfrom = bytes[0];
+                    if (bytes[1] < keyto)
+                        keyto = bytes[1];
+                }
+                if (presetzone.contains(SF2Region.GENERATOR_VELRANGE)) {
+                    byte[] bytes = presetzone.getBytes(
+                            SF2Region.GENERATOR_VELRANGE);
+                    if (bytes[0] > velfrom)
+                        velfrom = bytes[0];
+                    if (bytes[1] < velto)
+                        velto = bytes[1];
+                }
+                performer.setKeyFrom(keyfrom);
+                performer.setKeyTo(keyto);
+                performer.setVelFrom(velfrom);
+                performer.setVelTo(velto);
+
+                int startAddrsOffset = layerzone.getShort(
+                        SF2Region.GENERATOR_STARTADDRSOFFSET);
+                int endAddrsOffset = layerzone.getShort(
+                        SF2Region.GENERATOR_ENDADDRSOFFSET);
+                int startloopAddrsOffset = layerzone.getShort(
+                        SF2Region.GENERATOR_STARTLOOPADDRSOFFSET);
+                int endloopAddrsOffset = layerzone.getShort(
+                        SF2Region.GENERATOR_ENDLOOPADDRSOFFSET);
+
+                startAddrsOffset += layerzone.getShort(
+                        SF2Region.GENERATOR_STARTADDRSCOARSEOFFSET) * 32768;
+                endAddrsOffset += layerzone.getShort(
+                        SF2Region.GENERATOR_ENDADDRSCOARSEOFFSET) * 32768;
+                startloopAddrsOffset += layerzone.getShort(
+                        SF2Region.GENERATOR_STARTLOOPADDRSCOARSEOFFSET) * 32768;
+                endloopAddrsOffset += layerzone.getShort(
+                        SF2Region.GENERATOR_ENDLOOPADDRSCOARSEOFFSET) * 32768;
+                startloopAddrsOffset -= startAddrsOffset;
+                endloopAddrsOffset -= startAddrsOffset;
+
+                SF2Sample sample = layerzone.getSample();
+                int rootkey = sample.originalPitch;
+                if (layerzone.getShort(SF2Region.GENERATOR_OVERRIDINGROOTKEY) != -1) {
+                    rootkey = layerzone.getShort(
+                            SF2Region.GENERATOR_OVERRIDINGROOTKEY);
+                }
+                float pitchcorrection = (-rootkey * 100) + sample.pitchCorrection;
+                ModelByteBuffer buff = sample.getDataBuffer();
+                ModelByteBuffer buff24 = sample.getData24Buffer();
+
+                if (startAddrsOffset != 0 || endAddrsOffset != 0) {
+                    buff = buff.subbuffer(startAddrsOffset * 2,
+                            buff.capacity() + endAddrsOffset * 2);
+                    if (buff24 != null) {
+                        buff24 = buff24.subbuffer(startAddrsOffset,
+                                buff24.capacity() + endAddrsOffset);
+                    }
+
+                    /*
+                    if (startAddrsOffset < 0)
+                        startAddrsOffset = 0;
+                    if (endAddrsOffset > (buff.capacity()/2-startAddrsOffset))
+                        startAddrsOffset = (int)buff.capacity()/2-startAddrsOffset;
+                    byte[] data = buff.array();
+                    int off = (int)buff.arrayOffset() + startAddrsOffset*2;
+                    int len = (int)buff.capacity() + endAddrsOffset*2;
+                    if (off+len > data.length)
+                        len = data.length - off;
+                    buff = new ModelByteBuffer(data, off, len);
+                    if(buff24 != null) {
+                        data = buff.array();
+                        off = (int)buff.arrayOffset() + startAddrsOffset;
+                        len = (int)buff.capacity() + endAddrsOffset;
+                        buff24 = new ModelByteBuffer(data, off, len);
+                    }
+                    */
+                }
+
+                ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
+                        buff, sample.getFormat(), pitchcorrection);
+                if (buff24 != null)
+                    osc.set8BitExtensionBuffer(buff24);
+
+                Map<Integer, Short> generators = new HashMap<Integer, Short>();
+                if (layerglobal != null)
+                    generators.putAll(layerglobal.getGenerators());
+                generators.putAll(layerzone.getGenerators());
+                for (Map.Entry<Integer, Short> gen : pgenerators.entrySet()) {
+                    short val;
+                    if (!generators.containsKey(gen.getKey()))
+                        val = layerzone.getShort(gen.getKey());
+                    else
+                        val = generators.get(gen.getKey());
+                    val += gen.getValue();
+                    generators.put(gen.getKey(), val);
+                }
+
+                // SampleMode:
+                // 0 indicates a sound reproduced with no loop
+                // 1 indicates a sound which loops continuously
+                // 2 is unused but should be interpreted as indicating no loop
+                // 3 indicates a sound which loops for the duration of key
+                //   depression then proceeds to play the remainder of the sample.
+                int sampleMode = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_SAMPLEMODES);
+                if ((sampleMode == 1) || (sampleMode == 3)) {
+                    if (sample.startLoop >= 0 && sample.endLoop > 0) {
+                        osc.setLoopStart((int)(sample.startLoop
+                                + startloopAddrsOffset));
+                        osc.setLoopLength((int)(sample.endLoop - sample.startLoop
+                                + endloopAddrsOffset - startloopAddrsOffset));
+                        if (sampleMode == 1)
+                            osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
+                        if (sampleMode == 3)
+                            osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE);
+                    }
+                }
+                performer.getOscillators().add(osc);
+
+
+                short volDelay = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_DELAYVOLENV);
+                short volAttack = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_ATTACKVOLENV);
+                short volHold = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_HOLDVOLENV);
+                short volDecay = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_DECAYVOLENV);
+                short volSustain = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_SUSTAINVOLENV);
+                short volRelease = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_RELEASEVOLENV);
+
+                if (volHold != -12000) {
+                    short volKeyNumToHold = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_KEYNUMTOVOLENVHOLD);
+                    volHold += 60 * volKeyNumToHold;
+                    float fvalue = -volKeyNumToHold * 128;
+                    ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_EG1_HOLD;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(new ModelSource(src), fvalue,
+                            new ModelDestination(dest)));
+                }
+                if (volDecay != -12000) {
+                    short volKeyNumToDecay = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_KEYNUMTOVOLENVDECAY);
+                    volDecay += 60 * volKeyNumToDecay;
+                    float fvalue = -volKeyNumToDecay * 128;
+                    ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_EG1_DECAY;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(new ModelSource(src), fvalue,
+                            new ModelDestination(dest)));
+                }
+
+                addTimecentValue(performer,
+                        ModelDestination.DESTINATION_EG1_DELAY, volDelay);
+                addTimecentValue(performer,
+                        ModelDestination.DESTINATION_EG1_ATTACK, volAttack);
+                addTimecentValue(performer,
+                        ModelDestination.DESTINATION_EG1_HOLD, volHold);
+                addTimecentValue(performer,
+                        ModelDestination.DESTINATION_EG1_DECAY, volDecay);
+                //float fvolsustain = (960-volSustain)*(1000.0f/960.0f);
+
+                volSustain = (short)(1000 - volSustain);
+                if (volSustain < 0)
+                    volSustain = 0;
+                if (volSustain > 1000)
+                    volSustain = 1000;
+
+                addValue(performer,
+                        ModelDestination.DESTINATION_EG1_SUSTAIN, volSustain);
+                addTimecentValue(performer,
+                        ModelDestination.DESTINATION_EG1_RELEASE, volRelease);
+
+                if (getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODENVTOFILTERFC) != 0
+                        || getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODENVTOPITCH) != 0) {
+                    short modDelay = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_DELAYMODENV);
+                    short modAttack = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_ATTACKMODENV);
+                    short modHold = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_HOLDMODENV);
+                    short modDecay = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_DECAYMODENV);
+                    short modSustain = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_SUSTAINMODENV);
+                    short modRelease = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_RELEASEMODENV);
+
+
+                    if (modHold != -12000) {
+                        short modKeyNumToHold = getGeneratorValue(generators,
+                                SF2Region.GENERATOR_KEYNUMTOMODENVHOLD);
+                        modHold += 60 * modKeyNumToHold;
+                        float fvalue = -modKeyNumToHold * 128;
+                        ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
+                        ModelIdentifier dest = ModelDestination.DESTINATION_EG2_HOLD;
+                        performer.getConnectionBlocks().add(
+                            new ModelConnectionBlock(new ModelSource(src),
+                                fvalue, new ModelDestination(dest)));
+                    }
+                    if (modDecay != -12000) {
+                        short modKeyNumToDecay = getGeneratorValue(generators,
+                                SF2Region.GENERATOR_KEYNUMTOMODENVDECAY);
+                        modDecay += 60 * modKeyNumToDecay;
+                        float fvalue = -modKeyNumToDecay * 128;
+                        ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
+                        ModelIdentifier dest = ModelDestination.DESTINATION_EG2_DECAY;
+                        performer.getConnectionBlocks().add(
+                            new ModelConnectionBlock(new ModelSource(src),
+                                fvalue, new ModelDestination(dest)));
+                    }
+
+                    addTimecentValue(performer,
+                            ModelDestination.DESTINATION_EG2_DELAY, modDelay);
+                    addTimecentValue(performer,
+                            ModelDestination.DESTINATION_EG2_ATTACK, modAttack);
+                    addTimecentValue(performer,
+                            ModelDestination.DESTINATION_EG2_HOLD, modHold);
+                    addTimecentValue(performer,
+                            ModelDestination.DESTINATION_EG2_DECAY, modDecay);
+                    if (modSustain < 0)
+                        modSustain = 0;
+                    if (modSustain > 1000)
+                        modSustain = 1000;
+                    addValue(performer, ModelDestination.DESTINATION_EG2_SUSTAIN,
+                            1000 - modSustain);
+                    addTimecentValue(performer,
+                            ModelDestination.DESTINATION_EG2_RELEASE, modRelease);
+
+                    if (getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODENVTOFILTERFC) != 0) {
+                        double fvalue = getGeneratorValue(generators,
+                                SF2Region.GENERATOR_MODENVTOFILTERFC);
+                        ModelIdentifier src = ModelSource.SOURCE_EG2;
+                        ModelIdentifier dest
+                                = ModelDestination.DESTINATION_FILTER_FREQ;
+                        performer.getConnectionBlocks().add(
+                            new ModelConnectionBlock(new ModelSource(src),
+                                fvalue, new ModelDestination(dest)));
+                    }
+
+                    if (getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODENVTOPITCH) != 0) {
+                        double fvalue = getGeneratorValue(generators,
+                                SF2Region.GENERATOR_MODENVTOPITCH);
+                        ModelIdentifier src = ModelSource.SOURCE_EG2;
+                        ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
+                        performer.getConnectionBlocks().add(
+                            new ModelConnectionBlock(new ModelSource(src),
+                                fvalue, new ModelDestination(dest)));
+                    }
+
+                }
+
+                if (getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODLFOTOFILTERFC) != 0
+                        || getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODLFOTOPITCH) != 0
+                        || getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODLFOTOVOLUME) != 0) {
+                    short lfo_freq = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_FREQMODLFO);
+                    short lfo_delay = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_DELAYMODLFO);
+                    addTimecentValue(performer,
+                            ModelDestination.DESTINATION_LFO1_DELAY, lfo_delay);
+                    addValue(performer,
+                            ModelDestination.DESTINATION_LFO1_FREQ, lfo_freq);
+                }
+
+                short vib_freq = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_FREQVIBLFO);
+                short vib_delay = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_DELAYVIBLFO);
+                addTimecentValue(performer,
+                        ModelDestination.DESTINATION_LFO2_DELAY, vib_delay);
+                addValue(performer,
+                        ModelDestination.DESTINATION_LFO2_FREQ, vib_freq);
+
+
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_VIBLFOTOPITCH) != 0) {
+                    double fvalue = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_VIBLFOTOPITCH);
+                    ModelIdentifier src = ModelSource.SOURCE_LFO2;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(
+                            new ModelSource(src,
+                                ModelStandardTransform.DIRECTION_MIN2MAX,
+                                ModelStandardTransform.POLARITY_BIPOLAR),
+                            fvalue, new ModelDestination(dest)));
+                }
+
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_MODLFOTOFILTERFC) != 0) {
+                    double fvalue = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODLFOTOFILTERFC);
+                    ModelIdentifier src = ModelSource.SOURCE_LFO1;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_FILTER_FREQ;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(
+                            new ModelSource(src,
+                                ModelStandardTransform.DIRECTION_MIN2MAX,
+                                ModelStandardTransform.POLARITY_BIPOLAR),
+                            fvalue, new ModelDestination(dest)));
+                }
+
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_MODLFOTOPITCH) != 0) {
+                    double fvalue = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODLFOTOPITCH);
+                    ModelIdentifier src = ModelSource.SOURCE_LFO1;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(
+                            new ModelSource(src,
+                                ModelStandardTransform.DIRECTION_MIN2MAX,
+                                ModelStandardTransform.POLARITY_BIPOLAR),
+                            fvalue, new ModelDestination(dest)));
+                }
+
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_MODLFOTOVOLUME) != 0) {
+                    double fvalue = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODLFOTOVOLUME);
+                    ModelIdentifier src = ModelSource.SOURCE_LFO1;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_GAIN;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(
+                            new ModelSource(src,
+                                ModelStandardTransform.DIRECTION_MIN2MAX,
+                                ModelStandardTransform.POLARITY_BIPOLAR),
+                            fvalue, new ModelDestination(dest)));
+                }
+
+                if (layerzone.getShort(SF2Region.GENERATOR_KEYNUM) != -1) {
+                    double val = layerzone.getShort(SF2Region.GENERATOR_KEYNUM)/128.0;
+                    addValue(performer, ModelDestination.DESTINATION_KEYNUMBER, val);
+                }
+
+                if (layerzone.getShort(SF2Region.GENERATOR_VELOCITY) != -1) {
+                    double val = layerzone.getShort(SF2Region.GENERATOR_VELOCITY)
+                                 / 128.0;
+                    addValue(performer, ModelDestination.DESTINATION_VELOCITY, val);
+                }
+
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_INITIALFILTERFC) < 13500) {
+                    short filter_freq = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_INITIALFILTERFC);
+                    short filter_q = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_INITIALFILTERQ);
+                    addValue(performer,
+                            ModelDestination.DESTINATION_FILTER_FREQ, filter_freq);
+                    addValue(performer,
+                            ModelDestination.DESTINATION_FILTER_Q, filter_q);
+                }
+
+                int tune = 100 * getGeneratorValue(generators,
+                        SF2Region.GENERATOR_COARSETUNE);
+                tune += getGeneratorValue(generators,
+                        SF2Region.GENERATOR_FINETUNE);
+                if (tune != 0) {
+                    addValue(performer,
+                            ModelDestination.DESTINATION_PITCH, (short) tune);
+                }
+                if (getGeneratorValue(generators, SF2Region.GENERATOR_PAN) != 0) {
+                    short val = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_PAN);
+                    addValue(performer, ModelDestination.DESTINATION_PAN, val);
+                }
+                if (getGeneratorValue(generators, SF2Region.GENERATOR_INITIALATTENUATION) != 0) {
+                    short val = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_INITIALATTENUATION);
+                    addValue(performer,
+                            ModelDestination.DESTINATION_GAIN, -0.376287f * val);
+                }
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_CHORUSEFFECTSSEND) != 0) {
+                    short val = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_CHORUSEFFECTSSEND);
+                    addValue(performer, ModelDestination.DESTINATION_CHORUS, val);
+                }
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_REVERBEFFECTSSEND) != 0) {
+                    short val = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_REVERBEFFECTSSEND);
+                    addValue(performer, ModelDestination.DESTINATION_REVERB, val);
+                }
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_SCALETUNING) != 100) {
+                    short fvalue = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_SCALETUNING);
+                    if (fvalue == 0) {
+                        ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
+                        performer.getConnectionBlocks().add(
+                            new ModelConnectionBlock(null, rootkey * 100,
+                                new ModelDestination(dest)));
+                    } else {
+                        ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
+                        performer.getConnectionBlocks().add(
+                            new ModelConnectionBlock(null, rootkey * (100 - fvalue),
+                                new ModelDestination(dest)));
+                    }
+
+                    ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(new ModelSource(src),
+                            128 * fvalue, new ModelDestination(dest)));
+
+                }
+
+                performer.getConnectionBlocks().add(
+                    new ModelConnectionBlock(
+                        new ModelSource(ModelSource.SOURCE_NOTEON_VELOCITY,
+                            new ModelTransform() {
+                                public double transform(double value) {
+                                    if (value < 0.5)
+                                        return 1 - value * 2;
+                                    else
+                                        return 0;
+                                }
+                            }),
+                        -2400,
+                        new ModelDestination(
+                            ModelDestination.DESTINATION_FILTER_FREQ)));
+
+
+                performer.getConnectionBlocks().add(
+                    new ModelConnectionBlock(
+                        new ModelSource(ModelSource.SOURCE_LFO2,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_BIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        new ModelSource(new ModelIdentifier("midi_cc", "1", 0),
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_UNIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        50, new ModelDestination(
+                            ModelDestination.DESTINATION_PITCH)));
+
+                if (layer.getGlobalRegion() != null) {
+                    for (SF2Modulator modulator
+                            : layer.getGlobalRegion().getModulators()) {
+                        convertModulator(performer, modulator);
+                    }
+                }
+                for (SF2Modulator modulator : layerzone.getModulators())
+                    convertModulator(performer, modulator);
+
+                if (presetglobal != null) {
+                    for (SF2Modulator modulator : presetglobal.getModulators())
+                        convertModulator(performer, modulator);
+                }
+                for (SF2Modulator modulator : presetzone.getModulators())
+                    convertModulator(performer, modulator);
+
+            }
+        }
+        return performers;
+    }
+
+    private void convertModulator(ModelPerformer performer,
+            SF2Modulator modulator) {
+        ModelSource src1 = convertSource(modulator.getSourceOperator());
+        ModelSource src2 = convertSource(modulator.getAmountSourceOperator());
+        if (src1 == null && modulator.getSourceOperator() != 0)
+            return;
+        if (src2 == null && modulator.getAmountSourceOperator() != 0)
+            return;
+        double amount = modulator.getAmount();
+        double[] amountcorrection = new double[1];
+        ModelSource[] extrasrc = new ModelSource[1];
+        amountcorrection[0] = 1;
+        ModelDestination dst = convertDestination(
+                modulator.getDestinationOperator(), amountcorrection, extrasrc);
+        amount *= amountcorrection[0];
+        if (dst == null)
+            return;
+        if (modulator.getTransportOperator() == SF2Modulator.TRANSFORM_ABSOLUTE) {
+            ((ModelStandardTransform)dst.getTransform()).setTransform(
+                    ModelStandardTransform.TRANSFORM_ABSOLUTE);
+        }
+        ModelConnectionBlock conn = new ModelConnectionBlock(src1, src2, amount, dst);
+        if (extrasrc[0] != null)
+            conn.addSource(extrasrc[0]);
+        performer.getConnectionBlocks().add(conn);
+
+    }
+
+    private static ModelSource convertSource(int src) {
+        if (src == 0)
+            return null;
+        ModelIdentifier id = null;
+        int idsrc = src & 0x7F;
+        if ((src & SF2Modulator.SOURCE_MIDI_CONTROL) != 0) {
+            id = new ModelIdentifier("midi_cc", Integer.toString(idsrc));
+        } else {
+            if (idsrc == SF2Modulator.SOURCE_NOTE_ON_VELOCITY)
+                id = ModelSource.SOURCE_NOTEON_VELOCITY;
+            if (idsrc == SF2Modulator.SOURCE_NOTE_ON_KEYNUMBER)
+                id = ModelSource.SOURCE_NOTEON_KEYNUMBER;
+            if (idsrc == SF2Modulator.SOURCE_POLY_PRESSURE)
+                id = ModelSource.SOURCE_MIDI_POLY_PRESSURE;
+            if (idsrc == SF2Modulator.SOURCE_CHANNEL_PRESSURE)
+                id = ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
+            if (idsrc == SF2Modulator.SOURCE_PITCH_WHEEL)
+                id = ModelSource.SOURCE_MIDI_PITCH;
+            if (idsrc == SF2Modulator.SOURCE_PITCH_SENSITIVITY)
+                id = new ModelIdentifier("midi_rpn", "0");
+        }
+        if (id == null)
+            return null;
+
+        ModelSource msrc = new ModelSource(id);
+        ModelStandardTransform transform
+                = (ModelStandardTransform) msrc.getTransform();
+
+        if ((SF2Modulator.SOURCE_DIRECTION_MAX_MIN & src) != 0)
+            transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+        else
+            transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+
+        if ((SF2Modulator.SOURCE_POLARITY_BIPOLAR & src) != 0)
+            transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+        else
+            transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+
+        if ((SF2Modulator.SOURCE_TYPE_CONCAVE & src) != 0)
+            transform.setTransform(ModelStandardTransform.TRANSFORM_CONCAVE);
+        if ((SF2Modulator.SOURCE_TYPE_CONVEX & src) != 0)
+            transform.setTransform(ModelStandardTransform.TRANSFORM_CONVEX);
+        if ((SF2Modulator.SOURCE_TYPE_SWITCH & src) != 0)
+            transform.setTransform(ModelStandardTransform.TRANSFORM_SWITCH);
+
+        return msrc;
+    }
+
+    protected static ModelDestination convertDestination(int dst,
+            double[] amountcorrection, ModelSource[] extrasrc) {
+        ModelIdentifier id = null;
+        switch (dst) {
+            case SF2Region.GENERATOR_INITIALFILTERFC:
+                id = ModelDestination.DESTINATION_FILTER_FREQ;
+                break;
+            case SF2Region.GENERATOR_INITIALFILTERQ:
+                id = ModelDestination.DESTINATION_FILTER_Q;
+                break;
+            case SF2Region.GENERATOR_CHORUSEFFECTSSEND:
+                id = ModelDestination.DESTINATION_CHORUS;
+                break;
+            case SF2Region.GENERATOR_REVERBEFFECTSSEND:
+                id = ModelDestination.DESTINATION_REVERB;
+                break;
+            case SF2Region.GENERATOR_PAN:
+                id = ModelDestination.DESTINATION_PAN;
+                break;
+            case SF2Region.GENERATOR_DELAYMODLFO:
+                id = ModelDestination.DESTINATION_LFO1_DELAY;
+                break;
+            case SF2Region.GENERATOR_FREQMODLFO:
+                id = ModelDestination.DESTINATION_LFO1_FREQ;
+                break;
+            case SF2Region.GENERATOR_DELAYVIBLFO:
+                id = ModelDestination.DESTINATION_LFO2_DELAY;
+                break;
+            case SF2Region.GENERATOR_FREQVIBLFO:
+                id = ModelDestination.DESTINATION_LFO2_FREQ;
+                break;
+
+            case SF2Region.GENERATOR_DELAYMODENV:
+                id = ModelDestination.DESTINATION_EG2_DELAY;
+                break;
+            case SF2Region.GENERATOR_ATTACKMODENV:
+                id = ModelDestination.DESTINATION_EG2_ATTACK;
+                break;
+            case SF2Region.GENERATOR_HOLDMODENV:
+                id = ModelDestination.DESTINATION_EG2_HOLD;
+                break;
+            case SF2Region.GENERATOR_DECAYMODENV:
+                id = ModelDestination.DESTINATION_EG2_DECAY;
+                break;
+            case SF2Region.GENERATOR_SUSTAINMODENV:
+                id = ModelDestination.DESTINATION_EG2_SUSTAIN;
+                amountcorrection[0] = -1;
+                break;
+            case SF2Region.GENERATOR_RELEASEMODENV:
+                id = ModelDestination.DESTINATION_EG2_RELEASE;
+                break;
+            case SF2Region.GENERATOR_DELAYVOLENV:
+                id = ModelDestination.DESTINATION_EG1_DELAY;
+                break;
+            case SF2Region.GENERATOR_ATTACKVOLENV:
+                id = ModelDestination.DESTINATION_EG1_ATTACK;
+                break;
+            case SF2Region.GENERATOR_HOLDVOLENV:
+                id = ModelDestination.DESTINATION_EG1_HOLD;
+                break;
+            case SF2Region.GENERATOR_DECAYVOLENV:
+                id = ModelDestination.DESTINATION_EG1_DECAY;
+                break;
+            case SF2Region.GENERATOR_SUSTAINVOLENV:
+                id = ModelDestination.DESTINATION_EG1_SUSTAIN;
+                amountcorrection[0] = -1;
+                break;
+            case SF2Region.GENERATOR_RELEASEVOLENV:
+                id = ModelDestination.DESTINATION_EG1_RELEASE;
+                break;
+            case SF2Region.GENERATOR_KEYNUM:
+                id = ModelDestination.DESTINATION_KEYNUMBER;
+                break;
+            case SF2Region.GENERATOR_VELOCITY:
+                id = ModelDestination.DESTINATION_VELOCITY;
+                break;
+
+            case SF2Region.GENERATOR_COARSETUNE:
+                amountcorrection[0] = 100;
+                id = ModelDestination.DESTINATION_PITCH;
+                break;
+
+            case SF2Region.GENERATOR_FINETUNE:
+                id = ModelDestination.DESTINATION_PITCH;
+                break;
+
+            case SF2Region.GENERATOR_INITIALATTENUATION:
+                id = ModelDestination.DESTINATION_GAIN;
+                amountcorrection[0] = -0.376287f;
+                break;
+
+            case SF2Region.GENERATOR_VIBLFOTOPITCH:
+                id = ModelDestination.DESTINATION_PITCH;
+                extrasrc[0] = new ModelSource(
+                        ModelSource.SOURCE_LFO2,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR);
+                break;
+
+            case SF2Region.GENERATOR_MODLFOTOPITCH:
+                id = ModelDestination.DESTINATION_PITCH;
+                extrasrc[0] = new ModelSource(
+                        ModelSource.SOURCE_LFO1,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR);
+                break;
+
+            case SF2Region.GENERATOR_MODLFOTOFILTERFC:
+                id = ModelDestination.DESTINATION_FILTER_FREQ;
+                extrasrc[0] = new ModelSource(
+                        ModelSource.SOURCE_LFO1,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR);
+                break;
+
+            case SF2Region.GENERATOR_MODLFOTOVOLUME:
+                id = ModelDestination.DESTINATION_GAIN;
+                amountcorrection[0] = -0.376287f;
+                extrasrc[0] = new ModelSource(
+                        ModelSource.SOURCE_LFO1,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR);
+                break;
+
+            case SF2Region.GENERATOR_MODENVTOPITCH:
+                id = ModelDestination.DESTINATION_PITCH;
+                extrasrc[0] = new ModelSource(
+                        ModelSource.SOURCE_EG2,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR);
+                break;
+
+            case SF2Region.GENERATOR_MODENVTOFILTERFC:
+                id = ModelDestination.DESTINATION_FILTER_FREQ;
+                extrasrc[0] = new ModelSource(
+                        ModelSource.SOURCE_EG2,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR);
+                break;
+
+            default:
+                break;
+        }
+        if (id != null)
+            return new ModelDestination(id);
+        return null;
+    }
+
+    private void addTimecentValue(ModelPerformer performer,
+            ModelIdentifier dest, short value) {
+        double fvalue;
+        if (value == -12000)
+            fvalue = Double.NEGATIVE_INFINITY;
+        else
+            fvalue = value;
+        performer.getConnectionBlocks().add(
+                new ModelConnectionBlock(fvalue, new ModelDestination(dest)));
+    }
+
+    private void addValue(ModelPerformer performer,
+            ModelIdentifier dest, short value) {
+        double fvalue = value;
+        performer.getConnectionBlocks().add(
+                new ModelConnectionBlock(fvalue, new ModelDestination(dest)));
+    }
+
+    private void addValue(ModelPerformer performer,
+            ModelIdentifier dest, double value) {
+        double fvalue = value;
+        performer.getConnectionBlocks().add(
+                new ModelConnectionBlock(fvalue, new ModelDestination(dest)));
+    }
+
+    private short getGeneratorValue(Map<Integer, Short> generators, int gen) {
+        if (generators.containsKey(gen))
+            return generators.get(gen);
+        return SF2Region.getDefaultValue(gen);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2InstrumentRegion.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Soundfont instrument region.
+ *
+ * @author Karl Helgason
+ */
+public class SF2InstrumentRegion extends SF2Region {
+
+    protected SF2Layer layer;
+
+    public SF2Layer getLayer() {
+        return layer;
+    }
+
+    public void setLayer(SF2Layer layer) {
+        this.layer = layer;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2Layer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.sound.midi.SoundbankResource;
+
+/**
+ * Soundfont layer.
+ *
+ * @author Karl Helgason
+ */
+public class SF2Layer extends SoundbankResource {
+
+    protected String name = "";
+    protected SF2GlobalRegion globalregion = null;
+    protected List<SF2LayerRegion> regions = new ArrayList<SF2LayerRegion>();
+
+    public SF2Layer(SF2Soundbank soundBank) {
+        super(soundBank, null, null);
+    }
+
+    public SF2Layer() {
+        super(null, null, null);
+    }
+
+    public Object getData() {
+        return null;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<SF2LayerRegion> getRegions() {
+        return regions;
+    }
+
+    public SF2GlobalRegion getGlobalRegion() {
+        return globalregion;
+    }
+
+    public void setGlobalZone(SF2GlobalRegion zone) {
+        globalregion = zone;
+    }
+
+    public String toString() {
+        return "Layer: " + name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2LayerRegion.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Soundfont layer region.
+ *
+ * @author Karl Helgason
+ */
+public class SF2LayerRegion extends SF2Region {
+
+    protected SF2Sample sample;
+
+    public SF2Sample getSample() {
+        return sample;
+    }
+
+    public void setSample(SF2Sample sample) {
+        this.sample = sample;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2Modulator.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Soundfont modulator container.
+ *
+ * @author Karl Helgason
+ */
+public class SF2Modulator {
+
+    public final static int SOURCE_NONE = 0;
+    public final static int SOURCE_NOTE_ON_VELOCITY = 2;
+    public final static int SOURCE_NOTE_ON_KEYNUMBER = 3;
+    public final static int SOURCE_POLY_PRESSURE = 10;
+    public final static int SOURCE_CHANNEL_PRESSURE = 13;
+    public final static int SOURCE_PITCH_WHEEL = 14;
+    public final static int SOURCE_PITCH_SENSITIVITY = 16;
+    public final static int SOURCE_MIDI_CONTROL = 128 * 1;
+    public final static int SOURCE_DIRECTION_MIN_MAX = 256 * 0;
+    public final static int SOURCE_DIRECTION_MAX_MIN = 256 * 1;
+    public final static int SOURCE_POLARITY_UNIPOLAR = 512 * 0;
+    public final static int SOURCE_POLARITY_BIPOLAR = 512 * 1;
+    public final static int SOURCE_TYPE_LINEAR = 1024 * 0;
+    public final static int SOURCE_TYPE_CONCAVE = 1024 * 1;
+    public final static int SOURCE_TYPE_CONVEX = 1024 * 2;
+    public final static int SOURCE_TYPE_SWITCH = 1024 * 3;
+    public final static int TRANSFORM_LINEAR = 0;
+    public final static int TRANSFORM_ABSOLUTE = 2;
+    protected int sourceOperator;
+    protected int destinationOperator;
+    protected short amount;
+    protected int amountSourceOperator;
+    protected int transportOperator;
+
+    public short getAmount() {
+        return amount;
+    }
+
+    public void setAmount(short amount) {
+        this.amount = amount;
+    }
+
+    public int getAmountSourceOperator() {
+        return amountSourceOperator;
+    }
+
+    public void setAmountSourceOperator(int amountSourceOperator) {
+        this.amountSourceOperator = amountSourceOperator;
+    }
+
+    public int getTransportOperator() {
+        return transportOperator;
+    }
+
+    public void setTransportOperator(int transportOperator) {
+        this.transportOperator = transportOperator;
+    }
+
+    public int getDestinationOperator() {
+        return destinationOperator;
+    }
+
+    public void setDestinationOperator(int destinationOperator) {
+        this.destinationOperator = destinationOperator;
+    }
+
+    public int getSourceOperator() {
+        return sourceOperator;
+    }
+
+    public void setSourceOperator(int sourceOperator) {
+        this.sourceOperator = sourceOperator;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2Region.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Soundfont general region.
+ *
+ * @author Karl Helgason
+ */
+public class SF2Region {
+
+    public final static int GENERATOR_STARTADDRSOFFSET = 0;
+    public final static int GENERATOR_ENDADDRSOFFSET = 1;
+    public final static int GENERATOR_STARTLOOPADDRSOFFSET = 2;
+    public final static int GENERATOR_ENDLOOPADDRSOFFSET = 3;
+    public final static int GENERATOR_STARTADDRSCOARSEOFFSET = 4;
+    public final static int GENERATOR_MODLFOTOPITCH = 5;
+    public final static int GENERATOR_VIBLFOTOPITCH = 6;
+    public final static int GENERATOR_MODENVTOPITCH = 7;
+    public final static int GENERATOR_INITIALFILTERFC = 8;
+    public final static int GENERATOR_INITIALFILTERQ = 9;
+    public final static int GENERATOR_MODLFOTOFILTERFC = 10;
+    public final static int GENERATOR_MODENVTOFILTERFC = 11;
+    public final static int GENERATOR_ENDADDRSCOARSEOFFSET = 12;
+    public final static int GENERATOR_MODLFOTOVOLUME = 13;
+    public final static int GENERATOR_UNUSED1 = 14;
+    public final static int GENERATOR_CHORUSEFFECTSSEND = 15;
+    public final static int GENERATOR_REVERBEFFECTSSEND = 16;
+    public final static int GENERATOR_PAN = 17;
+    public final static int GENERATOR_UNUSED2 = 18;
+    public final static int GENERATOR_UNUSED3 = 19;
+    public final static int GENERATOR_UNUSED4 = 20;
+    public final static int GENERATOR_DELAYMODLFO = 21;
+    public final static int GENERATOR_FREQMODLFO = 22;
+    public final static int GENERATOR_DELAYVIBLFO = 23;
+    public final static int GENERATOR_FREQVIBLFO = 24;
+    public final static int GENERATOR_DELAYMODENV = 25;
+    public final static int GENERATOR_ATTACKMODENV = 26;
+    public final static int GENERATOR_HOLDMODENV = 27;
+    public final static int GENERATOR_DECAYMODENV = 28;
+    public final static int GENERATOR_SUSTAINMODENV = 29;
+    public final static int GENERATOR_RELEASEMODENV = 30;
+    public final static int GENERATOR_KEYNUMTOMODENVHOLD = 31;
+    public final static int GENERATOR_KEYNUMTOMODENVDECAY = 32;
+    public final static int GENERATOR_DELAYVOLENV = 33;
+    public final static int GENERATOR_ATTACKVOLENV = 34;
+    public final static int GENERATOR_HOLDVOLENV = 35;
+    public final static int GENERATOR_DECAYVOLENV = 36;
+    public final static int GENERATOR_SUSTAINVOLENV = 37;
+    public final static int GENERATOR_RELEASEVOLENV = 38;
+    public final static int GENERATOR_KEYNUMTOVOLENVHOLD = 39;
+    public final static int GENERATOR_KEYNUMTOVOLENVDECAY = 40;
+    public final static int GENERATOR_INSTRUMENT = 41;
+    public final static int GENERATOR_RESERVED1 = 42;
+    public final static int GENERATOR_KEYRANGE = 43;
+    public final static int GENERATOR_VELRANGE = 44;
+    public final static int GENERATOR_STARTLOOPADDRSCOARSEOFFSET = 45;
+    public final static int GENERATOR_KEYNUM = 46;
+    public final static int GENERATOR_VELOCITY = 47;
+    public final static int GENERATOR_INITIALATTENUATION = 48;
+    public final static int GENERATOR_RESERVED2 = 49;
+    public final static int GENERATOR_ENDLOOPADDRSCOARSEOFFSET = 50;
+    public final static int GENERATOR_COARSETUNE = 51;
+    public final static int GENERATOR_FINETUNE = 52;
+    public final static int GENERATOR_SAMPLEID = 53;
+    public final static int GENERATOR_SAMPLEMODES = 54;
+    public final static int GENERATOR_RESERVED3 = 55;
+    public final static int GENERATOR_SCALETUNING = 56;
+    public final static int GENERATOR_EXCLUSIVECLASS = 57;
+    public final static int GENERATOR_OVERRIDINGROOTKEY = 58;
+    public final static int GENERATOR_UNUSED5 = 59;
+    public final static int GENERATOR_ENDOPR = 60;
+    protected Map<Integer, Short> generators = new HashMap<Integer, Short>();
+    protected List<SF2Modulator> modulators = new ArrayList<SF2Modulator>();
+
+    public Map<Integer, Short> getGenerators() {
+        return generators;
+    }
+
+    public boolean contains(int generator) {
+        return generators.containsKey(generator);
+    }
+
+    static public short getDefaultValue(int generator) {
+        if (generator == 8) return (short)13500;
+        if (generator == 21) return (short)-12000;
+        if (generator == 23) return (short)-12000;
+        if (generator == 25) return (short)-12000;
+        if (generator == 26) return (short)-12000;
+        if (generator == 27) return (short)-12000;
+        if (generator == 28) return (short)-12000;
+        if (generator == 30) return (short)-12000;
+        if (generator == 33) return (short)-12000;
+        if (generator == 34) return (short)-12000;
+        if (generator == 35) return (short)-12000;
+        if (generator == 36) return (short)-12000;
+        if (generator == 38) return (short)-12000;
+        if (generator == 43) return (short)0x7F00;
+        if (generator == 44) return (short)0x7F00;
+        if (generator == 46) return (short)-1;
+        if (generator == 47) return (short)-1;
+        if (generator == 56) return (short)100;
+        if (generator == 58) return (short)-1;
+        return 0;
+    }
+
+    public short getShort(int generator) {
+        if (!contains(generator))
+            return getDefaultValue(generator);
+        return generators.get(generator);
+    }
+
+    public void putShort(int generator, short value) {
+        generators.put(generator, value);
+    }
+
+    public byte[] getBytes(int generator) {
+        int val = getInteger(generator);
+        byte[] bytes = new byte[2];
+        bytes[0] = (byte) (0xFF & val);
+        bytes[1] = (byte) ((0xFF00 & val) >> 8);
+        return bytes;
+    }
+
+    public void putBytes(int generator, byte[] bytes) {
+        generators.put(generator, (short) (bytes[0] + (bytes[1] << 8)));
+    }
+
+    public int getInteger(int generator) {
+        return 0xFFFF & getShort(generator);
+    }
+
+    public void putInteger(int generator, int value) {
+        generators.put(generator, (short) value);
+    }
+
+    public List<SF2Modulator> getModulators() {
+        return modulators;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2Sample.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.InputStream;
+
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+
+/**
+ * Soundfont sample storage.
+ *
+ * @author Karl Helgason
+ */
+public class SF2Sample extends SoundbankResource {
+
+    protected String name = "";
+    protected long startLoop = 0;
+    protected long endLoop = 0;
+    protected long sampleRate = 44100;
+    protected int originalPitch = 60;
+    protected byte pitchCorrection = 0;
+    protected int sampleLink = 0;
+    protected int sampleType = 0;
+    protected ModelByteBuffer data;
+    protected ModelByteBuffer data24;
+
+    public SF2Sample(Soundbank soundBank) {
+        super(soundBank, null, AudioInputStream.class);
+    }
+
+    public SF2Sample() {
+        super(null, null, AudioInputStream.class);
+    }
+
+    public Object getData() {
+
+        AudioFormat format = getFormat();
+        /*
+        if (sampleFile != null) {
+            FileInputStream fis;
+            try {
+                fis = new FileInputStream(sampleFile);
+                RIFFReader riff = new RIFFReader(fis);
+                if (!riff.getFormat().equals("RIFF")) {
+                    throw new RIFFInvalidDataException(
+                        "Input stream is not a valid RIFF stream!");
+                }
+                if (!riff.getType().equals("sfbk")) {
+                    throw new RIFFInvalidDataException(
+                        "Input stream is not a valid SoundFont!");
+                }
+                while (riff.hasNextChunk()) {
+                    RIFFReader chunk = riff.nextChunk();
+                    if (chunk.getFormat().equals("LIST")) {
+                        if (chunk.getType().equals("sdta")) {
+                            while(chunk.hasNextChunk()) {
+                                RIFFReader chunkchunk = chunk.nextChunk();
+                                if(chunkchunk.getFormat().equals("smpl")) {
+                                    chunkchunk.skip(sampleOffset);
+                                    return new AudioInputStream(chunkchunk,
+                                            format, sampleLen);
+                                }
+                            }
+                        }
+                    }
+                }
+                return null;
+            } catch (Exception e) {
+                return new Throwable(e.toString());
+            }
+        }
+        */
+        InputStream is = data.getInputStream();
+        if (is == null)
+            return null;
+        return new AudioInputStream(is, format, data.capacity());
+    }
+
+    public ModelByteBuffer getDataBuffer() {
+        return data;
+    }
+
+    public ModelByteBuffer getData24Buffer() {
+        return data24;
+    }
+
+    public AudioFormat getFormat() {
+        return new AudioFormat(sampleRate, 16, 1, true, false);
+    }
+
+    public void setData(ModelByteBuffer data) {
+        this.data = data;
+    }
+
+    public void setData(byte[] data) {
+        this.data = new ModelByteBuffer(data);
+    }
+
+    public void setData(byte[] data, int offset, int length) {
+        this.data = new ModelByteBuffer(data, offset, length);
+    }
+
+    public void setData24(ModelByteBuffer data24) {
+        this.data24 = data24;
+    }
+
+    public void setData24(byte[] data24) {
+        this.data24 = new ModelByteBuffer(data24);
+    }
+
+    public void setData24(byte[] data24, int offset, int length) {
+        this.data24 = new ModelByteBuffer(data24, offset, length);
+    }
+
+    /*
+    public void setData(File file, int offset, int length) {
+        this.data = null;
+        this.sampleFile = file;
+        this.sampleOffset = offset;
+        this.sampleLen = length;
+    }
+    */
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public long getEndLoop() {
+        return endLoop;
+    }
+
+    public void setEndLoop(long endLoop) {
+        this.endLoop = endLoop;
+    }
+
+    public int getOriginalPitch() {
+        return originalPitch;
+    }
+
+    public void setOriginalPitch(int originalPitch) {
+        this.originalPitch = originalPitch;
+    }
+
+    public byte getPitchCorrection() {
+        return pitchCorrection;
+    }
+
+    public void setPitchCorrection(byte pitchCorrection) {
+        this.pitchCorrection = pitchCorrection;
+    }
+
+    public int getSampleLink() {
+        return sampleLink;
+    }
+
+    public void setSampleLink(int sampleLink) {
+        this.sampleLink = sampleLink;
+    }
+
+    public long getSampleRate() {
+        return sampleRate;
+    }
+
+    public void setSampleRate(long sampleRate) {
+        this.sampleRate = sampleRate;
+    }
+
+    public int getSampleType() {
+        return sampleType;
+    }
+
+    public void setSampleType(int sampleType) {
+        this.sampleType = sampleType;
+    }
+
+    public long getStartLoop() {
+        return startLoop;
+    }
+
+    public void setStartLoop(long startLoop) {
+        this.startLoop = startLoop;
+    }
+
+    public String toString() {
+        return "Sample: " + name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2Soundbank.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,973 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+
+/**
+ * A SoundFont 2.04 soundbank reader.
+ *
+ * Based on SoundFont 2.04 specification from:
+ * <p>  http://developer.creative.com <br>
+ *      http://www.soundfont.com/ ;
+ *
+ * @author Karl Helgason
+ */
+public class SF2Soundbank implements Soundbank {
+
+    // version of the Sound Font RIFF file
+    protected int major = 2;
+    protected int minor = 1;
+    // target Sound Engine
+    protected String targetEngine = "EMU8000";
+    // Sound Font Bank Name
+    protected String name = "untitled";
+    // Sound ROM Name
+    protected String romName = null;
+    // Sound ROM Version
+    protected int romVersionMajor = -1;
+    protected int romVersionMinor = -1;
+    // Date of Creation of the Bank
+    protected String creationDate = null;
+    // Sound Designers and Engineers for the Bank
+    protected String engineers = null;
+    // Product for which the Bank was intended
+    protected String product = null;
+    // Copyright message
+    protected String copyright = null;
+    // Comments
+    protected String comments = null;
+    // The SoundFont tools used to create and alter the bank
+    protected String tools = null;
+    // The Sample Data loaded from the SoundFont
+    private ModelByteBuffer sampleData = null;
+    private ModelByteBuffer sampleData24 = null;
+    private File sampleFile = null;
+    private boolean largeFormat = false;
+    private List<SF2Instrument> instruments = new ArrayList<SF2Instrument>();
+    private List<SF2Layer> layers = new ArrayList<SF2Layer>();
+    private List<SF2Sample> samples = new ArrayList<SF2Sample>();
+
+    public SF2Soundbank() {
+    }
+
+    public SF2Soundbank(URL url) throws IOException {
+
+        InputStream is = url.openStream();
+        try {
+            readSoundbank(is);
+        } finally {
+            is.close();
+        }
+    }
+
+    public SF2Soundbank(File file) throws IOException {
+        largeFormat = true;
+        sampleFile = file;
+        InputStream is = new FileInputStream(file);
+        try {
+            readSoundbank(is);
+        } finally {
+            is.close();
+        }
+    }
+
+    public SF2Soundbank(InputStream inputstream) throws IOException {
+        readSoundbank(inputstream);
+    }
+
+    private void readSoundbank(InputStream inputstream) throws IOException {
+        RIFFReader riff = new RIFFReader(inputstream);
+        if (!riff.getFormat().equals("RIFF")) {
+            throw new RIFFInvalidFormatException(
+                    "Input stream is not a valid RIFF stream!");
+        }
+        if (!riff.getType().equals("sfbk")) {
+            throw new RIFFInvalidFormatException(
+                    "Input stream is not a valid SoundFont!");
+        }
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("LIST")) {
+                if (chunk.getType().equals("INFO"))
+                    readInfoChunk(chunk);
+                if (chunk.getType().equals("sdta"))
+                    readSdtaChunk(chunk);
+                if (chunk.getType().equals("pdta"))
+                    readPdtaChunk(chunk);
+            }
+        }
+    }
+
+    private void readInfoChunk(RIFFReader riff) throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("ifil")) {
+                major = chunk.readUnsignedShort();
+                minor = chunk.readUnsignedShort();
+            } else if (format.equals("isng")) {
+                this.targetEngine = chunk.readString(chunk.available());
+            } else if (format.equals("INAM")) {
+                this.name = chunk.readString(chunk.available());
+            } else if (format.equals("irom")) {
+                this.romName = chunk.readString(chunk.available());
+            } else if (format.equals("iver")) {
+                romVersionMajor = chunk.readUnsignedShort();
+                romVersionMinor = chunk.readUnsignedShort();
+            } else if (format.equals("ICRD")) {
+                this.creationDate = chunk.readString(chunk.available());
+            } else if (format.equals("IENG")) {
+                this.engineers = chunk.readString(chunk.available());
+            } else if (format.equals("IPRD")) {
+                this.product = chunk.readString(chunk.available());
+            } else if (format.equals("ICOP")) {
+                this.copyright = chunk.readString(chunk.available());
+            } else if (format.equals("ICMT")) {
+                this.comments = chunk.readString(chunk.available());
+            } else if (format.equals("ISFT")) {
+                this.tools = chunk.readString(chunk.available());
+            }
+
+        }
+    }
+
+    private void readSdtaChunk(RIFFReader riff) throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("smpl")) {
+                if (!largeFormat) {
+                    byte[] sampleData = new byte[chunk.available()];
+
+                    int read = 0;
+                    int avail = chunk.available();
+                    while (read != avail) {
+                        if (avail - read > 65536) {
+                            chunk.readFully(sampleData, read, 65536);
+                            read += 65536;
+                        } else {
+                            chunk.readFully(sampleData, read, avail - read);
+                            read = avail;
+                        }
+
+                    }
+                    this.sampleData = new ModelByteBuffer(sampleData);
+                    //chunk.read(sampleData);
+                } else {
+                    this.sampleData = new ModelByteBuffer(sampleFile,
+                            chunk.getFilePointer(), chunk.available());
+                }
+            }
+            if (chunk.getFormat().equals("sm24")) {
+                if (!largeFormat) {
+                    byte[] sampleData24 = new byte[chunk.available()];
+                    //chunk.read(sampleData24);
+
+                    int read = 0;
+                    int avail = chunk.available();
+                    while (read != avail) {
+                        if (avail - read > 65536) {
+                            chunk.readFully(sampleData24, read, 65536);
+                            read += 65536;
+                        } else {
+                            chunk.readFully(sampleData24, read, avail - read);
+                            read = avail;
+                        }
+
+                    }
+                    this.sampleData24 = new ModelByteBuffer(sampleData24);
+                } else {
+                    this.sampleData24 = new ModelByteBuffer(sampleFile,
+                            chunk.getFilePointer(), chunk.available());
+                }
+
+            }
+        }
+    }
+
+    private void readPdtaChunk(RIFFReader riff) throws IOException {
+
+        List<SF2Instrument> presets = new ArrayList<SF2Instrument>();
+        List<Integer> presets_bagNdx = new ArrayList<Integer>();
+        List<SF2InstrumentRegion> presets_splits_gen
+                = new ArrayList<SF2InstrumentRegion>();
+        List<SF2InstrumentRegion> presets_splits_mod
+                = new ArrayList<SF2InstrumentRegion>();
+
+        List<SF2Layer> instruments = new ArrayList<SF2Layer>();
+        List<Integer> instruments_bagNdx = new ArrayList<Integer>();
+        List<SF2LayerRegion> instruments_splits_gen
+                = new ArrayList<SF2LayerRegion>();
+        List<SF2LayerRegion> instruments_splits_mod
+                = new ArrayList<SF2LayerRegion>();
+
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("phdr")) {
+                // Preset Header / Instrument
+                if (chunk.available() % 38 != 0)
+                    throw new RIFFInvalidDataException();
+                int count = chunk.available() / 38;
+                for (int i = 0; i < count; i++) {
+                    SF2Instrument preset = new SF2Instrument(this);
+                    preset.name = chunk.readString(20);
+                    preset.preset = chunk.readUnsignedShort();
+                    preset.bank = chunk.readUnsignedShort();
+                    presets_bagNdx.add(chunk.readUnsignedShort());
+                    preset.library = chunk.readUnsignedInt();
+                    preset.genre = chunk.readUnsignedInt();
+                    preset.morphology = chunk.readUnsignedInt();
+                    presets.add(preset);
+                    if (i != count - 1)
+                        this.instruments.add(preset);
+                }
+            } else if (format.equals("pbag")) {
+                // Preset Zones / Instruments splits
+                if (chunk.available() % 4 != 0)
+                    throw new RIFFInvalidDataException();
+                int count = chunk.available() / 4;
+
+                // Skip first record
+                {
+                    int gencount = chunk.readUnsignedShort();
+                    int modcount = chunk.readUnsignedShort();
+                    while (presets_splits_gen.size() < gencount)
+                        presets_splits_gen.add(null);
+                    while (presets_splits_mod.size() < modcount)
+                        presets_splits_mod.add(null);
+                    count--;
+                }
+
+                int offset = presets_bagNdx.get(0);
+                // Offset should be 0 (but just case)
+                for (int i = 0; i < offset; i++) {
+                    if (count == 0)
+                        throw new RIFFInvalidDataException();
+                    int gencount = chunk.readUnsignedShort();
+                    int modcount = chunk.readUnsignedShort();
+                    while (presets_splits_gen.size() < gencount)
+                        presets_splits_gen.add(null);
+                    while (presets_splits_mod.size() < modcount)
+                        presets_splits_mod.add(null);
+                    count--;
+                }
+
+                for (int i = 0; i < presets_bagNdx.size() - 1; i++) {
+                    int zone_count = presets_bagNdx.get(i + 1)
+                                     - presets_bagNdx.get(i);
+                    SF2Instrument preset = presets.get(i);
+                    for (int ii = 0; ii < zone_count; ii++) {
+                        if (count == 0)
+                            throw new RIFFInvalidDataException();
+                        int gencount = chunk.readUnsignedShort();
+                        int modcount = chunk.readUnsignedShort();
+                        SF2InstrumentRegion split = new SF2InstrumentRegion();
+                        preset.regions.add(split);
+                        while (presets_splits_gen.size() < gencount)
+                            presets_splits_gen.add(split);
+                        while (presets_splits_mod.size() < modcount)
+                            presets_splits_mod.add(split);
+                        count--;
+                    }
+                }
+            } else if (format.equals("pmod")) {
+                // Preset Modulators / Split Modulators
+                for (int i = 0; i < presets_splits_mod.size(); i++) {
+                    SF2Modulator modulator = new SF2Modulator();
+                    modulator.sourceOperator = chunk.readUnsignedShort();
+                    modulator.destinationOperator = chunk.readUnsignedShort();
+                    modulator.amount = chunk.readShort();
+                    modulator.amountSourceOperator = chunk.readUnsignedShort();
+                    modulator.transportOperator = chunk.readUnsignedShort();
+                    SF2InstrumentRegion split = presets_splits_mod.get(i);
+                    if (split != null)
+                        split.modulators.add(modulator);
+                }
+            } else if (format.equals("pgen")) {
+                // Preset Generators / Split Generators
+                for (int i = 0; i < presets_splits_gen.size(); i++) {
+                    int operator = chunk.readUnsignedShort();
+                    short amount = chunk.readShort();
+                    SF2InstrumentRegion split = presets_splits_gen.get(i);
+                    if (split != null)
+                        split.generators.put(operator, amount);
+                }
+            } else if (format.equals("inst")) {
+                // Instrument Header / Layers
+                if (chunk.available() % 22 != 0)
+                    throw new RIFFInvalidDataException();
+                int count = chunk.available() / 22;
+                for (int i = 0; i < count; i++) {
+                    SF2Layer layer = new SF2Layer(this);
+                    layer.name = chunk.readString(20);
+                    instruments_bagNdx.add(chunk.readUnsignedShort());
+                    instruments.add(layer);
+                    if (i != count - 1)
+                        this.layers.add(layer);
+                }
+            } else if (format.equals("ibag")) {
+                // Instrument Zones / Layer splits
+                if (chunk.available() % 4 != 0)
+                    throw new RIFFInvalidDataException();
+                int count = chunk.available() / 4;
+
+                // Skip first record
+                {
+                    int gencount = chunk.readUnsignedShort();
+                    int modcount = chunk.readUnsignedShort();
+                    while (instruments_splits_gen.size() < gencount)
+                        instruments_splits_gen.add(null);
+                    while (instruments_splits_mod.size() < modcount)
+                        instruments_splits_mod.add(null);
+                    count--;
+                }
+
+                int offset = instruments_bagNdx.get(0);
+                // Offset should be 0 (but just case)
+                for (int i = 0; i < offset; i++) {
+                    if (count == 0)
+                        throw new RIFFInvalidDataException();
+                    int gencount = chunk.readUnsignedShort();
+                    int modcount = chunk.readUnsignedShort();
+                    while (instruments_splits_gen.size() < gencount)
+                        instruments_splits_gen.add(null);
+                    while (instruments_splits_mod.size() < modcount)
+                        instruments_splits_mod.add(null);
+                    count--;
+                }
+
+                for (int i = 0; i < instruments_bagNdx.size() - 1; i++) {
+                    int zone_count = instruments_bagNdx.get(i + 1) - instruments_bagNdx.get(i);
+                    SF2Layer layer = layers.get(i);
+                    for (int ii = 0; ii < zone_count; ii++) {
+                        if (count == 0)
+                            throw new RIFFInvalidDataException();
+                        int gencount = chunk.readUnsignedShort();
+                        int modcount = chunk.readUnsignedShort();
+                        SF2LayerRegion split = new SF2LayerRegion();
+                        layer.regions.add(split);
+                        while (instruments_splits_gen.size() < gencount)
+                            instruments_splits_gen.add(split);
+                        while (instruments_splits_mod.size() < modcount)
+                            instruments_splits_mod.add(split);
+                        count--;
+                    }
+                }
+
+            } else if (format.equals("imod")) {
+                // Instrument Modulators / Split Modulators
+                for (int i = 0; i < instruments_splits_mod.size(); i++) {
+                    SF2Modulator modulator = new SF2Modulator();
+                    modulator.sourceOperator = chunk.readUnsignedShort();
+                    modulator.destinationOperator = chunk.readUnsignedShort();
+                    modulator.amount = chunk.readShort();
+                    modulator.amountSourceOperator = chunk.readUnsignedShort();
+                    modulator.transportOperator = chunk.readUnsignedShort();
+                    SF2LayerRegion split = instruments_splits_gen.get(i);
+                    if (split != null)
+                        split.modulators.add(modulator);
+                }
+            } else if (format.equals("igen")) {
+                // Instrument Generators / Split Generators
+                for (int i = 0; i < instruments_splits_gen.size(); i++) {
+                    int operator = chunk.readUnsignedShort();
+                    short amount = chunk.readShort();
+                    SF2LayerRegion split = instruments_splits_gen.get(i);
+                    if (split != null)
+                        split.generators.put(operator, amount);
+                }
+            } else if (format.equals("shdr")) {
+                // Sample Headers
+                if (chunk.available() % 46 != 0)
+                    throw new RIFFInvalidDataException();
+                int count = chunk.available() / 46;
+                for (int i = 0; i < count; i++) {
+                    SF2Sample sample = new SF2Sample(this);
+                    sample.name = chunk.readString(20);
+                    long start = chunk.readUnsignedInt();
+                    long end = chunk.readUnsignedInt();
+                    sample.data = sampleData.subbuffer(start * 2, end * 2, true);
+                    if (sampleData24 != null)
+                        sample.data24 = sampleData24.subbuffer(start, end, true);
+                    /*
+                    sample.data = new ModelByteBuffer(sampleData, (int)(start*2),
+                            (int)((end - start)*2));
+                    if (sampleData24 != null)
+                        sample.data24 = new ModelByteBuffer(sampleData24,
+                                (int)start, (int)(end - start));
+                     */
+                    sample.startLoop = chunk.readUnsignedInt() - start;
+                    sample.endLoop = chunk.readUnsignedInt() - start;
+                    if (sample.startLoop < 0)
+                        sample.startLoop = -1;
+                    if (sample.endLoop < 0)
+                        sample.endLoop = -1;
+                    sample.sampleRate = chunk.readUnsignedInt();
+                    sample.originalPitch = chunk.readUnsignedByte();
+                    sample.pitchCorrection = chunk.readByte();
+                    sample.sampleLink = chunk.readUnsignedShort();
+                    sample.sampleType = chunk.readUnsignedShort();
+                    if (i != count - 1)
+                        this.samples.add(sample);
+                }
+            }
+        }
+
+        Iterator<SF2Layer> liter = this.layers.iterator();
+        while (liter.hasNext()) {
+            SF2Layer layer = liter.next();
+            Iterator<SF2LayerRegion> siter = layer.regions.iterator();
+            SF2Region globalsplit = null;
+            while (siter.hasNext()) {
+                SF2LayerRegion split = siter.next();
+                if (split.generators.get(SF2LayerRegion.GENERATOR_SAMPLEID) != null) {
+                    int sampleid = split.generators.get(
+                            SF2LayerRegion.GENERATOR_SAMPLEID);
+                    split.generators.remove(SF2LayerRegion.GENERATOR_SAMPLEID);
+                    split.sample = samples.get(sampleid);
+                } else {
+                    globalsplit = split;
+                }
+            }
+            if (globalsplit != null) {
+                layer.getRegions().remove(globalsplit);
+                SF2GlobalRegion gsplit = new SF2GlobalRegion();
+                gsplit.generators = globalsplit.generators;
+                gsplit.modulators = globalsplit.modulators;
+                layer.setGlobalZone(gsplit);
+            }
+        }
+
+
+        Iterator<SF2Instrument> iiter = this.instruments.iterator();
+        while (iiter.hasNext()) {
+            SF2Instrument instrument = iiter.next();
+            Iterator<SF2InstrumentRegion> siter = instrument.regions.iterator();
+            SF2Region globalsplit = null;
+            while (siter.hasNext()) {
+                SF2InstrumentRegion split = siter.next();
+                if (split.generators.get(SF2LayerRegion.GENERATOR_INSTRUMENT) != null) {
+                    int instrumentid = split.generators.get(
+                            SF2InstrumentRegion.GENERATOR_INSTRUMENT);
+                    split.generators.remove(SF2LayerRegion.GENERATOR_INSTRUMENT);
+                    split.layer = layers.get(instrumentid);
+                } else {
+                    globalsplit = split;
+                }
+            }
+
+            if (globalsplit != null) {
+                instrument.getRegions().remove(globalsplit);
+                SF2GlobalRegion gsplit = new SF2GlobalRegion();
+                gsplit.generators = globalsplit.generators;
+                gsplit.modulators = globalsplit.modulators;
+                instrument.setGlobalZone(gsplit);
+            }
+        }
+
+    }
+
+    public void save(String name) throws IOException {
+        writeSoundbank(new RIFFWriter(name, "sfbk"));
+    }
+
+    public void save(File file) throws IOException {
+        writeSoundbank(new RIFFWriter(file, "sfbk"));
+    }
+
+    public void save(OutputStream out) throws IOException {
+        writeSoundbank(new RIFFWriter(out, "sfbk"));
+    }
+
+    private void writeSoundbank(RIFFWriter writer) throws IOException {
+        writeInfo(writer.writeList("INFO"));
+        writeSdtaChunk(writer.writeList("sdta"));
+        writePdtaChunk(writer.writeList("pdta"));
+        writer.close();
+    }
+
+    private void writeInfoStringChunk(RIFFWriter writer, String name,
+            String value) throws IOException {
+        if (value == null)
+            return;
+        RIFFWriter chunk = writer.writeChunk(name);
+        chunk.writeString(value);
+        int len = value.getBytes("ascii").length;
+        chunk.write(0);
+        len++;
+        if (len % 2 != 0)
+            chunk.write(0);
+    }
+
+    private void writeInfo(RIFFWriter writer) throws IOException {
+        if (this.targetEngine == null)
+            this.targetEngine = "EMU8000";
+        if (this.name == null)
+            this.name = "";
+
+        RIFFWriter ifil_chunk = writer.writeChunk("ifil");
+        ifil_chunk.writeUnsignedShort(this.major);
+        ifil_chunk.writeUnsignedShort(this.minor);
+        writeInfoStringChunk(writer, "isng", this.targetEngine);
+        writeInfoStringChunk(writer, "INAM", this.name);
+        writeInfoStringChunk(writer, "irom", this.romName);
+        if (romVersionMajor != -1) {
+            RIFFWriter iver_chunk = writer.writeChunk("iver");
+            iver_chunk.writeUnsignedShort(this.romVersionMajor);
+            iver_chunk.writeUnsignedShort(this.romVersionMinor);
+        }
+        writeInfoStringChunk(writer, "ICRD", this.creationDate);
+        writeInfoStringChunk(writer, "IENG", this.engineers);
+        writeInfoStringChunk(writer, "IPRD", this.product);
+        writeInfoStringChunk(writer, "ICOP", this.copyright);
+        writeInfoStringChunk(writer, "ICMT", this.comments);
+        writeInfoStringChunk(writer, "ISFT", this.tools);
+
+        writer.close();
+    }
+
+    private void writeSdtaChunk(RIFFWriter writer) throws IOException {
+
+        byte[] pad = new byte[32];
+
+        RIFFWriter smpl_chunk = writer.writeChunk("smpl");
+        for (SF2Sample sample : samples) {
+            ModelByteBuffer data = sample.getDataBuffer();
+            data.writeTo(smpl_chunk);
+            /*
+            smpl_chunk.write(data.array(),
+            data.arrayOffset(),
+            data.capacity());
+             */
+            smpl_chunk.write(pad);
+            smpl_chunk.write(pad);
+        }
+        if (major < 2)
+            return;
+        if (major == 2 && minor < 4)
+            return;
+
+
+        for (SF2Sample sample : samples) {
+            ModelByteBuffer data24 = sample.getData24Buffer();
+            if (data24 == null)
+                return;
+        }
+
+        RIFFWriter sm24_chunk = writer.writeChunk("sm24");
+        for (SF2Sample sample : samples) {
+            ModelByteBuffer data = sample.getData24Buffer();
+            data.writeTo(sm24_chunk);
+            /*
+            sm24_chunk.write(data.array(),
+            data.arrayOffset(),
+            data.capacity());*/
+            smpl_chunk.write(pad);
+        }
+    }
+
+    private void writeModulators(RIFFWriter writer, List<SF2Modulator> modulators)
+            throws IOException {
+        for (SF2Modulator modulator : modulators) {
+            writer.writeUnsignedShort(modulator.sourceOperator);
+            writer.writeUnsignedShort(modulator.destinationOperator);
+            writer.writeShort(modulator.amount);
+            writer.writeUnsignedShort(modulator.amountSourceOperator);
+            writer.writeUnsignedShort(modulator.transportOperator);
+        }
+    }
+
+    private void writeGenerators(RIFFWriter writer, Map<Integer, Short> generators)
+            throws IOException {
+        Short keyrange = (Short) generators.get(SF2Region.GENERATOR_KEYRANGE);
+        Short velrange = (Short) generators.get(SF2Region.GENERATOR_VELRANGE);
+        if (keyrange != null) {
+            writer.writeUnsignedShort(SF2Region.GENERATOR_KEYRANGE);
+            writer.writeShort(keyrange);
+        }
+        if (velrange != null) {
+            writer.writeUnsignedShort(SF2Region.GENERATOR_VELRANGE);
+            writer.writeShort(velrange);
+        }
+        for (Map.Entry<Integer, Short> generator : generators.entrySet()) {
+            if (generator.getKey() == SF2Region.GENERATOR_KEYRANGE)
+                continue;
+            if (generator.getKey() == SF2Region.GENERATOR_VELRANGE)
+                continue;
+            writer.writeUnsignedShort(generator.getKey());
+            writer.writeShort(generator.getValue());
+        }
+    }
+
+    private void writePdtaChunk(RIFFWriter writer) throws IOException {
+
+        RIFFWriter phdr_chunk = writer.writeChunk("phdr");
+        int phdr_zone_count = 0;
+        for (SF2Instrument preset : this.instruments) {
+            phdr_chunk.writeString(preset.name, 20);
+            phdr_chunk.writeUnsignedShort(preset.preset);
+            phdr_chunk.writeUnsignedShort(preset.bank);
+            phdr_chunk.writeUnsignedShort(phdr_zone_count);
+            if (preset.getGlobalRegion() != null)
+                phdr_zone_count += 1;
+            phdr_zone_count += preset.getRegions().size();
+            phdr_chunk.writeUnsignedInt(preset.library);
+            phdr_chunk.writeUnsignedInt(preset.genre);
+            phdr_chunk.writeUnsignedInt(preset.morphology);
+        }
+        phdr_chunk.writeString("EOP", 20);
+        phdr_chunk.writeUnsignedShort(0);
+        phdr_chunk.writeUnsignedShort(0);
+        phdr_chunk.writeUnsignedShort(phdr_zone_count);
+        phdr_chunk.writeUnsignedInt(0);
+        phdr_chunk.writeUnsignedInt(0);
+        phdr_chunk.writeUnsignedInt(0);
+
+
+        RIFFWriter pbag_chunk = writer.writeChunk("pbag");
+        int pbag_gencount = 0;
+        int pbag_modcount = 0;
+        for (SF2Instrument preset : this.instruments) {
+            if (preset.getGlobalRegion() != null) {
+                pbag_chunk.writeUnsignedShort(pbag_gencount);
+                pbag_chunk.writeUnsignedShort(pbag_modcount);
+                pbag_gencount += preset.getGlobalRegion().getGenerators().size();
+                pbag_modcount += preset.getGlobalRegion().getModulators().size();
+            }
+            for (SF2InstrumentRegion region : preset.getRegions()) {
+                pbag_chunk.writeUnsignedShort(pbag_gencount);
+                pbag_chunk.writeUnsignedShort(pbag_modcount);
+                if (layers.indexOf(region.layer) != -1) {
+                    // One generator is used to reference to instrument record
+                    pbag_gencount += 1;
+                }
+                pbag_gencount += region.getGenerators().size();
+                pbag_modcount += region.getModulators().size();
+
+            }
+        }
+        pbag_chunk.writeUnsignedShort(pbag_gencount);
+        pbag_chunk.writeUnsignedShort(pbag_modcount);
+
+        RIFFWriter pmod_chunk = writer.writeChunk("pmod");
+        for (SF2Instrument preset : this.instruments) {
+            if (preset.getGlobalRegion() != null) {
+                writeModulators(pmod_chunk,
+                        preset.getGlobalRegion().getModulators());
+            }
+            for (SF2InstrumentRegion region : preset.getRegions())
+                writeModulators(pmod_chunk, region.getModulators());
+        }
+        pmod_chunk.write(new byte[10]);
+
+        RIFFWriter pgen_chunk = writer.writeChunk("pgen");
+        for (SF2Instrument preset : this.instruments) {
+            if (preset.getGlobalRegion() != null) {
+                writeGenerators(pgen_chunk,
+                        preset.getGlobalRegion().getGenerators());
+            }
+            for (SF2InstrumentRegion region : preset.getRegions()) {
+                writeGenerators(pgen_chunk, region.getGenerators());
+                int ix = (int) layers.indexOf(region.layer);
+                if (ix != -1) {
+                    pgen_chunk.writeUnsignedShort(SF2Region.GENERATOR_INSTRUMENT);
+                    pgen_chunk.writeShort((short) ix);
+                }
+            }
+        }
+        pgen_chunk.write(new byte[4]);
+
+        RIFFWriter inst_chunk = writer.writeChunk("inst");
+        int inst_zone_count = 0;
+        for (SF2Layer instrument : this.layers) {
+            inst_chunk.writeString(instrument.name, 20);
+            inst_chunk.writeUnsignedShort(inst_zone_count);
+            if (instrument.getGlobalRegion() != null)
+                inst_zone_count += 1;
+            inst_zone_count += instrument.getRegions().size();
+        }
+        inst_chunk.writeString("EOI", 20);
+        inst_chunk.writeUnsignedShort(inst_zone_count);
+
+
+        RIFFWriter ibag_chunk = writer.writeChunk("ibag");
+        int ibag_gencount = 0;
+        int ibag_modcount = 0;
+        for (SF2Layer instrument : this.layers) {
+            if (instrument.getGlobalRegion() != null) {
+                ibag_chunk.writeUnsignedShort(ibag_gencount);
+                ibag_chunk.writeUnsignedShort(ibag_modcount);
+                ibag_gencount
+                        += instrument.getGlobalRegion().getGenerators().size();
+                ibag_modcount
+                        += instrument.getGlobalRegion().getModulators().size();
+            }
+            for (SF2LayerRegion region : instrument.getRegions()) {
+                ibag_chunk.writeUnsignedShort(ibag_gencount);
+                ibag_chunk.writeUnsignedShort(ibag_modcount);
+                if (samples.indexOf(region.sample) != -1) {
+                    // One generator is used to reference to instrument record
+                    ibag_gencount += 1;
+                }
+                ibag_gencount += region.getGenerators().size();
+                ibag_modcount += region.getModulators().size();
+
+            }
+        }
+        ibag_chunk.writeUnsignedShort(ibag_gencount);
+        ibag_chunk.writeUnsignedShort(ibag_modcount);
+
+
+        RIFFWriter imod_chunk = writer.writeChunk("imod");
+        for (SF2Layer instrument : this.layers) {
+            if (instrument.getGlobalRegion() != null) {
+                writeModulators(imod_chunk,
+                        instrument.getGlobalRegion().getModulators());
+            }
+            for (SF2LayerRegion region : instrument.getRegions())
+                writeModulators(imod_chunk, region.getModulators());
+        }
+        imod_chunk.write(new byte[10]);
+
+        RIFFWriter igen_chunk = writer.writeChunk("igen");
+        for (SF2Layer instrument : this.layers) {
+            if (instrument.getGlobalRegion() != null) {
+                writeGenerators(igen_chunk,
+                        instrument.getGlobalRegion().getGenerators());
+            }
+            for (SF2LayerRegion region : instrument.getRegions()) {
+                writeGenerators(igen_chunk, region.getGenerators());
+                int ix = samples.indexOf(region.sample);
+                if (ix != -1) {
+                    igen_chunk.writeUnsignedShort(SF2Region.GENERATOR_SAMPLEID);
+                    igen_chunk.writeShort((short) ix);
+                }
+            }
+        }
+        igen_chunk.write(new byte[4]);
+
+
+        RIFFWriter shdr_chunk = writer.writeChunk("shdr");
+        long sample_pos = 0;
+        for (SF2Sample sample : samples) {
+            shdr_chunk.writeString(sample.name, 20);
+            long start = sample_pos;
+            sample_pos += sample.data.capacity() / 2;
+            long end = sample_pos;
+            long startLoop = sample.startLoop + start;
+            long endLoop = sample.endLoop + start;
+            if (startLoop < start)
+                startLoop = start;
+            if (endLoop > end)
+                endLoop = end;
+            shdr_chunk.writeUnsignedInt(start);
+            shdr_chunk.writeUnsignedInt(end);
+            shdr_chunk.writeUnsignedInt(startLoop);
+            shdr_chunk.writeUnsignedInt(endLoop);
+            shdr_chunk.writeUnsignedInt(sample.sampleRate);
+            shdr_chunk.writeUnsignedByte(sample.originalPitch);
+            shdr_chunk.writeByte(sample.pitchCorrection);
+            shdr_chunk.writeUnsignedShort(sample.sampleLink);
+            shdr_chunk.writeUnsignedShort(sample.sampleType);
+            sample_pos += 32;
+        }
+        shdr_chunk.writeString("EOS", 20);
+        shdr_chunk.write(new byte[26]);
+
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getVersion() {
+        return major + "." + minor;
+    }
+
+    public String getVendor() {
+        return engineers;
+    }
+
+    public String getDescription() {
+        return comments;
+    }
+
+    public void setName(String s) {
+        name = s;
+    }
+
+    public void setVendor(String s) {
+        engineers = s;
+    }
+
+    public void setDescription(String s) {
+        comments = s;
+    }
+
+    public SoundbankResource[] getResources() {
+        SoundbankResource[] resources
+                = new SoundbankResource[layers.size() + samples.size()];
+        int j = 0;
+        for (int i = 0; i < layers.size(); i++)
+            resources[j++] = layers.get(i);
+        for (int i = 0; i < samples.size(); i++)
+            resources[j++] = samples.get(i);
+        return resources;
+    }
+
+    public SF2Instrument[] getInstruments() {
+        SF2Instrument[] inslist_array
+                = instruments.toArray(new SF2Instrument[instruments.size()]);
+        Arrays.sort(inslist_array, new ModelInstrumentComparator());
+        return inslist_array;
+    }
+
+    public SF2Layer[] getLayers() {
+        return layers.toArray(new SF2Layer[layers.size()]);
+    }
+
+    public SF2Sample[] getSamples() {
+        return samples.toArray(new SF2Sample[samples.size()]);
+    }
+
+    public Instrument getInstrument(Patch patch) {
+        int program = patch.getProgram();
+        int bank = patch.getBank();
+        boolean percussion = false;
+        if (patch instanceof ModelPatch)
+            percussion = ((ModelPatch)patch).isPercussion();
+        for (Instrument instrument : instruments) {
+            Patch patch2 = instrument.getPatch();
+            int program2 = patch2.getProgram();
+            int bank2 = patch2.getBank();
+            if (program == program2 && bank == bank2) {
+                boolean percussion2 = false;
+                if (patch2 instanceof ModelPatch)
+                    percussion2 = ((ModelPatch) patch2).isPercussion();
+                if (percussion == percussion2)
+                    return instrument;
+            }
+        }
+        return null;
+    }
+
+    public String getCreationDate() {
+        return creationDate;
+    }
+
+    public void setCreationDate(String creationDate) {
+        this.creationDate = creationDate;
+    }
+
+    public String getProduct() {
+        return product;
+    }
+
+    public void setProduct(String product) {
+        this.product = product;
+    }
+
+    public String getRomName() {
+        return romName;
+    }
+
+    public void setRomName(String romName) {
+        this.romName = romName;
+    }
+
+    public int getRomVersionMajor() {
+        return romVersionMajor;
+    }
+
+    public void setRomVersionMajor(int romVersionMajor) {
+        this.romVersionMajor = romVersionMajor;
+    }
+
+    public int getRomVersionMinor() {
+        return romVersionMinor;
+    }
+
+    public void setRomVersionMinor(int romVersionMinor) {
+        this.romVersionMinor = romVersionMinor;
+    }
+
+    public String getTargetEngine() {
+        return targetEngine;
+    }
+
+    public void setTargetEngine(String targetEngine) {
+        this.targetEngine = targetEngine;
+    }
+
+    public String getTools() {
+        return tools;
+    }
+
+    public void setTools(String tools) {
+        this.tools = tools;
+    }
+
+    public void addResource(SoundbankResource resource) {
+        if (resource instanceof SF2Instrument)
+            instruments.add((SF2Instrument)resource);
+        if (resource instanceof SF2Layer)
+            layers.add((SF2Layer)resource);
+        if (resource instanceof SF2Sample)
+            samples.add((SF2Sample)resource);
+    }
+
+    public void removeResource(SoundbankResource resource) {
+        if (resource instanceof SF2Instrument)
+            instruments.remove((SF2Instrument)resource);
+        if (resource instanceof SF2Layer)
+            layers.remove((SF2Layer)resource);
+        if (resource instanceof SF2Sample)
+            samples.remove((SF2Sample)resource);
+    }
+
+    public void addInstrument(SF2Instrument resource) {
+        instruments.add(resource);
+    }
+
+    public void removeInstrument(SF2Instrument resource) {
+        instruments.remove(resource);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2SoundbankReader.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.spi.SoundbankReader;
+
+/**
+ * This class is used to connect the SF2SoundBank class
+ * to the SoundbankReader SPI interface.
+ *
+ * @author Karl Helgason
+ */
+public class SF2SoundbankReader extends SoundbankReader {
+
+    public Soundbank getSoundbank(URL url)
+            throws InvalidMidiDataException, IOException {
+        try {
+            return new SF2Soundbank(url);
+        } catch (RIFFInvalidFormatException e) {
+            return null;
+        } catch(IOException ioe) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        try {
+            stream.mark(512);
+            return new SF2Soundbank(stream);
+        } catch (RIFFInvalidFormatException e) {
+            stream.reset();
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(File file)
+            throws InvalidMidiDataException, IOException {
+        try {
+            return new SF2Soundbank(file);
+        } catch (RIFFInvalidFormatException e) {
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SimpleInstrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.sound.midi.Patch;
+
+/**
+ * A simple instrument that is made of other ModelInstrument, ModelPerformer
+ * objects.
+ *
+ * @author Karl Helgason
+ */
+public class SimpleInstrument extends ModelInstrument {
+
+    private static class SimpleInstrumentPart {
+        ModelPerformer[] performers;
+        int keyFrom;
+        int keyTo;
+        int velFrom;
+        int velTo;
+        int exclusiveClass;
+    }
+    protected int preset = 0;
+    protected int bank = 0;
+    protected boolean percussion = false;
+    protected String name = "";
+    protected List<SimpleInstrumentPart> parts
+            = new ArrayList<SimpleInstrumentPart>();
+
+    public SimpleInstrument() {
+        super(null, null, null, null);
+    }
+
+    public void clear() {
+        parts.clear();
+    }
+
+    public void add(ModelPerformer[] performers, int keyFrom, int keyTo,
+            int velFrom, int velTo, int exclusiveClass) {
+        SimpleInstrumentPart part = new SimpleInstrumentPart();
+        part.performers = performers;
+        part.keyFrom = keyFrom;
+        part.keyTo = keyTo;
+        part.velFrom = velFrom;
+        part.velTo = velTo;
+        part.exclusiveClass = exclusiveClass;
+        parts.add(part);
+    }
+
+    public void add(ModelPerformer[] performers, int keyFrom, int keyTo,
+            int velFrom, int velTo) {
+        add(performers, keyFrom, keyTo, velFrom, velTo, -1);
+    }
+
+    public void add(ModelPerformer[] performers, int keyFrom, int keyTo) {
+        add(performers, keyFrom, keyTo, 0, 127, -1);
+    }
+
+    public void add(ModelPerformer[] performers) {
+        add(performers, 0, 127, 0, 127, -1);
+    }
+
+    public void add(ModelPerformer performer, int keyFrom, int keyTo,
+            int velFrom, int velTo, int exclusiveClass) {
+        add(new ModelPerformer[]{performer}, keyFrom, keyTo, velFrom, velTo,
+                exclusiveClass);
+    }
+
+    public void add(ModelPerformer performer, int keyFrom, int keyTo,
+            int velFrom, int velTo) {
+        add(new ModelPerformer[]{performer}, keyFrom, keyTo, velFrom, velTo);
+    }
+
+    public void add(ModelPerformer performer, int keyFrom, int keyTo) {
+        add(new ModelPerformer[]{performer}, keyFrom, keyTo);
+    }
+
+    public void add(ModelPerformer performer) {
+        add(new ModelPerformer[]{performer});
+    }
+
+    public void add(ModelInstrument ins, int keyFrom, int keyTo, int velFrom,
+            int velTo, int exclusiveClass) {
+        add(ins.getPerformers(), keyFrom, keyTo, velFrom, velTo, exclusiveClass);
+    }
+
+    public void add(ModelInstrument ins, int keyFrom, int keyTo, int velFrom,
+            int velTo) {
+        add(ins.getPerformers(), keyFrom, keyTo, velFrom, velTo);
+    }
+
+    public void add(ModelInstrument ins, int keyFrom, int keyTo) {
+        add(ins.getPerformers(), keyFrom, keyTo);
+    }
+
+    public void add(ModelInstrument ins) {
+        add(ins.getPerformers());
+    }
+
+    public ModelPerformer[] getPerformers() {
+
+        int percount = 0;
+        for (SimpleInstrumentPart part : parts)
+            if (part.performers != null)
+                percount += part.performers.length;
+
+        ModelPerformer[] performers = new ModelPerformer[percount];
+        int px = 0;
+        for (SimpleInstrumentPart part : parts) {
+            if (part.performers != null) {
+                for (ModelPerformer mperfm : part.performers) {
+                    ModelPerformer performer = new ModelPerformer();
+                    performer.setName(getName());
+                    performers[px++] = performer;
+
+                    performer.setDefaultConnectionsEnabled(
+                            mperfm.isDefaultConnectionsEnabled());
+                    performer.setKeyFrom(mperfm.getKeyFrom());
+                    performer.setKeyTo(mperfm.getKeyTo());
+                    performer.setVelFrom(mperfm.getVelFrom());
+                    performer.setVelTo(mperfm.getVelTo());
+                    performer.setExclusiveClass(mperfm.getExclusiveClass());
+                    performer.setSelfNonExclusive(mperfm.isSelfNonExclusive());
+                    performer.setReleaseTriggered(mperfm.isReleaseTriggered());
+                    if (part.exclusiveClass != -1)
+                        performer.setExclusiveClass(part.exclusiveClass);
+                    if (part.keyFrom > performer.getKeyFrom())
+                        performer.setKeyFrom(part.keyFrom);
+                    if (part.keyTo < performer.getKeyTo())
+                        performer.setKeyTo(part.keyTo);
+                    if (part.velFrom > performer.getVelFrom())
+                        performer.setVelFrom(part.velFrom);
+                    if (part.velTo < performer.getVelTo())
+                        performer.setVelTo(part.velTo);
+                    performer.getOscillators().addAll(mperfm.getOscillators());
+                    performer.getConnectionBlocks().addAll(
+                            mperfm.getConnectionBlocks());
+                }
+            }
+        }
+
+        return performers;
+    }
+
+    public Object getData() {
+        return null;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public ModelPatch getPatch() {
+        return new ModelPatch(bank, preset, percussion);
+    }
+
+    public void setPatch(Patch patch) {
+        if (patch instanceof ModelPatch && ((ModelPatch)patch).isPercussion()) {
+            percussion = true;
+            bank = patch.getBank();
+            preset = patch.getProgram();
+        } else {
+            percussion = false;
+            bank = patch.getBank();
+            preset = patch.getProgram();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SimpleSoundbank.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+
+/**
+ * A simple soundbank that contains instruments and soundbankresources.
+ *
+ * @author Karl Helgason
+ */
+public class SimpleSoundbank implements Soundbank {
+
+    String name = "";
+    String version = "";
+    String vendor = "";
+    String description = "";
+    List<SoundbankResource> resources = new ArrayList<SoundbankResource>();
+    List<Instrument> instruments = new ArrayList<Instrument>();
+
+    public String getName() {
+        return name;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public String getVendor() {
+        return vendor;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setVendor(String vendor) {
+        this.vendor = vendor;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public SoundbankResource[] getResources() {
+        return resources.toArray(new SoundbankResource[resources.size()]);
+    }
+
+    public Instrument[] getInstruments() {
+        Instrument[] inslist_array
+                = instruments.toArray(new Instrument[resources.size()]);
+        Arrays.sort(inslist_array, new ModelInstrumentComparator());
+        return inslist_array;
+    }
+
+    public Instrument getInstrument(Patch patch) {
+        int program = patch.getProgram();
+        int bank = patch.getBank();
+        boolean percussion = false;
+        if (patch instanceof ModelPatch)
+            percussion = ((ModelPatch)patch).isPercussion();
+        for (Instrument instrument : instruments) {
+            Patch patch2 = instrument.getPatch();
+            int program2 = patch2.getProgram();
+            int bank2 = patch2.getBank();
+            if (program == program2 && bank == bank2) {
+                boolean percussion2 = false;
+                if (patch2 instanceof ModelPatch)
+                    percussion2 = ((ModelPatch)patch2).isPercussion();
+                if (percussion == percussion2)
+                    return instrument;
+            }
+        }
+        return null;
+    }
+
+    public void addResource(SoundbankResource resource) {
+        if (resource instanceof Instrument)
+            instruments.add((Instrument) resource);
+        else
+            resources.add(resource);
+    }
+
+    public void removeResource(SoundbankResource resource) {
+        if (resource instanceof Instrument)
+            instruments.remove((Instrument) resource);
+        else
+            resources.remove(resource);
+    }
+
+    public void addInstrument(Instrument resource) {
+        instruments.add(resource);
+    }
+
+    public void removeInstrument(Instrument resource) {
+        instruments.remove(resource);
+    }
+
+    public void addAllInstruments(Soundbank soundbank) {
+        for (Instrument ins : soundbank.getInstruments())
+            addInstrument(ins);
+    }
+
+    public void removeAllInstruments(Soundbank soundbank) {
+        for (Instrument ins : soundbank.getInstruments())
+            removeInstrument(ins);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftAbstractResampler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,390 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.VoiceStatus;
+
+/**
+ * Abstract resampler class.
+ *
+ * @author Karl Helgason
+ */
+public abstract class SoftAbstractResampler implements SoftResampler {
+
+    private class ModelAbstractResamplerStream implements SoftResamplerStreamer {
+
+        AudioFloatInputStream stream;
+        boolean stream_eof = false;
+        int loopmode;
+        boolean loopdirection = true; // true = forward
+        float loopstart;
+        float looplen;
+        float target_pitch;
+        float[] current_pitch = new float[1];
+        boolean started;
+        boolean eof;
+        int sector_pos = 0;
+        int sector_size = 400;
+        int sector_loopstart = -1;
+        boolean markset = false;
+        int marklimit = 0;
+        int streampos = 0;
+        int nrofchannels = 2;
+        boolean noteOff_flag = false;
+        float[][] ibuffer;
+        boolean ibuffer_order = true;
+        float[] sbuffer;
+        int pad;
+        int pad2;
+        float[] ix = new float[1];
+        int[] ox = new int[1];
+        float samplerateconv = 1;
+        float pitchcorrection = 0;
+
+        public ModelAbstractResamplerStream() {
+            pad = getPadding();
+            pad2 = getPadding() * 2;
+            ibuffer = new float[2][sector_size + pad2];
+            ibuffer_order = true;
+        }
+
+        public void noteOn(MidiChannel channel, VoiceStatus voice,
+                int noteNumber, int velocity) {
+        }
+
+        public void noteOff(int velocity) {
+            noteOff_flag = true;
+        }
+
+        public void open(ModelWavetable osc, float outputsamplerate)
+                throws IOException {
+
+            eof = false;
+            nrofchannels = osc.getChannels();
+            if (ibuffer.length < nrofchannels) {
+                ibuffer = new float[nrofchannels][sector_size + pad2];
+            }
+
+            stream = osc.openStream();
+            streampos = 0;
+            stream_eof = false;
+            pitchcorrection = osc.getPitchcorrection();
+            samplerateconv
+                    = stream.getFormat().getSampleRate() / outputsamplerate;
+            looplen = osc.getLoopLength();
+            loopstart = osc.getLoopStart();
+            sector_loopstart = (int) (loopstart / sector_size);
+            sector_loopstart = sector_loopstart - 1;
+
+            sector_pos = 0;
+
+            if (sector_loopstart < 0)
+                sector_loopstart = 0;
+            started = false;
+            loopmode = osc.getLoopType();
+
+            if (loopmode != 0) {
+                markset = false;
+                marklimit = nrofchannels * (int) (looplen + pad2 + 1);
+            } else
+                markset = true;
+            // loopmode = 0;
+
+            target_pitch = samplerateconv;
+            current_pitch[0] = samplerateconv;
+
+            ibuffer_order = true;
+            loopdirection = true;
+            noteOff_flag = false;
+
+            for (int i = 0; i < nrofchannels; i++)
+                Arrays.fill(ibuffer[i], sector_size, sector_size + pad2, 0);
+            ix[0] = pad;
+            eof = false;
+
+            ix[0] = sector_size + pad;
+            sector_pos = -1;
+            streampos = -sector_size;
+
+            nextBuffer();
+        }
+
+        public void setPitch(float pitch) {
+            /*
+            this.pitch = (float) Math.pow(2f,
+            (pitchcorrection + pitch) / 1200.0f)
+             * samplerateconv;
+             */
+            this.target_pitch = (float)Math.exp(
+                    (pitchcorrection + pitch) * (Math.log(2.0) / 1200.0))
+                * samplerateconv;
+
+            if (!started)
+                current_pitch[0] = this.target_pitch;
+        }
+
+        public void nextBuffer() throws IOException {
+            if (ix[0] < pad) {
+                if (markset) {
+                    // reset to target sector
+                    stream.reset();
+                    ix[0] += streampos - (sector_loopstart * sector_size);
+                    sector_pos = sector_loopstart;
+                    streampos = sector_pos * sector_size;
+
+                    // and go one sector backward
+                    ix[0] += sector_size;
+                    sector_pos -= 1;
+                    streampos -= sector_size;
+                    stream_eof = false;
+                }
+            }
+
+            if (ix[0] >= sector_size + pad) {
+                if (stream_eof) {
+                    eof = true;
+                    return;
+                }
+            }
+
+            if (ix[0] >= sector_size * 4 + pad) {
+                int skips = (int)((ix[0] - sector_size * 4 + pad) / sector_size);
+                ix[0] -= sector_size * skips;
+                sector_pos += skips;
+                streampos += sector_size * skips;
+                stream.skip(sector_size * skips);
+            }
+
+            while (ix[0] >= sector_size + pad) {
+                if (!markset) {
+                    if (sector_pos + 1 == sector_loopstart) {
+                        stream.mark(marklimit);
+                        markset = true;
+                    }
+                }
+                ix[0] -= sector_size;
+                sector_pos++;
+                streampos += sector_size;
+
+                for (int c = 0; c < nrofchannels; c++) {
+                    float[] cbuffer = ibuffer[c];
+                    for (int i = 0; i < pad2; i++)
+                        cbuffer[i] = cbuffer[i + sector_size];
+                }
+
+                int ret;
+                if (nrofchannels == 1)
+                    ret = stream.read(ibuffer[0], pad2, sector_size);
+                else {
+                    int slen = sector_size * nrofchannels;
+                    if (sbuffer == null || sbuffer.length < slen)
+                        sbuffer = new float[slen];
+                    int sret = stream.read(sbuffer, 0, slen);
+                    if (sret == -1)
+                        ret = -1;
+                    else {
+                        ret = sret / nrofchannels;
+                        for (int i = 0; i < nrofchannels; i++) {
+                            float[] buff = ibuffer[i];
+                            int ix = i;
+                            int ix_step = nrofchannels;
+                            int ox = pad2;
+                            for (int j = 0; j < ret; j++, ix += ix_step, ox++)
+                                buff[ox] = sbuffer[ix];
+                        }
+                    }
+
+                }
+
+                if (ret == -1) {
+                    ret = 0;
+                    stream_eof = true;
+                    for (int i = 0; i < nrofchannels; i++)
+                        Arrays.fill(ibuffer[i], pad2, pad2 + sector_size, 0f);
+                    return;
+                }
+                if (ret != sector_size) {
+                    for (int i = 0; i < nrofchannels; i++)
+                        Arrays.fill(ibuffer[i], pad2 + ret, pad2 + sector_size, 0f);
+                }
+
+                ibuffer_order = true;
+
+            }
+
+        }
+
+        public void reverseBuffers() {
+            ibuffer_order = !ibuffer_order;
+            for (int c = 0; c < nrofchannels; c++) {
+                float[] cbuff = ibuffer[c];
+                int len = cbuff.length - 1;
+                int len2 = cbuff.length / 2;
+                for (int i = 0; i < len2; i++) {
+                    float x = cbuff[i];
+                    cbuff[i] = cbuff[len - i];
+                    cbuff[len - i] = x;
+                }
+            }
+        }
+
+        public int read(float[][] buffer, int offset, int len)
+                throws IOException {
+
+            if (eof)
+                return -1;
+
+            if (noteOff_flag)
+                if ((loopmode & 2) != 0)
+                    if (loopdirection)
+                        loopmode = 0;
+
+
+            float pitchstep = (target_pitch - current_pitch[0]) / len;
+            float[] current_pitch = this.current_pitch;
+            started = true;
+
+            int[] ox = this.ox;
+            ox[0] = offset;
+            int ox_end = len + offset;
+
+            float ixend = sector_size + pad;
+            if (!loopdirection)
+                ixend = pad;
+            while (ox[0] != ox_end) {
+                nextBuffer();
+                if (!loopdirection) {
+                    // If we are in backward playing part of pingpong
+                    // or reverse loop
+
+                    if (streampos < (loopstart + pad)) {
+                        ixend = loopstart - streampos + pad2;
+                        if (ix[0] <= ixend) {
+                            if ((loopmode & 4) != 0) {
+                                // Ping pong loop, change loopdirection
+                                loopdirection = true;
+                                ixend = sector_size + pad;
+                                continue;
+                            }
+
+                            ix[0] += looplen;
+                            ixend = pad;
+                            continue;
+                        }
+                    }
+
+                    if (ibuffer_order != loopdirection)
+                        reverseBuffers();
+
+                    ix[0] = (sector_size + pad2) - ix[0];
+                    ixend = (sector_size + pad2) - ixend;
+                    ixend++;
+
+                    float bak_ix = ix[0];
+                    int bak_ox = ox[0];
+                    float bak_pitch = current_pitch[0];
+                    for (int i = 0; i < nrofchannels; i++) {
+                        if (buffer[i] != null) {
+                            ix[0] = bak_ix;
+                            ox[0] = bak_ox;
+                            current_pitch[0] = bak_pitch;
+                            interpolate(ibuffer[i], ix, ixend, current_pitch,
+                                    pitchstep, buffer[i], ox, ox_end);
+                        }
+                    }
+
+                    ix[0] = (sector_size + pad2) - ix[0];
+                    ixend--;
+                    ixend = (sector_size + pad2) - ixend;
+
+                    if (eof) {
+                        current_pitch[0] = this.target_pitch;
+                        return ox[0] - offset;
+                    }
+
+                    continue;
+                }
+                if (loopmode != 0) {
+                    if (streampos + sector_size > (looplen + loopstart + pad)) {
+                        ixend = loopstart + looplen - streampos + pad2;
+                        if (ix[0] >= ixend) {
+                            if ((loopmode & 4) != 0 || (loopmode & 8) != 0) {
+                                // Ping pong or revese loop, change loopdirection
+                                loopdirection = false;
+                                ixend = pad;
+                                continue;
+                            }
+                            ixend = sector_size + pad;
+                            ix[0] -= looplen;
+                            continue;
+                        }
+                    }
+                }
+
+                if (ibuffer_order != loopdirection)
+                    reverseBuffers();
+
+                float bak_ix = ix[0];
+                int bak_ox = ox[0];
+                float bak_pitch = current_pitch[0];
+                for (int i = 0; i < nrofchannels; i++) {
+                    if (buffer[i] != null) {
+                        ix[0] = bak_ix;
+                        ox[0] = bak_ox;
+                        current_pitch[0] = bak_pitch;
+                        interpolate(ibuffer[i], ix, ixend, current_pitch,
+                                pitchstep, buffer[i], ox, ox_end);
+                    }
+                }
+
+                if (eof) {
+                    current_pitch[0] = this.target_pitch;
+                    return ox[0] - offset;
+                }
+            }
+
+            current_pitch[0] = this.target_pitch;
+            return len;
+        }
+
+        public void close() throws IOException {
+            stream.close();
+        }
+    }
+
+    public abstract int getPadding();
+
+    public abstract void interpolate(float[] in, float[] in_offset,
+            float in_end, float[] pitch, float pitchstep, float[] out,
+            int[] out_offset, int out_end);
+
+    public SoftResamplerStreamer openStreamer() {
+        return new ModelAbstractResamplerStream();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftAudioBuffer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * This class is used to store audio buffer.
+ *
+ * @author Karl Helgason
+ */
+public class SoftAudioBuffer {
+
+    private int size;
+    private float[] buffer;
+    private boolean empty = true;
+    private AudioFormat format;
+    private AudioFloatConverter converter;
+    private byte[] converter_buffer;
+
+    public SoftAudioBuffer(int size, AudioFormat format) {
+        this.size = size;
+        this.format = format;
+        converter = AudioFloatConverter.getConverter(format);
+    }
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public void clear() {
+        if (!empty) {
+            Arrays.fill(buffer, 0);
+            empty = true;
+        }
+    }
+
+    public boolean isSilent() {
+        return empty;
+    }
+
+    public float[] array() {
+        empty = false;
+        if (buffer == null)
+            buffer = new float[size];
+        return buffer;
+    }
+
+    public void get(byte[] buffer, int channel) {
+
+        int framesize_pc = (format.getFrameSize() / format.getChannels());
+        int c_len = size * framesize_pc;
+        if (converter_buffer == null || converter_buffer.length < c_len)
+            converter_buffer = new byte[c_len];
+
+        if (format.getChannels() == 1) {
+            converter.toByteArray(array(), size, buffer);
+        } else {
+            converter.toByteArray(array(), size, converter_buffer);
+            if (channel >= format.getChannels())
+                return;
+            int z_stepover = format.getChannels() * framesize_pc;
+            int k_stepover = framesize_pc;
+            for (int j = 0; j < framesize_pc; j++) {
+                int k = j;
+                int z = channel * framesize_pc + j;
+                for (int i = 0; i < size; i++) {
+                    buffer[z] = converter_buffer[k];
+                    z += z_stepover;
+                    k += k_stepover;
+                }
+            }
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftAudioProcessor.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Audio processor interface.
+ *
+ * @author Karl Helgason
+ */
+public interface SoftAudioProcessor {
+
+    public void globalParameterControlChange(int[] slothpath, long param,
+            long value);
+
+    public void init(float samplerate, float controlrate);
+
+    public void setInput(int pin, SoftAudioBuffer input);
+
+    public void setOutput(int pin, SoftAudioBuffer output);
+
+    public void setMixMode(boolean mix);
+
+    public void processAudio();
+
+    public void processControlLogic();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftAudioPusher.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * This is a processor object that writes into SourceDataLine
+ *
+ * @author Karl Helgason
+ */
+public class SoftAudioPusher implements Runnable {
+
+    private volatile boolean active = false;
+    private SourceDataLine sourceDataLine = null;
+    private Thread audiothread;
+    private AudioInputStream ais;
+    private byte[] buffer;
+
+    public SoftAudioPusher(SourceDataLine sourceDataLine, AudioInputStream ais,
+            int workbuffersizer) {
+        this.ais = ais;
+        this.buffer = new byte[workbuffersizer];
+        this.sourceDataLine = sourceDataLine;
+    }
+
+    public synchronized void start() {
+        if (active)
+            return;
+        active = true;
+        audiothread = new Thread(this);
+        audiothread.setPriority(Thread.MAX_PRIORITY);
+        audiothread.start();
+    }
+
+    public synchronized void stop() {
+        if (!active)
+            return;
+        active = false;
+        try {
+            audiothread.join();
+        } catch (InterruptedException e) {
+            //e.printStackTrace();
+        }
+    }
+
+    public void run() {
+        byte[] buffer = SoftAudioPusher.this.buffer;
+        AudioInputStream ais = SoftAudioPusher.this.ais;
+        SourceDataLine sourceDataLine = SoftAudioPusher.this.sourceDataLine;
+
+        try {
+            while (active) {
+                // Read from audio source
+                int count = ais.read(buffer);
+                if(count < 0) break;
+                // Write byte buffer to source output
+                sourceDataLine.write(buffer, 0, count);
+            }
+        } catch (IOException e) {
+            active = false;
+            //e.printStackTrace();
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftChannel.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,1548 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.Patch;
+
+/**
+ * Software Synthesizer MIDI channel class.
+ *
+ * @author Karl Helgason
+ */
+public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
+
+    private static boolean[] dontResetControls = new boolean[128];
+    static {
+        for (int i = 0; i < dontResetControls.length; i++)
+            dontResetControls[i] = false;
+
+        dontResetControls[0] = true;   // Bank Select (MSB)
+        dontResetControls[32] = true;  // Bank Select (LSB)
+        dontResetControls[7] = true;   // Channel Volume (MSB)
+        dontResetControls[8] = true;   // Balance (MSB)
+        dontResetControls[10] = true;  // Pan (MSB)
+        dontResetControls[11] = true;  // Expression (MSB)
+        dontResetControls[91] = true;  // Effects 1 Depth (default: Reverb Send)
+        dontResetControls[92] = true;  // Effects 2 Depth (default: Tremolo Depth)
+        dontResetControls[93] = true;  // Effects 3 Depth (default: Chorus Send)
+        dontResetControls[94] = true;  // Effects 4 Depth (default: Celeste [Detune] Depth)
+        dontResetControls[95] = true;  // Effects 5 Depth (default: Phaser Depth)
+        dontResetControls[70] = true;  // Sound Controller 1 (default: Sound Variation)
+        dontResetControls[71] = true;  // Sound Controller 2 (default: Timbre / Harmonic Quality)
+        dontResetControls[72] = true;  // Sound Controller 3 (default: Release Time)
+        dontResetControls[73] = true;  // Sound Controller 4 (default: Attack Time)
+        dontResetControls[74] = true;  // Sound Controller 5 (default: Brightness)
+        dontResetControls[75] = true;  // Sound Controller 6 (GM2 default: Decay Time)
+        dontResetControls[76] = true;  // Sound Controller 7 (GM2 default: Vibrato Rate)
+        dontResetControls[77] = true;  // Sound Controller 8 (GM2 default: Vibrato Depth)
+        dontResetControls[78] = true;  // Sound Controller 9 (GM2 default: Vibrato Delay)
+        dontResetControls[79] = true;  // Sound Controller 10 (GM2 default: Undefined)
+        dontResetControls[120] = true; // All Sound Off
+        dontResetControls[121] = true; // Reset All Controllers
+        dontResetControls[122] = true; // Local Control On/Off
+        dontResetControls[123] = true; // All Notes Off
+        dontResetControls[124] = true; // Omni Mode Off
+        dontResetControls[125] = true; // Omni Mode On
+        dontResetControls[126] = true; // Poly Mode Off
+        dontResetControls[127] = true; // Poly Mode On
+
+        dontResetControls[6] = true;   // Data Entry (MSB)
+        dontResetControls[38] = true;  // Data Entry (LSB)
+        dontResetControls[96] = true;  // Data Increment
+        dontResetControls[97] = true;  // Data Decrement
+        dontResetControls[98] = true;  // Non-Registered Parameter Number (LSB)
+        dontResetControls[99] = true;  // Non-Registered Parameter Number(MSB)
+        dontResetControls[100] = true; // RPN = Null
+        dontResetControls[101] = true; // RPN = Null
+
+    }
+
+    private static final int RPN_NULL_VALUE = (127 << 7) + 127;
+    private int rpn_control = RPN_NULL_VALUE;
+    private int nrpn_control = RPN_NULL_VALUE;
+    protected double portamento_time = 1; // keyschanges per control buffer time
+    protected int[] portamento_lastnote = new int[128];
+    protected int portamento_lastnote_ix = 0;
+    private int portamento_control_note = -1;
+    private boolean portamento = false;
+    private boolean mono = false;
+    private boolean mute = false;
+    private boolean solo = false;
+    private boolean solomute = false;
+    private Object control_mutex;
+    private int channel;
+    private SoftVoice[] voices;
+    private int bank;
+    private int program;
+    private SoftSynthesizer synthesizer;
+    private SoftMainMixer mainmixer;
+    private int[] polypressure = new int[128];
+    private int channelpressure = 0;
+    private int[] controller = new int[128];
+    private int pitchbend;
+    private double[] co_midi_pitch = new double[1];
+    private double[] co_midi_channel_pressure = new double[1];
+    protected SoftTuning tuning = new SoftTuning();
+    protected int tuning_bank = 0;
+    protected int tuning_program = 0;
+    protected SoftInstrument current_instrument = null;
+    protected ModelChannelMixer current_mixer = null;
+    private ModelDirector current_director = null;
+
+    // Controller Destination Settings
+    protected int cds_control_number = -1;
+    protected ModelConnectionBlock[] cds_control_connections = null;
+    protected ModelConnectionBlock[] cds_channelpressure_connections = null;
+    protected ModelConnectionBlock[] cds_polypressure_connections = null;
+    protected boolean sustain = false;
+    protected boolean[][] keybasedcontroller_active = null;
+    protected double[][] keybasedcontroller_value = null;
+
+    private class MidiControlObject implements SoftControl {
+        double[] pitch = co_midi_pitch;
+        double[] channel_pressure = co_midi_channel_pressure;
+        double[] poly_pressure = new double[1];
+
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            if (name.equals("pitch"))
+                return pitch;
+            if (name.equals("channel_pressure"))
+                return channel_pressure;
+            if (name.equals("poly_pressure"))
+                return poly_pressure;
+            return null;
+        }
+    }
+
+    private SoftControl[] co_midi = new SoftControl[128];
+    {
+        for (int i = 0; i < co_midi.length; i++) {
+            co_midi[i] = new MidiControlObject();
+        }
+    }
+
+    private double[][] co_midi_cc_cc = new double[128][1];
+    private SoftControl co_midi_cc = new SoftControl() {
+        double[][] cc = co_midi_cc_cc;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            return cc[Integer.parseInt(name)];
+        }
+    };
+    Map<Integer, int[]> co_midi_rpn_rpn_i = new HashMap<Integer, int[]>();
+    Map<Integer, double[]> co_midi_rpn_rpn = new HashMap<Integer, double[]>();
+    private SoftControl co_midi_rpn = new SoftControl() {
+        Map<Integer, double[]> rpn = co_midi_rpn_rpn;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            int iname = Integer.parseInt(name);
+            double[] v = rpn.get(iname);
+            if (v == null) {
+                v = new double[1];
+                rpn.put(iname, v);
+            }
+            return v;
+        }
+    };
+    Map<Integer, int[]> co_midi_nrpn_nrpn_i = new HashMap<Integer, int[]>();
+    Map<Integer, double[]> co_midi_nrpn_nrpn = new HashMap<Integer, double[]>();
+    private SoftControl co_midi_nrpn = new SoftControl() {
+        Map<Integer, double[]> nrpn = co_midi_nrpn_nrpn;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            int iname = Integer.parseInt(name);
+            double[] v = nrpn.get(iname);
+            if (v == null) {
+                v = new double[1];
+                nrpn.put(iname, v);
+            }
+            return v;
+        }
+    };
+
+    private static int restrict7Bit(int value)
+    {
+        if(value < 0) return 0;
+        if(value > 127) return 127;
+        return value;
+    }
+
+    private static int restrict14Bit(int value)
+    {
+        if(value < 0) return 0;
+        if(value > 16256) return 16256;
+        return value;
+    }
+
+    public SoftChannel(SoftSynthesizer synth, int channel) {
+        this.channel = channel;
+        this.voices = synth.getVoices();
+        this.synthesizer = synth;
+        this.mainmixer = synth.getMainMixer();
+        control_mutex = synth.control_mutex;
+        resetAllControllers(true);
+    }
+
+    private int findFreeVoice(int x) {
+        for (int i = x; i < voices.length; i++)
+            if (!voices[i].active)
+                return i;
+
+        // No free voice was found, we must steal one
+
+        int vmode = synthesizer.getVoiceAllocationMode();
+        if (vmode == 1) {
+            // DLS Static Voice Allocation
+
+            //  * priority ( 10, 1-9, 11-16)
+            // Search for channel to steal from
+            int steal_channel = channel;
+            for (int j = 0; j < voices.length; j++) {
+                if (voices[j].stealer_channel == null) {
+                    if (steal_channel == 9) {
+                        steal_channel = voices[j].channel;
+                    } else {
+                        if (voices[j].channel != 9) {
+                            if (voices[j].channel > steal_channel)
+                                steal_channel = voices[j].channel;
+                        }
+                    }
+                }
+            }
+
+            int voiceNo = -1;
+
+            SoftVoice v = null;
+            // Search for oldest voice in off state on steal_channel
+            for (int j = 0; j < voices.length; j++) {
+                if (voices[j].channel == steal_channel) {
+                    if (voices[j].stealer_channel == null && !voices[j].on) {
+                        if (v == null) {
+                            v = voices[j];
+                            voiceNo = j;
+                        }
+                        if (voices[j].voiceID < v.voiceID) {
+                            v = voices[j];
+                            voiceNo = j;
+                        }
+                    }
+                }
+            }
+            // Search for oldest voice in on state on steal_channel
+            if (voiceNo == -1) {
+                for (int j = 0; j < voices.length; j++) {
+                    if (voices[j].channel == steal_channel) {
+                        if (voices[j].stealer_channel == null) {
+                            if (v == null) {
+                                v = voices[j];
+                                voiceNo = j;
+                            }
+                            if (voices[j].voiceID < v.voiceID) {
+                                v = voices[j];
+                                voiceNo = j;
+                            }
+                        }
+                    }
+                }
+            }
+
+            return voiceNo;
+
+        } else {
+            // Default Voice Allocation
+            //  * Find voice that is on
+            //    and Find voice which has lowest voiceID ( oldest voice)
+            //  * Or find voice that is off
+            //    and Find voice which has lowest voiceID ( oldest voice)
+
+            int voiceNo = -1;
+
+            SoftVoice v = null;
+            // Search for oldest voice in off state
+            for (int j = 0; j < voices.length; j++) {
+                if (voices[j].stealer_channel == null && !voices[j].on) {
+                    if (v == null) {
+                        v = voices[j];
+                        voiceNo = j;
+                    }
+                    if (voices[j].voiceID < v.voiceID) {
+                        v = voices[j];
+                        voiceNo = j;
+                    }
+                }
+            }
+            // Search for oldest voice in on state
+            if (voiceNo == -1) {
+
+                for (int j = 0; j < voices.length; j++) {
+                    if (voices[j].stealer_channel == null) {
+                        if (v == null) {
+                            v = voices[j];
+                            voiceNo = j;
+                        }
+                        if (voices[j].voiceID < v.voiceID) {
+                            v = voices[j];
+                            voiceNo = j;
+                        }
+                    }
+                }
+            }
+
+            return voiceNo;
+        }
+
+    }
+
+    protected void initVoice(SoftVoice voice, SoftPerformer p, int voiceID,
+            int noteNumber, int velocity, ModelConnectionBlock[] connectionBlocks,
+            ModelChannelMixer channelmixer, boolean releaseTriggered) {
+        if (voice.active) {
+            // Voice is active , we must steal the voice
+            voice.stealer_channel = this;
+            voice.stealer_performer = p;
+            voice.stealer_voiceID = voiceID;
+            voice.stealer_noteNumber = noteNumber;
+            voice.stealer_velocity = velocity;
+            voice.stealer_extendedConnectionBlocks = connectionBlocks;
+            voice.stealer_channelmixer = channelmixer;
+            voice.stealer_releaseTriggered = releaseTriggered;
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active && voices[i].voiceID == voice.voiceID)
+                    voices[i].soundOff();
+            return;
+        }
+
+        voice.extendedConnectionBlocks = connectionBlocks;
+        voice.channelmixer = channelmixer;
+        voice.releaseTriggered = releaseTriggered;
+        voice.voiceID = voiceID;
+        voice.tuning = tuning;
+        voice.exclusiveClass = p.exclusiveClass;
+        voice.softchannel = this;
+        voice.channel = channel;
+        voice.bank = bank;
+        voice.program = program;
+        voice.instrument = current_instrument;
+        voice.performer = p;
+        voice.objects.clear();
+        voice.objects.put("midi", co_midi[noteNumber]);
+        voice.objects.put("midi_cc", co_midi_cc);
+        voice.objects.put("midi_rpn", co_midi_rpn);
+        voice.objects.put("midi_nrpn", co_midi_nrpn);
+        voice.noteOn(noteNumber, velocity);
+        voice.setMute(mute);
+        voice.setSoloMute(solomute);
+        if (releaseTriggered)
+            return;
+        if (portamento_control_note != -1) {
+            voice.co_noteon_keynumber[0]
+                    = (tuning.getTuning(portamento_control_note) / 100.0)
+                    * (1f / 128f);
+            voice.portamento = true;
+            portamento_control_note = -1;
+        } else if (portamento) {
+            if (mono) {
+                if (portamento_lastnote[0] != -1) {
+                    voice.co_noteon_keynumber[0]
+                            = (tuning.getTuning(portamento_lastnote[0]) / 100.0)
+                            * (1f / 128f);
+                    voice.portamento = true;
+                    portamento_control_note = -1;
+                }
+                portamento_lastnote[0] = noteNumber;
+            } else {
+                if (portamento_lastnote_ix != 0) {
+                    portamento_lastnote_ix--;
+                    voice.co_noteon_keynumber[0]
+                            = (tuning.getTuning(
+                                    portamento_lastnote[portamento_lastnote_ix])
+                                / 100.0)
+                            * (1f / 128f);
+                    voice.portamento = true;
+                }
+            }
+        }
+    }
+
+    public void noteOn(int noteNumber, int velocity) {
+        noteNumber = restrict7Bit(noteNumber);
+        velocity = restrict7Bit(velocity);
+        noteOn_internal(noteNumber, velocity);
+        if (current_mixer != null)
+            current_mixer.noteOn(noteNumber, velocity);
+    }
+
+    private void noteOn_internal(int noteNumber, int velocity) {
+
+        if (velocity == 0) {
+            noteOff_internal(noteNumber, 64);
+            return;
+        }
+
+        synchronized (control_mutex) {
+            if (sustain) {
+                sustain = false;
+                for (int i = 0; i < voices.length; i++) {
+                    if ((voices[i].sustain || voices[i].on)
+                            && voices[i].channel == channel && voices[i].active
+                            && voices[i].note == noteNumber) {
+                        voices[i].sustain = false;
+                        voices[i].on = true;
+                        voices[i].noteOff(0);
+                    }
+                }
+                sustain = true;
+            }
+
+            mainmixer.activity();
+
+            if (mono) {
+                if (portamento) {
+                    boolean n_found = false;
+                    for (int i = 0; i < voices.length; i++) {
+                        if (voices[i].on && voices[i].channel == channel
+                                && voices[i].active
+                                && voices[i].releaseTriggered == false) {
+                            voices[i].portamento = true;
+                            voices[i].setNote(noteNumber);
+                            n_found = true;
+                        }
+                    }
+                    if (n_found) {
+                        portamento_lastnote[0] = noteNumber;
+                        return;
+                    }
+                }
+
+                if (portamento_control_note != -1) {
+                    boolean n_found = false;
+                    for (int i = 0; i < voices.length; i++) {
+                        if (voices[i].on && voices[i].channel == channel
+                                && voices[i].active
+                                && voices[i].note == portamento_control_note
+                                && voices[i].releaseTriggered == false) {
+                            voices[i].portamento = true;
+                            voices[i].setNote(noteNumber);
+                            n_found = true;
+                        }
+                    }
+                    portamento_control_note = -1;
+                    if (n_found)
+                        return;
+                }
+            }
+
+            if (mono)
+                allNotesOff();
+
+            if (current_instrument == null) {
+                current_instrument
+                        = synthesizer.findInstrument(program, bank, channel);
+                if (current_instrument == null)
+                    return;
+                if (current_mixer != null)
+                    mainmixer.stopMixer(current_mixer);
+                current_mixer = current_instrument.getSourceInstrument()
+                        .getChannelMixer(this, synthesizer.getFormat());
+                if (current_mixer != null)
+                    mainmixer.registerMixer(current_mixer);
+                current_director = current_instrument.getDirector(this, this);
+                applyInstrumentCustomization();
+            }
+            prevVoiceID = synthesizer.voiceIDCounter++;
+            firstVoice = true;
+            voiceNo = 0;
+
+            int tunedKey = (int)(Math.round(tuning.getTuning()[noteNumber]/100.0));
+            play_noteNumber = noteNumber;
+            play_velocity = velocity;
+            play_releasetriggered = false;
+            lastVelocity[noteNumber] = velocity;
+            current_director.noteOn(tunedKey, velocity);
+
+            /*
+            SoftPerformer[] performers = current_instrument.getPerformers();
+            for (int i = 0; i < performers.length; i++) {
+                SoftPerformer p = performers[i];
+                if (p.keyFrom <= tunedKey && p.keyTo >= tunedKey) {
+                    if (p.velFrom <= velocity && p.velTo >= velocity) {
+                        if (firstVoice) {
+                            firstVoice = false;
+                            if (p.exclusiveClass != 0) {
+                                int x = p.exclusiveClass;
+                                for (int j = 0; j < voices.length; j++) {
+                                    if (voices[j].active
+                                            && voices[j].channel == channel
+                                            && voices[j].exclusiveClass == x) {
+                                        if (!(p.selfNonExclusive
+                                                && voices[j].note == noteNumber))
+                                            voices[j].shutdown();
+                                    }
+                                }
+                            }
+                        }
+                        voiceNo = findFreeVoice(voiceNo);
+                        if (voiceNo == -1)
+                            return;
+                        initVoice(voices[voiceNo], p, prevVoiceID, noteNumber,
+                                velocity);
+                    }
+                }
+            }
+            */
+        }
+    }
+
+    public void noteOff(int noteNumber, int velocity) {
+        noteNumber = restrict7Bit(noteNumber);
+        velocity = restrict7Bit(velocity);
+        noteOff_internal(noteNumber, velocity);
+
+        if (current_mixer != null)
+            current_mixer.noteOff(noteNumber, velocity);
+    }
+
+    private void noteOff_internal(int noteNumber, int velocity) {
+        synchronized (control_mutex) {
+
+            if (!mono) {
+                if (portamento) {
+                    if (portamento_lastnote_ix != 127) {
+                        portamento_lastnote[portamento_lastnote_ix] = noteNumber;
+                        portamento_lastnote_ix++;
+                    }
+                }
+            }
+
+            mainmixer.activity();
+            for (int i = 0; i < voices.length; i++) {
+                if (voices[i].on && voices[i].channel == channel
+                        && voices[i].note == noteNumber
+                        && voices[i].releaseTriggered == false) {
+                    voices[i].noteOff(velocity);
+                }
+            }
+
+            // Try play back note-off triggered voices,
+
+            if (current_instrument == null) {
+                current_instrument
+                        = synthesizer.findInstrument(program, bank, channel);
+                if (current_instrument == null)
+                    return;
+                if (current_mixer != null)
+                    mainmixer.stopMixer(current_mixer);
+                current_mixer = current_instrument.getSourceInstrument()
+                        .getChannelMixer(this, synthesizer.getFormat());
+                if (current_mixer != null)
+                    mainmixer.registerMixer(current_mixer);
+                current_director = current_instrument.getDirector(this, this);
+                applyInstrumentCustomization();
+
+            }
+            prevVoiceID = synthesizer.voiceIDCounter++;
+            firstVoice = true;
+            voiceNo = 0;
+
+            int tunedKey = (int)(Math.round(tuning.getTuning()[noteNumber]/100.0));
+            play_noteNumber = noteNumber;
+            play_velocity = lastVelocity[noteNumber];
+            play_releasetriggered = true;
+            current_director.noteOff(tunedKey, velocity);
+
+        }
+    }
+    private int[] lastVelocity = new int[128];
+    private int prevVoiceID;
+    private boolean firstVoice = true;
+    private int voiceNo = 0;
+    private int play_noteNumber = 0;
+    private int play_velocity = 0;
+    private boolean play_releasetriggered = false;
+
+    public void play(int performerIndex, ModelConnectionBlock[] connectionBlocks) {
+
+        int noteNumber = play_noteNumber;
+        int velocity = play_velocity;
+        boolean releasetriggered = play_releasetriggered;
+
+        SoftPerformer p = current_instrument.getPerformers()[performerIndex];
+
+        if (firstVoice) {
+            firstVoice = false;
+            if (p.exclusiveClass != 0) {
+                int x = p.exclusiveClass;
+                for (int j = 0; j < voices.length; j++) {
+                    if (voices[j].active && voices[j].channel == channel
+                            && voices[j].exclusiveClass == x) {
+                        if (!(p.selfNonExclusive && voices[j].note == noteNumber))
+                            voices[j].shutdown();
+                    }
+                }
+            }
+        }
+
+        voiceNo = findFreeVoice(voiceNo);
+
+        if (voiceNo == -1)
+            return;
+
+        initVoice(voices[voiceNo], p, prevVoiceID, noteNumber, velocity,
+                connectionBlocks, current_mixer, releasetriggered);
+    }
+
+    public void noteOff(int noteNumber) {
+        if(noteNumber < 0 || noteNumber > 127) return;
+        noteOff_internal(noteNumber, 64);
+    }
+
+    public void setPolyPressure(int noteNumber, int pressure) {
+        noteNumber = restrict7Bit(noteNumber);
+        pressure = restrict7Bit(pressure);
+
+        if (current_mixer != null)
+            current_mixer.setPolyPressure(noteNumber, pressure);
+
+        synchronized (control_mutex) {
+            mainmixer.activity();
+            co_midi[noteNumber].get(0, "poly_pressure")[0] = pressure*(1.0/128.0);
+            polypressure[noteNumber] = pressure;
+            for (int i = 0; i < voices.length; i++) {
+                if (voices[i].active && voices[i].note == noteNumber)
+                    voices[i].setPolyPressure(pressure);
+            }
+        }
+    }
+
+    public int getPolyPressure(int noteNumber) {
+        synchronized (control_mutex) {
+            return polypressure[noteNumber];
+        }
+    }
+
+    public void setChannelPressure(int pressure) {
+        pressure = restrict7Bit(pressure);
+        if (current_mixer != null)
+            current_mixer.setChannelPressure(pressure);
+        synchronized (control_mutex) {
+            mainmixer.activity();
+            co_midi_channel_pressure[0] = pressure * (1.0 / 128.0);
+            channelpressure = pressure;
+            for (int i = 0; i < voices.length; i++) {
+                if (voices[i].active)
+                    voices[i].setChannelPressure(pressure);
+            }
+        }
+    }
+
+    public int getChannelPressure() {
+        synchronized (control_mutex) {
+            return channelpressure;
+        }
+    }
+
+    protected void applyInstrumentCustomization() {
+        if (cds_control_connections == null
+                && cds_channelpressure_connections == null
+                && cds_polypressure_connections == null) {
+            return;
+        }
+
+        ModelInstrument src_instrument = current_instrument.getSourceInstrument();
+        ModelPerformer[] performers = src_instrument.getPerformers();
+        ModelPerformer[] new_performers = new ModelPerformer[performers.length];
+        for (int i = 0; i < new_performers.length; i++) {
+            ModelPerformer performer = performers[i];
+            ModelPerformer new_performer = new ModelPerformer();
+            new_performer.setName(performer.getName());
+            new_performer.setExclusiveClass(performer.getExclusiveClass());
+            new_performer.setKeyFrom(performer.getKeyFrom());
+            new_performer.setKeyTo(performer.getKeyTo());
+            new_performer.setVelFrom(performer.getVelFrom());
+            new_performer.setVelTo(performer.getVelTo());
+            new_performer.getOscillators().addAll(performer.getOscillators());
+            new_performer.getConnectionBlocks().addAll(
+                    performer.getConnectionBlocks());
+            new_performers[i] = new_performer;
+
+            List<ModelConnectionBlock> connblocks =
+                    new_performer.getConnectionBlocks();
+
+            if (cds_control_connections != null) {
+                String cc = Integer.toString(cds_control_number);
+                Iterator<ModelConnectionBlock> iter = connblocks.iterator();
+                while (iter.hasNext()) {
+                    ModelConnectionBlock conn = iter.next();
+                    ModelSource[] sources = conn.getSources();
+                    boolean removeok = false;
+                    if (sources != null) {
+                        for (int j = 0; j < sources.length; j++) {
+                            ModelSource src = sources[j];
+                            if ("midi_cc".equals(src.getIdentifier().getObject())
+                                    && cc.equals(src.getIdentifier().getVariable())) {
+                                removeok = true;
+                            }
+                        }
+                    }
+                    if (removeok)
+                        iter.remove();
+                }
+                for (int j = 0; j < cds_control_connections.length; j++)
+                    connblocks.add(cds_control_connections[j]);
+            }
+
+            if (cds_polypressure_connections != null) {
+                Iterator<ModelConnectionBlock> iter = connblocks.iterator();
+                while (iter.hasNext()) {
+                    ModelConnectionBlock conn = iter.next();
+                    ModelSource[] sources = conn.getSources();
+                    boolean removeok = false;
+                    if (sources != null) {
+                        for (int j = 0; j < sources.length; j++) {
+                            ModelSource src = sources[j];
+                            if ("midi".equals(src.getIdentifier().getObject())
+                                    && "poly_pressure".equals(
+                                        src.getIdentifier().getVariable())) {
+                                removeok = true;
+                            }
+                        }
+                    }
+                    if (removeok)
+                        iter.remove();
+                }
+                for (int j = 0; j < cds_polypressure_connections.length; j++)
+                    connblocks.add(cds_polypressure_connections[j]);
+            }
+
+
+            if (cds_channelpressure_connections != null) {
+                Iterator<ModelConnectionBlock> iter = connblocks.iterator();
+                while (iter.hasNext()) {
+                    ModelConnectionBlock conn = iter.next();
+                    ModelSource[] sources = conn.getSources();
+                    boolean removeok = false;
+                    if (sources != null) {
+                        for (int j = 0; j < sources.length; j++) {
+                            ModelIdentifier srcid = sources[j].getIdentifier();
+                            if ("midi".equals(srcid.getObject()) &&
+                                    "channel_pressure".equals(srcid.getVariable())) {
+                                removeok = true;
+                            }
+                        }
+                    }
+                    if (removeok)
+                        iter.remove();
+                }
+                for (int j = 0; j < cds_channelpressure_connections.length; j++)
+                    connblocks.add(cds_channelpressure_connections[j]);
+            }
+
+        }
+
+        current_instrument = new SoftInstrument(src_instrument, new_performers);
+
+    }
+
+    private ModelConnectionBlock[] createModelConnections(ModelIdentifier sid,
+            int[] destination, int[] range) {
+
+        /*
+        controlled parameter (pp)|range (rr)| Description             |Default
+        -------------------------|----------|-------------------------|-------
+        00 Pitch Control         | 28H..58H | -24..+24 semitones      | 40H
+        01 Filter Cutoff Control | 00H..7FH | -9600..+9450 cents      | 40H
+        02 Amplitude Control     | 00H..7FH | 0..(127/64)*100 percent | 40H
+        03 LFO Pitch Depth       | 00H..7FH | 0..600 cents            |  0
+        04 LFO Filter Depth      | 00H..7FH | 0..2400 cents           |  0
+        05 LFO Amplitude Depth   | 00H..7FH | 0..100 percent          |  0
+        */
+
+        List<ModelConnectionBlock> conns = new ArrayList<ModelConnectionBlock>();
+
+        for (int i = 0; i < destination.length; i++) {
+            int d = destination[i];
+            int r = range[i];
+            if (d == 0) {
+                double scale = (r - 64) * 100;
+                ModelConnectionBlock conn = new ModelConnectionBlock(
+                        new ModelSource(sid,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_UNIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        scale,
+                        new ModelDestination(
+                            new ModelIdentifier("osc", "pitch")));
+                conns.add(conn);
+
+            }
+            if (d == 1) {
+                double scale = (r / 64.0 - 1.0) * 9600.0;
+                ModelConnectionBlock conn;
+                if (scale > 0) {
+                    conn = new ModelConnectionBlock(
+                            new ModelSource(sid,
+                                ModelStandardTransform.DIRECTION_MAX2MIN,
+                                ModelStandardTransform.POLARITY_UNIPOLAR,
+                                ModelStandardTransform.TRANSFORM_LINEAR),
+                            -scale,
+                            new ModelDestination(
+                                ModelDestination.DESTINATION_FILTER_FREQ));
+                } else {
+                    conn = new ModelConnectionBlock(
+                            new ModelSource(sid,
+                                ModelStandardTransform.DIRECTION_MIN2MAX,
+                                ModelStandardTransform.POLARITY_UNIPOLAR,
+                                ModelStandardTransform.TRANSFORM_LINEAR),
+                            scale,
+                            new ModelDestination(
+                                ModelDestination.DESTINATION_FILTER_FREQ));
+                }
+                conns.add(conn);
+            }
+            if (d == 2) {
+                final double scale = (r / 64.0);
+                ModelTransform mt = new ModelTransform() {
+                    double s = scale;
+                    public double transform(double value) {
+                        if (s < 1)
+                            value = s + (value * (1.0 - s));
+                        else if (s > 1)
+                            value = 1 + (value * (s - 1.0));
+                        else
+                            return 0;
+                        return -((5.0 / 12.0) / Math.log(10)) * Math.log(value);
+                    }
+                };
+
+                ModelConnectionBlock conn = new ModelConnectionBlock(
+                        new ModelSource(sid, mt), -960,
+                        new ModelDestination(ModelDestination.DESTINATION_GAIN));
+                conns.add(conn);
+
+            }
+            if (d == 3) {
+                double scale = (r / 64.0 - 1.0) * 9600.0;
+                ModelConnectionBlock conn = new ModelConnectionBlock(
+                        new ModelSource(ModelSource.SOURCE_LFO1,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_BIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        new ModelSource(sid,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_UNIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        scale,
+                        new ModelDestination(
+                            ModelDestination.DESTINATION_PITCH));
+                conns.add(conn);
+            }
+            if (d == 4) {
+                double scale = (r / 128.0) * 2400.0;
+                ModelConnectionBlock conn = new ModelConnectionBlock(
+                        new ModelSource(ModelSource.SOURCE_LFO1,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_BIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        new ModelSource(sid,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_UNIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        scale,
+                        new ModelDestination(
+                            ModelDestination.DESTINATION_FILTER_FREQ));
+                conns.add(conn);
+            }
+            if (d == 5) {
+                final double scale = (r / 127.0);
+
+                ModelTransform mt = new ModelTransform() {
+                    double s = scale;
+                    public double transform(double value) {
+                        return -((5.0 / 12.0) / Math.log(10))
+                                * Math.log(1 - value * s);
+                    }
+                };
+
+                ModelConnectionBlock conn = new ModelConnectionBlock(
+                        new ModelSource(ModelSource.SOURCE_LFO1,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_UNIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        new ModelSource(sid, mt),
+                        -960,
+                        new ModelDestination(
+                            ModelDestination.DESTINATION_GAIN));
+                conns.add(conn);
+            }
+        }
+
+        return conns.toArray(new ModelConnectionBlock[conns.size()]);
+    }
+
+    public void mapPolyPressureToDestination(int[] destination, int[] range) {
+        current_instrument = null;
+        if (destination.length == 0) {
+            cds_polypressure_connections = null;
+            return;
+        }
+        cds_polypressure_connections
+                = createModelConnections(
+                    new ModelIdentifier("midi", "poly_pressure"),
+                    destination, range);
+    }
+
+    public void mapChannelPressureToDestination(int[] destination, int[] range) {
+        current_instrument = null;
+        if (destination.length == 0) {
+            cds_channelpressure_connections = null;
+            return;
+        }
+        cds_channelpressure_connections
+                = createModelConnections(
+                    new ModelIdentifier("midi", "channel_pressure"),
+                    destination, range);
+    }
+
+    public void mapControlToDestination(int control, int[] destination, int[] range) {
+
+        if (!((control >= 0x01 && control <= 0x1F)
+                || (control >= 0x40 && control <= 0x5F))) {
+            cds_control_connections = null;
+            return;
+        }
+
+        current_instrument = null;
+        cds_control_number = control;
+        if (destination.length == 0) {
+            cds_control_connections = null;
+            return;
+        }
+        cds_control_connections
+                = createModelConnections(
+                    new ModelIdentifier("midi_cc", Integer.toString(control)),
+                    destination, range);
+    }
+
+    public void controlChangePerNote(int noteNumber, int controller, int value) {
+
+/*
+ CC# | nn   | Name                    | vv             | default    | description
+-----|------|-------------------------|----------------|------------|-------------------------------
+7    |07H   |Note Volume              |00H-40H-7FH     |40H         |0-100-(127/64)*100(%)(Relative)
+10   |0AH   |*Pan                     |00H-7FH absolute|Preset Value|Left-Center-Right (absolute)
+33-63|21-3FH|LSB for                  |01H-1FH         |            |
+71   |47H   |Timbre/Harmonic Intensity|00H-40H-7FH     |40H (???)   |
+72   |48H   |Release Time             |00H-40H-7FH     |40H (???)   |
+73   |49H   |Attack Time              |00H-40H-7FH     |40H (???)   |
+74   |4AH   |Brightness               |00H-40H-7FH     |40H (???)   |
+75   |4BH   |Decay Time               |00H-40H-7FH     |40H (???)   |
+76   |4CH   |Vibrato Rate             |00H-40H-7FH     |40H (???)   |
+77   |4DH   |Vibrato Depth            |00H-40H-7FH     |40H (???)   |
+78   |4EH   |Vibrato Delay            |00H-40H-7FH     |40H (???)   |
+91   |5BH   |*Reverb Send             |00H-7FH absolute|Preset Value|Left-Center-Right (absolute)
+93   |5DH   |*Chorus Send             |00H-7FH absolute|Preset Value|Left-Center-Right (absolute)
+120  |78H   |**Fine Tuning            |00H-40H-7FH     |40H (???)   |
+121  |79H   |**Coarse Tuning          |00H-40H-7FH     |40H (???)   |
+*/
+
+        if (keybasedcontroller_active == null) {
+            keybasedcontroller_active = new boolean[128][];
+            keybasedcontroller_value = new double[128][];
+        }
+        if (keybasedcontroller_active[noteNumber] == null) {
+            keybasedcontroller_active[noteNumber] = new boolean[128];
+            Arrays.fill(keybasedcontroller_active[noteNumber], false);
+            keybasedcontroller_value[noteNumber] = new double[128];
+            Arrays.fill(keybasedcontroller_value[noteNumber], 0);
+        }
+
+        if (value == -1) {
+            keybasedcontroller_active[noteNumber][controller] = false;
+        } else {
+            keybasedcontroller_active[noteNumber][controller] = true;
+            keybasedcontroller_value[noteNumber][controller] = value / 128.0;
+        }
+
+        if (controller < 120) {
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active)
+                    voices[i].controlChange(controller, -1);
+        } else if (controller == 120) {
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active)
+                    voices[i].rpnChange(1, -1);
+        } else if (controller == 121) {
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active)
+                    voices[i].rpnChange(2, -1);
+        }
+
+    }
+
+    public int getControlPerNote(int noteNumber, int controller) {
+        if (keybasedcontroller_active == null)
+            return -1;
+        if (keybasedcontroller_active[noteNumber] == null)
+            return -1;
+        if (!keybasedcontroller_active[noteNumber][controller])
+            return -1;
+        return (int)(keybasedcontroller_value[noteNumber][controller] * 128);
+    }
+
+    public void controlChange(int controller, int value) {
+        controller = restrict7Bit(controller);
+        value = restrict7Bit(value);
+        if (current_mixer != null)
+            current_mixer.controlChange(controller, value);
+
+        synchronized (control_mutex) {
+            switch (controller) {
+            /*
+            Map<String, int[]>co_midi_rpn_rpn_i = new HashMap<String, int[]>();
+            Map<String, double[]>co_midi_rpn_rpn = new HashMap<String, double[]>();
+            Map<String, int[]>co_midi_nrpn_nrpn_i = new HashMap<String, int[]>();
+            Map<String, double[]>co_midi_nrpn_nrpn = new HashMap<String, double[]>();
+             */
+
+            case 5:
+                // This produce asin-like curve
+                // as described in General Midi Level 2 Specification, page 6
+                double x = -Math.asin((value / 128.0) * 2 - 1) / Math.PI + 0.5;
+                x = Math.pow(100000.0, x) / 100.0;  // x is now cent/msec
+                // Convert x from cent/msec to key/controlbuffertime
+                x = x / 100.0;                      // x is now keys/msec
+                x = x * 1000.0;                     // x is now keys/sec
+                x = x / synthesizer.getControlRate(); // x is now keys/controlbuffertime
+                portamento_time = x;
+                break;
+            case 6:
+            case 38:
+            case 96:
+            case 97:
+                int val = 0;
+                if (nrpn_control != RPN_NULL_VALUE) {
+                    int[] val_i = co_midi_nrpn_nrpn_i.get(nrpn_control);
+                    if (val_i != null)
+                        val = val_i[0];
+                }
+                if (rpn_control != RPN_NULL_VALUE) {
+                    int[] val_i = co_midi_rpn_rpn_i.get(rpn_control);
+                    if (val_i != null)
+                        val = val_i[0];
+                }
+
+                if (controller == 6)
+                    val = (val & 127) + (value << 7);
+                else if (controller == 38)
+                    val = (val & (127 << 7)) + value;
+                else if (controller == 96 || controller == 97) {
+                    int step = 1;
+                    if (rpn_control == 2 || rpn_control == 3 || rpn_control == 4)
+                        step = 128;
+                    if (controller == 96)
+                        val += step;
+                    if (controller == 97)
+                        val -= step;
+                }
+
+                if (nrpn_control != RPN_NULL_VALUE)
+                    nrpnChange(nrpn_control, val);
+                if (rpn_control != RPN_NULL_VALUE)
+                    rpnChange(rpn_control, val);
+
+                break;
+            case 64: // Hold1 (Damper) (cc#64)
+                boolean on = value >= 64;
+                if (sustain != on) {
+                    sustain = on;
+                    if (!on) {
+                        for (int i = 0; i < voices.length; i++) {
+                            if (voices[i].active && voices[i].sustain &&
+                                    voices[i].channel == channel) {
+                                voices[i].sustain = false;
+                                if (!voices[i].on) {
+                                    voices[i].on = true;
+                                    voices[i].noteOff(0);
+                                }
+                            }
+                        }
+                    } else {
+                        for (int i = 0; i < voices.length; i++)
+                            if (voices[i].active && voices[i].channel == channel)
+                                voices[i].redamp();
+                    }
+                }
+                break;
+            case 65:
+                //allNotesOff();
+                portamento = value >= 64;
+                portamento_lastnote[0] = -1;
+                /*
+                for (int i = 0; i < portamento_lastnote.length; i++)
+                    portamento_lastnote[i] = -1;
+                 */
+                portamento_lastnote_ix = 0;
+                break;
+            case 66: // Sostenuto (cc#66)
+                on = value >= 64;
+                if (on) {
+                    for (int i = 0; i < voices.length; i++) {
+                        if (voices[i].active && voices[i].on &&
+                                voices[i].channel == channel) {
+                            voices[i].sostenuto = true;
+                        }
+                    }
+                }
+                if (!on) {
+                    for (int i = 0; i < voices.length; i++) {
+                        if (voices[i].active && voices[i].sostenuto &&
+                                voices[i].channel == channel) {
+                            voices[i].sostenuto = false;
+                            if (!voices[i].on) {
+                                voices[i].on = true;
+                                voices[i].noteOff(0);
+                            }
+                        }
+                    }
+                }
+                break;
+            case 84:
+                portamento_control_note = value;
+                break;
+            case 98:
+                nrpn_control = (nrpn_control & (127 << 7)) + value;
+                rpn_control = RPN_NULL_VALUE;
+                break;
+            case 99:
+                nrpn_control = (nrpn_control & 127) + (value << 7);
+                rpn_control = RPN_NULL_VALUE;
+                break;
+            case 100:
+                rpn_control = (rpn_control & (127 << 7)) + value;
+                nrpn_control = RPN_NULL_VALUE;
+                break;
+            case 101:
+                rpn_control = (rpn_control & 127) + (value << 7);
+                nrpn_control = RPN_NULL_VALUE;
+                break;
+            case 120:
+                allSoundOff();
+                break;
+            case 121:
+                resetAllControllers(value == 127);
+                break;
+            case 122:
+                localControl(value >= 64);
+                break;
+            case 123:
+                allNotesOff();
+                break;
+            case 124:
+                setOmni(false);
+                break;
+            case 125:
+                setOmni(true);
+                break;
+            case 126:
+                if (value == 1)
+                    setMono(true);
+                break;
+            case 127:
+                setMono(false);
+                break;
+
+            default:
+                break;
+            }
+
+            co_midi_cc_cc[controller][0] = value * (1.0 / 128.0);
+
+            if (controller == 0x00) {
+                bank = /*(bank & 127) +*/ (value << 7);
+                return;
+            }
+
+            if (controller == 0x20) {
+                bank = (bank & (127 << 7)) + value;
+                return;
+            }
+
+            this.controller[controller] = value;
+            if(controller < 0x20)
+                this.controller[controller + 0x20] = 0;
+
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active)
+                    voices[i].controlChange(controller, value);
+
+        }
+    }
+
+    public int getController(int controller) {
+        synchronized (control_mutex) {
+            // Should only return lower 7 bits,
+            // even when controller is "boosted" higher.
+            return this.controller[controller] & 127;
+        }
+    }
+
+    public void tuningChange(int program) {
+        tuningChange(0, program);
+    }
+
+    public void tuningChange(int bank, int program) {
+        synchronized (control_mutex) {
+            tuning = synthesizer.getTuning(new Patch(bank, program));
+        }
+    }
+
+    public void programChange(int program) {
+        programChange(bank, program);
+    }
+
+    public void programChange(int bank, int program) {
+        bank = restrict7Bit(bank);
+        program = restrict7Bit(program);
+        synchronized (control_mutex) {
+            mainmixer.activity();
+            this.bank = bank;
+            this.program = program;
+            current_instrument = null;
+        }
+    }
+
+    public int getProgram() {
+        synchronized (control_mutex) {
+            return program;
+        }
+    }
+
+    public void setPitchBend(int bend) {
+        bend = restrict14Bit(bend);
+        if (current_mixer != null)
+            current_mixer.setPitchBend(bend);
+        synchronized (control_mutex) {
+            mainmixer.activity();
+            co_midi_pitch[0] = bend * (1.0 / 16384.0);
+            pitchbend = bend;
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active)
+                    voices[i].setPitchBend(bend);
+        }
+    }
+
+    public int getPitchBend() {
+        synchronized (control_mutex) {
+            return pitchbend;
+        }
+    }
+
+    public void nrpnChange(int controller, int value) {
+
+        /*
+        System.out.println("(" + channel + ").nrpnChange("
+                + Integer.toHexString(controller >> 7)
+                + " " + Integer.toHexString(controller & 127)
+                + ", " + Integer.toHexString(value >> 7)
+                + " " + Integer.toHexString(value & 127) + ")");
+         */
+
+        if (synthesizer.getGeneralMidiMode() == 0) {
+            if (controller == (0x01 << 7) + (0x08)) // Vibrato Rate
+                controlChange(76, value >> 7);
+            if (controller == (0x01 << 7) + (0x09)) // Vibrato Depth
+                controlChange(77, value >> 7);
+            if (controller == (0x01 << 7) + (0x0A)) // Vibrato Delay
+                controlChange(78, value >> 7);
+            if (controller == (0x01 << 7) + (0x20)) // Brightness
+                controlChange(74, value >> 7);
+            if (controller == (0x01 << 7) + (0x21)) // Filter Resonance
+                controlChange(71, value >> 7);
+            if (controller == (0x01 << 7) + (0x63)) // Attack Time
+                controlChange(73, value >> 7);
+            if (controller == (0x01 << 7) + (0x64)) // Decay Time
+                controlChange(75, value >> 7);
+            if (controller == (0x01 << 7) + (0x66)) // Release Time
+                controlChange(72, value >> 7);
+
+            if (controller >> 7 == 0x18) // Pitch coarse
+                controlChangePerNote(controller % 128, 120, value >> 7);
+            if (controller >> 7 == 0x1A) // Volume
+                controlChangePerNote(controller % 128, 7, value >> 7);
+            if (controller >> 7 == 0x1C) // Panpot
+                controlChangePerNote(controller % 128, 10, value >> 7);
+            if (controller >> 7 == 0x1D) // Reverb
+                controlChangePerNote(controller % 128, 91, value >> 7);
+            if (controller >> 7 == 0x1E) // Chorus
+                controlChangePerNote(controller % 128, 93, value >> 7);
+        }
+
+        int[] val_i = co_midi_nrpn_nrpn_i.get(controller);
+        double[] val_d = co_midi_nrpn_nrpn.get(controller);
+        if (val_i == null) {
+            val_i = new int[1];
+            co_midi_nrpn_nrpn_i.put(controller, val_i);
+        }
+        if (val_d == null) {
+            val_d = new double[1];
+            co_midi_nrpn_nrpn.put(controller, val_d);
+        }
+        val_i[0] = value;
+        val_d[0] = val_i[0] * (1.0 / 16384.0);
+
+        for (int i = 0; i < voices.length; i++)
+            if (voices[i].active)
+                voices[i].nrpnChange(controller, val_i[0]);
+
+    }
+
+    public void rpnChange(int controller, int value) {
+
+        /*
+        System.out.println("(" + channel + ").rpnChange("
+                + Integer.toHexString(controller >> 7)
+                + " " + Integer.toHexString(controller & 127)
+                + ", " + Integer.toHexString(value >> 7)
+                + " " + Integer.toHexString(value & 127) + ")");
+         */
+
+        if (controller == 3) {
+            tuning_program = (value >> 7) & 127;
+            tuningChange(tuning_bank, tuning_program);
+        }
+        if (controller == 4) {
+            tuning_bank = (value >> 7) & 127;
+        }
+
+        int[] val_i = co_midi_rpn_rpn_i.get(controller);
+        double[] val_d = co_midi_rpn_rpn.get(controller);
+        if (val_i == null) {
+            val_i = new int[1];
+            co_midi_rpn_rpn_i.put(controller, val_i);
+        }
+        if (val_d == null) {
+            val_d = new double[1];
+            co_midi_rpn_rpn.put(controller, val_d);
+        }
+        val_i[0] = value;
+        val_d[0] = val_i[0] * (1.0 / 16384.0);
+
+        for (int i = 0; i < voices.length; i++)
+            if (voices[i].active)
+                voices[i].rpnChange(controller, val_i[0]);
+    }
+
+    public void resetAllControllers() {
+        resetAllControllers(false);
+    }
+
+    public void resetAllControllers(boolean allControls) {
+        synchronized (control_mutex) {
+            mainmixer.activity();
+
+            for (int i = 0; i < 128; i++) {
+                setPolyPressure(i, 0);
+            }
+            setChannelPressure(0);
+            setPitchBend(8192);
+            for (int i = 0; i < 128; i++) {
+                if (!dontResetControls[i])
+                    controlChange(i, 0);
+            }
+
+            controlChange(71, 64); // Filter Resonance
+            controlChange(72, 64); // Release Time
+            controlChange(73, 64); // Attack Time
+            controlChange(74, 64); // Brightness
+            controlChange(75, 64); // Decay Time
+            controlChange(76, 64); // Vibrato Rate
+            controlChange(77, 64); // Vibrato Depth
+            controlChange(78, 64); // Vibrato Delay
+
+            controlChange(8, 64); // Balance
+            controlChange(11, 127); // Expression
+            controlChange(98, 127); // NRPN Null
+            controlChange(99, 127); // NRPN Null
+            controlChange(100, 127); // RPN = Null
+            controlChange(101, 127); // RPN = Null
+
+            // see DLS 2.1 (Power-on Default Values)
+            if (allControls) {
+
+                keybasedcontroller_active = null;
+                keybasedcontroller_value = null;
+
+                controlChange(7, 100); // Volume
+                controlChange(10, 64); // Pan
+                controlChange(91, 40); // Reverb
+
+                for (int controller : co_midi_rpn_rpn.keySet()) {
+                    // don't reset tuning settings
+                    if (controller != 3 && controller != 4)
+                        rpnChange(controller, 0);
+                }
+                for (int controller : co_midi_nrpn_nrpn.keySet())
+                    nrpnChange(controller, 0);
+                rpnChange(0, 2 << 7);   // Bitch Bend sensitivity
+                rpnChange(1, 64 << 7);  // Channel fine tunning
+                rpnChange(2, 64 << 7);  // Channel Coarse Tuning
+                rpnChange(5, 64);       // Modulation Depth, +/- 50 cent
+
+                tuning_bank = 0;
+                tuning_program = 0;
+                tuning = new SoftTuning();
+
+            }
+
+        }
+    }
+
+    public void allNotesOff() {
+        if (current_mixer != null)
+            current_mixer.allNotesOff();
+        synchronized (control_mutex) {
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].on && voices[i].channel == channel
+                        && voices[i].releaseTriggered == false) {
+                    voices[i].noteOff(0);
+                }
+        }
+    }
+
+    public void allSoundOff() {
+        if (current_mixer != null)
+            current_mixer.allSoundOff();
+        synchronized (control_mutex) {
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].on && voices[i].channel == channel)
+                    voices[i].soundOff();
+        }
+    }
+
+    public boolean localControl(boolean on) {
+        return false;
+    }
+
+    public void setMono(boolean on) {
+        if (current_mixer != null)
+            current_mixer.setMono(on);
+        synchronized (control_mutex) {
+            allNotesOff();
+            mono = on;
+        }
+    }
+
+    public boolean getMono() {
+        synchronized (control_mutex) {
+            return mono;
+        }
+    }
+
+    public void setOmni(boolean on) {
+        if (current_mixer != null)
+            current_mixer.setOmni(on);
+        allNotesOff();
+    // Omni is not supported by GM2
+    }
+
+    public boolean getOmni() {
+        return false;
+    }
+
+    public void setMute(boolean mute) {
+        if (current_mixer != null)
+            current_mixer.setMute(mute);
+        synchronized (control_mutex) {
+            this.mute = mute;
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active && voices[i].channel == channel)
+                    voices[i].setMute(mute);
+        }
+    }
+
+    public boolean getMute() {
+        synchronized (control_mutex) {
+            return mute;
+        }
+    }
+
+    public void setSolo(boolean soloState) {
+        if (current_mixer != null)
+            current_mixer.setSolo(soloState);
+
+        synchronized (control_mutex) {
+            this.solo = soloState;
+
+            boolean soloinuse = false;
+            for (SoftChannel c : synthesizer.channels) {
+                if (c.solo) {
+                    soloinuse = true;
+                    break;
+                }
+            }
+
+            if (!soloinuse) {
+                for (SoftChannel c : synthesizer.channels)
+                    c.setSoloMute(false);
+                return;
+            }
+
+            for (SoftChannel c : synthesizer.channels)
+                c.setSoloMute(!c.solo);
+
+        }
+
+    }
+
+    private void setSoloMute(boolean mute) {
+        synchronized (control_mutex) {
+            if (solomute == mute)
+                return;
+            this.solomute = mute;
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active && voices[i].channel == channel)
+                    voices[i].setSoloMute(solomute);
+        }
+    }
+
+    public boolean getSolo() {
+        synchronized (control_mutex) {
+            return solo;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftChannelProxy.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.MidiChannel;
+
+/**
+ * A MidiChannel proxy object used for external access to synthesizer internal
+ * channel objects.
+ *
+ * @author Karl Helgason
+ */
+public class SoftChannelProxy implements MidiChannel {
+
+    private MidiChannel channel = null;
+
+    public MidiChannel getChannel() {
+        return channel;
+    }
+
+    public void setChannel(MidiChannel channel) {
+        this.channel = channel;
+    }
+
+    public void allNotesOff() {
+        if (channel == null)
+            return;
+        channel.allNotesOff();
+    }
+
+    public void allSoundOff() {
+        if (channel == null)
+            return;
+        channel.allSoundOff();
+    }
+
+    public void controlChange(int controller, int value) {
+        if (channel == null)
+            return;
+        channel.controlChange(controller, value);
+    }
+
+    public int getChannelPressure() {
+        if (channel == null)
+            return 0;
+        return channel.getChannelPressure();
+    }
+
+    public int getController(int controller) {
+        if (channel == null)
+            return 0;
+        return channel.getController(controller);
+    }
+
+    public boolean getMono() {
+        if (channel == null)
+            return false;
+        return channel.getMono();
+    }
+
+    public boolean getMute() {
+        if (channel == null)
+            return false;
+        return channel.getMute();
+    }
+
+    public boolean getOmni() {
+        if (channel == null)
+            return false;
+        return channel.getOmni();
+    }
+
+    public int getPitchBend() {
+        if (channel == null)
+            return 8192;
+        return channel.getPitchBend();
+    }
+
+    public int getPolyPressure(int noteNumber) {
+        if (channel == null)
+            return 0;
+        return channel.getPolyPressure(noteNumber);
+    }
+
+    public int getProgram() {
+        if (channel == null)
+            return 0;
+        return channel.getProgram();
+    }
+
+    public boolean getSolo() {
+        if (channel == null)
+            return false;
+        return channel.getSolo();
+    }
+
+    public boolean localControl(boolean on) {
+        if (channel == null)
+            return false;
+        return channel.localControl(on);
+    }
+
+    public void noteOff(int noteNumber) {
+        if (channel == null)
+            return;
+        channel.noteOff(noteNumber);
+    }
+
+    public void noteOff(int noteNumber, int velocity) {
+        if (channel == null)
+            return;
+        channel.noteOff(noteNumber, velocity);
+    }
+
+    public void noteOn(int noteNumber, int velocity) {
+        if (channel == null)
+            return;
+        channel.noteOn(noteNumber, velocity);
+    }
+
+    public void programChange(int program) {
+        if (channel == null)
+            return;
+        channel.programChange(program);
+    }
+
+    public void programChange(int bank, int program) {
+        if (channel == null)
+            return;
+        channel.programChange(bank, program);
+    }
+
+    public void resetAllControllers() {
+        if (channel == null)
+            return;
+        channel.resetAllControllers();
+    }
+
+    public void setChannelPressure(int pressure) {
+        if (channel == null)
+            return;
+        channel.setChannelPressure(pressure);
+    }
+
+    public void setMono(boolean on) {
+        if (channel == null)
+            return;
+        channel.setMono(on);
+    }
+
+    public void setMute(boolean mute) {
+        if (channel == null)
+            return;
+        channel.setMute(mute);
+    }
+
+    public void setOmni(boolean on) {
+        if (channel == null)
+            return;
+        channel.setOmni(on);
+    }
+
+    public void setPitchBend(int bend) {
+        if (channel == null)
+            return;
+        channel.setPitchBend(bend);
+    }
+
+    public void setPolyPressure(int noteNumber, int pressure) {
+        if (channel == null)
+            return;
+        channel.setPolyPressure(noteNumber, pressure);
+    }
+
+    public void setSolo(boolean soloState) {
+        if (channel == null)
+            return;
+        channel.setSolo(soloState);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftChorus.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Arrays;
+
+/**
+ * A chorus effect made using LFO and variable delay. One for each channel
+ * (left,right), with different starting phase for stereo effect.
+ *
+ * @author Karl Helgason
+ */
+public class SoftChorus implements SoftAudioProcessor {
+
+    private static class VariableDelay {
+
+        private float[] delaybuffer;
+        private int rovepos = 0;
+        private volatile float gain = 1;
+        private volatile float rgain = 0;
+        private volatile float delay = 0;
+        private float lastdelay = 0;
+        private volatile float feedback = 0;
+
+        public VariableDelay(int maxbuffersize) {
+            delaybuffer = new float[maxbuffersize];
+        }
+
+        public void setDelay(float delay) {
+            this.delay = delay;
+        }
+
+        public void setFeedBack(float feedback) {
+            this.feedback = feedback;
+        }
+
+        public void setGain(float gain) {
+            this.gain = gain;
+        }
+
+        public void setReverbSendGain(float rgain) {
+            this.rgain = rgain;
+        }
+
+        public void processMix(float[] in, float[] out, float[] rout) {
+            float gain = this.gain;
+            float delay = this.delay;
+            float feedback = this.feedback;
+
+            float[] delaybuffer = this.delaybuffer;
+            int len = in.length;
+            float delaydelta = (delay - lastdelay) / len;
+            int rnlen = delaybuffer.length;
+            int rovepos = this.rovepos;
+
+            if (rout == null)
+                for (int i = 0; i < len; i++) {
+                    float r = rovepos - (lastdelay + 2) + rnlen;
+                    int ri = (int) r;
+                    float s = r - ri;
+                    float a = delaybuffer[ri % rnlen];
+                    float b = delaybuffer[(ri + 1) % rnlen];
+                    float o = a * (1 - s) + b * (s);
+                    out[i] += o * gain;
+                    delaybuffer[rovepos] = in[i] + o * feedback;
+                    rovepos = (rovepos + 1) % rnlen;
+                    lastdelay += delaydelta;
+                }
+            else
+                for (int i = 0; i < len; i++) {
+                    float r = rovepos - (lastdelay + 2) + rnlen;
+                    int ri = (int) r;
+                    float s = r - ri;
+                    float a = delaybuffer[ri % rnlen];
+                    float b = delaybuffer[(ri + 1) % rnlen];
+                    float o = a * (1 - s) + b * (s);
+                    out[i] += o * gain;
+                    rout[i] += o * rgain;
+                    delaybuffer[rovepos] = in[i] + o * feedback;
+                    rovepos = (rovepos + 1) % rnlen;
+                    lastdelay += delaydelta;
+                }
+            this.rovepos = rovepos;
+            lastdelay = delay;
+        }
+
+        public void processReplace(float[] in, float[] out, float[] rout) {
+            Arrays.fill(out, 0);
+            Arrays.fill(rout, 0);
+            processMix(in, out, rout);
+        }
+    }
+
+    private static class LFODelay {
+
+        private volatile double c_cos_delta;
+        private volatile double c_sin_delta;
+        private double c_cos = 1;
+        private double c_sin = 0;
+        private double depth = 0;
+        private VariableDelay vdelay;
+        private double samplerate;
+        private double controlrate;
+
+        public LFODelay(double samplerate, double controlrate) {
+            this.samplerate = samplerate;
+            this.controlrate = controlrate;
+            // vdelay = new VariableDelay((int)(samplerate*4));
+            vdelay = new VariableDelay((int) ((this.depth + 10) * 2));
+
+        }
+
+        public void setDepth(double depth) {
+            this.depth = depth * samplerate;
+            vdelay = new VariableDelay((int) ((this.depth + 10) * 2));
+        }
+
+        public void setRate(double rate) {
+            double g = (Math.PI * 2) * (rate / controlrate);
+            c_cos_delta = Math.cos(g);
+            c_sin_delta = Math.sin(g);
+        }
+
+        public void setPhase(double phase) {
+            c_cos = Math.cos(phase);
+            c_sin = Math.sin(phase);
+        }
+
+        public void setFeedBack(float feedback) {
+            vdelay.setFeedBack(feedback);
+        }
+
+        public void setGain(float gain) {
+            vdelay.setGain(gain);
+        }
+
+        public void setReverbSendGain(float rgain) {
+            vdelay.setReverbSendGain(rgain);
+        }
+
+        public void processMix(float[] in, float[] out, float[] rout) {
+            c_cos = c_cos * c_cos_delta - c_sin * c_sin_delta;
+            c_sin = c_cos * c_sin_delta + c_sin * c_cos_delta;
+            vdelay.setDelay((float) (depth * 0.5 * (c_cos + 2)));
+            vdelay.processMix(in, out, rout);
+        }
+
+        public void processReplace(float[] in, float[] out, float[] rout) {
+            c_cos = c_cos * c_cos_delta - c_sin * c_sin_delta;
+            c_sin = c_cos * c_sin_delta + c_sin * c_cos_delta;
+            vdelay.setDelay((float) (depth * 0.5 * (c_cos + 2)));
+            vdelay.processReplace(in, out, rout);
+
+        }
+    }
+    private boolean mix = true;
+    private SoftAudioBuffer inputA;
+    private SoftAudioBuffer left;
+    private SoftAudioBuffer right;
+    private SoftAudioBuffer reverb;
+    private LFODelay vdelay1L;
+    private LFODelay vdelay1R;
+    private float rgain = 0;
+    private boolean dirty = true;
+    private double dirty_vdelay1L_rate;
+    private double dirty_vdelay1R_rate;
+    private double dirty_vdelay1L_depth;
+    private double dirty_vdelay1R_depth;
+    private float dirty_vdelay1L_feedback;
+    private float dirty_vdelay1R_feedback;
+    private float dirty_vdelay1L_reverbsendgain;
+    private float dirty_vdelay1R_reverbsendgain;
+    private float controlrate;
+
+    public void init(float samplerate, float controlrate) {
+        this.controlrate = controlrate;
+        vdelay1L = new LFODelay(samplerate, controlrate);
+        vdelay1R = new LFODelay(samplerate, controlrate);
+        vdelay1L.setGain(1.0f); // %
+        vdelay1R.setGain(1.0f); // %
+        vdelay1L.setPhase(0.5 * Math.PI);
+        vdelay1R.setPhase(0);
+
+        globalParameterControlChange(new int[]{0x01 * 128 + 0x02}, 0, 2);
+    }
+
+    public void globalParameterControlChange(int[] slothpath, long param,
+            long value) {
+        if (slothpath.length == 1) {
+            if (slothpath[0] == 0x01 * 128 + 0x02) {
+                if (param == 0) { // Chorus Type
+                    switch ((int)value) {
+                    case 0: // Chorus 1 0 (0%) 3 (0.4Hz) 5 (1.9ms) 0 (0%)
+                        globalParameterControlChange(slothpath, 3, 0);
+                        globalParameterControlChange(slothpath, 1, 3);
+                        globalParameterControlChange(slothpath, 2, 5);
+                        globalParameterControlChange(slothpath, 4, 0);
+                        break;
+                    case 1: // Chorus 2 5 (4%) 9 (1.1Hz) 19 (6.3ms) 0 (0%)
+                        globalParameterControlChange(slothpath, 3, 5);
+                        globalParameterControlChange(slothpath, 1, 9);
+                        globalParameterControlChange(slothpath, 2, 19);
+                        globalParameterControlChange(slothpath, 4, 0);
+                        break;
+                    case 2: // Chorus 3 8 (6%) 3 (0.4Hz) 19 (6.3ms) 0 (0%)
+                        globalParameterControlChange(slothpath, 3, 8);
+                        globalParameterControlChange(slothpath, 1, 3);
+                        globalParameterControlChange(slothpath, 2, 19);
+                        globalParameterControlChange(slothpath, 4, 0);
+                        break;
+                    case 3: // Chorus 4 16 (12%) 9 (1.1Hz) 16 (5.3ms) 0 (0%)
+                        globalParameterControlChange(slothpath, 3, 16);
+                        globalParameterControlChange(slothpath, 1, 9);
+                        globalParameterControlChange(slothpath, 2, 16);
+                        globalParameterControlChange(slothpath, 4, 0);
+                        break;
+                    case 4: // FB Chorus 64 (49%) 2 (0.2Hz) 24 (7.8ms) 0 (0%)
+                        globalParameterControlChange(slothpath, 3, 64);
+                        globalParameterControlChange(slothpath, 1, 2);
+                        globalParameterControlChange(slothpath, 2, 24);
+                        globalParameterControlChange(slothpath, 4, 0);
+                        break;
+                    case 5: // Flanger 112 (86%) 1 (0.1Hz) 5 (1.9ms) 0 (0%)
+                        globalParameterControlChange(slothpath, 3, 112);
+                        globalParameterControlChange(slothpath, 1, 1);
+                        globalParameterControlChange(slothpath, 2, 5);
+                        globalParameterControlChange(slothpath, 4, 0);
+                        break;
+                    default:
+                        break;
+                    }
+                } else if (param == 1) { // Mod Rate
+                    dirty_vdelay1L_rate = (value * 0.122);
+                    dirty_vdelay1R_rate = (value * 0.122);
+                    dirty = true;
+                } else if (param == 2) { // Mod Depth
+                    dirty_vdelay1L_depth = ((value + 1) / 3200.0);
+                    dirty_vdelay1R_depth = ((value + 1) / 3200.0);
+                    dirty = true;
+                } else if (param == 3) { // Feedback
+                    dirty_vdelay1L_feedback = (value * 0.00763f);
+                    dirty_vdelay1R_feedback = (value * 0.00763f);
+                    dirty = true;
+                }
+                if (param == 4) { // Send to Reverb
+                    rgain = value * 0.00787f;
+                    dirty_vdelay1L_reverbsendgain = (value * 0.00787f);
+                    dirty_vdelay1R_reverbsendgain = (value * 0.00787f);
+                    dirty = true;
+                }
+
+            }
+        }
+    }
+
+    public void processControlLogic() {
+        if (dirty) {
+            dirty = false;
+            vdelay1L.setRate(dirty_vdelay1L_rate);
+            vdelay1R.setRate(dirty_vdelay1R_rate);
+            vdelay1L.setDepth(dirty_vdelay1L_depth);
+            vdelay1R.setDepth(dirty_vdelay1R_depth);
+            vdelay1L.setFeedBack(dirty_vdelay1L_feedback);
+            vdelay1R.setFeedBack(dirty_vdelay1R_feedback);
+            vdelay1L.setReverbSendGain(dirty_vdelay1L_reverbsendgain);
+            vdelay1R.setReverbSendGain(dirty_vdelay1R_reverbsendgain);
+        }
+    }
+    double silentcounter = 1000;
+
+    public void processAudio() {
+
+        if (inputA.isSilent()) {
+            silentcounter += 1 / controlrate;
+
+            if (silentcounter > 1) {
+                if (!mix) {
+                    left.clear();
+                    right.clear();
+                }
+                return;
+            }
+        } else
+            silentcounter = 0;
+
+        float[] inputA = this.inputA.array();
+        float[] left = this.left.array();
+        float[] right = this.right == null ? null : this.right.array();
+        float[] reverb = rgain != 0 ? this.reverb.array() : null;
+
+        if (mix) {
+            vdelay1L.processMix(inputA, left, reverb);
+            if (right != null)
+                vdelay1R.processMix(inputA, right, reverb);
+        } else {
+            vdelay1L.processReplace(inputA, left, reverb);
+            if (right != null)
+                vdelay1R.processReplace(inputA, right, reverb);
+        }
+    }
+
+    public void setInput(int pin, SoftAudioBuffer input) {
+        if (pin == 0)
+            inputA = input;
+    }
+
+    public void setMixMode(boolean mix) {
+        this.mix = mix;
+    }
+
+    public void setOutput(int pin, SoftAudioBuffer output) {
+        if (pin == 0)
+            left = output;
+        if (pin == 1)
+            right = output;
+        if (pin == 2)
+            reverb = output;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftControl.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * <code>SoftControl</code> are the basic controls
+ * used for control-rate processing.
+ *
+ * @author Karl Helgason
+ */
+public interface SoftControl {
+
+    public double[] get(int instance, String name);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftCubicResampler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A resampler that uses third-order (cubic) interpolation.
+ *
+ * @author Karl Helgason
+ */
+public class SoftCubicResampler extends SoftAbstractResampler {
+
+    public int getPadding() {
+        return 3;
+    }
+
+    public void interpolate(float[] in, float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+        if (pitchstep == 0) {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float fix = ix - iix;
+                float y0 = in[iix - 1];
+                float y1 = in[iix];
+                float y2 = in[iix + 1];
+                float y3 = in[iix + 2];
+                float a0 = y3 - y2 + y1 - y0;
+                float a1 = y0 - y1 - a0;
+                float a2 = y2 - y0;
+                float a3 = y1;
+                //float fix2 = fix * fix;
+                //out[ox++] = (a0 * fix + a1) * fix2 + (a2 * fix + a3);
+                out[ox++] = ((a0 * fix + a1) * fix + a2) * fix + a3;
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float fix = ix - iix;
+                float y0 = in[iix - 1];
+                float y1 = in[iix];
+                float y2 = in[iix + 1];
+                float y3 = in[iix + 2];
+                float a0 = y3 - y2 + y1 - y0;
+                float a1 = y0 - y1 - a0;
+                float a2 = y2 - y0;
+                float a3 = y1;
+                //float fix2 = fix * fix;
+                //out[ox++] = (a0 * fix + a1) * fix2 + (a2 * fix + a3);
+                out[ox++] = ((a0 * fix + a1) * fix + a2) * fix + a3;
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftEnvelopeGenerator.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,298 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * AHDSR control signal envelope generator.
+ *
+ * @author Karl Helgason
+ */
+public class SoftEnvelopeGenerator implements SoftProcess {
+
+    public final static int EG_OFF = 0;
+    public final static int EG_DELAY = 1;
+    public final static int EG_ATTACK = 2;
+    public final static int EG_HOLD = 3;
+    public final static int EG_DECAY = 4;
+    public final static int EG_SUSTAIN = 5;
+    public final static int EG_RELEASE = 6;
+    public final static int EG_SHUTDOWN = 7;
+    public final static int EG_END = 8;
+    int max_count = 10;
+    int used_count = 0;
+    private int[] stage = new int[max_count];
+    private int[] stage_ix = new int[max_count];
+    private double[] stage_v = new double[max_count];
+    private int[] stage_count = new int[max_count];
+    private double[][] on = new double[max_count][1];
+    private double[][] active = new double[max_count][1];
+    private double[][] out = new double[max_count][1];
+    private double[][] delay = new double[max_count][1];
+    private double[][] attack = new double[max_count][1];
+    private double[][] hold = new double[max_count][1];
+    private double[][] decay = new double[max_count][1];
+    private double[][] sustain = new double[max_count][1];
+    private double[][] release = new double[max_count][1];
+    private double[][] shutdown = new double[max_count][1];
+    private double[][] release2 = new double[max_count][1];
+    private double[][] attack2 = new double[max_count][1];
+    private double[][] decay2 = new double[max_count][1];
+    private double control_time = 0;
+
+    public void reset() {
+        for (int i = 0; i < used_count; i++) {
+            stage[i] = 0;
+            on[i][0] = 0;
+            out[i][0] = 0;
+            delay[i][0] = 0;
+            attack[i][0] = 0;
+            hold[i][0] = 0;
+            decay[i][0] = 0;
+            sustain[i][0] = 0;
+            release[i][0] = 0;
+            shutdown[i][0] = 0;
+            attack2[i][0] = 0;
+            decay2[i][0] = 0;
+            release2[i][0] = 0;
+        }
+        used_count = 0;
+    }
+
+    public void init(SoftSynthesizer synth) {
+        control_time = 1.0 / synth.getControlRate();
+        processControlLogic();
+    }
+
+    public double[] get(int instance, String name) {
+        if (instance >= used_count)
+            used_count = instance + 1;
+        if (name == null)
+            return out[instance];
+        if (name.equals("on"))
+            return on[instance];
+        if (name.equals("active"))
+            return active[instance];
+        if (name.equals("delay"))
+            return delay[instance];
+        if (name.equals("attack"))
+            return attack[instance];
+        if (name.equals("hold"))
+            return hold[instance];
+        if (name.equals("decay"))
+            return decay[instance];
+        if (name.equals("sustain"))
+            return sustain[instance];
+        if (name.equals("release"))
+            return release[instance];
+        if (name.equals("shutdown"))
+            return shutdown[instance];
+        if (name.equals("attack2"))
+            return attack2[instance];
+        if (name.equals("decay2"))
+            return decay2[instance];
+        if (name.equals("release2"))
+            return release2[instance];
+
+        return null;
+    }
+
+    public void processControlLogic() {
+        for (int i = 0; i < used_count; i++) {
+
+            if (stage[i] == EG_END)
+                continue;
+
+            if ((stage[i] > EG_OFF) && (stage[i] < EG_RELEASE)) {
+                if (on[i][0] < 0.5) {
+                    if (on[i][0] < -0.5) {
+                        stage_count[i] = (int)(Math.pow(2,
+                                this.shutdown[i][0] / 1200.0) / control_time);
+                        if (stage_count[i] < 0)
+                            stage_count[i] = 0;
+                        stage_v[i] = out[i][0];
+                        stage_ix[i] = 0;
+                        stage[i] = EG_SHUTDOWN;
+                    } else {
+                        if ((release2[i][0] < 0.000001) && release[i][0] < 0
+                                && Double.isInfinite(release[i][0])) {
+                            out[i][0] = 0;
+                            active[i][0] = 0;
+                            stage[i] = EG_END;
+                            continue;
+                        }
+
+                        stage_count[i] = (int)(Math.pow(2,
+                                this.release[i][0] / 1200.0) / control_time);
+                        stage_count[i]
+                                += (int)(this.release2[i][0]/(control_time * 1000));
+                        if (stage_count[i] < 0)
+                            stage_count[i] = 0;
+                        // stage_v[i] = out[i][0];
+                        stage_ix[i] = 0;
+
+                        double m = 1 - out[i][0];
+                        stage_ix[i] = (int)(stage_count[i] * m);
+
+                        stage[i] = EG_RELEASE;
+                    }
+                }
+            }
+
+            switch (stage[i]) {
+            case EG_OFF:
+                active[i][0] = 1;
+                if (on[i][0] < 0.5)
+                    break;
+                stage[i] = EG_DELAY;
+                stage_ix[i] = (int)(Math.pow(2,
+                        this.delay[i][0] / 1200.0) / control_time);
+                if (stage_ix[i] < 0)
+                    stage_ix[i] = 0;
+            case EG_DELAY:
+                if (stage_ix[i] == 0) {
+                    double attack = this.attack[i][0];
+                    double attack2 = this.attack2[i][0];
+
+                    if (attack2 < 0.000001
+                            && (attack < 0 && Double.isInfinite(attack))) {
+                        out[i][0] = 1;
+                        stage[i] = EG_HOLD;
+                        stage_count[i] = (int)(Math.pow(2,
+                                this.hold[i][0] / 1200.0) / control_time);
+                        stage_ix[i] = 0;
+                    } else {
+                        stage[i] = EG_ATTACK;
+                        stage_count[i] = (int)(Math.pow(2,
+                                attack / 1200.0) / control_time);
+                        stage_count[i] += (int)(attack2 / (control_time * 1000));
+                        if (stage_count[i] < 0)
+                            stage_count[i] = 0;
+                        stage_ix[i] = 0;
+                    }
+                } else
+                    stage_ix[i]--;
+                break;
+            case EG_ATTACK:
+                stage_ix[i]++;
+                if (stage_ix[i] >= stage_count[i]) {
+                    out[i][0] = 1;
+                    stage[i] = EG_HOLD;
+                } else {
+                    // CONVEX attack
+                    double a = ((double)stage_ix[i]) / ((double)stage_count[i]);
+                    a = 1 + ((40.0 / 96.0) / Math.log(10)) * Math.log(a);
+                    if (a < 0)
+                        a = 0;
+                    else if (a > 1)
+                        a = 1;
+                    out[i][0] = a;
+                }
+                break;
+            case EG_HOLD:
+                stage_ix[i]++;
+                if (stage_ix[i] >= stage_count[i]) {
+                    stage[i] = EG_DECAY;
+                    stage_count[i] = (int)(Math.pow(2,
+                            this.decay[i][0] / 1200.0) / control_time);
+                    stage_count[i] += (int)(this.decay2[i][0]/(control_time*1000));
+                    if (stage_count[i] < 0)
+                        stage_count[i] = 0;
+                    stage_ix[i] = 0;
+                }
+                break;
+            case EG_DECAY:
+                stage_ix[i]++;
+                double sustain = this.sustain[i][0] * (1.0 / 1000.0);
+                if (stage_ix[i] >= stage_count[i]) {
+                    out[i][0] = sustain;
+                    stage[i] = EG_SUSTAIN;
+                    if (sustain < 0.001) {
+                        out[i][0] = 0;
+                        active[i][0] = 0;
+                        stage[i] = EG_END;
+                    }
+                } else {
+                    double m = ((double)stage_ix[i]) / ((double)stage_count[i]);
+                    out[i][0] = (1 - m) + sustain * m;
+                }
+                break;
+            case EG_SUSTAIN:
+                break;
+            case EG_RELEASE:
+                stage_ix[i]++;
+                if (stage_ix[i] >= stage_count[i]) {
+                    out[i][0] = 0;
+                    active[i][0] = 0;
+                    stage[i] = EG_END;
+                } else {
+                    double m = ((double)stage_ix[i]) / ((double)stage_count[i]);
+                    out[i][0] = (1 - m); // *stage_v[i];
+
+                    if (on[i][0] < -0.5) {
+                        stage_count[i] = (int)(Math.pow(2,
+                                this.shutdown[i][0] / 1200.0) / control_time);
+                        if (stage_count[i] < 0)
+                            stage_count[i] = 0;
+                        stage_v[i] = out[i][0];
+                        stage_ix[i] = 0;
+                        stage[i] = EG_SHUTDOWN;
+                    }
+
+                    // re-damping
+                    if (on[i][0] > 0.5) {
+                        sustain = this.sustain[i][0] * (1.0 / 1000.0);
+                        if (out[i][0] > sustain) {
+                            stage[i] = EG_DECAY;
+                            stage_count[i] = (int)(Math.pow(2,
+                                    this.decay[i][0] / 1200.0) / control_time);
+                            stage_count[i] +=
+                                    (int)(this.decay2[i][0]/(control_time*1000));
+                            if (stage_count[i] < 0)
+                                stage_count[i] = 0;
+                            m = (out[i][0] - 1) / (sustain - 1);
+                            stage_ix[i] = (int) (stage_count[i] * m);
+                        }
+                    }
+
+                }
+                break;
+            case EG_SHUTDOWN:
+                stage_ix[i]++;
+                if (stage_ix[i] >= stage_count[i]) {
+                    out[i][0] = 0;
+                    active[i][0] = 0;
+                    stage[i] = EG_END;
+                } else {
+                    double m = ((double)stage_ix[i]) / ((double)stage_count[i]);
+                    out[i][0] = (1 - m) * stage_v[i];
+                }
+                break;
+            default:
+                break;
+            }
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftFilter.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,614 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Infinite impulse response (IIR) filter class.
+ *
+ * The filters where implemented and adapted using algorithms from musicdsp.org
+ * archive: 1-RC and C filter, Simple 2-pole LP LP and HP filter, biquad,
+ * tweaked butterworth RBJ Audio-EQ-Cookbook, EQ filter kookbook
+ *
+ * @author Karl Helgason
+ */
+public class SoftFilter {
+
+    public final static int FILTERTYPE_LP6 = 0x00;
+    public final static int FILTERTYPE_LP12 = 0x01;
+    public final static int FILTERTYPE_HP12 = 0x11;
+    public final static int FILTERTYPE_BP12 = 0x21;
+    public final static int FILTERTYPE_NP12 = 0x31;
+    public final static int FILTERTYPE_LP24 = 0x03;
+    public final static int FILTERTYPE_HP24 = 0x13;
+
+    //
+    // 0x0 = 1st-order, 6 dB/oct
+    // 0x1 = 2nd-order, 12 dB/oct
+    // 0x2 = 3rd-order, 18 dB/oct
+    // 0x3 = 4th-order, 24 db/oct
+    //
+    // 0x00 = LP, Low Pass Filter
+    // 0x10 = HP, High Pass Filter
+    // 0x20 = BP, Band Pass Filter
+    // 0x30 = NP, Notch or Band Elimination Filter
+    //
+    private int filtertype = FILTERTYPE_LP6;
+    private float samplerate;
+    private float x1;
+    private float x2;
+    private float y1;
+    private float y2;
+    private float xx1;
+    private float xx2;
+    private float yy1;
+    private float yy2;
+    private float a0;
+    private float a1;
+    private float a2;
+    private float b1;
+    private float b2;
+    private float q;
+    private float gain = 1;
+    private float wet = 0;
+    private float last_wet = 0;
+    private float last_a0;
+    private float last_a1;
+    private float last_a2;
+    private float last_b1;
+    private float last_b2;
+    private float last_q;
+    private float last_gain;
+    private boolean last_set = false;
+    private double cutoff = 44100;
+    private double resonancedB = 0;
+    private boolean dirty = true;
+
+    public SoftFilter(float samplerate) {
+        this.samplerate = samplerate;
+        dirty = true;
+    }
+
+    public void setFrequency(double cent) {
+        if (cutoff == cent)
+            return;
+        cutoff = cent;
+        dirty = true;
+    }
+
+    public void setResonance(double db) {
+        if (resonancedB == db)
+            return;
+        resonancedB = db;
+        dirty = true;
+    }
+
+    public void reset() {
+        dirty = true;
+        last_set = false;
+        x1 = 0;
+        x2 = 0;
+        y1 = 0;
+        y2 = 0;
+        xx1 = 0;
+        xx2 = 0;
+        yy1 = 0;
+        yy2 = 0;
+        wet = 0.0f;
+        gain = 1.0f;
+        a0 = 0;
+        a1 = 0;
+        a2 = 0;
+        b1 = 0;
+        b2 = 0;
+    }
+
+    public void setFilterType(int filtertype) {
+        this.filtertype = filtertype;
+    }
+
+    public void processAudio(SoftAudioBuffer sbuffer) {
+        if (filtertype == FILTERTYPE_LP6)
+            filter1(sbuffer);
+        if (filtertype == FILTERTYPE_LP12)
+            filter2(sbuffer);
+        if (filtertype == FILTERTYPE_HP12)
+            filter2(sbuffer);
+        if (filtertype == FILTERTYPE_BP12)
+            filter2(sbuffer);
+        if (filtertype == FILTERTYPE_NP12)
+            filter2(sbuffer);
+        if (filtertype == FILTERTYPE_LP24)
+            filter4(sbuffer);
+        if (filtertype == FILTERTYPE_HP24)
+            filter4(sbuffer);
+    }
+
+    public void filter4(SoftAudioBuffer sbuffer) {
+
+        float[] buffer = sbuffer.array();
+
+        if (dirty) {
+            filter2calc();
+            dirty = false;
+        }
+        if (!last_set) {
+            last_a0 = a0;
+            last_a1 = a1;
+            last_a2 = a2;
+            last_b1 = b1;
+            last_b2 = b2;
+            last_gain = gain;
+            last_wet = wet;
+            last_set = true;
+        }
+
+        if (wet > 0 || last_wet > 0) {
+
+            int len = buffer.length;
+            float a0 = this.last_a0;
+            float a1 = this.last_a1;
+            float a2 = this.last_a2;
+            float b1 = this.last_b1;
+            float b2 = this.last_b2;
+            float gain = this.last_gain;
+            float wet = this.last_wet;
+            float a0_delta = (this.a0 - this.last_a0) / len;
+            float a1_delta = (this.a1 - this.last_a1) / len;
+            float a2_delta = (this.a2 - this.last_a2) / len;
+            float b1_delta = (this.b1 - this.last_b1) / len;
+            float b2_delta = (this.b2 - this.last_b2) / len;
+            float gain_delta = (this.gain - this.last_gain) / len;
+            float wet_delta = (this.wet - this.last_wet) / len;
+            float x1 = this.x1;
+            float x2 = this.x2;
+            float y1 = this.y1;
+            float y2 = this.y2;
+            float xx1 = this.xx1;
+            float xx2 = this.xx2;
+            float yy1 = this.yy1;
+            float yy2 = this.yy2;
+
+            if (wet_delta != 0) {
+                for (int i = 0; i < len; i++) {
+                    a0 += a0_delta;
+                    a1 += a1_delta;
+                    a2 += a2_delta;
+                    b1 += b1_delta;
+                    b2 += b2_delta;
+                    gain += gain_delta;
+                    wet += wet_delta;
+                    float x = buffer[i];
+                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
+                    float xx = (y * gain) * wet + (x) * (1 - wet);
+                    x2 = x1;
+                    x1 = x;
+                    y2 = y1;
+                    y1 = y;
+                    float yy = (a0*xx + a1*xx1 + a2*xx2 - b1*yy1 - b2*yy2);
+                    buffer[i] = (yy * gain) * wet + (xx) * (1 - wet);
+                    xx2 = xx1;
+                    xx1 = xx;
+                    yy2 = yy1;
+                    yy1 = yy;
+                }
+            } else if (a0_delta == 0 && a1_delta == 0 && a2_delta == 0
+                    && b1_delta == 0 && b2_delta == 0) {
+                for (int i = 0; i < len; i++) {
+                    float x = buffer[i];
+                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
+                    float xx = (y * gain) * wet + (x) * (1 - wet);
+                    x2 = x1;
+                    x1 = x;
+                    y2 = y1;
+                    y1 = y;
+                    float yy = (a0*xx + a1*xx1 + a2*xx2 - b1*yy1 - b2*yy2);
+                    buffer[i] = (yy * gain) * wet + (xx) * (1 - wet);
+                    xx2 = xx1;
+                    xx1 = xx;
+                    yy2 = yy1;
+                    yy1 = yy;
+                }
+            } else {
+                for (int i = 0; i < len; i++) {
+                    a0 += a0_delta;
+                    a1 += a1_delta;
+                    a2 += a2_delta;
+                    b1 += b1_delta;
+                    b2 += b2_delta;
+                    gain += gain_delta;
+                    float x = buffer[i];
+                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
+                    float xx = (y * gain) * wet + (x) * (1 - wet);
+                    x2 = x1;
+                    x1 = x;
+                    y2 = y1;
+                    y1 = y;
+                    float yy = (a0*xx + a1*xx1 + a2*xx2 - b1*yy1 - b2*yy2);
+                    buffer[i] = (yy * gain) * wet + (xx) * (1 - wet);
+                    xx2 = xx1;
+                    xx1 = xx;
+                    yy2 = yy1;
+                    yy1 = yy;
+                }
+            }
+
+            if (Math.abs(x1) < 1.0E-8)
+                x1 = 0;
+            if (Math.abs(x2) < 1.0E-8)
+                x2 = 0;
+            if (Math.abs(y1) < 1.0E-8)
+                y1 = 0;
+            if (Math.abs(y2) < 1.0E-8)
+                y2 = 0;
+            this.x1 = x1;
+            this.x2 = x2;
+            this.y1 = y1;
+            this.y2 = y2;
+            this.xx1 = xx1;
+            this.xx2 = xx2;
+            this.yy1 = yy1;
+            this.yy2 = yy2;
+        }
+
+        this.last_a0 = this.a0;
+        this.last_a1 = this.a1;
+        this.last_a2 = this.a2;
+        this.last_b1 = this.b1;
+        this.last_b2 = this.b2;
+        this.last_gain = this.gain;
+        this.last_wet = this.wet;
+
+    }
+
+    private double sinh(double x) {
+        return (Math.exp(x) - Math.exp(-x)) * 0.5;
+    }
+
+    public void filter2calc() {
+
+        double resonancedB = this.resonancedB;
+        if (resonancedB < 0)
+            resonancedB = 0;    // Negative dB are illegal.
+        if (resonancedB > 30)
+            resonancedB = 30;   // At least 22.5 dB is needed.
+        if (filtertype == FILTERTYPE_LP24 || filtertype == FILTERTYPE_HP24)
+            resonancedB *= 0.6;
+
+        if (filtertype == FILTERTYPE_BP12) {
+            wet = 1;
+            double r = (cutoff / samplerate);
+            if (r > 0.45)
+                r = 0.45;
+
+            double bandwidth = Math.PI * Math.pow(10.0, -(resonancedB / 20));
+
+            double omega = 2 * Math.PI * r;
+            double cs = Math.cos(omega);
+            double sn = Math.sin(omega);
+            double alpha = sn * sinh((Math.log(2)*bandwidth*omega) / (sn * 2));
+
+            double b0 = alpha;
+            double b1 = 0;
+            double b2 = -alpha;
+            double a0 = 1 + alpha;
+            double a1 = -2 * cs;
+            double a2 = 1 - alpha;
+
+            double cf = 1.0 / a0;
+            this.b1 = (float) (a1 * cf);
+            this.b2 = (float) (a2 * cf);
+            this.a0 = (float) (b0 * cf);
+            this.a1 = (float) (b1 * cf);
+            this.a2 = (float) (b2 * cf);
+        }
+
+        if (filtertype == FILTERTYPE_NP12) {
+            wet = 1;
+            double r = (cutoff / samplerate);
+            if (r > 0.45)
+                r = 0.45;
+
+            double bandwidth = Math.PI * Math.pow(10.0, -(resonancedB / 20));
+
+            double omega = 2 * Math.PI * r;
+            double cs = Math.cos(omega);
+            double sn = Math.sin(omega);
+            double alpha = sn * sinh((Math.log(2)*bandwidth*omega) / (sn*2));
+
+            double b0 = 1;
+            double b1 = -2 * cs;
+            double b2 = 1;
+            double a0 = 1 + alpha;
+            double a1 = -2 * cs;
+            double a2 = 1 - alpha;
+
+            double cf = 1.0 / a0;
+            this.b1 = (float)(a1 * cf);
+            this.b2 = (float)(a2 * cf);
+            this.a0 = (float)(b0 * cf);
+            this.a1 = (float)(b1 * cf);
+            this.a2 = (float)(b2 * cf);
+        }
+
+        if (filtertype == FILTERTYPE_LP12 || filtertype == FILTERTYPE_LP24) {
+            double r = (cutoff / samplerate);
+            if (r > 0.45) {
+                if (wet == 0) {
+                    if (resonancedB < 0.00001)
+                        wet = 0.0f;
+                    else
+                        wet = 1.0f;
+                }
+                r = 0.45;
+            } else
+                wet = 1.0f;
+
+            double c = 1.0 / (Math.tan(Math.PI * r));
+            double csq = c * c;
+            double resonance = Math.pow(10.0, -(resonancedB / 20));
+            double q = Math.sqrt(2.0f) * resonance;
+            double a0 = 1.0 / (1.0 + (q * c) + (csq));
+            double a1 = 2.0 * a0;
+            double a2 = a0;
+            double b1 = (2.0 * a0) * (1.0 - csq);
+            double b2 = a0 * (1.0 - (q * c) + csq);
+
+            this.a0 = (float)a0;
+            this.a1 = (float)a1;
+            this.a2 = (float)a2;
+            this.b1 = (float)b1;
+            this.b2 = (float)b2;
+
+        }
+
+        if (filtertype == FILTERTYPE_HP12 || filtertype == FILTERTYPE_HP24) {
+            double r = (cutoff / samplerate);
+            if (r > 0.45)
+                r = 0.45;
+            if (r < 0.0001)
+                r = 0.0001;
+            wet = 1.0f;
+            double c = (Math.tan(Math.PI * (r)));
+            double csq = c * c;
+            double resonance = Math.pow(10.0, -(resonancedB / 20));
+            double q = Math.sqrt(2.0f) * resonance;
+            double a0 = 1.0 / (1.0 + (q * c) + (csq));
+            double a1 = -2.0 * a0;
+            double a2 = a0;
+            double b1 = (2.0 * a0) * (csq - 1.0);
+            double b2 = a0 * (1.0 - (q * c) + csq);
+
+            this.a0 = (float)a0;
+            this.a1 = (float)a1;
+            this.a2 = (float)a2;
+            this.b1 = (float)b1;
+            this.b2 = (float)b2;
+
+        }
+
+    }
+
+    public void filter2(SoftAudioBuffer sbuffer) {
+
+        float[] buffer = sbuffer.array();
+
+        if (dirty) {
+            filter2calc();
+            dirty = false;
+        }
+        if (!last_set) {
+            last_a0 = a0;
+            last_a1 = a1;
+            last_a2 = a2;
+            last_b1 = b1;
+            last_b2 = b2;
+            last_q = q;
+            last_gain = gain;
+            last_wet = wet;
+            last_set = true;
+        }
+
+        if (wet > 0 || last_wet > 0) {
+
+            int len = buffer.length;
+            float a0 = this.last_a0;
+            float a1 = this.last_a1;
+            float a2 = this.last_a2;
+            float b1 = this.last_b1;
+            float b2 = this.last_b2;
+            float gain = this.last_gain;
+            float wet = this.last_wet;
+            float a0_delta = (this.a0 - this.last_a0) / len;
+            float a1_delta = (this.a1 - this.last_a1) / len;
+            float a2_delta = (this.a2 - this.last_a2) / len;
+            float b1_delta = (this.b1 - this.last_b1) / len;
+            float b2_delta = (this.b2 - this.last_b2) / len;
+            float gain_delta = (this.gain - this.last_gain) / len;
+            float wet_delta = (this.wet - this.last_wet) / len;
+            float x1 = this.x1;
+            float x2 = this.x2;
+            float y1 = this.y1;
+            float y2 = this.y2;
+
+            if (wet_delta != 0) {
+                for (int i = 0; i < len; i++) {
+                    a0 += a0_delta;
+                    a1 += a1_delta;
+                    a2 += a2_delta;
+                    b1 += b1_delta;
+                    b2 += b2_delta;
+                    gain += gain_delta;
+                    wet += wet_delta;
+                    float x = buffer[i];
+                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
+                    buffer[i] = (y * gain) * wet + (x) * (1 - wet);
+                    x2 = x1;
+                    x1 = x;
+                    y2 = y1;
+                    y1 = y;
+                }
+            } else if (a0_delta == 0 && a1_delta == 0 && a2_delta == 0
+                    && b1_delta == 0 && b2_delta == 0) {
+                for (int i = 0; i < len; i++) {
+                    float x = buffer[i];
+                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
+                    buffer[i] = y * gain;
+                    x2 = x1;
+                    x1 = x;
+                    y2 = y1;
+                    y1 = y;
+                }
+            } else {
+                for (int i = 0; i < len; i++) {
+                    a0 += a0_delta;
+                    a1 += a1_delta;
+                    a2 += a2_delta;
+                    b1 += b1_delta;
+                    b2 += b2_delta;
+                    gain += gain_delta;
+                    float x = buffer[i];
+                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
+                    buffer[i] = y * gain;
+                    x2 = x1;
+                    x1 = x;
+                    y2 = y1;
+                    y1 = y;
+                }
+            }
+
+            if (Math.abs(x1) < 1.0E-8)
+                x1 = 0;
+            if (Math.abs(x2) < 1.0E-8)
+                x2 = 0;
+            if (Math.abs(y1) < 1.0E-8)
+                y1 = 0;
+            if (Math.abs(y2) < 1.0E-8)
+                y2 = 0;
+            this.x1 = x1;
+            this.x2 = x2;
+            this.y1 = y1;
+            this.y2 = y2;
+        }
+
+        this.last_a0 = this.a0;
+        this.last_a1 = this.a1;
+        this.last_a2 = this.a2;
+        this.last_b1 = this.b1;
+        this.last_b2 = this.b2;
+        this.last_q = this.q;
+        this.last_gain = this.gain;
+        this.last_wet = this.wet;
+
+    }
+
+    public void filter1calc() {
+        if (cutoff < 120)
+            cutoff = 120;
+        double c = (7.0 / 6.0) * Math.PI * 2 * cutoff / samplerate;
+        if (c > 1)
+            c = 1;
+        a0 = (float)(Math.sqrt(1 - Math.cos(c)) * Math.sqrt(0.5 * Math.PI));
+        if (resonancedB < 0)
+            resonancedB = 0;
+        if (resonancedB > 20)
+            resonancedB = 20;
+        q = (float)(Math.sqrt(0.5) * Math.pow(10.0, -(resonancedB / 20)));
+        gain = (float)Math.pow(10, -((resonancedB)) / 40.0);
+        if (wet == 0.0f)
+            if (resonancedB > 0.00001 || c < 0.9999999)
+                wet = 1.0f;
+    }
+
+    public void filter1(SoftAudioBuffer sbuffer) {
+
+        float[] buffer = sbuffer.array();
+
+        if (dirty) {
+            filter1calc();
+            dirty = false;
+        }
+        if (!last_set) {
+            last_a0 = a0;
+            last_q = q;
+            last_gain = gain;
+            last_wet = wet;
+            last_set = true;
+        }
+
+        if (wet > 0 || last_wet > 0) {
+
+            int len = buffer.length;
+            float a0 = this.last_a0;
+            float q = this.last_q;
+            float gain = this.last_gain;
+            float wet = this.last_wet;
+            float a0_delta = (this.a0 - this.last_a0) / len;
+            float q_delta = (this.q - this.last_q) / len;
+            float gain_delta = (this.gain - this.last_gain) / len;
+            float wet_delta = (this.wet - this.last_wet) / len;
+            float y2 = this.y2;
+            float y1 = this.y1;
+
+            if (wet_delta != 0) {
+                for (int i = 0; i < len; i++) {
+                    a0 += a0_delta;
+                    q += q_delta;
+                    gain += gain_delta;
+                    wet += wet_delta;
+                    y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i];
+                    y2 = (1 - q * a0) * y2 + (a0) * y1;
+                    buffer[i] = y2 * gain * wet + buffer[i] * (1 - wet);
+                }
+            } else if (a0_delta == 0 && q_delta == 0) {
+                for (int i = 0; i < len; i++) {
+                    y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i];
+                    y2 = (1 - q * a0) * y2 + (a0) * y1;
+                    buffer[i] = y2 * gain;
+                }
+            } else {
+                for (int i = 0; i < len; i++) {
+                    a0 += a0_delta;
+                    q += q_delta;
+                    gain += gain_delta;
+                    y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i];
+                    y2 = (1 - q * a0) * y2 + (a0) * y1;
+                    buffer[i] = y2 * gain;
+                }
+            }
+
+            if (Math.abs(y2) < 1.0E-8)
+                y2 = 0;
+            if (Math.abs(y1) < 1.0E-8)
+                y1 = 0;
+            this.y2 = y2;
+            this.y1 = y1;
+        }
+
+        this.last_a0 = this.a0;
+        this.last_q = this.q;
+        this.last_gain = this.gain;
+        this.last_wet = this.wet;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftInstrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiChannel;
+
+/**
+ * Software synthesizer internal instrument.
+ *
+ * @author Karl Helgason
+ */
+public class SoftInstrument extends Instrument {
+
+    private SoftPerformer[] performers;
+    private ModelPerformer[] modelperformers;
+    private Object data;
+    private ModelInstrument ins;
+
+    public SoftInstrument(ModelInstrument ins) {
+        super(ins.getSoundbank(), ins.getPatch(), ins.getName(),
+                ins.getDataClass());
+        data = ins.getData();
+        this.ins = ins;
+        initPerformers(((ModelInstrument)ins).getPerformers());
+    }
+
+    public SoftInstrument(ModelInstrument ins,
+            ModelPerformer[] overrideperformers) {
+        super(ins.getSoundbank(), ins.getPatch(), ins.getName(),
+                ins.getDataClass());
+        data = ins.getData();
+        this.ins = ins;
+        initPerformers(overrideperformers);
+    }
+
+    private void initPerformers(ModelPerformer[] modelperformers) {
+        this.modelperformers = modelperformers;
+        performers = new SoftPerformer[modelperformers.length];
+        for (int i = 0; i < modelperformers.length; i++)
+            performers[i] = new SoftPerformer(modelperformers[i]);
+    }
+
+    public ModelDirector getDirector(MidiChannel channel,
+            ModelDirectedPlayer player) {
+        return ins.getDirector(modelperformers, channel, player);
+    }
+
+    public ModelInstrument getSourceInstrument() {
+        return ins;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public SoftPerformer[] getPerformers() {
+        return performers;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftJitterCorrector.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+
+/**
+ * A jitter corrector to be used with SoftAudioPusher.
+ *
+ * @author Karl Helgason
+ */
+public class SoftJitterCorrector extends AudioInputStream {
+
+    private static class JitterStream extends InputStream {
+
+        static int MAX_BUFFER_SIZE = 1048576;
+        boolean active = true;
+        Thread thread;
+        AudioInputStream stream;
+        // Cyclic buffer
+        int writepos = 0;
+        int readpos = 0;
+        byte[][] buffers;
+        Object buffers_mutex = new Object();
+
+        // Adapative Drift Statistics
+        int w_count = 1000;
+        int w_min_tol = 2;
+        int w_max_tol = 10;
+        int w = 0;
+        int w_min = -1;
+        // Current read buffer
+        int bbuffer_pos = 0;
+        int bbuffer_max = 0;
+        byte[] bbuffer = null;
+
+        public byte[] nextReadBuffer() {
+            synchronized (buffers_mutex) {
+                if (writepos > readpos) {
+                    int w_m = writepos - readpos;
+                    if (w_m < w_min)
+                        w_min = w_m;
+
+                    int buffpos = readpos;
+                    readpos++;
+                    return buffers[buffpos % buffers.length];
+                }
+                w_min = -1;
+                w = w_count - 1;
+            }
+            while (true) {
+                try {
+                    Thread.sleep(1);
+                } catch (InterruptedException e) {
+                    //e.printStackTrace();
+                    return null;
+                }
+                synchronized (buffers_mutex) {
+                    if (writepos > readpos) {
+                        w = 0;
+                        w_min = -1;
+                        w = w_count - 1;
+                        int buffpos = readpos;
+                        readpos++;
+                        return buffers[buffpos % buffers.length];
+                    }
+                }
+            }
+        }
+
+        public byte[] nextWriteBuffer() {
+            synchronized (buffers_mutex) {
+                return buffers[writepos % buffers.length];
+            }
+        }
+
+        public void commit() {
+            synchronized (buffers_mutex) {
+                writepos++;
+                if ((writepos - readpos) > buffers.length) {
+                    int newsize = (writepos - readpos) + 10;
+                    newsize = Math.max(buffers.length * 2, newsize);
+                    buffers = new byte[newsize][buffers[0].length];
+                }
+            }
+        }
+
+        public JitterStream(AudioInputStream s, int buffersize,
+                int smallbuffersize) {
+            this.w_count = 10 * (buffersize / smallbuffersize);
+            if (w_count < 100)
+                w_count = 100;
+            this.buffers
+                    = new byte[(buffersize/smallbuffersize)+10][smallbuffersize];
+            this.bbuffer_max = MAX_BUFFER_SIZE / smallbuffersize;
+            this.stream = s;
+
+
+            Runnable runnable = new Runnable() {
+
+                public void run() {
+                    AudioFormat format = stream.getFormat();
+                    int bufflen = buffers[0].length;
+                    int frames = bufflen / format.getFrameSize();
+                    long nanos = (long) (frames * 1000000000.0
+                                            / format.getSampleRate());
+                    long now = System.nanoTime();
+                    long next = now + nanos;
+                    int correction = 0;
+                    while (true) {
+                        synchronized (JitterStream.this) {
+                            if (!active)
+                                break;
+                        }
+                        int curbuffsize;
+                        synchronized (buffers) {
+                            curbuffsize = writepos - readpos;
+                            if (correction == 0) {
+                                w++;
+                                if (w_min != Integer.MAX_VALUE) {
+                                    if (w == w_count) {
+                                        correction = 0;
+                                        if (w_min < w_min_tol) {
+                                            correction = (w_min_tol + w_max_tol)
+                                                            / 2 - w_min;
+                                        }
+                                        if (w_min > w_max_tol) {
+                                            correction = (w_min_tol + w_max_tol)
+                                                            / 2 - w_min;
+                                        }
+                                        w = 0;
+                                        w_min = Integer.MAX_VALUE;
+                                    }
+                                }
+                            }
+                        }
+                        while (curbuffsize > bbuffer_max) {
+                            synchronized (buffers) {
+                                curbuffsize = writepos - readpos;
+                            }
+                            synchronized (JitterStream.this) {
+                                if (!active)
+                                    break;
+                            }
+                            try {
+                                Thread.sleep(1);
+                            } catch (InterruptedException e) {
+                                //e.printStackTrace();
+                            }
+                        }
+
+                        if (correction < 0)
+                            correction++;
+                        else {
+                            byte[] buff = nextWriteBuffer();
+                            try {
+                                int n = 0;
+                                while (n != buff.length) {
+                                    int s = stream.read(buff, n, buff.length
+                                            - n);
+                                    if (s < 0)
+                                        throw new EOFException();
+                                    if (s == 0)
+                                        Thread.yield();
+                                    n += s;
+                                }
+                            } catch (IOException e1) {
+                                //e1.printStackTrace();
+                            }
+                            commit();
+                        }
+
+                        if (correction > 0) {
+                            correction--;
+                            next = System.nanoTime() + nanos;
+                            continue;
+                        }
+                        long wait = next - System.nanoTime();
+                        if (wait > 0) {
+                            try {
+                                Thread.sleep(wait / 1000000L);
+                            } catch (InterruptedException e) {
+                                //e.printStackTrace();
+                            }
+                        }
+                        next += nanos;
+                    }
+                }
+            };
+
+            thread = new Thread(runnable);
+            thread.setPriority(Thread.MAX_PRIORITY);
+            thread.start();
+        }
+
+        public void close() throws IOException {
+            synchronized (this) {
+                active = false;
+            }
+            try {
+                thread.join();
+            } catch (InterruptedException e) {
+                //e.printStackTrace();
+            }
+            stream.close();
+        }
+
+        public int read() throws IOException {
+            byte[] b = new byte[1];
+            if (read(b) == -1)
+                return -1;
+            return b[0] & 0xFF;
+        }
+
+        public void fillBuffer() {
+            bbuffer = nextReadBuffer();
+            bbuffer_pos = 0;
+        }
+
+        public int read(byte[] b, int off, int len) {
+            if (bbuffer == null)
+                fillBuffer();
+            int bbuffer_len = bbuffer.length;
+            int offlen = off + len;
+            while (off < offlen) {
+                if (available() == 0)
+                    fillBuffer();
+                else {
+                    byte[] bbuffer = this.bbuffer;
+                    int bbuffer_pos = this.bbuffer_pos;
+                    while (off < offlen && bbuffer_pos < bbuffer_len)
+                        b[off++] = bbuffer[bbuffer_pos++];
+                    this.bbuffer_pos = bbuffer_pos;
+                }
+            }
+            return len;
+        }
+
+        public int available() {
+            return bbuffer.length - bbuffer_pos;
+        }
+    }
+
+    public SoftJitterCorrector(AudioInputStream stream, int buffersize,
+            int smallbuffersize) {
+        super(new JitterStream(stream, buffersize, smallbuffersize),
+                stream.getFormat(), stream.getFrameLength());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftLanczosResampler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Lanczos interpolation resampler.
+ *
+ * @author Karl Helgason
+ */
+public class SoftLanczosResampler extends SoftAbstractResampler {
+
+    float[][] sinc_table;
+    int sinc_table_fsize = 2000;
+    int sinc_table_size = 5;
+    int sinc_table_center = sinc_table_size / 2;
+
+    public SoftLanczosResampler() {
+        super();
+        sinc_table = new float[sinc_table_fsize][];
+        for (int i = 0; i < sinc_table_fsize; i++) {
+            sinc_table[i] = sincTable(sinc_table_size, -i
+                            / ((float) sinc_table_fsize));
+        }
+    }
+
+    // Normalized sinc function
+    public static double sinc(double x) {
+        return (x == 0.0) ? 1.0 : Math.sin(Math.PI * x) / (Math.PI * x);
+    }
+
+    // Generate sinc table
+    public static float[] sincTable(int size, float offset) {
+        int center = size / 2;
+        float[] w = new float[size];
+        for (int k = 0; k < size; k++) {
+            float x = (-center + k + offset);
+            if (x < -2 || x > 2)
+                w[k] = 0;
+            else if (x == 0)
+                w[k] = 1;
+            else {
+                w[k] = (float)(2.0 * Math.sin(Math.PI * x)
+                                * Math.sin(Math.PI * x / 2.0)
+                                / ((Math.PI * x) * (Math.PI * x)));
+            }
+        }
+        return w;
+    }
+
+    public int getPadding() // must be at least half of sinc_table_size
+    {
+        return sinc_table_size / 2 + 2;
+    }
+
+    public void interpolate(float[] in, float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+
+        if (pitchstep == 0) {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float[] sinc_table
+                        = this.sinc_table[(int) ((ix - iix) * sinc_table_fsize)];
+                int xx = iix - sinc_table_center;
+                float y = 0;
+                for (int i = 0; i < sinc_table_size; i++, xx++)
+                    y += in[xx] * sinc_table[i];
+                out[ox++] = y;
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float[] sinc_table
+                        = this.sinc_table[(int) ((ix - iix) * sinc_table_fsize)];
+                int xx = iix - sinc_table_center;
+                float y = 0;
+                for (int i = 0; i < sinc_table_size; i++, xx++)
+                    y += in[xx] * sinc_table[i];
+                out[ox++] = y;
+
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftLimiter.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A simple look-ahead volume limiter with very fast attack and fast release.
+ * This filter is used for preventing clipping.
+ *
+ * @author Karl Helgason
+ */
+public class SoftLimiter implements SoftAudioProcessor {
+
+    float lastmax = 0;
+    float gain = 1;
+    float[] temp_bufferL;
+    float[] temp_bufferR;
+    boolean mix = false;
+    SoftAudioBuffer bufferL;
+    SoftAudioBuffer bufferR;
+    SoftAudioBuffer bufferLout;
+    SoftAudioBuffer bufferRout;
+    float controlrate;
+
+    public void init(float samplerate, float controlrate) {
+        this.controlrate = controlrate;
+    }
+
+    public void setInput(int pin, SoftAudioBuffer input) {
+        if (pin == 0)
+            bufferL = input;
+        if (pin == 1)
+            bufferR = input;
+    }
+
+    public void setOutput(int pin, SoftAudioBuffer output) {
+        if (pin == 0)
+            bufferLout = output;
+        if (pin == 1)
+            bufferRout = output;
+    }
+
+    public void setMixMode(boolean mix) {
+        this.mix = mix;
+    }
+
+    public void globalParameterControlChange(int[] slothpath, long param,
+            long value) {
+    }
+
+    double silentcounter = 0;
+
+    public void processAudio() {
+        if (this.bufferL.isSilent()
+                && (this.bufferR == null || this.bufferR.isSilent())) {
+            silentcounter += 1 / controlrate;
+
+            if (silentcounter > 60) {
+                if (!mix) {
+                    bufferLout.clear();
+                    bufferRout.clear();
+                }
+                return;
+            }
+        } else
+            silentcounter = 0;
+
+        float[] bufferL = this.bufferL.array();
+        float[] bufferR = this.bufferR == null ? null : this.bufferR.array();
+        float[] bufferLout = this.bufferLout.array();
+        float[] bufferRout = this.bufferRout == null
+                                ? null : this.bufferRout.array();
+
+        if (temp_bufferL == null || temp_bufferL.length < bufferL.length)
+            temp_bufferL = new float[bufferL.length];
+        if (bufferR != null)
+            if (temp_bufferR == null || temp_bufferR.length < bufferR.length)
+                temp_bufferR = new float[bufferR.length];
+
+        float max = 0;
+        int len = bufferL.length;
+
+        if (bufferR == null) {
+            for (int i = 0; i < len; i++) {
+                if (bufferL[i] > max)
+                    max = bufferL[i];
+                if (-bufferL[i] > max)
+                    max = -bufferL[i];
+            }
+        } else {
+            for (int i = 0; i < len; i++) {
+                if (bufferL[i] > max)
+                    max = bufferL[i];
+                if (bufferR[i] > max)
+                    max = bufferR[i];
+                if (-bufferL[i] > max)
+                    max = -bufferL[i];
+                if (-bufferR[i] > max)
+                    max = -bufferR[i];
+            }
+        }
+
+        float lmax = lastmax;
+        lastmax = max;
+        if (lmax > max)
+            max = lmax;
+
+        float newgain = 1;
+        if (max > 0.99f)
+            newgain = 0.99f / max;
+        else
+            newgain = 1;
+
+        if (newgain > gain)
+            newgain = (newgain + gain * 9) / 10f;
+
+        float gaindelta = (newgain - gain) / len;
+        if (mix) {
+            if (bufferR == null) {
+                for (int i = 0; i < len; i++) {
+                    gain += gaindelta;
+                    float bL = bufferL[i];
+                    float tL = temp_bufferL[i];
+                    temp_bufferL[i] = bL;
+                    bufferLout[i] += tL * gain;
+                }
+            } else {
+                for (int i = 0; i < len; i++) {
+                    gain += gaindelta;
+                    float bL = bufferL[i];
+                    float bR = bufferR[i];
+                    float tL = temp_bufferL[i];
+                    float tR = temp_bufferR[i];
+                    temp_bufferL[i] = bL;
+                    temp_bufferR[i] = bR;
+                    bufferLout[i] += tL * gain;
+                    bufferRout[i] += tR * gain;
+                }
+            }
+
+        } else {
+            if (bufferR == null) {
+                for (int i = 0; i < len; i++) {
+                    gain += gaindelta;
+                    float bL = bufferL[i];
+                    float tL = temp_bufferL[i];
+                    temp_bufferL[i] = bL;
+                    bufferLout[i] = tL * gain;
+                }
+            } else {
+                for (int i = 0; i < len; i++) {
+                    gain += gaindelta;
+                    float bL = bufferL[i];
+                    float bR = bufferR[i];
+                    float tL = temp_bufferL[i];
+                    float tR = temp_bufferR[i];
+                    temp_bufferL[i] = bL;
+                    temp_bufferR[i] = bR;
+                    bufferLout[i] = tL * gain;
+                    bufferRout[i] = tR * gain;
+                }
+            }
+
+        }
+        gain = newgain;
+    }
+
+    public void processControlLogic() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftLinearResampler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A resampler that uses first-order (linear) interpolation.
+ *
+ * @author Karl Helgason
+ */
+public class SoftLinearResampler extends SoftAbstractResampler {
+
+    public int getPadding() {
+        return 2;
+    }
+
+    public void interpolate(float[] in, float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+        if (pitchstep == 0f) {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float fix = ix - iix;
+                float i = in[iix];
+                out[ox++] = i + (in[iix + 1] - i) * fix;
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float fix = ix - iix;
+                float i = in[iix];
+                out[ox++] = i + (in[iix + 1] - i) * fix;
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftLinearResampler2.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A resampler that uses first-order (linear) interpolation.
+ *
+ * This one doesn't perform float to int casting inside the processing loop.
+ *
+ * @author Karl Helgason
+ */
+public class SoftLinearResampler2 extends SoftAbstractResampler {
+
+    public int getPadding() {
+        return 2;
+    }
+
+    public void interpolate(float[] in, float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+
+        // Check if we have do anything
+        if (!(ix < ix_end && ox < ox_end))
+            return;
+
+        // 15 bit shift was choosed because
+        // it resulted in no drift between p_ix and ix.
+        int p_ix = (int) (ix * (1 << 15));
+        int p_ix_end = (int) (ix_end * (1 << 15));
+        int p_pitch = (int) (pitch * (1 << 15));
+        // Pitch needs to recalculated
+        // to ensure no drift between p_ix and ix.
+        pitch = p_pitch * (1f / (1 << 15));
+
+        if (pitchstep == 0f) {
+
+            // To reduce
+            //    while (p_ix < p_ix_end && ox < ox_end)
+            // into
+            //    while  (ox < ox_end)
+            // We need to calculate new ox_end value.
+            int p_ix_len = p_ix_end - p_ix;
+            int p_mod = p_ix_len % p_pitch;
+            if (p_mod != 0)
+                p_ix_len += p_pitch - p_mod;
+            int ox_end2 = ox + p_ix_len / p_pitch;
+            if (ox_end2 < ox_end)
+                ox_end = ox_end2;
+
+            while (ox < ox_end) {
+                int iix = p_ix >> 15;
+                float fix = ix - iix;
+                float i = in[iix];
+                out[ox++] = i + (in[iix + 1] - i) * fix;
+                p_ix += p_pitch;
+                ix += pitch;
+            }
+
+        } else {
+
+            int p_pitchstep = (int) (pitchstep * (1 << 15));
+            pitchstep = p_pitchstep * (1f / (1 << 15));
+
+            while (p_ix < p_ix_end && ox < ox_end) {
+                int iix = p_ix >> 15;
+                float fix = ix - iix;
+                float i = in[iix];
+                out[ox++] = i + (in[iix + 1] - i) * fix;
+                ix += pitch;
+                p_ix += p_pitch;
+                pitch += pitchstep;
+                p_pitch += p_pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftLowFrequencyOscillator.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * LFO control signal generator.
+ *
+ * @author Karl Helgason
+ */
+public class SoftLowFrequencyOscillator implements SoftProcess {
+
+    private int max_count = 10;
+    private int used_count = 0;
+    private double[][] out = new double[max_count][1];
+    private double[][] delay = new double[max_count][1];
+    private double[][] delay2 = new double[max_count][1];
+    private double[][] freq = new double[max_count][1];
+    private int[] delay_counter = new int[max_count];
+    private double[] sin_phase = new double[max_count];
+    private double[] sin_stepfreq = new double[max_count];
+    private double[] sin_step = new double[max_count];
+    private double control_time = 0;
+    private double sin_factor = 0;
+    private static double PI2 = 2.0 * Math.PI;
+
+    public void reset() {
+        for (int i = 0; i < used_count; i++) {
+            out[i][0] = 0;
+            delay[i][0] = 0;
+            delay2[i][0] = 0;
+            freq[i][0] = 0;
+            delay_counter[i] = 0;
+            sin_phase[i] = 0;
+            sin_stepfreq[i] = 0;
+            sin_step[i] = 0;
+        }
+        used_count = 0;
+    }
+
+    public void init(SoftSynthesizer synth) {
+        control_time = 1.0 / synth.getControlRate();
+        sin_factor = control_time * 2 * Math.PI;
+        for (int i = 0; i < used_count; i++) {
+            delay_counter[i] = (int)(Math.pow(2,
+                    this.delay[i][0] / 1200.0) / control_time);
+            delay_counter[i] += (int)(delay2[i][0] / (control_time * 1000));
+        }
+        processControlLogic();
+    }
+
+    public void processControlLogic() {
+        for (int i = 0; i < used_count; i++) {
+            if (delay_counter[i] > 0) {
+                delay_counter[i]--;
+                out[i][0] = 0.5;
+            } else {
+                double f = freq[i][0];
+
+                if (sin_stepfreq[i] != f) {
+                    sin_stepfreq[i] = f;
+                    double fr = 440.0 * Math.exp(
+                            (f - 6900.0) * (Math.log(2) / 1200.0));
+                    sin_step[i] = fr * sin_factor;
+                }
+                /*
+                double fr = 440.0 * Math.pow(2.0,
+                (freq[i][0] - 6900.0) / 1200.0);
+                sin_phase[i] += fr * sin_factor;
+                 */
+                /*
+                sin_phase[i] += sin_step[i];
+                while (sin_phase[i] > PI2)
+                sin_phase[i] -= PI2;
+                out[i][0] = 0.5 + Math.sin(sin_phase[i]) * 0.5;
+                 */
+                double p = sin_phase[i];
+                p += sin_step[i];
+                while (p > PI2)
+                    p -= PI2;
+                out[i][0] = 0.5 + Math.sin(p) * 0.5;
+                sin_phase[i] = p;
+
+            }
+        }
+    }
+
+    public double[] get(int instance, String name) {
+        if (instance >= used_count)
+            used_count = instance + 1;
+        if (name == null)
+            return out[instance];
+        if (name.equals("delay"))
+            return delay[instance];
+        if (name.equals("delay2"))
+            return delay2[instance];
+        if (name.equals("freq"))
+            return freq[instance];
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,982 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.Patch;
+import javax.sound.midi.ShortMessage;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * Software synthesizer main audio mixer.
+ *
+ * @author Karl Helgason
+ */
+public class SoftMainMixer {
+
+    public final static int CHANNEL_LEFT = 0;
+    public final static int CHANNEL_RIGHT = 1;
+    public final static int CHANNEL_EFFECT1 = 2;
+    public final static int CHANNEL_EFFECT2 = 3;
+    public final static int CHANNEL_EFFECT3 = 4;
+    public final static int CHANNEL_EFFECT4 = 5;
+    public final static int CHANNEL_LEFT_DRY = 10;
+    public final static int CHANNEL_RIGHT_DRY = 11;
+    public final static int CHANNEL_SCRATCH1 = 12;
+    public final static int CHANNEL_SCRATCH2 = 13;
+    public final static int CHANNEL_CHANNELMIXER_LEFT = 14;
+    public final static int CHANNEL_CHANNELMIXER_RIGHT = 15;
+    protected boolean active_sensing_on = false;
+    private long msec_last_activity = -1;
+    private boolean pusher_silent = false;
+    private int pusher_silent_count = 0;
+    private long msec_pos = 0;
+    protected boolean readfully = true;
+    private Object control_mutex;
+    private SoftSynthesizer synth;
+    private int nrofchannels = 2;
+    private SoftVoice[] voicestatus = null;
+    private SoftAudioBuffer[] buffers;
+    private SoftReverb reverb;
+    private SoftAudioProcessor chorus;
+    private SoftAudioProcessor agc;
+    private long msec_buffer_len = 0;
+    protected TreeMap<Long, Object> midimessages = new TreeMap<Long, Object>();
+    double last_volume_left = 1.0;
+    double last_volume_right = 1.0;
+    private double[] co_master_balance = new double[1];
+    private double[] co_master_volume = new double[1];
+    private double[] co_master_coarse_tuning = new double[1];
+    private double[] co_master_fine_tuning = new double[1];
+    private AudioInputStream ais;
+    private Set<ModelChannelMixer> registeredMixers = null;
+    private Set<ModelChannelMixer> stoppedMixers = null;
+    private ModelChannelMixer[] cur_registeredMixers = null;
+    protected SoftControl co_master = new SoftControl() {
+
+        double[] balance = co_master_balance;
+        double[] volume = co_master_volume;
+        double[] coarse_tuning = co_master_coarse_tuning;
+        double[] fine_tuning = co_master_fine_tuning;
+
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            if (name.equals("balance"))
+                return balance;
+            if (name.equals("volume"))
+                return volume;
+            if (name.equals("coarse_tuning"))
+                return coarse_tuning;
+            if (name.equals("fine_tuning"))
+                return fine_tuning;
+            return null;
+        }
+    };
+
+    private void processSystemExclusiveMessage(byte[] data) {
+        synchronized (synth.control_mutex) {
+            activity();
+
+            // Universal Non-Real-Time SysEx
+            if ((data[1] & 0xFF) == 0x7E) {
+                int deviceID = data[2] & 0xFF;
+                if (deviceID == 0x7F || deviceID == synth.getDeviceID()) {
+                    int subid1 = data[3] & 0xFF;
+                    int subid2;
+                    switch (subid1) {
+                    case 0x08:  // MIDI Tuning Standard
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x01:  // BULK TUNING DUMP
+                        {
+                            // http://www.midi.org/about-midi/tuning.shtml
+                            SoftTuning tuning = synth.getTuning(new Patch(0,
+                                    data[5] & 0xFF));
+                            tuning.load(data);
+                            break;
+                        }
+                        case 0x04:  // KEY-BASED TUNING DUMP
+                        case 0x05:  // SCALE/OCTAVE TUNING DUMP, 1 byte format
+                        case 0x06:  // SCALE/OCTAVE TUNING DUMP, 2 byte format
+                        case 0x07:  // SINGLE NOTE TUNING CHANGE (NON REAL-TIME)
+                                    // (BANK)
+                        {
+                            // http://www.midi.org/about-midi/tuning_extens.shtml
+                            SoftTuning tuning = synth.getTuning(new Patch(
+                                    data[5] & 0xFF, data[6] & 0xFF));
+                            tuning.load(data);
+                            break;
+                        }
+                        case 0x08:  // scale/octave tuning 1-byte form (Non
+                                    // Real-Time)
+                        case 0x09:  // scale/octave tuning 2-byte form (Non
+                                    // Real-Time)
+                        {
+                            // http://www.midi.org/about-midi/tuning-scale.shtml
+                            SoftTuning tuning = new SoftTuning(data);
+                            int channelmask = (data[5] & 0xFF) * 16384
+                                    + (data[6] & 0xFF) * 128 + (data[7] & 0xFF);
+                            SoftChannel[] channels = synth.channels;
+                            for (int i = 0; i < channels.length; i++)
+                                if ((channelmask & (1 << i)) != 0)
+                                    channels[i].tuning = tuning;
+                            break;
+                        }
+                        default:
+                            break;
+                        }
+                        break;
+                    case 0x09:  // General Midi Message
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x01:  // General Midi 1 On
+                            synth.setGeneralMidiMode(1);
+                            reset();
+                            break;
+                        case 0x02:  // General Midi Off
+                            synth.setGeneralMidiMode(0);
+                            reset();
+                            break;
+                        case 0x03:  // General MidI Level 2 On
+                            synth.setGeneralMidiMode(2);
+                            reset();
+                            break;
+                        default:
+                            break;
+                        }
+                        break;
+                    case 0x0A: // DLS Message
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x01:  // DLS On
+                            if (synth.getGeneralMidiMode() == 0)
+                                synth.setGeneralMidiMode(1);
+                            synth.voice_allocation_mode = 1;
+                            reset();
+                            break;
+                        case 0x02:  // DLS Off
+                            synth.setGeneralMidiMode(0);
+                            synth.voice_allocation_mode = 0;
+                            reset();
+                            break;
+                        case 0x03:  // DLS Static Voice Allocation Off
+                            synth.voice_allocation_mode = 0;
+                            break;
+                        case 0x04:  // DLS Static Voice Allocation On
+                            synth.voice_allocation_mode = 1;
+                            break;
+                        default:
+                            break;
+                        }
+                        break;
+
+                    default:
+                        break;
+                    }
+                }
+            }
+
+            // Universal Real-Time SysEx
+            if ((data[1] & 0xFF) == 0x7F) {
+                int deviceID = data[2] & 0xFF;
+                if (deviceID == 0x7F || deviceID == synth.getDeviceID()) {
+                    int subid1 = data[3] & 0xFF;
+                    int subid2;
+                    switch (subid1) {
+                    case 0x04: // Device Control
+
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x01: // Master Volume
+                        case 0x02: // Master Balane
+                        case 0x03: // Master fine tuning
+                        case 0x04: // Master coarse tuning
+                            int val = (data[5] & 0x7F)
+                                    + ((data[6] & 0x7F) * 128);
+                            if (subid2 == 0x01)
+                                setVolume(val);
+                            else if (subid2 == 0x02)
+                                setBalance(val);
+                            else if (subid2 == 0x03)
+                                setFineTuning(val);
+                            else if (subid2 == 0x04)
+                                setCoarseTuning(val);
+                            break;
+                        case 0x05: // Global Parameter Control
+                            int ix = 5;
+                            int slotPathLen = (data[ix++] & 0xFF);
+                            int paramWidth = (data[ix++] & 0xFF);
+                            int valueWidth = (data[ix++] & 0xFF);
+                            int[] slotPath = new int[slotPathLen];
+                            for (int i = 0; i < slotPathLen; i++) {
+                                int msb = (data[ix++] & 0xFF);
+                                int lsb = (data[ix++] & 0xFF);
+                                slotPath[i] = msb * 128 + lsb;
+                            }
+                            int paramCount = (data.length - 1 - ix)
+                                    / (paramWidth + valueWidth);
+                            long[] params = new long[paramCount];
+                            long[] values = new long[paramCount];
+                            for (int i = 0; i < paramCount; i++) {
+                                values[i] = 0;
+                                for (int j = 0; j < paramWidth; j++)
+                                    params[i] = params[i] * 128
+                                            + (data[ix++] & 0xFF);
+                                for (int j = 0; j < valueWidth; j++)
+                                    values[i] = values[i] * 128
+                                            + (data[ix++] & 0xFF);
+
+                            }
+                            globalParameterControlChange(slotPath, params, values);
+                            break;
+                        default:
+                            break;
+                        }
+                        break;
+
+                    case 0x08:  // MIDI Tuning Standard
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x02:  // SINGLE NOTE TUNING CHANGE (REAL-TIME)
+                        {
+                            // http://www.midi.org/about-midi/tuning.shtml
+                            SoftTuning tuning = synth.getTuning(new Patch(0,
+                                    data[5] & 0xFF));
+                            tuning.load(data);
+                            SoftVoice[] voices = synth.getVoices();
+                            for (int i = 0; i < voices.length; i++)
+                                if (voices[i].active)
+                                    if (voices[i].tuning == tuning)
+                                        voices[i].updateTuning(tuning);
+                            break;
+                        }
+                        case 0x07:  // SINGLE NOTE TUNING CHANGE (REAL-TIME)
+                                    // (BANK)
+                        {
+                            // http://www.midi.org/about-midi/tuning_extens.shtml
+                            SoftTuning tuning = synth.getTuning(new Patch(
+                                    data[5] & 0xFF, data[6] & 0xFF));
+                            tuning.load(data);
+                            SoftVoice[] voices = synth.getVoices();
+                            for (int i = 0; i < voices.length; i++)
+                                if (voices[i].active)
+                                    if (voices[i].tuning == tuning)
+                                        voices[i].updateTuning(tuning);
+                            break;
+                        }
+                        case 0x08:  // scale/octave tuning 1-byte form
+                                    //(Real-Time)
+                        case 0x09:  // scale/octave tuning 2-byte form
+                                    // (Real-Time)
+                        {
+                            // http://www.midi.org/about-midi/tuning-scale.shtml
+                            SoftTuning tuning = new SoftTuning(data);
+                            int channelmask = (data[5] & 0xFF) * 16384
+                                    + (data[6] & 0xFF) * 128 + (data[7] & 0xFF);
+                            SoftChannel[] channels = synth.channels;
+                            for (int i = 0; i < channels.length; i++)
+                                if ((channelmask & (1 << i)) != 0)
+                                    channels[i].tuning = tuning;
+                            SoftVoice[] voices = synth.getVoices();
+                            for (int i = 0; i < voices.length; i++)
+                                if (voices[i].active)
+                                    if ((channelmask & (1 << (voices[i].channel))) != 0)
+                                        voices[i].updateTuning(tuning);
+                            break;
+                        }
+                        default:
+                            break;
+                        }
+                        break;
+                    case 0x09:  // Control Destination Settings
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x01: // Channel Pressure
+                        {
+                            int[] destinations = new int[(data.length - 7) / 2];
+                            int[] ranges = new int[(data.length - 7) / 2];
+                            int ix = 0;
+                            for (int j = 6; j < data.length - 1; j += 2) {
+                                destinations[ix] = data[j] & 0xFF;
+                                ranges[ix] = data[j + 1] & 0xFF;
+                                ix++;
+                            }
+                            int channel = data[5] & 0xFF;
+                            SoftChannel softchannel = synth.channels[channel];
+                            softchannel.mapChannelPressureToDestination(
+                                    destinations, ranges);
+                            break;
+                        }
+                        case 0x02: // Poly Pressure
+                        {
+                            int[] destinations = new int[(data.length - 7) / 2];
+                            int[] ranges = new int[(data.length - 7) / 2];
+                            int ix = 0;
+                            for (int j = 6; j < data.length - 1; j += 2) {
+                                destinations[ix] = data[j] & 0xFF;
+                                ranges[ix] = data[j + 1] & 0xFF;
+                                ix++;
+                            }
+                            int channel = data[5] & 0xFF;
+                            SoftChannel softchannel = synth.channels[channel];
+                            softchannel.mapPolyPressureToDestination(
+                                    destinations, ranges);
+                            break;
+                        }
+                        case 0x03: // Control Change
+                        {
+                            int[] destinations = new int[(data.length - 7) / 2];
+                            int[] ranges = new int[(data.length - 7) / 2];
+                            int ix = 0;
+                            for (int j = 7; j < data.length - 1; j += 2) {
+                                destinations[ix] = data[j] & 0xFF;
+                                ranges[ix] = data[j + 1] & 0xFF;
+                                ix++;
+                            }
+                            int channel = data[5] & 0xFF;
+                            SoftChannel softchannel = synth.channels[channel];
+                            int control = data[6] & 0xFF;
+                            softchannel.mapControlToDestination(control,
+                                    destinations, ranges);
+                            break;
+                        }
+                        default:
+                            break;
+                        }
+                        break;
+
+                    case 0x0A:  // Key Based Instrument Control
+                    {
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x01: // Basic Message
+                            int channel = data[5] & 0xFF;
+                            int keynumber = data[6] & 0xFF;
+                            SoftChannel softchannel = synth.channels[channel];
+                            for (int j = 7; j < data.length - 1; j += 2) {
+                                int controlnumber = data[j] & 0xFF;
+                                int controlvalue = data[j + 1] & 0xFF;
+                                softchannel.controlChangePerNote(keynumber,
+                                        controlnumber, controlvalue);
+                            }
+                            break;
+                        default:
+                            break;
+                        }
+                        break;
+                    }
+                    default:
+                        break;
+                    }
+                }
+            }
+
+        }
+    }
+
+    private void processMessages(long timeStamp) {
+        Iterator<Entry<Long, Object>> iter = midimessages.entrySet().iterator();
+        while (iter.hasNext()) {
+            Entry<Long, Object> entry = iter.next();
+            if (entry.getKey() > (timeStamp + 100))
+                return;
+            processMessage(entry.getValue());
+            iter.remove();
+        }
+    }
+
+    protected void processAudioBuffers() {
+        for (int i = 0; i < buffers.length; i++) {
+            buffers[i].clear();
+        }
+
+        double volume_left;
+        double volume_right;
+
+        ModelChannelMixer[] act_registeredMixers;
+
+        // perform control logic
+        synchronized (control_mutex) {
+
+            processMessages(msec_pos);
+
+            if (active_sensing_on) {
+                // Active Sensing
+                // if no message occurs for max 1000 ms
+                // then do AllSoundOff on all channels
+                if ((msec_pos - msec_last_activity) > 1000000) {
+                    active_sensing_on = false;
+                    for (SoftChannel c : synth.channels)
+                        c.allSoundOff();
+                }
+
+            }
+
+            for (int i = 0; i < voicestatus.length; i++)
+                if (voicestatus[i].active)
+                    voicestatus[i].processControlLogic();
+            msec_pos += msec_buffer_len;
+
+            double volume = co_master_volume[0];
+            volume_left = volume;
+            volume_right = volume;
+
+            double balance = co_master_balance[0];
+            if (balance > 0.5)
+                volume_left *= (1 - balance) * 2;
+            else
+                volume_right *= balance * 2;
+
+            chorus.processControlLogic();
+            reverb.processControlLogic();
+            agc.processControlLogic();
+
+            if (cur_registeredMixers == null) {
+                if (registeredMixers != null) {
+                    cur_registeredMixers =
+                            new ModelChannelMixer[registeredMixers.size()];
+                    registeredMixers.toArray(cur_registeredMixers);
+                }
+            }
+
+            act_registeredMixers = cur_registeredMixers;
+            if (act_registeredMixers != null)
+                if (act_registeredMixers.length == 0)
+                    act_registeredMixers = null;
+
+        }
+
+        if (act_registeredMixers != null) {
+
+            // Reroute default left,right output
+            // to channelmixer left,right input/output
+            SoftAudioBuffer leftbak = buffers[CHANNEL_LEFT];
+            SoftAudioBuffer rightbak = buffers[CHANNEL_RIGHT];
+            buffers[CHANNEL_LEFT] = buffers[CHANNEL_CHANNELMIXER_LEFT];
+            buffers[CHANNEL_RIGHT] = buffers[CHANNEL_CHANNELMIXER_LEFT];
+
+            int bufferlen = buffers[CHANNEL_LEFT].getSize();
+
+            float[][] cbuffer = new float[nrofchannels][];
+            cbuffer[0] = buffers[CHANNEL_LEFT].array();
+            if (nrofchannels != 1)
+                cbuffer[1] = buffers[CHANNEL_RIGHT].array();
+
+            float[][] obuffer = new float[nrofchannels][];
+            obuffer[0] = leftbak.array();
+            if (nrofchannels != 1)
+                obuffer[1] = rightbak.array();
+
+            for (ModelChannelMixer cmixer : act_registeredMixers) {
+                for (int i = 0; i < cbuffer.length; i++)
+                    Arrays.fill(cbuffer[i], 0);
+                boolean hasactivevoices = false;
+                for (int i = 0; i < voicestatus.length; i++)
+                    if (voicestatus[i].active)
+                        if (voicestatus[i].channelmixer == cmixer) {
+                            voicestatus[i].processAudioLogic(buffers);
+                            hasactivevoices = true;
+                        }
+                if (!cmixer.process(cbuffer, 0, bufferlen)) {
+                    synchronized (control_mutex) {
+                        registeredMixers.remove(cmixer);
+                        cur_registeredMixers = null;
+                    }
+                }
+
+                for (int i = 0; i < cbuffer.length; i++) {
+                    float[] cbuff = cbuffer[i];
+                    float[] obuff = obuffer[i];
+                    for (int j = 0; j < bufferlen; j++)
+                        obuff[j] += cbuff[j];
+                }
+
+                if (!hasactivevoices) {
+                    synchronized (control_mutex) {
+                        if (stoppedMixers != null) {
+                            if (stoppedMixers.contains(cmixer)) {
+                                stoppedMixers.remove(cmixer);
+                                cmixer.stop();
+                            }
+                        }
+                    }
+                }
+
+            }
+
+            buffers[CHANNEL_LEFT] = leftbak;
+            buffers[CHANNEL_RIGHT] = rightbak;
+
+        }
+
+        for (int i = 0; i < voicestatus.length; i++)
+            if (voicestatus[i].active)
+                if (voicestatus[i].channelmixer == null)
+                    voicestatus[i].processAudioLogic(buffers);
+
+        // Run effects
+        if (synth.chorus_on)
+            chorus.processAudio();
+
+        if (synth.reverb_on)
+            reverb.processAudio();
+
+        if (nrofchannels == 1)
+            volume_left = (volume_left + volume_right) / 2;
+
+        // Set Volume / Balance
+        if (last_volume_left != volume_left || last_volume_right != volume_right) {
+            float[] left = buffers[CHANNEL_LEFT].array();
+            float[] right = buffers[CHANNEL_RIGHT].array();
+            int bufferlen = buffers[CHANNEL_LEFT].getSize();
+
+            float amp;
+            float amp_delta;
+            amp = (float)(last_volume_left * last_volume_left);
+            amp_delta = (float)((volume_left * volume_left - amp) / bufferlen);
+            for (int i = 0; i < bufferlen; i++) {
+                amp += amp_delta;
+                left[i] *= amp;
+            }
+            if (nrofchannels != 1) {
+                amp = (float)(last_volume_right * last_volume_right);
+                amp_delta = (float)((volume_right*volume_right - amp) / bufferlen);
+                for (int i = 0; i < bufferlen; i++) {
+                    amp += amp_delta;
+                    right[i] *= volume_right;
+                }
+            }
+            last_volume_left = volume_left;
+            last_volume_right = volume_right;
+
+        } else {
+            if (volume_left != 1.0 || volume_right != 1.0) {
+                float[] left = buffers[CHANNEL_LEFT].array();
+                float[] right = buffers[CHANNEL_RIGHT].array();
+                int bufferlen = buffers[CHANNEL_LEFT].getSize();
+                float amp;
+                amp = (float) (volume_left * volume_left);
+                for (int i = 0; i < bufferlen; i++)
+                    left[i] *= amp;
+                if (nrofchannels != 1) {
+                    amp = (float)(volume_right * volume_right);
+                    for (int i = 0; i < bufferlen; i++)
+                        right[i] *= amp;
+                }
+
+            }
+        }
+
+        if(buffers[CHANNEL_LEFT].isSilent()
+            && buffers[CHANNEL_RIGHT].isSilent())
+        {
+            pusher_silent_count++;
+            if(pusher_silent_count > 5)
+            {
+                pusher_silent_count = 0;
+                synchronized (control_mutex) {
+                    pusher_silent = true;
+                    if(synth.weakstream != null)
+                        synth.weakstream.setInputStream(null);
+                }
+            }
+        }
+        else
+            pusher_silent_count = 0;
+
+        if (synth.agc_on)
+            agc.processAudio();
+
+    }
+
+    // Must only we called within control_mutex synchronization
+    public void activity()
+    {
+        msec_last_activity = msec_pos;
+        if(pusher_silent)
+        {
+            pusher_silent = false;
+            if(synth.weakstream != null)
+                synth.weakstream.setInputStream(ais);
+        }
+    }
+
+    public void stopMixer(ModelChannelMixer mixer) {
+        if (stoppedMixers == null)
+            stoppedMixers = new HashSet<ModelChannelMixer>();
+        stoppedMixers.add(mixer);
+    }
+
+    public void registerMixer(ModelChannelMixer mixer) {
+        if (registeredMixers == null)
+            registeredMixers = new HashSet<ModelChannelMixer>();
+        registeredMixers.add(mixer);
+        cur_registeredMixers = null;
+    }
+
+    public SoftMainMixer(SoftSynthesizer synth) {
+        this.synth = synth;
+
+        msec_pos = 0;
+
+        co_master_balance[0] = 0.5;
+        co_master_volume[0] = 1;
+        co_master_coarse_tuning[0] = 0.5;
+        co_master_fine_tuning[0] = 0.5;
+
+        msec_buffer_len = (long) (1000000.0 / synth.getControlRate());
+
+        nrofchannels = synth.getFormat().getChannels();
+
+        int buffersize = (int) (synth.getFormat().getSampleRate()
+                                / synth.getControlRate());
+
+        control_mutex = synth.control_mutex;
+        buffers = new SoftAudioBuffer[16];
+        for (int i = 0; i < buffers.length; i++) {
+            buffers[i] = new SoftAudioBuffer(buffersize, synth.getFormat());
+        }
+        voicestatus = synth.getVoices();
+
+        reverb = new SoftReverb();
+        chorus = new SoftChorus();
+        agc = new SoftLimiter();
+
+        float samplerate = synth.getFormat().getSampleRate();
+        float controlrate = synth.getControlRate();
+        reverb.init(samplerate, controlrate);
+        chorus.init(samplerate, controlrate);
+        agc.init(samplerate, controlrate);
+
+        reverb.setLightMode(synth.reverb_light);
+
+        reverb.setMixMode(true);
+        chorus.setMixMode(true);
+        agc.setMixMode(false);
+
+        chorus.setInput(0, buffers[CHANNEL_EFFECT2]);
+        chorus.setOutput(0, buffers[CHANNEL_LEFT]);
+        if (nrofchannels != 1)
+            chorus.setOutput(1, buffers[CHANNEL_RIGHT]);
+        chorus.setOutput(2, buffers[CHANNEL_EFFECT1]);
+
+        reverb.setInput(0, buffers[CHANNEL_EFFECT1]);
+        reverb.setOutput(0, buffers[CHANNEL_LEFT]);
+        if (nrofchannels != 1)
+            reverb.setOutput(1, buffers[CHANNEL_RIGHT]);
+
+        agc.setInput(0, buffers[CHANNEL_LEFT]);
+        if (nrofchannels != 1)
+            agc.setInput(1, buffers[CHANNEL_RIGHT]);
+        agc.setOutput(0, buffers[CHANNEL_LEFT]);
+        if (nrofchannels != 1)
+            agc.setOutput(1, buffers[CHANNEL_RIGHT]);
+
+        InputStream in = new InputStream() {
+
+            private SoftAudioBuffer[] buffers = SoftMainMixer.this.buffers;
+            private int nrofchannels
+                    = SoftMainMixer.this.synth.getFormat().getChannels();
+            private int buffersize = buffers[0].getSize();
+            private byte[] bbuffer = new byte[buffersize
+                    * (SoftMainMixer.this.synth.getFormat()
+                        .getSampleSizeInBits() / 8)
+                    * nrofchannels];
+            private int bbuffer_pos = 0;
+            private byte[] single = new byte[1];
+
+            public void fillBuffer() {
+                /*
+                boolean pusher_silent2;
+                synchronized (control_mutex) {
+                    pusher_silent2 = pusher_silent;
+                }
+                if(!pusher_silent2)*/
+                processAudioBuffers();
+                for (int i = 0; i < nrofchannels; i++)
+                    buffers[i].get(bbuffer, i);
+                bbuffer_pos = 0;
+            }
+
+            public int read(byte[] b, int off, int len) {
+                int bbuffer_len = bbuffer.length;
+                int offlen = off + len;
+                int orgoff = off;
+                byte[] bbuffer = this.bbuffer;
+                while (off < offlen) {
+                    if (available() == 0)
+                        fillBuffer();
+                    else {
+                        int bbuffer_pos = this.bbuffer_pos;
+                        while (off < offlen && bbuffer_pos < bbuffer_len)
+                            b[off++] = bbuffer[bbuffer_pos++];
+                        this.bbuffer_pos = bbuffer_pos;
+                        if (!readfully)
+                            return off - orgoff;
+                    }
+                }
+                return len;
+            }
+
+            public int read() throws IOException {
+                int ret = read(single);
+                if (ret == -1)
+                    return -1;
+                return single[0] & 0xFF;
+            }
+
+            public int available() {
+                return bbuffer.length - bbuffer_pos;
+            }
+
+            public void close() {
+                SoftMainMixer.this.synth.close();
+            }
+        };
+
+        ais = new AudioInputStream(in, synth.getFormat(), AudioSystem.NOT_SPECIFIED);
+
+    }
+
+    public AudioInputStream getInputStream() {
+        return ais;
+    }
+
+    public void reset() {
+
+        SoftChannel[] channels = synth.channels;
+        for (int i = 0; i < channels.length; i++) {
+            channels[i].allSoundOff();
+            channels[i].resetAllControllers(true);
+
+            if (synth.getGeneralMidiMode() == 2) {
+                if (i == 9)
+                    channels[i].programChange(0, 0x78 * 128);
+                else
+                    channels[i].programChange(0, 0x79 * 128);
+            } else
+                channels[i].programChange(0, 0);
+        }
+        setVolume(0x7F * 128 + 0x7F);
+        setBalance(0x40 * 128 + 0x00);
+        setCoarseTuning(0x40 * 128 + 0x00);
+        setFineTuning(0x40 * 128 + 0x00);
+        // Reset Reverb
+        globalParameterControlChange(
+                new int[]{0x01 * 128 + 0x01}, new long[]{0}, new long[]{4});
+        // Reset Chorus
+        globalParameterControlChange(
+                new int[]{0x01 * 128 + 0x02}, new long[]{0}, new long[]{2});
+    }
+
+    public void setVolume(int value) {
+        synchronized (control_mutex) {
+            co_master_volume[0] = value / 16384.0;
+        }
+    }
+
+    public void setBalance(int value) {
+        synchronized (control_mutex) {
+            co_master_balance[0] = value / 16384.0;
+        }
+    }
+
+    public void setFineTuning(int value) {
+        synchronized (control_mutex) {
+            co_master_fine_tuning[0] = value / 16384.0;
+        }
+    }
+
+    public void setCoarseTuning(int value) {
+        synchronized (control_mutex) {
+            co_master_coarse_tuning[0] = value / 16384.0;
+        }
+    }
+
+    public int getVolume() {
+        synchronized (control_mutex) {
+            return (int) (co_master_volume[0] * 16384.0);
+        }
+    }
+
+    public int getBalance() {
+        synchronized (control_mutex) {
+            return (int) (co_master_balance[0] * 16384.0);
+        }
+    }
+
+    public int getFineTuning() {
+        synchronized (control_mutex) {
+            return (int) (co_master_fine_tuning[0] * 16384.0);
+        }
+    }
+
+    public int getCoarseTuning() {
+        synchronized (control_mutex) {
+            return (int) (co_master_coarse_tuning[0] * 16384.0);
+        }
+    }
+
+    public void globalParameterControlChange(int[] slothpath, long[] params,
+            long[] paramsvalue) {
+        if (slothpath.length == 0)
+            return;
+
+        synchronized (control_mutex) {
+
+            // slothpath: 01xx are reserved only for GM2
+
+            if (slothpath[0] == 0x01 * 128 + 0x01) {
+                for (int i = 0; i < paramsvalue.length; i++) {
+                    reverb.globalParameterControlChange(slothpath, params[i],
+                            paramsvalue[i]);
+                }
+            }
+            if (slothpath[0] == 0x01 * 128 + 0x02) {
+                for (int i = 0; i < paramsvalue.length; i++) {
+                    chorus.globalParameterControlChange(slothpath, params[i],
+                            paramsvalue[i]);
+                }
+
+            }
+
+        }
+    }
+
+    public void processMessage(Object object) {
+        if (object instanceof byte[])
+            processMessage((byte[]) object);
+        if (object instanceof MidiMessage)
+            processMessage((MidiMessage)object);
+    }
+
+    public void processMessage(MidiMessage message) {
+        if (message instanceof ShortMessage) {
+            ShortMessage sms = (ShortMessage)message;
+            processMessage(sms.getChannel(), sms.getCommand(),
+                    sms.getData1(), sms.getData2());
+            return;
+        }
+        processMessage(message.getMessage());
+    }
+
+    public void processMessage(byte[] data) {
+        int status = 0;
+        if (data.length > 0)
+            status = data[0] & 0xFF;
+
+        if (status == 0xF0) {
+            processSystemExclusiveMessage(data);
+            return;
+        }
+
+        int cmd = (status & 0xF0);
+        int ch = (status & 0x0F);
+
+        int data1;
+        int data2;
+        if (data.length > 1)
+            data1 = data[1] & 0xFF;
+        else
+            data1 = 0;
+        if (data.length > 2)
+            data2 = data[2] & 0xFF;
+        else
+            data2 = 0;
+
+        processMessage(ch, cmd, data1, data2);
+
+    }
+
+    public void processMessage(int ch, int cmd, int data1, int data2) {
+        synchronized (synth.control_mutex) {
+            activity();
+        }
+
+        if (cmd == 0xF0) {
+            int status = cmd | ch;
+            switch (status) {
+            case ShortMessage.ACTIVE_SENSING:
+                synchronized (synth.control_mutex) {
+                    active_sensing_on = true;
+                }
+                break;
+            default:
+                break;
+            }
+            return;
+        }
+
+        SoftChannel[] channels = synth.channels;
+        if (ch >= channels.length)
+            return;
+        SoftChannel softchannel = channels[ch];
+
+        switch (cmd) {
+        case ShortMessage.NOTE_ON:
+            softchannel.noteOn(data1, data2);
+            break;
+        case ShortMessage.NOTE_OFF:
+            softchannel.noteOff(data1, data2);
+            break;
+        case ShortMessage.POLY_PRESSURE:
+            softchannel.setPolyPressure(data1, data2);
+            break;
+        case ShortMessage.CONTROL_CHANGE:
+            softchannel.controlChange(data1, data2);
+            break;
+        case ShortMessage.PROGRAM_CHANGE:
+            softchannel.programChange(data1);
+            break;
+        case ShortMessage.CHANNEL_PRESSURE:
+            softchannel.setChannelPressure(data1);
+            break;
+        case ShortMessage.PITCH_BEND:
+            softchannel.setPitchBend(data1 + data2 * 128);
+            break;
+        default:
+            break;
+        }
+
+    }
+
+    public long getMicrosecondPosition() {
+        return msec_pos;
+    }
+
+    public void close() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftMidiAudioFileReader.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Track;
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import javax.sound.sampled.AudioFileFormat.Type;
+import javax.sound.sampled.spi.AudioFileReader;
+
+/**
+ * MIDI File Audio Renderer/Reader
+ *
+ * @author Karl Helgason
+ */
+public class SoftMidiAudioFileReader extends AudioFileReader {
+
+    public static final Type MIDI = new Type("MIDI", "mid");
+    private static AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+
+    public AudioFileFormat getAudioFileFormat(Sequence seq)
+            throws UnsupportedAudioFileException, IOException {
+
+        long totallen = seq.getMicrosecondLength() / 1000000;
+        long len = (long) (format.getFrameRate() * (totallen + 4));
+        return new AudioFileFormat(MIDI, format, (int) len);
+    }
+
+    public AudioInputStream getAudioInputStream(Sequence seq)
+            throws UnsupportedAudioFileException, IOException {
+        AudioSynthesizer synth = (AudioSynthesizer) new SoftSynthesizer();
+        AudioInputStream stream;
+        Receiver recv;
+        try {
+            stream = synth.openStream(format, null);
+            recv = synth.getReceiver();
+        } catch (MidiUnavailableException e) {
+            throw new IOException(e.toString());
+        }
+        float divtype = seq.getDivisionType();
+        Track[] tracks = seq.getTracks();
+        int[] trackspos = new int[tracks.length];
+        int mpq = 500000;
+        int seqres = seq.getResolution();
+        long lasttick = 0;
+        long curtime = 0;
+        while (true) {
+            MidiEvent selevent = null;
+            int seltrack = -1;
+            for (int i = 0; i < tracks.length; i++) {
+                int trackpos = trackspos[i];
+                Track track = tracks[i];
+                if (trackpos < track.size()) {
+                    MidiEvent event = track.get(trackpos);
+                    if (selevent == null || event.getTick() < selevent.getTick()) {
+                        selevent = event;
+                        seltrack = i;
+                    }
+                }
+            }
+            if (seltrack == -1)
+                break;
+            trackspos[seltrack]++;
+            long tick = selevent.getTick();
+            if (divtype == Sequence.PPQ)
+                curtime += ((tick - lasttick) * mpq) / seqres;
+            else
+                curtime = (long) ((tick * 1000000.0 * divtype) / seqres);
+            lasttick = tick;
+            MidiMessage msg = selevent.getMessage();
+            if (msg instanceof MetaMessage) {
+                if (divtype == Sequence.PPQ) {
+                    if (((MetaMessage) msg).getType() == 0x51) {
+                        byte[] data = ((MetaMessage) msg).getData();
+                        mpq = ((data[0] & 0xff) << 16)
+                                | ((data[1] & 0xff) << 8) | (data[2] & 0xff);
+                    }
+                }
+            } else {
+                recv.send(msg, curtime);
+            }
+        }
+
+        long totallen = curtime / 1000000;
+        long len = (long) (stream.getFormat().getFrameRate() * (totallen + 4));
+        stream = new AudioInputStream(stream, stream.getFormat(), len);
+        return stream;
+    }
+
+    public AudioInputStream getAudioInputStream(InputStream inputstream)
+            throws UnsupportedAudioFileException, IOException {
+
+        inputstream.mark(200);
+        Sequence seq;
+        try {
+            seq = MidiSystem.getSequence(inputstream);
+        } catch (InvalidMidiDataException e) {
+            inputstream.reset();
+            throw new UnsupportedAudioFileException();
+        } catch (IOException e) {
+            inputstream.reset();
+            throw new UnsupportedAudioFileException();
+        }
+        return getAudioInputStream(seq);
+    }
+
+    public AudioFileFormat getAudioFileFormat(URL url)
+            throws UnsupportedAudioFileException, IOException {
+        Sequence seq;
+        try {
+            seq = MidiSystem.getSequence(url);
+        } catch (InvalidMidiDataException e) {
+            throw new UnsupportedAudioFileException();
+        } catch (IOException e) {
+            throw new UnsupportedAudioFileException();
+        }
+        return getAudioFileFormat(seq);
+    }
+
+    public AudioFileFormat getAudioFileFormat(File file)
+            throws UnsupportedAudioFileException, IOException {
+        Sequence seq;
+        try {
+            seq = MidiSystem.getSequence(file);
+        } catch (InvalidMidiDataException e) {
+            throw new UnsupportedAudioFileException();
+        } catch (IOException e) {
+            throw new UnsupportedAudioFileException();
+        }
+        return getAudioFileFormat(seq);
+    }
+
+    public AudioInputStream getAudioInputStream(URL url)
+            throws UnsupportedAudioFileException, IOException {
+        Sequence seq;
+        try {
+            seq = MidiSystem.getSequence(url);
+        } catch (InvalidMidiDataException e) {
+            throw new UnsupportedAudioFileException();
+        } catch (IOException e) {
+            throw new UnsupportedAudioFileException();
+        }
+        return getAudioInputStream(seq);
+    }
+
+    public AudioInputStream getAudioInputStream(File file)
+            throws UnsupportedAudioFileException, IOException {
+        if (!file.getName().toLowerCase().endsWith(".mid"))
+            throw new UnsupportedAudioFileException();
+        Sequence seq;
+        try {
+            seq = MidiSystem.getSequence(file);
+        } catch (InvalidMidiDataException e) {
+            throw new UnsupportedAudioFileException();
+        } catch (IOException e) {
+            throw new UnsupportedAudioFileException();
+        }
+        return getAudioInputStream(seq);
+    }
+
+    public AudioFileFormat getAudioFileFormat(InputStream inputstream)
+            throws UnsupportedAudioFileException, IOException {
+
+        inputstream.mark(200);
+        Sequence seq;
+        try {
+            seq = MidiSystem.getSequence(inputstream);
+        } catch (InvalidMidiDataException e) {
+            inputstream.reset();
+            throw new UnsupportedAudioFileException();
+        } catch (IOException e) {
+            inputstream.reset();
+            throw new UnsupportedAudioFileException();
+        }
+        return getAudioFileFormat(seq);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftMixingClip.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,539 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+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.LineUnavailableException;
+
+/**
+ * Clip implemention for the SoftMixingMixer.
+ *
+ * @author Karl Helgason
+ */
+public class SoftMixingClip extends SoftMixingDataLine implements Clip {
+
+    private AudioFormat format;
+
+    private int framesize;
+
+    private byte[] data;
+
+    private InputStream datastream = new InputStream() {
+
+        public int read() throws IOException {
+            byte[] b = new byte[1];
+            int ret = read(b);
+            if (ret < 0)
+                return ret;
+            return b[0] & 0xFF;
+        }
+
+        public int read(byte[] b, int off, int len) throws IOException {
+
+            if (_loopcount != 0) {
+                int bloopend = _loopend * framesize;
+                int bloopstart = _loopstart * framesize;
+                int pos = _frameposition * framesize;
+
+                if (pos + len >= bloopend)
+                    if (pos < bloopend) {
+                        int offend = off + len;
+                        int o = off;
+                        while (off != offend) {
+                            if (pos == bloopend) {
+                                if (_loopcount == 0)
+                                    break;
+                                pos = bloopstart;
+                                if (_loopcount != LOOP_CONTINUOUSLY)
+                                    _loopcount--;
+                            }
+                            len = offend - off;
+                            int left = bloopend - pos;
+                            if (len > left)
+                                len = left;
+                            System.arraycopy(data, pos, b, off, len);
+                            off += len;
+                        }
+                        if (_loopcount == 0) {
+                            len = offend - off;
+                            int left = bloopend - pos;
+                            if (len > left)
+                                len = left;
+                            System.arraycopy(data, pos, b, off, len);
+                            off += len;
+                        }
+                        _frameposition = pos / framesize;
+                        return o - off;
+                    }
+            }
+
+            int pos = _frameposition * framesize;
+            int left = bufferSize - pos;
+            if (left == 0)
+                return -1;
+            if (len > left)
+                len = left;
+            System.arraycopy(data, pos, b, off, len);
+            _frameposition += len / framesize;
+            return len;
+        }
+
+    };
+
+    private int offset;
+
+    private int bufferSize;
+
+    private float[] readbuffer;
+
+    private boolean open = false;
+
+    private AudioFormat outputformat;
+
+    private int out_nrofchannels;
+
+    private int in_nrofchannels;
+
+    private int frameposition = 0;
+
+    private boolean frameposition_sg = false;
+
+    private boolean active_sg = false;
+
+    private int loopstart = 0;
+
+    private int loopend = -1;
+
+    private boolean active = false;
+
+    private int loopcount = 0;
+
+    private boolean _active = false;
+
+    private int _frameposition = 0;
+
+    private boolean loop_sg = false;
+
+    private int _loopcount = 0;
+
+    private int _loopstart = 0;
+
+    private int _loopend = -1;
+
+    private float _rightgain;
+
+    private float _leftgain;
+
+    private float _eff1gain;
+
+    private float _eff2gain;
+
+    private AudioFloatInputStream afis;
+
+    protected SoftMixingClip(SoftMixingMixer mixer, DataLine.Info info) {
+        super(mixer, info);
+    }
+
+    protected void processControlLogic() {
+
+        _rightgain = rightgain;
+        _leftgain = leftgain;
+        _eff1gain = eff1gain;
+        _eff2gain = eff2gain;
+
+        if (active_sg) {
+            _active = active;
+            active_sg = false;
+        } else {
+            active = _active;
+        }
+
+        if (frameposition_sg) {
+            _frameposition = frameposition;
+            frameposition_sg = false;
+            afis = null;
+        } else {
+            frameposition = _frameposition;
+        }
+        if (loop_sg) {
+            _loopcount = loopcount;
+            _loopstart = loopstart;
+            _loopend = loopend;
+        }
+
+        if (afis == null) {
+            afis = AudioFloatInputStream.getInputStream(new AudioInputStream(
+                    datastream, format, AudioSystem.NOT_SPECIFIED));
+
+            if (Math.abs(format.getSampleRate() - outputformat.getSampleRate()) > 0.000001)
+                afis = new AudioFloatInputStreamResampler(afis, outputformat);
+        }
+
+    }
+
+    protected void processAudioLogic(SoftAudioBuffer[] buffers) {
+        if (_active) {
+            float[] left = buffers[SoftMixingMainMixer.CHANNEL_LEFT].array();
+            float[] right = buffers[SoftMixingMainMixer.CHANNEL_RIGHT].array();
+            int bufferlen = buffers[SoftMixingMainMixer.CHANNEL_LEFT].getSize();
+
+            int readlen = bufferlen * in_nrofchannels;
+            if (readbuffer == null || readbuffer.length < readlen) {
+                readbuffer = new float[readlen];
+            }
+            int ret = 0;
+            try {
+                ret = afis.read(readbuffer);
+                if (ret == -1) {
+                    _active = false;
+                    return;
+                }
+                if (ret != in_nrofchannels)
+                    Arrays.fill(readbuffer, ret, readlen, 0);
+            } catch (IOException e) {
+            }
+
+            int in_c = in_nrofchannels;
+            for (int i = 0, ix = 0; i < bufferlen; i++, ix += in_c) {
+                left[i] += readbuffer[ix] * _leftgain;
+            }
+
+            if (out_nrofchannels != 1) {
+                if (in_nrofchannels == 1) {
+                    for (int i = 0, ix = 0; i < bufferlen; i++, ix += in_c) {
+                        right[i] += readbuffer[ix] * _rightgain;
+                    }
+                } else {
+                    for (int i = 0, ix = 1; i < bufferlen; i++, ix += in_c) {
+                        right[i] += readbuffer[ix] * _rightgain;
+                    }
+                }
+
+            }
+
+            if (_eff1gain > 0.0002) {
+
+                float[] eff1 = buffers[SoftMixingMainMixer.CHANNEL_EFFECT1]
+                        .array();
+                for (int i = 0, ix = 0; i < bufferlen; i++, ix += in_c) {
+                    eff1[i] += readbuffer[ix] * _eff1gain;
+                }
+                if (in_nrofchannels == 2) {
+                    for (int i = 0, ix = 1; i < bufferlen; i++, ix += in_c) {
+                        eff1[i] += readbuffer[ix] * _eff1gain;
+                    }
+                }
+            }
+
+            if (_eff2gain > 0.0002) {
+                float[] eff2 = buffers[SoftMixingMainMixer.CHANNEL_EFFECT2]
+                        .array();
+                for (int i = 0, ix = 0; i < bufferlen; i++, ix += in_c) {
+                    eff2[i] += readbuffer[ix] * _eff2gain;
+                }
+                if (in_nrofchannels == 2) {
+                    for (int i = 0, ix = 1; i < bufferlen; i++, ix += in_c) {
+                        eff2[i] += readbuffer[ix] * _eff2gain;
+                    }
+                }
+            }
+
+        }
+    }
+
+    public int getFrameLength() {
+        return bufferSize / format.getFrameSize();
+    }
+
+    public long getMicrosecondLength() {
+        return (long) (getFrameLength() * (1000000.0 / (double) getFormat()
+                .getSampleRate()));
+    }
+
+    public void loop(int count) {
+        LineEvent event = null;
+
+        synchronized (control_mutex) {
+            if (isOpen()) {
+                if (active)
+                    return;
+                active = true;
+                active_sg = true;
+                loopcount = count;
+                event = new LineEvent(this, LineEvent.Type.START,
+                        getLongFramePosition());
+            }
+        }
+
+        if (event != null)
+            sendEvent(event);
+
+    }
+
+    public void open(AudioInputStream stream) throws LineUnavailableException,
+            IOException {
+        if (isOpen()) {
+            throw new IllegalStateException("Clip is already open with format "
+                    + getFormat() + " and frame lengh of " + getFrameLength());
+        }
+        if (AudioFloatConverter.getConverter(stream.getFormat()) == null)
+            throw new IllegalArgumentException("Invalid format : "
+                    + stream.getFormat().toString());
+
+        if (stream.getFrameLength() != AudioSystem.NOT_SPECIFIED) {
+            byte[] data = new byte[(int) stream.getFrameLength()
+                    * stream.getFormat().getFrameSize()];
+            int readsize = 512 * stream.getFormat().getFrameSize();
+            int len = 0;
+            while (len != data.length) {
+                if (readsize > data.length - len)
+                    readsize = data.length - len;
+                int ret = stream.read(data, len, readsize);
+                if (ret == -1)
+                    break;
+                if (ret == 0)
+                    Thread.yield();
+                len += ret;
+            }
+            open(stream.getFormat(), data, 0, len);
+        } else {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            byte[] b = new byte[512 * stream.getFormat().getFrameSize()];
+            int r = 0;
+            while ((r = stream.read(b)) != -1) {
+                if (r == 0)
+                    Thread.yield();
+                baos.write(b, 0, r);
+            }
+            open(stream.getFormat(), baos.toByteArray(), 0, baos.size());
+        }
+
+    }
+
+    public void open(AudioFormat format, byte[] data, int offset, int bufferSize)
+            throws LineUnavailableException {
+        synchronized (control_mutex) {
+            if (isOpen()) {
+                throw new IllegalStateException(
+                        "Clip is already open with format " + getFormat()
+                                + " and frame lengh of " + getFrameLength());
+            }
+            if (AudioFloatConverter.getConverter(format) == null)
+                throw new IllegalArgumentException("Invalid format : "
+                        + format.toString());
+            if (bufferSize % format.getFrameSize() != 0)
+                throw new IllegalArgumentException(
+                        "Buffer size does not represent an integral number of sample frames!");
+
+            this.data = data;
+            this.offset = offset;
+            this.bufferSize = bufferSize;
+            this.format = format;
+            this.framesize = format.getFrameSize();
+
+            loopstart = 0;
+            loopend = -1;
+            loop_sg = true;
+
+            if (!mixer.isOpen()) {
+                mixer.open();
+                mixer.implicitOpen = true;
+            }
+
+            outputformat = mixer.getFormat();
+            out_nrofchannels = outputformat.getChannels();
+            in_nrofchannels = format.getChannels();
+
+            open = true;
+
+            mixer.getMainMixer().openLine(this);
+        }
+
+    }
+
+    public void setFramePosition(int frames) {
+        synchronized (control_mutex) {
+            frameposition_sg = true;
+            frameposition = frames;
+        }
+    }
+
+    public void setLoopPoints(int start, int end) {
+        synchronized (control_mutex) {
+            if (end != -1) {
+                if (end < start)
+                    throw new IllegalArgumentException("Invalid loop points : "
+                            + start + " - " + end);
+                if (end * framesize > bufferSize)
+                    throw new IllegalArgumentException("Invalid loop points : "
+                            + start + " - " + end);
+            }
+            if (start * framesize > bufferSize)
+                throw new IllegalArgumentException("Invalid loop points : "
+                        + start + " - " + end);
+            if (0 < start)
+                throw new IllegalArgumentException("Invalid loop points : "
+                        + start + " - " + end);
+            loopstart = start;
+            loopend = end;
+            loop_sg = true;
+        }
+    }
+
+    public void setMicrosecondPosition(long microseconds) {
+        setFramePosition((int) (microseconds * (((double) getFormat()
+                .getSampleRate()) / 1000000.0)));
+    }
+
+    public int available() {
+        return 0;
+    }
+
+    public void drain() {
+    }
+
+    public void flush() {
+    }
+
+    public int getBufferSize() {
+        return bufferSize;
+    }
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public int getFramePosition() {
+        synchronized (control_mutex) {
+            return frameposition;
+        }
+    }
+
+    public float getLevel() {
+        return AudioSystem.NOT_SPECIFIED;
+    }
+
+    public long getLongFramePosition() {
+        return getFramePosition();
+    }
+
+    public long getMicrosecondPosition() {
+        return (long) (getFramePosition() * (1000000.0 / (double) getFormat()
+                .getSampleRate()));
+    }
+
+    public boolean isActive() {
+        synchronized (control_mutex) {
+            return active;
+        }
+    }
+
+    public boolean isRunning() {
+        synchronized (control_mutex) {
+            return active;
+        }
+    }
+
+    public void start() {
+
+        LineEvent event = null;
+
+        synchronized (control_mutex) {
+            if (isOpen()) {
+                if (active)
+                    return;
+                active = true;
+                active_sg = true;
+                loopcount = 0;
+                event = new LineEvent(this, LineEvent.Type.START,
+                        getLongFramePosition());
+            }
+        }
+
+        if (event != null)
+            sendEvent(event);
+    }
+
+    public void stop() {
+        LineEvent event = null;
+
+        synchronized (control_mutex) {
+            if (isOpen()) {
+                if (!active)
+                    return;
+                active = false;
+                active_sg = true;
+                event = new LineEvent(this, LineEvent.Type.STOP,
+                        getLongFramePosition());
+            }
+        }
+
+        if (event != null)
+            sendEvent(event);
+    }
+
+    public void close() {
+        LineEvent event = null;
+
+        synchronized (control_mutex) {
+            if (!isOpen())
+                return;
+            stop();
+
+            event = new LineEvent(this, LineEvent.Type.CLOSE,
+                    getLongFramePosition());
+
+            open = false;
+            mixer.getMainMixer().closeLine(this);
+        }
+
+        if (event != null)
+            sendEvent(event);
+
+    }
+
+    public boolean isOpen() {
+        return open;
+    }
+
+    public void open() throws LineUnavailableException {
+        if (data == null) {
+            throw new IllegalArgumentException(
+                    "Illegal call to open() in interface Clip");
+        }
+        open(format, data, offset, bufferSize);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftMixingDataLine.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,522 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.BooleanControl;
+import javax.sound.sampled.Control;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.FloatControl;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.Control.Type;
+
+/**
+ * General software mixing line.
+ *
+ * @author Karl Helgason
+ */
+public abstract class SoftMixingDataLine implements DataLine {
+
+    public static final FloatControl.Type CHORUS_SEND = new FloatControl.Type(
+            "Chorus Send") {
+    };
+
+    protected static class AudioFloatInputStreamResampler extends
+            AudioFloatInputStream {
+
+        private AudioFloatInputStream ais;
+
+        private AudioFormat targetFormat;
+
+        private float[] skipbuffer;
+
+        private SoftAbstractResampler resampler;
+
+        private float[] pitch = new float[1];
+
+        private float[] ibuffer2;
+
+        private float[][] ibuffer;
+
+        private float ibuffer_index = 0;
+
+        private int ibuffer_len = 0;
+
+        private int nrofchannels = 0;
+
+        private float[][] cbuffer;
+
+        private int buffer_len = 512;
+
+        private int pad;
+
+        private int pad2;
+
+        private float[] ix = new float[1];
+
+        private int[] ox = new int[1];
+
+        private float[][] mark_ibuffer = null;
+
+        private float mark_ibuffer_index = 0;
+
+        private int mark_ibuffer_len = 0;
+
+        public AudioFloatInputStreamResampler(AudioFloatInputStream ais,
+                AudioFormat format) {
+            this.ais = ais;
+            AudioFormat sourceFormat = ais.getFormat();
+            targetFormat = new AudioFormat(sourceFormat.getEncoding(), format
+                    .getSampleRate(), sourceFormat.getSampleSizeInBits(),
+                    sourceFormat.getChannels(), sourceFormat.getFrameSize(),
+                    format.getSampleRate(), sourceFormat.isBigEndian());
+            nrofchannels = targetFormat.getChannels();
+            Object interpolation = format.getProperty("interpolation");
+            if (interpolation != null && (interpolation instanceof String)) {
+                String resamplerType = (String) interpolation;
+                if (resamplerType.equalsIgnoreCase("point"))
+                    this.resampler = new SoftPointResampler();
+                if (resamplerType.equalsIgnoreCase("linear"))
+                    this.resampler = new SoftLinearResampler2();
+                if (resamplerType.equalsIgnoreCase("linear1"))
+                    this.resampler = new SoftLinearResampler();
+                if (resamplerType.equalsIgnoreCase("linear2"))
+                    this.resampler = new SoftLinearResampler2();
+                if (resamplerType.equalsIgnoreCase("cubic"))
+                    this.resampler = new SoftCubicResampler();
+                if (resamplerType.equalsIgnoreCase("lanczos"))
+                    this.resampler = new SoftLanczosResampler();
+                if (resamplerType.equalsIgnoreCase("sinc"))
+                    this.resampler = new SoftSincResampler();
+            }
+            if (resampler == null)
+                resampler = new SoftLinearResampler2(); // new
+            // SoftLinearResampler2();
+            pitch[0] = sourceFormat.getSampleRate() / format.getSampleRate();
+            pad = resampler.getPadding();
+            pad2 = pad * 2;
+            ibuffer = new float[nrofchannels][buffer_len + pad2];
+            ibuffer2 = new float[nrofchannels * buffer_len];
+            ibuffer_index = buffer_len + pad;
+            ibuffer_len = buffer_len;
+        }
+
+        public int available() throws IOException {
+            return 0;
+        }
+
+        public void close() throws IOException {
+            ais.close();
+        }
+
+        public AudioFormat getFormat() {
+            return targetFormat;
+        }
+
+        public long getFrameLength() {
+            return AudioSystem.NOT_SPECIFIED; // ais.getFrameLength();
+        }
+
+        public void mark(int readlimit) {
+            ais.mark((int) (readlimit * pitch[0]));
+            mark_ibuffer_index = ibuffer_index;
+            mark_ibuffer_len = ibuffer_len;
+            if (mark_ibuffer == null) {
+                mark_ibuffer = new float[ibuffer.length][ibuffer[0].length];
+            }
+            for (int c = 0; c < ibuffer.length; c++) {
+                float[] from = ibuffer[c];
+                float[] to = mark_ibuffer[c];
+                for (int i = 0; i < to.length; i++) {
+                    to[i] = from[i];
+                }
+            }
+        }
+
+        public boolean markSupported() {
+            return ais.markSupported();
+        }
+
+        private void readNextBuffer() throws IOException {
+
+            if (ibuffer_len == -1)
+                return;
+
+            for (int c = 0; c < nrofchannels; c++) {
+                float[] buff = ibuffer[c];
+                int buffer_len_pad = ibuffer_len + pad2;
+                for (int i = ibuffer_len, ix = 0; i < buffer_len_pad; i++, ix++) {
+                    buff[ix] = buff[i];
+                }
+            }
+
+            ibuffer_index -= (ibuffer_len);
+
+            ibuffer_len = ais.read(ibuffer2);
+            if (ibuffer_len >= 0) {
+                while (ibuffer_len < ibuffer2.length) {
+                    int ret = ais.read(ibuffer2, ibuffer_len, ibuffer2.length
+                            - ibuffer_len);
+                    if (ret == -1)
+                        break;
+                    ibuffer_len += ret;
+                }
+                Arrays.fill(ibuffer2, ibuffer_len, ibuffer2.length, 0);
+                ibuffer_len /= nrofchannels;
+            } else {
+                Arrays.fill(ibuffer2, 0, ibuffer2.length, 0);
+            }
+
+            int ibuffer2_len = ibuffer2.length;
+            for (int c = 0; c < nrofchannels; c++) {
+                float[] buff = ibuffer[c];
+                for (int i = c, ix = pad2; i < ibuffer2_len; i += nrofchannels, ix++) {
+                    buff[ix] = ibuffer2[i];
+                }
+            }
+
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+
+            if (cbuffer == null || cbuffer[0].length < len / nrofchannels) {
+                cbuffer = new float[nrofchannels][len / nrofchannels];
+            }
+            if (ibuffer_len == -1)
+                return -1;
+            if (len < 0)
+                return 0;
+            int remain = len / nrofchannels;
+            int destPos = 0;
+            int in_end = ibuffer_len;
+            while (remain > 0) {
+                if (ibuffer_len >= 0) {
+                    if (ibuffer_index >= (ibuffer_len + pad))
+                        readNextBuffer();
+                    in_end = ibuffer_len + pad;
+                }
+
+                if (ibuffer_len < 0) {
+                    in_end = pad2;
+                    if (ibuffer_index >= in_end)
+                        break;
+                }
+
+                if (ibuffer_index < 0)
+                    break;
+                int preDestPos = destPos;
+                for (int c = 0; c < nrofchannels; c++) {
+                    ix[0] = ibuffer_index;
+                    ox[0] = destPos;
+                    float[] buff = ibuffer[c];
+                    resampler.interpolate(buff, ix, in_end, pitch, 0,
+                            cbuffer[c], ox, len / nrofchannels);
+                }
+                ibuffer_index = ix[0];
+                destPos = ox[0];
+                remain -= destPos - preDestPos;
+            }
+            for (int c = 0; c < nrofchannels; c++) {
+                int ix = 0;
+                float[] buff = cbuffer[c];
+                for (int i = c; i < b.length; i += nrofchannels) {
+                    b[i] = buff[ix++];
+                }
+            }
+            return len - remain * nrofchannels;
+        }
+
+        public void reset() throws IOException {
+            ais.reset();
+            if (mark_ibuffer == null)
+                return;
+            ibuffer_index = mark_ibuffer_index;
+            ibuffer_len = mark_ibuffer_len;
+            for (int c = 0; c < ibuffer.length; c++) {
+                float[] from = mark_ibuffer[c];
+                float[] to = ibuffer[c];
+                for (int i = 0; i < to.length; i++) {
+                    to[i] = from[i];
+                }
+            }
+
+        }
+
+        public long skip(long len) throws IOException {
+            if (len > 0)
+                return 0;
+            if (skipbuffer == null)
+                skipbuffer = new float[1024 * targetFormat.getFrameSize()];
+            float[] l_skipbuffer = skipbuffer;
+            long remain = len;
+            while (remain > 0) {
+                int ret = read(l_skipbuffer, 0, (int) Math.min(remain,
+                        skipbuffer.length));
+                if (ret < 0) {
+                    if (remain == len)
+                        return ret;
+                    break;
+                }
+                remain -= ret;
+            }
+            return len - remain;
+
+        }
+
+    }
+
+    private class Gain extends FloatControl {
+
+        private Gain() {
+
+            super(FloatControl.Type.MASTER_GAIN, -80f, 6.0206f, 80f / 128.0f,
+                    -1, 0.0f, "dB", "Minimum", "", "Maximum");
+        }
+
+        public void setValue(float newValue) {
+            super.setValue(newValue);
+            calcVolume();
+        }
+    }
+
+    private class Mute extends BooleanControl {
+
+        private Mute() {
+            super(BooleanControl.Type.MUTE, false, "True", "False");
+        }
+
+        public void setValue(boolean newValue) {
+            super.setValue(newValue);
+            calcVolume();
+        }
+    }
+
+    private class ApplyReverb extends BooleanControl {
+
+        private ApplyReverb() {
+            super(BooleanControl.Type.APPLY_REVERB, false, "True", "False");
+        }
+
+        public void setValue(boolean newValue) {
+            super.setValue(newValue);
+            calcVolume();
+        }
+
+    }
+
+    private class Balance extends FloatControl {
+
+        private Balance() {
+            super(FloatControl.Type.BALANCE, -1.0f, 1.0f, (1.0f / 128.0f), -1,
+                    0.0f, "", "Left", "Center", "Right");
+        }
+
+        public void setValue(float newValue) {
+            super.setValue(newValue);
+            calcVolume();
+        }
+
+    }
+
+    private class Pan extends FloatControl {
+
+        private Pan() {
+            super(FloatControl.Type.PAN, -1.0f, 1.0f, (1.0f / 128.0f), -1,
+                    0.0f, "", "Left", "Center", "Right");
+        }
+
+        public void setValue(float newValue) {
+            super.setValue(newValue);
+            balance_control.setValue(newValue);
+        }
+
+        public float getValue() {
+            return balance_control.getValue();
+        }
+
+    }
+
+    private class ReverbSend extends FloatControl {
+
+        private ReverbSend() {
+            super(FloatControl.Type.REVERB_SEND, -80f, 6.0206f, 80f / 128.0f,
+                    -1, -80f, "dB", "Minimum", "", "Maximum");
+        }
+
+        public void setValue(float newValue) {
+            super.setValue(newValue);
+            balance_control.setValue(newValue);
+        }
+
+    }
+
+    private class ChorusSend extends FloatControl {
+
+        private ChorusSend() {
+            super(CHORUS_SEND, -80f, 6.0206f, 80f / 128.0f, -1, -80f, "dB",
+                    "Minimum", "", "Maximum");
+        }
+
+        public void setValue(float newValue) {
+            super.setValue(newValue);
+            balance_control.setValue(newValue);
+        }
+
+    }
+
+    private Gain gain_control = new Gain();
+
+    private Mute mute_control = new Mute();
+
+    private Balance balance_control = new Balance();
+
+    private Pan pan_control = new Pan();
+
+    private ReverbSend reverbsend_control = new ReverbSend();
+
+    private ChorusSend chorussend_control = new ChorusSend();
+
+    private ApplyReverb apply_reverb = new ApplyReverb();
+
+    private Control[] controls;
+
+    protected float leftgain = 1;
+
+    protected float rightgain = 1;
+
+    protected float eff1gain = 0;
+
+    protected float eff2gain = 0;
+
+    protected List<LineListener> listeners = new ArrayList<LineListener>();
+
+    protected Object control_mutex;
+
+    protected SoftMixingMixer mixer;
+
+    protected DataLine.Info info;
+
+    protected abstract void processControlLogic();
+
+    protected abstract void processAudioLogic(SoftAudioBuffer[] buffers);
+
+    protected SoftMixingDataLine(SoftMixingMixer mixer, DataLine.Info info) {
+        this.mixer = mixer;
+        this.info = info;
+        this.control_mutex = mixer.control_mutex;
+
+        controls = new Control[] { gain_control, mute_control, balance_control,
+                pan_control, reverbsend_control, chorussend_control,
+                apply_reverb };
+        calcVolume();
+    }
+
+    protected void calcVolume() {
+        synchronized (control_mutex) {
+            double gain = Math.pow(10.0, gain_control.getValue() / 20.0);
+            if (mute_control.getValue())
+                gain = 0;
+            leftgain = (float) gain;
+            rightgain = (float) gain;
+            if (mixer.getFormat().getChannels() > 1) {
+                // -1 = Left, 0 Center, 1 = Right
+                double balance = balance_control.getValue();
+                if (balance > 0)
+                    leftgain *= (1 - balance);
+                else
+                    rightgain *= (1 + balance);
+
+            }
+        }
+
+        eff1gain = (float) Math.pow(10.0, reverbsend_control.getValue() / 20.0);
+        eff2gain = (float) Math.pow(10.0, chorussend_control.getValue() / 20.0);
+
+        if (!apply_reverb.getValue()) {
+            eff1gain = 0;
+        }
+    }
+
+    protected void sendEvent(LineEvent event) {
+        if (listeners.size() == 0)
+            return;
+        LineListener[] listener_array = listeners
+                .toArray(new LineListener[listeners.size()]);
+        for (LineListener listener : listener_array) {
+            listener.update(event);
+        }
+    }
+
+    public void addLineListener(LineListener listener) {
+        synchronized (control_mutex) {
+            listeners.add(listener);
+        }
+    }
+
+    public void removeLineListener(LineListener listener) {
+        synchronized (control_mutex) {
+            listeners.add(listener);
+        }
+    }
+
+    public javax.sound.sampled.Line.Info getLineInfo() {
+        return info;
+    }
+
+    public Control getControl(Type control) {
+        if (control != null) {
+            for (int i = 0; i < controls.length; i++) {
+                if (controls[i].getType() == control) {
+                    return controls[i];
+                }
+            }
+        }
+        throw new IllegalArgumentException("Unsupported control type : "
+                + control);
+    }
+
+    public Control[] getControls() {
+        return controls;
+    }
+
+    public boolean isControlSupported(Type control) {
+        if (control != null) {
+            for (int i = 0; i < controls.length; i++) {
+                if (controls[i].getType() == control) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftMixingMainMixer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * Main mixer for SoftMixingMixer.
+ *
+ * @author Karl Helgason
+ */
+public class SoftMixingMainMixer {
+
+    public final static int CHANNEL_LEFT = 0;
+
+    public final static int CHANNEL_RIGHT = 1;
+
+    public final static int CHANNEL_EFFECT1 = 2;
+
+    public final static int CHANNEL_EFFECT2 = 3;
+
+    public final static int CHANNEL_EFFECT3 = 4;
+
+    public final static int CHANNEL_EFFECT4 = 5;
+
+    public final static int CHANNEL_LEFT_DRY = 10;
+
+    public final static int CHANNEL_RIGHT_DRY = 11;
+
+    public final static int CHANNEL_SCRATCH1 = 12;
+
+    public final static int CHANNEL_SCRATCH2 = 13;
+
+    public final static int CHANNEL_CHANNELMIXER_LEFT = 14;
+
+    public final static int CHANNEL_CHANNELMIXER_RIGHT = 15;
+
+    private SoftMixingMixer mixer;
+
+    private AudioInputStream ais;
+
+    private SoftAudioBuffer[] buffers;
+
+    private SoftAudioProcessor reverb;
+
+    private SoftAudioProcessor chorus;
+
+    private SoftAudioProcessor agc;
+
+    private int nrofchannels;
+
+    private Object control_mutex;
+
+    private List<SoftMixingDataLine> openLinesList = new ArrayList<SoftMixingDataLine>();
+
+    private SoftMixingDataLine[] openLines = new SoftMixingDataLine[0];
+
+    public AudioInputStream getInputStream() {
+        return ais;
+    }
+
+    protected void processAudioBuffers() {
+        for (int i = 0; i < buffers.length; i++) {
+            buffers[i].clear();
+        }
+
+        SoftMixingDataLine[] openLines;
+        synchronized (control_mutex) {
+            openLines = this.openLines;
+            for (int i = 0; i < openLines.length; i++) {
+                openLines[i].processControlLogic();
+            }
+            chorus.processControlLogic();
+            reverb.processControlLogic();
+            agc.processControlLogic();
+        }
+        for (int i = 0; i < openLines.length; i++) {
+            openLines[i].processAudioLogic(buffers);
+        }
+
+        chorus.processAudio();
+        reverb.processAudio();
+
+        agc.processAudio();
+
+    }
+
+    public SoftMixingMainMixer(SoftMixingMixer mixer) {
+        this.mixer = mixer;
+
+        nrofchannels = mixer.getFormat().getChannels();
+
+        int buffersize = (int) (mixer.getFormat().getSampleRate() / mixer
+                .getControlRate());
+
+        control_mutex = mixer.control_mutex;
+        buffers = new SoftAudioBuffer[16];
+        for (int i = 0; i < buffers.length; i++) {
+            buffers[i] = new SoftAudioBuffer(buffersize, mixer.getFormat());
+
+        }
+
+        reverb = new SoftReverb();
+        chorus = new SoftChorus();
+        agc = new SoftLimiter();
+
+        float samplerate = mixer.getFormat().getSampleRate();
+        float controlrate = mixer.getControlRate();
+        reverb.init(samplerate, controlrate);
+        chorus.init(samplerate, controlrate);
+        agc.init(samplerate, controlrate);
+
+        reverb.setMixMode(true);
+        chorus.setMixMode(true);
+        agc.setMixMode(false);
+
+        chorus.setInput(0, buffers[CHANNEL_EFFECT2]);
+        chorus.setOutput(0, buffers[CHANNEL_LEFT]);
+        if (nrofchannels != 1)
+            chorus.setOutput(1, buffers[CHANNEL_RIGHT]);
+        chorus.setOutput(2, buffers[CHANNEL_EFFECT1]);
+
+        reverb.setInput(0, buffers[CHANNEL_EFFECT1]);
+        reverb.setOutput(0, buffers[CHANNEL_LEFT]);
+        if (nrofchannels != 1)
+            reverb.setOutput(1, buffers[CHANNEL_RIGHT]);
+
+        agc.setInput(0, buffers[CHANNEL_LEFT]);
+        if (nrofchannels != 1)
+            agc.setInput(1, buffers[CHANNEL_RIGHT]);
+        agc.setOutput(0, buffers[CHANNEL_LEFT]);
+        if (nrofchannels != 1)
+            agc.setOutput(1, buffers[CHANNEL_RIGHT]);
+
+        InputStream in = new InputStream() {
+
+            private SoftAudioBuffer[] buffers = SoftMixingMainMixer.this.buffers;
+
+            private int nrofchannels = SoftMixingMainMixer.this.mixer
+                    .getFormat().getChannels();
+
+            private int buffersize = buffers[0].getSize();
+
+            private byte[] bbuffer = new byte[buffersize
+                    * (SoftMixingMainMixer.this.mixer.getFormat()
+                            .getSampleSizeInBits() / 8) * nrofchannels];
+
+            private int bbuffer_pos = 0;
+
+            private byte[] single = new byte[1];
+
+            public void fillBuffer() {
+                processAudioBuffers();
+                for (int i = 0; i < nrofchannels; i++)
+                    buffers[i].get(bbuffer, i);
+                bbuffer_pos = 0;
+            }
+
+            public int read(byte[] b, int off, int len) {
+                int bbuffer_len = bbuffer.length;
+                int offlen = off + len;
+                byte[] bbuffer = this.bbuffer;
+                while (off < offlen)
+                    if (available() == 0)
+                        fillBuffer();
+                    else {
+                        int bbuffer_pos = this.bbuffer_pos;
+                        while (off < offlen && bbuffer_pos < bbuffer_len)
+                            b[off++] = bbuffer[bbuffer_pos++];
+                        this.bbuffer_pos = bbuffer_pos;
+                    }
+                return len;
+            }
+
+            public int read() throws IOException {
+                int ret = read(single);
+                if (ret == -1)
+                    return -1;
+                return single[0] & 0xFF;
+            }
+
+            public int available() {
+                return bbuffer.length - bbuffer_pos;
+            }
+
+            public void close() {
+                SoftMixingMainMixer.this.mixer.close();
+            }
+
+        };
+
+        ais = new AudioInputStream(in, mixer.getFormat(),
+                AudioSystem.NOT_SPECIFIED);
+
+    }
+
+    public void openLine(SoftMixingDataLine line) {
+        synchronized (control_mutex) {
+            openLinesList.add(line);
+            openLines = openLinesList
+                    .toArray(new SoftMixingDataLine[openLinesList.size()]);
+        }
+    }
+
+    public void closeLine(SoftMixingDataLine line) {
+        synchronized (control_mutex) {
+            openLinesList.remove(line);
+            openLines = openLinesList
+                    .toArray(new SoftMixingDataLine[openLinesList.size()]);
+            if (openLines.length == 0)
+                if (mixer.implicitOpen)
+                    mixer.close();
+        }
+
+    }
+
+    public SoftMixingDataLine[] getOpenLines() {
+        synchronized (control_mutex) {
+            return openLines;
+        }
+
+    }
+
+    public void close() {
+        SoftMixingDataLine[] openLines = this.openLines;
+        for (int i = 0; i < openLines.length; i++) {
+            openLines[i].close();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftMixingMixer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,529 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.Control;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+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;
+import javax.sound.sampled.AudioFormat.Encoding;
+import javax.sound.sampled.Control.Type;
+
+/**
+ * Software audio mixer
+ *
+ * @author Karl Helgason
+ */
+public class SoftMixingMixer implements Mixer {
+
+    private static class Info extends Mixer.Info {
+        public Info() {
+            super(INFO_NAME, INFO_VENDOR, INFO_DESCRIPTION, INFO_VERSION);
+        }
+    }
+
+    protected static final String INFO_NAME = "Gervill Sound Mixer";
+
+    protected static final String INFO_VENDOR = "OpenJDK Proposal";
+
+    protected static final String INFO_DESCRIPTION = "Software Sound Mixer";
+
+    protected static final String INFO_VERSION = "1.0";
+
+    protected final static Mixer.Info info = new Info();
+
+    protected Object control_mutex = this;
+
+    protected boolean implicitOpen = false;
+
+    private boolean open = false;
+
+    private SoftMixingMainMixer mainmixer = null;
+
+    private AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+
+    private SourceDataLine sourceDataLine = null;
+
+    private SoftAudioPusher pusher = null;
+
+    private AudioInputStream pusher_stream = null;
+
+    private float controlrate = 147f;
+
+    private long latency = 100000; // 100 msec
+
+    private boolean jitter_correction = false;
+
+    private List<LineListener> listeners = new ArrayList<LineListener>();
+
+    private javax.sound.sampled.Line.Info[] sourceLineInfo;
+
+    public SoftMixingMixer() {
+
+        sourceLineInfo = new javax.sound.sampled.Line.Info[2];
+
+        ArrayList<AudioFormat> formats = new ArrayList<AudioFormat>();
+        for (int channels = 1; channels <= 2; channels++) {
+            formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+            for (int bits = 16; bits < 32; bits += 8) {
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+            }
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, true));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, true));
+        }
+        AudioFormat[] formats_array = formats.toArray(new AudioFormat[formats
+                .size()]);
+        sourceLineInfo[0] = new DataLine.Info(SourceDataLine.class,
+                formats_array, AudioSystem.NOT_SPECIFIED,
+                AudioSystem.NOT_SPECIFIED);
+        sourceLineInfo[1] = new DataLine.Info(Clip.class, formats_array,
+                AudioSystem.NOT_SPECIFIED, AudioSystem.NOT_SPECIFIED);
+    }
+
+    public Line getLine(Line.Info info) throws LineUnavailableException {
+
+        if (!isLineSupported(info))
+            throw new IllegalArgumentException("Line unsupported: " + info);
+
+        if ((info.getLineClass() == SourceDataLine.class)) {
+            return new SoftMixingSourceDataLine(this, (DataLine.Info) info);
+        }
+        if ((info.getLineClass() == Clip.class)) {
+            return new SoftMixingClip(this, (DataLine.Info) info);
+        }
+
+        throw new IllegalArgumentException("Line unsupported: " + info);
+    }
+
+    public int getMaxLines(Line.Info info) {
+        if (info.getLineClass() == SourceDataLine.class)
+            return AudioSystem.NOT_SPECIFIED;
+        if (info.getLineClass() == Clip.class)
+            return AudioSystem.NOT_SPECIFIED;
+        return 0;
+    }
+
+    public javax.sound.sampled.Mixer.Info getMixerInfo() {
+        return info;
+    }
+
+    public javax.sound.sampled.Line.Info[] getSourceLineInfo() {
+        Line.Info[] localArray = new Line.Info[sourceLineInfo.length];
+        System.arraycopy(sourceLineInfo, 0, localArray, 0,
+                sourceLineInfo.length);
+        return localArray;
+    }
+
+    public javax.sound.sampled.Line.Info[] getSourceLineInfo(
+            javax.sound.sampled.Line.Info info) {
+        int i;
+        ArrayList<javax.sound.sampled.Line.Info> infos = new ArrayList<javax.sound.sampled.Line.Info>();
+
+        for (i = 0; i < sourceLineInfo.length; i++) {
+            if (info.matches(sourceLineInfo[i])) {
+                infos.add(sourceLineInfo[i]);
+            }
+        }
+        return infos.toArray(new Line.Info[infos.size()]);
+    }
+
+    public Line[] getSourceLines() {
+
+        Line[] localLines;
+
+        synchronized (control_mutex) {
+
+            if (mainmixer == null)
+                return new Line[0];
+            SoftMixingDataLine[] sourceLines = mainmixer.getOpenLines();
+
+            localLines = new Line[sourceLines.length];
+
+            for (int i = 0; i < localLines.length; i++) {
+                localLines[i] = sourceLines[i];
+            }
+        }
+
+        return localLines;
+    }
+
+    public javax.sound.sampled.Line.Info[] getTargetLineInfo() {
+        return new javax.sound.sampled.Line.Info[0];
+    }
+
+    public javax.sound.sampled.Line.Info[] getTargetLineInfo(
+            javax.sound.sampled.Line.Info info) {
+        return new javax.sound.sampled.Line.Info[0];
+    }
+
+    public Line[] getTargetLines() {
+        return new Line[0];
+    }
+
+    public boolean isLineSupported(javax.sound.sampled.Line.Info info) {
+        if (info != null) {
+            for (int i = 0; i < sourceLineInfo.length; i++) {
+                if (info.matches(sourceLineInfo[i])) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public boolean isSynchronizationSupported(Line[] lines, boolean maintainSync) {
+        return false;
+    }
+
+    public void synchronize(Line[] lines, boolean maintainSync) {
+        throw new IllegalArgumentException(
+                "Synchronization not supported by this mixer.");
+    }
+
+    public void unsynchronize(Line[] lines) {
+        throw new IllegalArgumentException(
+                "Synchronization not supported by this mixer.");
+    }
+
+    public void addLineListener(LineListener listener) {
+        synchronized (control_mutex) {
+            listeners.add(listener);
+        }
+    }
+
+    private void sendEvent(LineEvent event) {
+        if (listeners.size() == 0)
+            return;
+        LineListener[] listener_array = listeners
+                .toArray(new LineListener[listeners.size()]);
+        for (LineListener listener : listener_array) {
+            listener.update(event);
+        }
+    }
+
+    public void close() {
+        if (!isOpen())
+            return;
+
+        sendEvent(new LineEvent(this, LineEvent.Type.CLOSE,
+                AudioSystem.NOT_SPECIFIED));
+
+        SoftAudioPusher pusher_to_be_closed = null;
+        AudioInputStream pusher_stream_to_be_closed = null;
+        synchronized (control_mutex) {
+            if (pusher != null) {
+                pusher_to_be_closed = pusher;
+                pusher_stream_to_be_closed = pusher_stream;
+                pusher = null;
+                pusher_stream = null;
+            }
+        }
+
+        if (pusher_to_be_closed != null) {
+            // Pusher must not be closed synchronized against control_mutex
+            // this may result in synchronized conflict between pusher and
+            // current thread.
+            pusher_to_be_closed.stop();
+
+            try {
+                pusher_stream_to_be_closed.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        synchronized (control_mutex) {
+
+            if (mainmixer != null)
+                mainmixer.close();
+            open = false;
+
+            if (sourceDataLine != null) {
+                sourceDataLine.drain();
+                sourceDataLine.close();
+                sourceDataLine = null;
+            }
+
+        }
+
+    }
+
+    public Control getControl(Type control) {
+        throw new IllegalArgumentException("Unsupported control type : "
+                + control);
+    }
+
+    public Control[] getControls() {
+        return new Control[0];
+    }
+
+    public javax.sound.sampled.Line.Info getLineInfo() {
+        return new Line.Info(Mixer.class);
+    }
+
+    public boolean isControlSupported(Type control) {
+        return false;
+    }
+
+    public boolean isOpen() {
+        synchronized (control_mutex) {
+            return open;
+        }
+    }
+
+    public void open() throws LineUnavailableException {
+        if (isOpen()) {
+            implicitOpen = false;
+            return;
+        }
+        open(null);
+    }
+
+    public void open(SourceDataLine line) throws LineUnavailableException {
+        if (isOpen()) {
+            implicitOpen = false;
+            return;
+        }
+        synchronized (control_mutex) {
+
+            try {
+
+                if (line != null)
+                    format = line.getFormat();
+
+                AudioInputStream ais = openStream(getFormat());
+
+                if (line == null) {
+                    synchronized (SoftMixingMixerProvider.mutex) {
+                        SoftMixingMixerProvider.lockthread = Thread
+                                .currentThread();
+                    }
+
+                    try {
+                        Mixer defaultmixer = AudioSystem.getMixer(null);
+                        if (defaultmixer != null)
+                        {
+                            // Search for suitable line
+
+                            DataLine.Info idealinfo = null;
+                            AudioFormat idealformat = null;
+
+                            Line.Info[] lineinfos = defaultmixer.getSourceLineInfo();
+                            idealFound:
+                            for (int i = 0; i < lineinfos.length; i++) {
+                                if(lineinfos[i].getLineClass() == SourceDataLine.class)
+                                {
+                                    DataLine.Info info = (DataLine.Info)lineinfos[i];
+                                    AudioFormat[] formats = info.getFormats();
+                                    for (int j = 0; j < formats.length; j++) {
+                                        AudioFormat format = formats[j];
+                                        if(format.getChannels() == 2 ||
+                                                format.getChannels() == AudioSystem.NOT_SPECIFIED)
+                                        if(format.getEncoding().equals(Encoding.PCM_SIGNED) ||
+                                                format.getEncoding().equals(Encoding.PCM_UNSIGNED))
+                                        if(format.getSampleRate() == AudioSystem.NOT_SPECIFIED ||
+                                                format.getSampleRate() == 48000.0)
+                                        if(format.getSampleSizeInBits() == AudioSystem.NOT_SPECIFIED ||
+                                                format.getSampleSizeInBits() == 16)
+                                        {
+                                            idealinfo = info;
+                                            int ideal_channels = format.getChannels();
+                                            boolean ideal_signed = format.getEncoding().equals(Encoding.PCM_SIGNED);
+                                            float ideal_rate = format.getSampleRate();
+                                            boolean ideal_endian = format.isBigEndian();
+                                            int ideal_bits = format.getSampleSizeInBits();
+                                            if(ideal_bits == AudioSystem.NOT_SPECIFIED) ideal_bits = 16;
+                                            if(ideal_channels == AudioSystem.NOT_SPECIFIED) ideal_channels = 2;
+                                            if(ideal_rate == AudioSystem.NOT_SPECIFIED) ideal_rate = 48000;
+                                            idealformat = new AudioFormat(ideal_rate, ideal_bits,
+                                                    ideal_channels, ideal_signed, ideal_endian);
+                                            break idealFound;
+                                        }
+                                    }
+                                }
+                            }
+
+                            if(idealformat != null)
+                            {
+                                format = idealformat;
+                                line = (SourceDataLine) defaultmixer.getLine(idealinfo);
+                            }
+                        }
+
+                        if(line == null)
+                            line = AudioSystem.getSourceDataLine(format);
+                    } finally {
+                        synchronized (SoftMixingMixerProvider.mutex) {
+                            SoftMixingMixerProvider.lockthread = null;
+                        }
+                    }
+
+                    if (line == null)
+                        throw new IllegalArgumentException("No line matching "
+                                + info.toString() + " is supported.");
+                }
+
+                double latency = this.latency;
+
+                if (!line.isOpen()) {
+                    int bufferSize = getFormat().getFrameSize()
+                            * (int) (getFormat().getFrameRate() * (latency / 1000000f));
+                    line.open(getFormat(), bufferSize);
+
+                    // Remember that we opened that line
+                    // so we can close again in SoftSynthesizer.close()
+                    sourceDataLine = line;
+                }
+                if (!line.isActive())
+                    line.start();
+
+                int controlbuffersize = 512;
+                try {
+                    controlbuffersize = ais.available();
+                } catch (IOException e) {
+                }
+
+                // Tell mixer not fill read buffers fully.
+                // This lowers latency, and tells DataPusher
+                // to read in smaller amounts.
+                // mainmixer.readfully = false;
+                // pusher = new DataPusher(line, ais);
+
+                int buffersize = line.getBufferSize();
+                buffersize -= buffersize % controlbuffersize;
+
+                if (buffersize < 3 * controlbuffersize)
+                    buffersize = 3 * controlbuffersize;
+
+                if (jitter_correction) {
+                    ais = new SoftJitterCorrector(ais, buffersize,
+                            controlbuffersize);
+                }
+                pusher = new SoftAudioPusher(line, ais, controlbuffersize);
+                pusher_stream = ais;
+                pusher.start();
+
+            } catch (LineUnavailableException e) {
+                if (isOpen())
+                    close();
+                throw new LineUnavailableException(e.toString());
+            }
+
+        }
+    }
+
+    public AudioInputStream openStream(AudioFormat targetFormat)
+            throws LineUnavailableException {
+
+        if (isOpen())
+            throw new LineUnavailableException("Mixer is already open");
+
+        synchronized (control_mutex) {
+
+            open = true;
+
+            implicitOpen = false;
+
+            if (targetFormat != null)
+                format = targetFormat;
+
+            mainmixer = new SoftMixingMainMixer(this);
+
+            sendEvent(new LineEvent(this, LineEvent.Type.OPEN,
+                    AudioSystem.NOT_SPECIFIED));
+
+            return mainmixer.getInputStream();
+
+        }
+
+    }
+
+    public void removeLineListener(LineListener listener) {
+        synchronized (control_mutex) {
+            listeners.remove(listener);
+        }
+    }
+
+    public long getLatency() {
+        synchronized (control_mutex) {
+            return latency;
+        }
+    }
+
+    public AudioFormat getFormat() {
+        synchronized (control_mutex) {
+            return format;
+        }
+    }
+
+    protected float getControlRate() {
+        return controlrate;
+    }
+
+    protected SoftMixingMainMixer getMainMixer() {
+        if (!isOpen())
+            return null;
+        return mainmixer;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftMixingMixerProvider.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.Mixer.Info;
+import javax.sound.sampled.spi.MixerProvider;
+
+/**
+ * Provider for software audio mixer
+ *
+ * @author Karl Helgason
+ */
+public class SoftMixingMixerProvider extends MixerProvider {
+
+    static SoftMixingMixer globalmixer = null;
+
+    static Thread lockthread = null;
+
+    protected final static Object mutex = new Object();
+
+    public Mixer getMixer(Info info) {
+        if (!(info == null || info == SoftMixingMixer.info)) {
+            throw new IllegalArgumentException("Mixer " + info.toString()
+                    + " not supported by this provider.");
+        }
+        synchronized (mutex) {
+            if (lockthread != null)
+                if (Thread.currentThread() == lockthread)
+                    throw new IllegalArgumentException("Mixer "
+                            + info.toString()
+                            + " not supported by this provider.");
+            if (globalmixer == null)
+                globalmixer = new SoftMixingMixer();
+            return globalmixer;
+        }
+
+    }
+
+    public Info[] getMixerInfo() {
+        return new Info[] { SoftMixingMixer.info };
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftMixingSourceDataLine.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,519 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * SourceDataLine implemention for the SoftMixingMixer.
+ *
+ * @author Karl Helgason
+ */
+public class SoftMixingSourceDataLine extends SoftMixingDataLine implements
+        SourceDataLine {
+
+    private boolean open = false;
+
+    private AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false);
+
+    private int framesize;
+
+    private int bufferSize = -1;
+
+    private float[] readbuffer;
+
+    private boolean active = false;
+
+    private byte[] cycling_buffer;
+
+    private int cycling_read_pos = 0;
+
+    private int cycling_write_pos = 0;
+
+    private int cycling_avail = 0;
+
+    private long cycling_framepos = 0;
+
+    private AudioFloatInputStream afis;
+
+    private static class NonBlockingFloatInputStream extends
+            AudioFloatInputStream {
+        AudioFloatInputStream ais;
+
+        public NonBlockingFloatInputStream(AudioFloatInputStream ais) {
+            this.ais = ais;
+        }
+
+        public int available() throws IOException {
+            return ais.available();
+        }
+
+        public void close() throws IOException {
+            ais.close();
+        }
+
+        public AudioFormat getFormat() {
+            return ais.getFormat();
+        }
+
+        public long getFrameLength() {
+            return ais.getFrameLength();
+        }
+
+        public void mark(int readlimit) {
+            ais.mark(readlimit);
+        }
+
+        public boolean markSupported() {
+            return ais.markSupported();
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+            int avail = available();
+            if (len > avail) {
+                int ret = ais.read(b, off, avail);
+                Arrays.fill(b, off + ret, off + len, 0);
+                return len;
+            }
+            return ais.read(b, off, len);
+        }
+
+        public void reset() throws IOException {
+            ais.reset();
+        }
+
+        public long skip(long len) throws IOException {
+            return ais.skip(len);
+        }
+
+    }
+
+    protected SoftMixingSourceDataLine(SoftMixingMixer mixer, DataLine.Info info) {
+        super(mixer, info);
+    }
+
+    public int write(byte[] b, int off, int len) {
+        if (!isOpen())
+            return 0;
+        if (len % framesize != 0)
+            throw new IllegalArgumentException(
+                    "Number of bytes does not represent an integral number of sample frames.");
+
+        byte[] buff = cycling_buffer;
+        int buff_len = cycling_buffer.length;
+
+        int l = 0;
+        while (l != len) {
+            int avail;
+            synchronized (cycling_buffer) {
+                int pos = cycling_write_pos;
+                avail = cycling_avail;
+                while (l != len) {
+                    if (avail == buff_len)
+                        break;
+                    buff[pos++] = b[off++];
+                    l++;
+                    avail++;
+                    if (pos == buff_len)
+                        pos = 0;
+                }
+                cycling_avail = avail;
+                cycling_write_pos = pos;
+                if (l == len)
+                    return l;
+            }
+            if (avail == buff_len) {
+                try {
+                    Thread.sleep(1);
+                } catch (InterruptedException e) {
+                    return l;
+                }
+                if (!isRunning())
+                    return l;
+            }
+        }
+
+        return l;
+    }
+
+    //
+    // BooleanControl.Type.APPLY_REVERB
+    // BooleanControl.Type.MUTE
+    // EnumControl.Type.REVERB
+    //
+    // FloatControl.Type.SAMPLE_RATE
+    // FloatControl.Type.REVERB_SEND
+    // FloatControl.Type.VOLUME
+    // FloatControl.Type.PAN
+    // FloatControl.Type.MASTER_GAIN
+    // FloatControl.Type.BALANCE
+
+    private boolean _active = false;
+
+    private AudioFormat outputformat;
+
+    private int out_nrofchannels;
+
+    private int in_nrofchannels;
+
+    private float _rightgain;
+
+    private float _leftgain;
+
+    private float _eff1gain;
+
+    private float _eff2gain;
+
+    protected void processControlLogic() {
+        _active = active;
+        _rightgain = rightgain;
+        _leftgain = leftgain;
+        _eff1gain = eff1gain;
+        _eff2gain = eff2gain;
+    }
+
+    protected void processAudioLogic(SoftAudioBuffer[] buffers) {
+        if (_active) {
+            float[] left = buffers[SoftMixingMainMixer.CHANNEL_LEFT].array();
+            float[] right = buffers[SoftMixingMainMixer.CHANNEL_RIGHT].array();
+            int bufferlen = buffers[SoftMixingMainMixer.CHANNEL_LEFT].getSize();
+
+            int readlen = bufferlen * in_nrofchannels;
+            if (readbuffer == null || readbuffer.length < readlen) {
+                readbuffer = new float[readlen];
+            }
+            int ret = 0;
+            try {
+                ret = afis.read(readbuffer);
+                if (ret != in_nrofchannels)
+                    Arrays.fill(readbuffer, ret, readlen, 0);
+            } catch (IOException e) {
+            }
+
+            int in_c = in_nrofchannels;
+            for (int i = 0, ix = 0; i < bufferlen; i++, ix += in_c) {
+                left[i] += readbuffer[ix] * _leftgain;
+            }
+            if (out_nrofchannels != 1) {
+                if (in_nrofchannels == 1) {
+                    for (int i = 0, ix = 0; i < bufferlen; i++, ix += in_c) {
+                        right[i] += readbuffer[ix] * _rightgain;
+                    }
+                } else {
+                    for (int i = 0, ix = 1; i < bufferlen; i++, ix += in_c) {
+                        right[i] += readbuffer[ix] * _rightgain;
+                    }
+                }
+
+            }
+
+            if (_eff1gain > 0.0001) {
+                float[] eff1 = buffers[SoftMixingMainMixer.CHANNEL_EFFECT1]
+                        .array();
+                for (int i = 0, ix = 0; i < bufferlen; i++, ix += in_c) {
+                    eff1[i] += readbuffer[ix] * _eff1gain;
+                }
+                if (in_nrofchannels == 2) {
+                    for (int i = 0, ix = 1; i < bufferlen; i++, ix += in_c) {
+                        eff1[i] += readbuffer[ix] * _eff1gain;
+                    }
+                }
+            }
+
+            if (_eff2gain > 0.0001) {
+                float[] eff2 = buffers[SoftMixingMainMixer.CHANNEL_EFFECT2]
+                        .array();
+                for (int i = 0, ix = 0; i < bufferlen; i++, ix += in_c) {
+                    eff2[i] += readbuffer[ix] * _eff2gain;
+                }
+                if (in_nrofchannels == 2) {
+                    for (int i = 0, ix = 1; i < bufferlen; i++, ix += in_c) {
+                        eff2[i] += readbuffer[ix] * _eff2gain;
+                    }
+                }
+            }
+
+        }
+    }
+
+    public void open() throws LineUnavailableException {
+        open(format);
+    }
+
+    public void open(AudioFormat format) throws LineUnavailableException {
+        if (bufferSize == -1)
+            bufferSize = ((int) (format.getFrameRate() / 2))
+                    * format.getFrameSize();
+        open(format, bufferSize);
+    }
+
+    public void open(AudioFormat format, int bufferSize)
+            throws LineUnavailableException {
+
+        LineEvent event = null;
+
+        if (bufferSize < format.getFrameSize() * 32)
+            bufferSize = format.getFrameSize() * 32;
+
+        synchronized (control_mutex) {
+
+            if (!isOpen()) {
+                if (!mixer.isOpen()) {
+                    mixer.open();
+                    mixer.implicitOpen = true;
+                }
+
+                event = new LineEvent(this, LineEvent.Type.OPEN, 0);
+
+                this.bufferSize = bufferSize - bufferSize
+                        % format.getFrameSize();
+                this.format = format;
+                this.framesize = format.getFrameSize();
+                this.outputformat = mixer.getFormat();
+                out_nrofchannels = outputformat.getChannels();
+                in_nrofchannels = format.getChannels();
+
+                open = true;
+
+                mixer.getMainMixer().openLine(this);
+
+                cycling_buffer = new byte[framesize * bufferSize];
+                cycling_read_pos = 0;
+                cycling_write_pos = 0;
+                cycling_avail = 0;
+                cycling_framepos = 0;
+
+                InputStream cycling_inputstream = new InputStream() {
+
+                    public int read() throws IOException {
+                        byte[] b = new byte[1];
+                        int ret = read(b);
+                        if (ret < 0)
+                            return ret;
+                        return b[0] & 0xFF;
+                    }
+
+                    public int available() throws IOException {
+                        synchronized (cycling_buffer) {
+                            return cycling_avail;
+                        }
+                    }
+
+                    public int read(byte[] b, int off, int len)
+                            throws IOException {
+
+                        synchronized (cycling_buffer) {
+                            if (len > cycling_avail)
+                                len = cycling_avail;
+                            int pos = cycling_read_pos;
+                            byte[] buff = cycling_buffer;
+                            int buff_len = buff.length;
+                            for (int i = 0; i < len; i++) {
+                                b[off++] = buff[pos];
+                                pos++;
+                                if (pos == buff_len)
+                                    pos = 0;
+                            }
+                            cycling_read_pos = pos;
+                            cycling_avail -= len;
+                            cycling_framepos += len / framesize;
+                        }
+                        return len;
+                    }
+
+                };
+
+                afis = AudioFloatInputStream
+                        .getInputStream(new AudioInputStream(
+                                cycling_inputstream, format,
+                                AudioSystem.NOT_SPECIFIED));
+                afis = new NonBlockingFloatInputStream(afis);
+
+                if (Math.abs(format.getSampleRate()
+                        - outputformat.getSampleRate()) > 0.000001)
+                    afis = new AudioFloatInputStreamResampler(afis,
+                            outputformat);
+
+            } else {
+                if (!format.matches(getFormat())) {
+                    throw new IllegalStateException(
+                            "Line is already open with format " + getFormat()
+                                    + " and bufferSize " + getBufferSize());
+                }
+            }
+
+        }
+
+        if (event != null)
+            sendEvent(event);
+
+    }
+
+    public int available() {
+        synchronized (cycling_buffer) {
+            return cycling_buffer.length - cycling_avail;
+        }
+    }
+
+    public void drain() {
+        while (true) {
+            int avail;
+            synchronized (cycling_buffer) {
+                avail = cycling_avail;
+            }
+            if (avail != 0)
+                return;
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+                return;
+            }
+        }
+    }
+
+    public void flush() {
+        synchronized (cycling_buffer) {
+            cycling_read_pos = 0;
+            cycling_write_pos = 0;
+            cycling_avail = 0;
+        }
+    }
+
+    public int getBufferSize() {
+        synchronized (control_mutex) {
+            return bufferSize;
+        }
+    }
+
+    public AudioFormat getFormat() {
+        synchronized (control_mutex) {
+            return format;
+        }
+    }
+
+    public int getFramePosition() {
+        return (int) getLongFramePosition();
+    }
+
+    public float getLevel() {
+        return AudioSystem.NOT_SPECIFIED;
+    }
+
+    public long getLongFramePosition() {
+        synchronized (cycling_buffer) {
+            return cycling_framepos;
+        }
+    }
+
+    public long getMicrosecondPosition() {
+        return (long) (getLongFramePosition() * (1000000.0 / (double) getFormat()
+                .getSampleRate()));
+    }
+
+    public boolean isActive() {
+        synchronized (control_mutex) {
+            return active;
+        }
+    }
+
+    public boolean isRunning() {
+        synchronized (control_mutex) {
+            return active;
+        }
+    }
+
+    public void start() {
+
+        LineEvent event = null;
+
+        synchronized (control_mutex) {
+            if (isOpen()) {
+                if (active)
+                    return;
+                active = true;
+                event = new LineEvent(this, LineEvent.Type.START,
+                        getLongFramePosition());
+            }
+        }
+
+        if (event != null)
+            sendEvent(event);
+    }
+
+    public void stop() {
+        LineEvent event = null;
+
+        synchronized (control_mutex) {
+            if (isOpen()) {
+                if (!active)
+                    return;
+                active = false;
+                event = new LineEvent(this, LineEvent.Type.STOP,
+                        getLongFramePosition());
+            }
+        }
+
+        if (event != null)
+            sendEvent(event);
+    }
+
+    public void close() {
+
+        LineEvent event = null;
+
+        synchronized (control_mutex) {
+            if (!isOpen())
+                return;
+            stop();
+
+            event = new LineEvent(this, LineEvent.Type.CLOSE,
+                    getLongFramePosition());
+
+            open = false;
+            mixer.getMainMixer().closeLine(this);
+        }
+
+        if (event != null)
+            sendEvent(event);
+
+    }
+
+    public boolean isOpen() {
+        synchronized (control_mutex) {
+            return open;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftPerformer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,775 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class decodes information from ModelPeformer for use in SoftVoice.
+ * It also adds default connections if they where missing in ModelPerformer.
+ *
+ * @author Karl Helgason
+ */
+public class SoftPerformer {
+
+    static ModelConnectionBlock[] defaultconnections
+            = new ModelConnectionBlock[42];
+
+    static {
+        int o = 0;
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("noteon", "on", 0),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1, new ModelDestination(new ModelIdentifier("eg", "on", 0)));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("noteon", "on", 0),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1, new ModelDestination(new ModelIdentifier("eg", "on", 1)));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("eg", "active", 0),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1, new ModelDestination(new ModelIdentifier("mixer", "active", 0)));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("eg", 0),
+                ModelStandardTransform.DIRECTION_MAX2MIN,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            -960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("noteon", "velocity"),
+                ModelStandardTransform.DIRECTION_MAX2MIN,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_CONCAVE),
+            -960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi", "pitch"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            new ModelSource(new ModelIdentifier("midi_rpn", "0"),
+                new ModelTransform() {
+                    public double transform(double value) {
+                        int v = (int) (value * 16384.0);
+                        int msb = v >> 7;
+                        int lsb = v & 127;
+                        return msb * 100 + lsb;
+                    }
+                }),
+            new ModelDestination(new ModelIdentifier("osc", "pitch")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("noteon", "keynumber"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            12800, new ModelDestination(new ModelIdentifier("osc", "pitch")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "7"),
+                ModelStandardTransform.DIRECTION_MAX2MIN,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_CONCAVE),
+            -960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "8"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1000, new ModelDestination(new ModelIdentifier("mixer", "balance")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "10"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1000, new ModelDestination(new ModelIdentifier("mixer", "pan")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "11"),
+                ModelStandardTransform.DIRECTION_MAX2MIN,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_CONCAVE),
+            -960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "91"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1000, new ModelDestination(new ModelIdentifier("mixer", "reverb")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "93"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1000, new ModelDestination(new ModelIdentifier("mixer", "chorus")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "71"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            200, new ModelDestination(new ModelIdentifier("filter", "q")));
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "74"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            9600, new ModelDestination(new ModelIdentifier("filter", "freq")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "72"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            6000, new ModelDestination(new ModelIdentifier("eg", "release2")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "73"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            2000, new ModelDestination(new ModelIdentifier("eg", "attack2")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "75"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            6000, new ModelDestination(new ModelIdentifier("eg", "decay2")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "67"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_SWITCH),
+            -50, new ModelDestination(ModelDestination.DESTINATION_GAIN));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "67"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_SWITCH),
+            -2400, new ModelDestination(ModelDestination.DESTINATION_FILTER_FREQ));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_rpn", "1"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            100, new ModelDestination(new ModelIdentifier("osc", "pitch")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_rpn", "2"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            12800, new ModelDestination(new ModelIdentifier("osc", "pitch")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("master", "fine_tuning"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            100, new ModelDestination(new ModelIdentifier("osc", "pitch")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("master", "coarse_tuning"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            12800, new ModelDestination(new ModelIdentifier("osc", "pitch")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(13500,
+                new ModelDestination(new ModelIdentifier("filter", "freq", 0)));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "delay", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "attack", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "hold", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "decay", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(1000,
+                new ModelDestination(new ModelIdentifier("eg", "sustain", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "release", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(1200.0
+                * Math.log(0.015) / Math.log(2), new ModelDestination(
+                new ModelIdentifier("eg", "shutdown", 0))); // 15 msec default
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "delay", 1)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "attack", 1)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "hold", 1)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "decay", 1)));
+        defaultconnections[o++] = new ModelConnectionBlock(1000,
+                new ModelDestination(new ModelIdentifier("eg", "sustain", 1)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "release", 1)));
+
+        defaultconnections[o++] = new ModelConnectionBlock(-8.51318,
+                new ModelDestination(new ModelIdentifier("lfo", "freq", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("lfo", "delay", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(-8.51318,
+                new ModelDestination(new ModelIdentifier("lfo", "freq", 1)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("lfo", "delay", 1)));
+
+    }
+    public int keyFrom = 0;
+    public int keyTo = 127;
+    public int velFrom = 0;
+    public int velTo = 127;
+    public int exclusiveClass = 0;
+    public boolean selfNonExclusive = false;
+    public boolean forcedVelocity = false;
+    public boolean forcedKeynumber = false;
+    public ModelPerformer performer;
+    public ModelConnectionBlock[] connections;
+    public ModelOscillator[] oscillators;
+    public Map<Integer, int[]> midi_rpn_connections = new HashMap<Integer, int[]>();
+    public Map<Integer, int[]> midi_nrpn_connections = new HashMap<Integer, int[]>();
+    public int[][] midi_ctrl_connections;
+    public int[][] midi_connections;
+    public int[] ctrl_connections;
+    private List<Integer> ctrl_connections_list = new ArrayList<Integer>();
+
+    private static class KeySortComparator implements Comparator<ModelSource> {
+
+        public int compare(ModelSource o1, ModelSource o2) {
+            return o1.getIdentifier().toString().compareTo(
+                    o2.getIdentifier().toString());
+        }
+    }
+    private static KeySortComparator keySortComparator = new KeySortComparator();
+
+    private String extractKeys(ModelConnectionBlock conn) {
+        StringBuffer sb = new StringBuffer();
+        if (conn.getSources() != null) {
+            sb.append("[");
+            ModelSource[] srcs = conn.getSources();
+            ModelSource[] srcs2 = new ModelSource[srcs.length];
+            for (int i = 0; i < srcs.length; i++)
+                srcs2[i] = srcs[i];
+            Arrays.sort(srcs2, keySortComparator);
+            for (int i = 0; i < srcs.length; i++) {
+                sb.append(srcs[i].getIdentifier());
+                sb.append(";");
+            }
+            sb.append("]");
+        }
+        sb.append(";");
+        if (conn.getDestination() != null) {
+            sb.append(conn.getDestination().getIdentifier());
+        }
+        sb.append(";");
+        return sb.toString();
+    }
+
+    private void processSource(ModelSource src, int ix) {
+        ModelIdentifier id = src.getIdentifier();
+        String o = id.getObject();
+        if (o.equals("midi_cc"))
+            processMidiControlSource(src, ix);
+        else if (o.equals("midi_rpn"))
+            processMidiRpnSource(src, ix);
+        else if (o.equals("midi_nrpn"))
+            processMidiNrpnSource(src, ix);
+        else if (o.equals("midi"))
+            processMidiSource(src, ix);
+        else if (o.equals("noteon"))
+            processNoteOnSource(src, ix);
+        else if (o.equals("osc"))
+            return;
+        else if (o.equals("mixer"))
+            return;
+        else
+            ctrl_connections_list.add(ix);
+    }
+
+    private void processMidiControlSource(ModelSource src, int ix) {
+        String v = src.getIdentifier().getVariable();
+        if (v == null)
+            return;
+        int c = Integer.parseInt(v);
+        if (midi_ctrl_connections[c] == null)
+            midi_ctrl_connections[c] = new int[]{ix};
+        else {
+            int[] olda = midi_ctrl_connections[c];
+            int[] newa = new int[olda.length + 1];
+            for (int i = 0; i < olda.length; i++)
+                newa[i] = olda[i];
+            newa[newa.length - 1] = ix;
+            midi_ctrl_connections[c] = newa;
+        }
+    }
+
+    private void processNoteOnSource(ModelSource src, int ix) {
+        String v = src.getIdentifier().getVariable();
+        int c = -1;
+        if (v.equals("on"))
+            c = 3;
+        if (v.equals("keynumber"))
+            c = 4;
+        if (c == -1)
+            return;
+        if (midi_connections[c] == null)
+            midi_connections[c] = new int[]{ix};
+        else {
+            int[] olda = midi_connections[c];
+            int[] newa = new int[olda.length + 1];
+            for (int i = 0; i < olda.length; i++)
+                newa[i] = olda[i];
+            newa[newa.length - 1] = ix;
+            midi_connections[c] = newa;
+        }
+    }
+
+    private void processMidiSource(ModelSource src, int ix) {
+        String v = src.getIdentifier().getVariable();
+        int c = -1;
+        if (v.equals("pitch"))
+            c = 0;
+        if (v.equals("channel_pressure"))
+            c = 1;
+        if (v.equals("poly_pressure"))
+            c = 2;
+        if (c == -1)
+            return;
+        if (midi_connections[c] == null)
+            midi_connections[c] = new int[]{ix};
+        else {
+            int[] olda = midi_connections[c];
+            int[] newa = new int[olda.length + 1];
+            for (int i = 0; i < olda.length; i++)
+                newa[i] = olda[i];
+            newa[newa.length - 1] = ix;
+            midi_connections[c] = newa;
+        }
+    }
+
+    private void processMidiRpnSource(ModelSource src, int ix) {
+        String v = src.getIdentifier().getVariable();
+        if (v == null)
+            return;
+        int c = Integer.parseInt(v);
+        if (midi_rpn_connections.get(c) == null)
+            midi_rpn_connections.put(c, new int[]{ix});
+        else {
+            int[] olda = midi_rpn_connections.get(c);
+            int[] newa = new int[olda.length + 1];
+            for (int i = 0; i < olda.length; i++)
+                newa[i] = olda[i];
+            newa[newa.length - 1] = ix;
+            midi_rpn_connections.put(c, newa);
+        }
+    }
+
+    private void processMidiNrpnSource(ModelSource src, int ix) {
+        String v = src.getIdentifier().getVariable();
+        if (v == null)
+            return;
+        int c = Integer.parseInt(v);
+        if (midi_nrpn_connections.get(c) == null)
+            midi_nrpn_connections.put(c, new int[]{ix});
+        else {
+            int[] olda = midi_nrpn_connections.get(c);
+            int[] newa = new int[olda.length + 1];
+            for (int i = 0; i < olda.length; i++)
+                newa[i] = olda[i];
+            newa[newa.length - 1] = ix;
+            midi_nrpn_connections.put(c, newa);
+        }
+    }
+
+    public SoftPerformer(ModelPerformer performer) {
+        this.performer = performer;
+
+        keyFrom = performer.getKeyFrom();
+        keyTo = performer.getKeyTo();
+        velFrom = performer.getVelFrom();
+        velTo = performer.getVelTo();
+        exclusiveClass = performer.getExclusiveClass();
+        selfNonExclusive = performer.isSelfNonExclusive();
+
+        Map<String, ModelConnectionBlock> connmap = new HashMap<String, ModelConnectionBlock>();
+
+        List<ModelConnectionBlock> performer_connections = new ArrayList<ModelConnectionBlock>();
+        performer_connections.addAll(performer.getConnectionBlocks());
+
+        if (performer.isDefaultConnectionsEnabled()) {
+
+            // Add modulation depth range (RPN 5) to the modulation wheel (cc#1)
+
+            boolean isModulationWheelConectionFound = false;
+            for (int j = 0; j < performer_connections.size(); j++) {
+                ModelConnectionBlock connection = performer_connections.get(j);
+                ModelSource[] sources = connection.getSources();
+                ModelDestination dest = connection.getDestination();
+                boolean isModulationWheelConection = false;
+                if (dest != null && sources != null && sources.length > 1) {
+                    for (int i = 0; i < sources.length; i++) {
+                        // check if connection block has the source "modulation
+                        // wheel cc#1"
+                        if (sources[i].getIdentifier().getObject().equals(
+                                "midi_cc")) {
+                            if (sources[i].getIdentifier().getVariable()
+                                    .equals("1")) {
+                                isModulationWheelConection = true;
+                                isModulationWheelConectionFound = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+                if (isModulationWheelConection) {
+
+                    ModelConnectionBlock newconnection = new ModelConnectionBlock();
+                    newconnection.setSources(connection.getSources());
+                    newconnection.setDestination(connection.getDestination());
+                    newconnection.addSource(new ModelSource(
+                            new ModelIdentifier("midi_rpn", "5")));
+                    newconnection.setScale(connection.getScale() * 256.0);
+                    performer_connections.set(j, newconnection);
+                }
+            }
+
+            if (!isModulationWheelConectionFound) {
+                ModelConnectionBlock conn = new ModelConnectionBlock(
+                        new ModelSource(ModelSource.SOURCE_LFO1,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR,
+                        ModelStandardTransform.TRANSFORM_LINEAR),
+                        new ModelSource(new ModelIdentifier("midi_cc", "1", 0),
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_UNIPOLAR,
+                        ModelStandardTransform.TRANSFORM_LINEAR),
+                        50,
+                        new ModelDestination(ModelDestination.DESTINATION_PITCH));
+                conn.addSource(new ModelSource(new ModelIdentifier("midi_rpn",
+                        "5")));
+                conn.setScale(conn.getScale() * 256.0);
+                performer_connections.add(conn);
+
+            }
+
+            // Let Aftertouch to behave just like modulation wheel (cc#1)
+            boolean channel_pressure_set = false;
+            boolean poly_pressure = false;
+            ModelConnectionBlock mod_cc_1_connection = null;
+            int mod_cc_1_connection_src_ix = 0;
+
+            for (ModelConnectionBlock connection : performer_connections) {
+                ModelSource[] sources = connection.getSources();
+                ModelDestination dest = connection.getDestination();
+                // if(dest != null && sources != null)
+                if (dest != null && sources != null) {
+                    for (int i = 0; i < sources.length; i++) {
+                        ModelIdentifier srcid = sources[i].getIdentifier();
+                        // check if connection block has the source "modulation
+                        // wheel cc#1"
+                        if (srcid.getObject().equals("midi_cc")) {
+                            if (srcid.getVariable().equals("1")) {
+                                mod_cc_1_connection = connection;
+                                mod_cc_1_connection_src_ix = i;
+                            }
+                        }
+                        // check if channel or poly pressure are already
+                        // connected
+                        if (srcid.getObject().equals("midi")) {
+                            if (srcid.getVariable().equals("channel_pressure"))
+                                channel_pressure_set = true;
+                            if (srcid.getVariable().equals("poly_pressure"))
+                                poly_pressure = true;
+                        }
+                    }
+                }
+
+            }
+
+            if (mod_cc_1_connection != null) {
+                if (!channel_pressure_set) {
+                    ModelConnectionBlock mc = new ModelConnectionBlock();
+                    mc.setDestination(mod_cc_1_connection.getDestination());
+                    mc.setScale(mod_cc_1_connection.getScale());
+                    ModelSource[] src_list = mod_cc_1_connection.getSources();
+                    ModelSource[] src_list_new = new ModelSource[src_list.length];
+                    for (int i = 0; i < src_list_new.length; i++)
+                        src_list_new[i] = src_list[i];
+                    src_list_new[mod_cc_1_connection_src_ix] = new ModelSource(
+                            new ModelIdentifier("midi", "channel_pressure"));
+                    mc.setSources(src_list_new);
+                    connmap.put(extractKeys(mc), mc);
+                }
+                if (!poly_pressure) {
+                    ModelConnectionBlock mc = new ModelConnectionBlock();
+                    mc.setDestination(mod_cc_1_connection.getDestination());
+                    mc.setScale(mod_cc_1_connection.getScale());
+                    ModelSource[] src_list = mod_cc_1_connection.getSources();
+                    ModelSource[] src_list_new = new ModelSource[src_list.length];
+                    for (int i = 0; i < src_list_new.length; i++)
+                        src_list_new[i] = src_list[i];
+                    src_list_new[mod_cc_1_connection_src_ix] = new ModelSource(
+                            new ModelIdentifier("midi", "poly_pressure"));
+                    mc.setSources(src_list_new);
+                    connmap.put(extractKeys(mc), mc);
+                }
+            }
+
+            // Enable Vibration Sound Controllers : 76, 77, 78
+            ModelConnectionBlock found_vib_connection = null;
+            for (ModelConnectionBlock connection : performer_connections) {
+                ModelSource[] sources = connection.getSources();
+                if (sources.length != 0
+                        && sources[0].getIdentifier().getObject().equals("lfo")) {
+                    if (connection.getDestination().getIdentifier().equals(
+                            ModelDestination.DESTINATION_PITCH)) {
+                        if (found_vib_connection == null)
+                            found_vib_connection = connection;
+                        else {
+                            if (found_vib_connection.getSources().length > sources.length)
+                                found_vib_connection = connection;
+                            else if (found_vib_connection.getSources()[0]
+                                    .getIdentifier().getInstance() < 1) {
+                                if (found_vib_connection.getSources()[0]
+                                        .getIdentifier().getInstance() >
+                                        sources[0].getIdentifier().getInstance()) {
+                                    found_vib_connection = connection;
+                                }
+                            }
+                        }
+
+                    }
+                }
+            }
+
+            int instance = 1;
+
+            if (found_vib_connection != null) {
+                instance = found_vib_connection.getSources()[0].getIdentifier()
+                        .getInstance();
+            }
+            ModelConnectionBlock connection;
+
+            connection = new ModelConnectionBlock(
+                new ModelSource(new ModelIdentifier("midi_cc", "78"),
+                    ModelStandardTransform.DIRECTION_MIN2MAX,
+                    ModelStandardTransform.POLARITY_BIPOLAR,
+                    ModelStandardTransform.TRANSFORM_LINEAR),
+                2000, new ModelDestination(
+                    new ModelIdentifier("lfo", "delay2", instance)));
+            connmap.put(extractKeys(connection), connection);
+
+            final double scale = found_vib_connection == null ? 0
+                    : found_vib_connection.getScale();
+            connection = new ModelConnectionBlock(
+                new ModelSource(new ModelIdentifier("lfo", instance)),
+                new ModelSource(new ModelIdentifier("midi_cc", "77"),
+                    new ModelTransform() {
+                        double s = scale;
+                        public double transform(double value) {
+                            value = value * 2 - 1;
+                            value *= 600;
+                            if (s == 0) {
+                                return value;
+                            } else if (s > 0) {
+                                if (value < -s)
+                                    value = -s;
+                                return value;
+                            } else {
+                                if (value < s)
+                                    value = -s;
+                                return -value;
+                            }
+                        }
+                    }), new ModelDestination(ModelDestination.DESTINATION_PITCH));
+            connmap.put(extractKeys(connection), connection);
+
+            connection = new ModelConnectionBlock(
+                new ModelSource(new ModelIdentifier("midi_cc", "76"),
+                    ModelStandardTransform.DIRECTION_MIN2MAX,
+                    ModelStandardTransform.POLARITY_BIPOLAR,
+                    ModelStandardTransform.TRANSFORM_LINEAR),
+                2400, new ModelDestination(
+                    new ModelIdentifier("lfo", "freq", instance)));
+            connmap.put(extractKeys(connection), connection);
+
+        }
+
+        // Add default connection blocks
+        if (performer.isDefaultConnectionsEnabled())
+            for (ModelConnectionBlock connection : defaultconnections)
+                connmap.put(extractKeys(connection), connection);
+        // Add connection blocks from modelperformer
+        for (ModelConnectionBlock connection : performer_connections)
+            connmap.put(extractKeys(connection), connection);
+        // seperate connection blocks : Init time, Midi Time, Midi/Control Time,
+        // Control Time
+        List<ModelConnectionBlock> connections = new ArrayList<ModelConnectionBlock>();
+
+        midi_ctrl_connections = new int[128][];
+        for (int i = 0; i < midi_ctrl_connections.length; i++) {
+            midi_ctrl_connections[i] = null;
+        }
+        midi_connections = new int[5][];
+        for (int i = 0; i < midi_connections.length; i++) {
+            midi_connections[i] = null;
+        }
+
+        int ix = 0;
+        boolean mustBeOnTop = false;
+
+        for (ModelConnectionBlock connection : connmap.values()) {
+            if (connection.getDestination() != null) {
+                ModelDestination dest = connection.getDestination();
+                ModelIdentifier id = dest.getIdentifier();
+                if (id.getObject().equals("noteon")) {
+                    mustBeOnTop = true;
+                    if (id.getVariable().equals("keynumber"))
+                        forcedKeynumber = true;
+                    if (id.getVariable().equals("velocity"))
+                        forcedVelocity = true;
+                }
+            }
+            if (mustBeOnTop) {
+                connections.add(0, connection);
+                mustBeOnTop = false;
+            } else
+                connections.add(connection);
+        }
+
+        for (ModelConnectionBlock connection : connections) {
+            if (connection.getSources() != null) {
+                ModelSource[] srcs = connection.getSources();
+                for (int i = 0; i < srcs.length; i++) {
+                    processSource(srcs[i], ix);
+                }
+            }
+            ix++;
+        }
+
+        this.connections = new ModelConnectionBlock[connections.size()];
+        connections.toArray(this.connections);
+
+        this.ctrl_connections = new int[ctrl_connections_list.size()];
+
+        for (int i = 0; i < this.ctrl_connections.length; i++)
+            this.ctrl_connections[i] = ctrl_connections_list.get(i);
+
+        oscillators = new ModelOscillator[performer.getOscillators().size()];
+        performer.getOscillators().toArray(oscillators);
+
+        for (ModelConnectionBlock conn : connections) {
+            if (conn.getDestination() != null) {
+                if (isUnnecessaryTransform(conn.getDestination().getTransform())) {
+                    conn.getDestination().setTransform(null);
+                }
+            }
+            if (conn.getSources() != null) {
+                for (ModelSource src : conn.getSources()) {
+                    if (isUnnecessaryTransform(src.getTransform())) {
+                        src.setTransform(null);
+                    }
+                }
+            }
+        }
+
+    }
+
+    private static boolean isUnnecessaryTransform(ModelTransform transform) {
+        if (transform == null)
+            return false;
+        if (!(transform instanceof ModelStandardTransform))
+            return false;
+        ModelStandardTransform stransform = (ModelStandardTransform)transform;
+        if (stransform.getDirection() != ModelStandardTransform.DIRECTION_MIN2MAX)
+            return false;
+        if (stransform.getPolarity() != ModelStandardTransform.POLARITY_UNIPOLAR)
+            return false;
+        if (stransform.getTransform() != ModelStandardTransform.TRANSFORM_LINEAR)
+            return false;
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftPointResampler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A resampler that uses 0-order (nearest-neighbor) interpolation.
+ *
+ * @author Karl Helgason
+ */
+public class SoftPointResampler extends SoftAbstractResampler {
+
+    public int getPadding() {
+        return 100;
+    }
+
+    public void interpolate(float[] in, float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        float ox_end = out_end;
+        if (pitchstep == 0) {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = in[(int) ix];
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = in[(int) ix];
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftProcess.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Control signal processor interface
+ *
+ * @author Karl Helgason
+ */
+public interface SoftProcess extends SoftControl {
+
+    public void init(SoftSynthesizer synth);
+
+    public double[] get(int instance, String name);
+
+    public void processControlLogic();
+
+    public void reset();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftProvider.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiDevice.Info;
+import javax.sound.midi.spi.MidiDeviceProvider;
+
+/**
+ * Software synthesizer provider class.
+ *
+ * @author Karl Helgason
+ */
+public class SoftProvider extends MidiDeviceProvider {
+
+    protected final static Info softinfo = SoftSynthesizer.info;
+    private static Info[] softinfos = {softinfo};
+
+    public MidiDevice.Info[] getDeviceInfo() {
+        return softinfos;
+    }
+
+    public MidiDevice getDevice(MidiDevice.Info info) {
+        if (info == softinfo) {
+            return new SoftSynthesizer();
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.TreeMap;
+
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.ShortMessage;
+
+/**
+ * Software synthesizer MIDI receiver class.
+ *
+ * @author Karl Helgason
+ */
+public class SoftReceiver implements Receiver {
+
+    protected boolean open = true;
+    private Object control_mutex;
+    private SoftSynthesizer synth;
+    protected TreeMap<Long, Object> midimessages;
+    protected SoftMainMixer mainmixer;
+
+    public SoftReceiver(SoftSynthesizer synth) {
+        this.control_mutex = synth.control_mutex;
+        this.synth = synth;
+        this.mainmixer = synth.getMainMixer();
+        if (mainmixer != null)
+            this.midimessages = mainmixer.midimessages;
+    }
+
+    public void send(MidiMessage message, long timeStamp) {
+
+        synchronized (control_mutex) {
+            if (!open)
+                throw new IllegalStateException("Receiver is not open");
+        }
+
+        if (timeStamp != -1) {
+            synchronized (control_mutex) {
+                while (midimessages.get(timeStamp) != null)
+                    timeStamp++;
+                if (message instanceof ShortMessage
+                        && (((ShortMessage)message).getChannel() > 0xF)) {
+                    midimessages.put(timeStamp, message.clone());
+                } else {
+                    midimessages.put(timeStamp, message.getMessage());
+                }
+            }
+        } else {
+            mainmixer.processMessage(message);
+        }
+    }
+
+    public void close() {
+        synchronized (control_mutex) {
+            open = false;
+        }
+        synth.removeReceiver(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftResampler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Basic resampler interface.
+ *
+ * @author Karl Helgason
+ */
+public interface SoftResampler {
+
+    public SoftResamplerStreamer openStreamer();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftResamplerStreamer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+
+/**
+ * Resampler stream interface.
+ *
+ * @author Karl Helgason
+ */
+public interface SoftResamplerStreamer extends ModelOscillatorStream {
+
+    public void open(ModelWavetable osc, float outputsamplerate)
+            throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftReverb.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,515 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Arrays;
+
+/**
+ * Reverb effect based on allpass/comb filters. First audio is send to 8
+ * parelled comb filters and then mixed together and then finally send thru 3
+ * different allpass filters.
+ *
+ * @author Karl Helgason
+ */
+public class SoftReverb implements SoftAudioProcessor {
+
+    private final static class Delay {
+
+        private float[] delaybuffer;
+        private int rovepos = 0;
+
+        public Delay() {
+            delaybuffer = null;
+        }
+
+        public void setDelay(int delay) {
+            if (delay == 0)
+                delaybuffer = null;
+            else
+                delaybuffer = new float[delay];
+            rovepos = 0;
+        }
+
+        public void processReplace(float[] inout) {
+            if (delaybuffer == null)
+                return;
+            int len = inout.length;
+            int rnlen = delaybuffer.length;
+            int rovepos = this.rovepos;
+
+            for (int i = 0; i < len; i++) {
+                float x = inout[i];
+                inout[i] = delaybuffer[rovepos];
+                delaybuffer[rovepos] = x;
+                if (++rovepos == rnlen)
+                    rovepos = 0;
+            }
+            this.rovepos = rovepos;
+        }
+    }
+
+    private final static class AllPass {
+
+        private final float[] delaybuffer;
+        private final int delaybuffersize;
+        private int rovepos = 0;
+        private float feedback;
+
+        public AllPass(int size) {
+            delaybuffer = new float[size];
+            delaybuffersize = size;
+        }
+
+        public void setFeedBack(float feedback) {
+            this.feedback = feedback;
+        }
+
+        public void processReplace(float inout[]) {
+            int len = inout.length;
+            int delaybuffersize = this.delaybuffersize;
+            int rovepos = this.rovepos;
+            for (int i = 0; i < len; i++) {
+                float delayout = delaybuffer[rovepos];
+                float input = inout[i];
+                inout[i] = delayout - input;
+                delaybuffer[rovepos] = input + delayout * feedback;
+                if (++rovepos == delaybuffersize)
+                    rovepos = 0;
+            }
+            this.rovepos = rovepos;
+        }
+
+        public void processReplace(float in[], float out[]) {
+            int len = in.length;
+            int delaybuffersize = this.delaybuffersize;
+            int rovepos = this.rovepos;
+            for (int i = 0; i < len; i++) {
+                float delayout = delaybuffer[rovepos];
+                float input = in[i];
+                out[i] = delayout - input;
+                delaybuffer[rovepos] = input + delayout * feedback;
+                if (++rovepos == delaybuffersize)
+                    rovepos = 0;
+            }
+            this.rovepos = rovepos;
+        }
+    }
+
+    private final static class Comb {
+
+        private final float[] delaybuffer;
+        private final int delaybuffersize;
+        private int rovepos = 0;
+        private float feedback;
+        private float filtertemp = 0;
+        private float filtercoeff1 = 0;
+        private float filtercoeff2 = 1;
+
+        public Comb(int size) {
+            delaybuffer = new float[size];
+            delaybuffersize = size;
+        }
+
+        public void setFeedBack(float feedback) {
+            this.feedback = feedback;
+            filtercoeff2 = (1 - filtercoeff1)* feedback;
+        }
+
+        public void processMix(float in[], float out[]) {
+            int len = in.length;
+            int delaybuffersize = this.delaybuffersize;
+            int rovepos = this.rovepos;
+            float filtertemp = this.filtertemp;
+            float filtercoeff1 = this.filtercoeff1;
+            float filtercoeff2 = this.filtercoeff2;
+            for (int i = 0; i < len; i++) {
+                float delayout = delaybuffer[rovepos];
+                // One Pole Lowpass Filter
+                filtertemp = (delayout * filtercoeff2)
+                        + (filtertemp * filtercoeff1);
+                out[i] += delayout;
+                delaybuffer[rovepos] = in[i] + filtertemp;
+                if (++rovepos == delaybuffersize)
+                    rovepos = 0;
+            }
+            this.filtertemp  = filtertemp;
+            this.rovepos = rovepos;
+        }
+
+        public void processReplace(float in[], float out[]) {
+            int len = in.length;
+            int delaybuffersize = this.delaybuffersize;
+            int rovepos = this.rovepos;
+            float filtertemp = this.filtertemp;
+            float filtercoeff1 = this.filtercoeff1;
+            float filtercoeff2 = this.filtercoeff2;
+            for (int i = 0; i < len; i++) {
+                float delayout = delaybuffer[rovepos];
+                // One Pole Lowpass Filter
+                filtertemp = (delayout * filtercoeff2)
+                        + (filtertemp * filtercoeff1);
+                out[i] = delayout;
+                delaybuffer[rovepos] = in[i] + filtertemp;
+                if (++rovepos == delaybuffersize)
+                    rovepos = 0;
+            }
+            this.filtertemp  = filtertemp;
+            this.rovepos = rovepos;
+        }
+
+        public void setDamp(float val) {
+            filtercoeff1 = val;
+            filtercoeff2 = (1 - filtercoeff1)* feedback;
+        }
+    }
+    private float roomsize;
+    private float damp;
+    private float gain = 1;
+    private Delay delay;
+    private Comb[] combL;
+    private Comb[] combR;
+    private AllPass[] allpassL;
+    private AllPass[] allpassR;
+    private float[] input;
+    private float[] out;
+    private float[] pre1;
+    private float[] pre2;
+    private float[] pre3;
+    private boolean denormal_flip = false;
+    private boolean mix = true;
+    private SoftAudioBuffer inputA;
+    private SoftAudioBuffer left;
+    private SoftAudioBuffer right;
+    private boolean dirty = true;
+    private float dirty_roomsize;
+    private float dirty_damp;
+    private float dirty_predelay;
+    private float dirty_gain;
+    private float samplerate;
+    private boolean light = true;
+
+    public void init(float samplerate, float controlrate) {
+        this.samplerate = samplerate;
+
+        double freqscale = ((double) samplerate) / 44100.0;
+        // freqscale = 1.0/ freqscale;
+
+        int stereospread = 23;
+
+        delay = new Delay();
+
+        combL = new Comb[8];
+        combR = new Comb[8];
+        combL[0] = new Comb((int) (freqscale * (1116)));
+        combR[0] = new Comb((int) (freqscale * (1116 + stereospread)));
+        combL[1] = new Comb((int) (freqscale * (1188)));
+        combR[1] = new Comb((int) (freqscale * (1188 + stereospread)));
+        combL[2] = new Comb((int) (freqscale * (1277)));
+        combR[2] = new Comb((int) (freqscale * (1277 + stereospread)));
+        combL[3] = new Comb((int) (freqscale * (1356)));
+        combR[3] = new Comb((int) (freqscale * (1356 + stereospread)));
+        combL[4] = new Comb((int) (freqscale * (1422)));
+        combR[4] = new Comb((int) (freqscale * (1422 + stereospread)));
+        combL[5] = new Comb((int) (freqscale * (1491)));
+        combR[5] = new Comb((int) (freqscale * (1491 + stereospread)));
+        combL[6] = new Comb((int) (freqscale * (1557)));
+        combR[6] = new Comb((int) (freqscale * (1557 + stereospread)));
+        combL[7] = new Comb((int) (freqscale * (1617)));
+        combR[7] = new Comb((int) (freqscale * (1617 + stereospread)));
+
+        allpassL = new AllPass[4];
+        allpassR = new AllPass[4];
+        allpassL[0] = new AllPass((int) (freqscale * (556)));
+        allpassR[0] = new AllPass((int) (freqscale * (556 + stereospread)));
+        allpassL[1] = new AllPass((int) (freqscale * (441)));
+        allpassR[1] = new AllPass((int) (freqscale * (441 + stereospread)));
+        allpassL[2] = new AllPass((int) (freqscale * (341)));
+        allpassR[2] = new AllPass((int) (freqscale * (341 + stereospread)));
+        allpassL[3] = new AllPass((int) (freqscale * (225)));
+        allpassR[3] = new AllPass((int) (freqscale * (225 + stereospread)));
+
+        for (int i = 0; i < allpassL.length; i++) {
+            allpassL[i].setFeedBack(0.5f);
+            allpassR[i].setFeedBack(0.5f);
+        }
+
+        /* Init other settings */
+        globalParameterControlChange(new int[]{0x01 * 128 + 0x01}, 0, 4);
+
+    }
+
+    public void setInput(int pin, SoftAudioBuffer input) {
+        if (pin == 0)
+            inputA = input;
+    }
+
+    public void setOutput(int pin, SoftAudioBuffer output) {
+        if (pin == 0)
+            left = output;
+        if (pin == 1)
+            right = output;
+    }
+
+    public void setMixMode(boolean mix) {
+        this.mix = mix;
+    }
+
+    private boolean silent = true;
+
+    public void processAudio() {
+        boolean silent_input = this.inputA.isSilent();
+        if(!silent_input)
+            silent = false;
+        if(silent)
+        {
+            if (!mix) {
+                left.clear();
+                right.clear();
+            }
+            return;
+        }
+
+        float[] inputA = this.inputA.array();
+        float[] left = this.left.array();
+        float[] right = this.right == null ? null : this.right.array();
+
+        int numsamples = inputA.length;
+        if (input == null || input.length < numsamples)
+            input = new float[numsamples];
+
+        float again = gain * 0.018f / 2;
+
+        denormal_flip = !denormal_flip;
+        if(denormal_flip)
+            for (int i = 0; i < numsamples; i++)
+                input[i] = inputA[i] * again + 1E-20f;
+        else
+            for (int i = 0; i < numsamples; i++)
+                input[i] = inputA[i] * again - 1E-20f;
+
+        delay.processReplace(input);
+
+        if(light && (right != null))
+        {
+            if (pre1 == null || pre1.length < numsamples)
+            {
+                pre1 = new float[numsamples];
+                pre2 = new float[numsamples];
+                pre3 = new float[numsamples];
+            }
+
+            for (int i = 0; i < allpassL.length; i++)
+                allpassL[i].processReplace(input);
+
+            combL[0].processReplace(input, pre3);
+            combL[1].processReplace(input, pre3);
+
+            combL[2].processReplace(input, pre1);
+            for (int i = 4; i < combL.length-2; i+=2)
+                combL[i].processMix(input, pre1);
+
+            combL[3].processReplace(input, pre2);;
+            for (int i = 5; i < combL.length-2; i+=2)
+                combL[i].processMix(input, pre2);
+
+            if (!mix)
+            {
+                Arrays.fill(right, 0);
+                Arrays.fill(left, 0);
+            }
+            for (int i = combR.length-2; i < combR.length; i++)
+                combR[i].processMix(input, right);
+            for (int i = combL.length-2; i < combL.length; i++)
+                combL[i].processMix(input, left);
+
+            for (int i = 0; i < numsamples; i++)
+            {
+                float p = pre1[i] - pre2[i];
+                float m = pre3[i];
+                left[i] += m + p;
+                right[i] += m - p;
+            }
+        }
+        else
+        {
+            if (out == null || out.length < numsamples)
+                out = new float[numsamples];
+
+            if (right != null) {
+                if (!mix)
+                    Arrays.fill(right, 0);
+                allpassR[0].processReplace(input, out);
+                for (int i = 1; i < allpassR.length; i++)
+                    allpassR[i].processReplace(out);
+                for (int i = 0; i < combR.length; i++)
+                    combR[i].processMix(out, right);
+            }
+
+            if (!mix)
+                Arrays.fill(left, 0);
+            allpassL[0].processReplace(input, out);
+            for (int i = 1; i < allpassL.length; i++)
+                allpassL[i].processReplace(out);
+            for (int i = 0; i < combL.length; i++)
+                combL[i].processMix(out, left);
+        }
+
+
+
+
+
+
+        if (silent_input) {
+            silent = true;
+            for (int i = 0; i < numsamples; i++)
+            {
+                float v = left[i];
+                if(v > 1E-10 || v < -1E-10)
+                {
+                    silent = false;
+                    break;
+                }
+            }
+        }
+
+    }
+
+    public void globalParameterControlChange(int[] slothpath, long param,
+            long value) {
+        if (slothpath.length == 1) {
+            if (slothpath[0] == 0x01 * 128 + 0x01) {
+
+                if (param == 0) {
+                    if (value == 0) {
+                        // Small Room A small size room with a length
+                        // of 5m or so.
+                        dirty_roomsize = (1.1f);
+                        dirty_damp = (5000);
+                        dirty_predelay = (0);
+                        dirty_gain = (4);
+                        dirty = true;
+                    }
+                    if (value == 1) {
+                        // Medium Room A medium size room with a length
+                        // of 10m or so.
+                        dirty_roomsize = (1.3f);
+                        dirty_damp = (5000);
+                        dirty_predelay = (0);
+                        dirty_gain = (3);
+                        dirty = true;
+                    }
+                    if (value == 2) {
+                        // Large Room A large size room suitable for
+                        // live performances.
+                        dirty_roomsize = (1.5f);
+                        dirty_damp = (5000);
+                        dirty_predelay = (0);
+                        dirty_gain = (2);
+                        dirty = true;
+                    }
+                    if (value == 3) {
+                        // Medium Hall A medium size concert hall.
+                        dirty_roomsize = (1.8f);
+                        dirty_damp = (24000);
+                        dirty_predelay = (0.02f);
+                        dirty_gain = (1.5f);
+                        dirty = true;
+                    }
+                    if (value == 4) {
+                        // Large Hall A large size concert hall
+                        // suitable for a full orchestra.
+                        dirty_roomsize = (1.8f);
+                        dirty_damp = (24000);
+                        dirty_predelay = (0.03f);
+                        dirty_gain = (1.5f);
+                        dirty = true;
+                    }
+                    if (value == 8) {
+                        // Plate A plate reverb simulation.
+                        dirty_roomsize = (1.3f);
+                        dirty_damp = (2500);
+                        dirty_predelay = (0);
+                        dirty_gain = (6);
+                        dirty = true;
+                    }
+                } else if (param == 1) {
+                    dirty_roomsize = ((float) (Math.exp((value - 40) * 0.025)));
+                    dirty = true;
+                }
+
+            }
+        }
+    }
+
+    public void processControlLogic() {
+        if (dirty) {
+            dirty = false;
+            setRoomSize(dirty_roomsize);
+            setDamp(dirty_damp);
+            setPreDelay(dirty_predelay);
+            setGain(dirty_gain);
+        }
+    }
+
+    public void setRoomSize(float value) {
+        roomsize = 1 - (0.17f / value);
+
+        for (int i = 0; i < combL.length; i++) {
+            combL[i].feedback = roomsize;
+            combR[i].feedback = roomsize;
+        }
+    }
+
+    public void setPreDelay(float value) {
+        delay.setDelay((int)(value * samplerate));
+    }
+
+    public void setGain(float gain) {
+        this.gain = gain;
+    }
+
+    public void setDamp(float value) {
+        double x = (value / samplerate) * (2 * Math.PI);
+        double cx = 2 - Math.cos(x);
+        damp = (float)(cx - Math.sqrt(cx * cx - 1));
+        if (damp > 1)
+            damp = 1;
+        if (damp < 0)
+            damp = 0;
+
+        // damp = value * 0.4f;
+        for (int i = 0; i < combL.length; i++) {
+            combL[i].setDamp(damp);
+            combR[i].setDamp(damp);
+        }
+
+    }
+
+    public void setLightMode(boolean light)
+    {
+        this.light = light;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftShortMessage.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.ShortMessage;
+
+/**
+ * A short message class that support for than 16 midi channels.
+ *
+ * @author Karl Helgason
+ */
+public class SoftShortMessage extends ShortMessage {
+
+    int channel = 0;
+
+    public int getChannel() {
+        return channel;
+    }
+
+    public void setMessage(int command, int channel, int data1, int data2)
+            throws InvalidMidiDataException {
+        this.channel = channel;
+        super.setMessage(command, channel & 0xF, data1, data2);
+    }
+
+    public Object clone() {
+        SoftShortMessage clone = new SoftShortMessage();
+        try {
+            clone.setMessage(getCommand(), getChannel(), getData1(), getData2());
+        } catch (InvalidMidiDataException e) {
+            throw new IllegalArgumentException(e);
+        }
+        return clone;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftSincResampler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Hann windowed sinc interpolation resampler with anti-alias filtering.
+ *
+ * Using 30 points for the interpolation.
+ *
+ * @author Karl Helgason
+ */
+public class SoftSincResampler extends SoftAbstractResampler {
+
+    float[][][] sinc_table;
+    int sinc_scale_size = 100;
+    int sinc_table_fsize = 800;
+    int sinc_table_size = 30;
+    int sinc_table_center = sinc_table_size / 2;
+
+    public SoftSincResampler() {
+        super();
+        sinc_table = new float[sinc_scale_size][sinc_table_fsize][];
+        for (int s = 0; s < sinc_scale_size; s++) {
+            float scale = (float) (1.0 / (1.0 + Math.pow(s, 1.1) / 10.0));
+            for (int i = 0; i < sinc_table_fsize; i++) {
+                sinc_table[s][i] = sincTable(sinc_table_size,
+                        -i / ((float)sinc_table_fsize), scale);
+            }
+        }
+    }
+
+    // Normalized sinc function
+    public static double sinc(double x) {
+        return (x == 0.0) ? 1.0 : Math.sin(Math.PI * x) / (Math.PI * x);
+    }
+
+    // Generate hann window suitable for windowing sinc
+    public static float[] wHanning(int size, float offset) {
+        float[] window_table = new float[size];
+        for (int k = 0; k < size; k++) {
+            window_table[k] = (float)(-0.5
+                    * Math.cos(2.0 * Math.PI * (double)(k + offset)
+                        / (double) size) + 0.5);
+        }
+        return window_table;
+    }
+
+    // Generate sinc table
+    public static float[] sincTable(int size, float offset, float scale) {
+        int center = size / 2;
+        float[] w = wHanning(size, offset);
+        for (int k = 0; k < size; k++)
+            w[k] *= sinc((-center + k + offset) * scale) * scale;
+        return w;
+    }
+
+    public int getPadding() // must be at least half of sinc_table_size
+    {
+        return sinc_table_size / 2 + 2;
+    }
+
+    public void interpolate(float[] in, float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+        int max_p = sinc_scale_size - 1;
+        if (pitchstep == 0) {
+
+            int p = (int) ((pitch - 1) * 10.0f);
+            if (p < 0)
+                p = 0;
+            else if (p > max_p)
+                p = max_p;
+            float[][] sinc_table_f = this.sinc_table[p];
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float[] sinc_table =
+                        sinc_table_f[(int)((ix - iix) * sinc_table_fsize)];
+                int xx = iix - sinc_table_center;
+                float y = 0;
+                for (int i = 0; i < sinc_table_size; i++, xx++)
+                    y += in[xx] * sinc_table[i];
+                out[ox++] = y;
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                int p = (int) ((pitch - 1) * 10.0f);
+                if (p < 0)
+                    p = 0;
+                else if (p > max_p)
+                    p = max_p;
+                float[][] sinc_table_f = this.sinc_table[p];
+
+                float[] sinc_table =
+                        sinc_table_f[(int)((ix - iix) * sinc_table_fsize)];
+                int xx = iix - sinc_table_center;
+                float y = 0;
+                for (int i = 0; i < sinc_table_size; i++, xx++)
+                    y += in[xx] * sinc_table[i];
+                out[ox++] = y;
+
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,1179 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.WeakReference;
+import java.security.AccessControlException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.Transmitter;
+import javax.sound.midi.VoiceStatus;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * The software synthesizer class.
+ *
+ * @author Karl Helgason
+ */
+public class SoftSynthesizer implements AudioSynthesizer,
+        ReferenceCountingDevice {
+
+    protected static class WeakAudioStream extends InputStream
+    {
+        private volatile AudioInputStream stream;
+        public SoftAudioPusher pusher = null;
+        public AudioInputStream jitter_stream = null;
+        public SourceDataLine sourceDataLine = null;
+        private WeakReference<AudioInputStream> weak_stream_link;
+        private AudioFloatConverter converter;
+        private float[] silentbuffer = null;
+        private int samplesize;
+
+        public void setInputStream(AudioInputStream stream)
+        {
+            this.stream = stream;
+        }
+
+        public int available() throws IOException {
+            AudioInputStream local_stream = stream;
+            if(local_stream != null)
+                return local_stream.available();
+            return 0;
+        }
+
+        public int read() throws IOException {
+             byte[] b = new byte[1];
+             if (read(b) == -1)
+                  return -1;
+             return b[0] & 0xFF;
+        }
+
+        public int read(byte[] b, int off, int len) throws IOException {
+             AudioInputStream local_stream = stream;
+             if(local_stream != null)
+                 return local_stream.read(b, off, len);
+             else
+             {
+                 int flen = len / samplesize;
+                 if(silentbuffer == null || silentbuffer.length < flen)
+                     silentbuffer = new float[flen];
+                 converter.toByteArray(silentbuffer, flen, b, off);
+
+                 if(pusher != null)
+                 if(weak_stream_link.get() == null)
+                 {
+                     Runnable runnable = new Runnable()
+                     {
+                         SoftAudioPusher _pusher = pusher;
+                         AudioInputStream _jitter_stream = jitter_stream;
+                         SourceDataLine _sourceDataLine = sourceDataLine;
+                         public void run()
+                         {
+                             _pusher.stop();
+                             if(_jitter_stream != null)
+                                try {
+                                    _jitter_stream.close();
+                                } catch (IOException e) {
+                                    e.printStackTrace();
+                                }
+                             if(_sourceDataLine != null)
+                                 _sourceDataLine.close();
+                         }
+                     };
+                     pusher = null;
+                     jitter_stream = null;
+                     sourceDataLine = null;
+                     new Thread(runnable).start();
+                 }
+                 return len;
+             }
+        }
+
+        public WeakAudioStream(AudioInputStream stream) {
+            this.stream = stream;
+            weak_stream_link = new WeakReference<AudioInputStream>(stream);
+            converter = AudioFloatConverter.getConverter(stream.getFormat());
+            samplesize = stream.getFormat().getFrameSize() / stream.getFormat().getChannels();
+        }
+
+        public AudioInputStream getAudioInputStream()
+        {
+            return new AudioInputStream(this, stream.getFormat(), AudioSystem.NOT_SPECIFIED);
+        }
+
+        public void close() throws IOException
+        {
+            AudioInputStream astream  = weak_stream_link.get();
+            if(astream != null)
+                astream.close();
+        }
+    }
+
+    private static class Info extends MidiDevice.Info {
+        public Info() {
+            super(INFO_NAME, INFO_VENDOR, INFO_DESCRIPTION, INFO_VERSION);
+        }
+    }
+
+    protected static final String INFO_NAME = "Gervill";
+    protected static final String INFO_VENDOR = "OpenJDK";
+    protected static final String INFO_DESCRIPTION = "Software MIDI Synthesizer";
+    protected static final String INFO_VERSION = "1.0";
+    protected final static MidiDevice.Info info = new Info();
+
+    private static SourceDataLine testline = null;
+
+    private static Soundbank defaultSoundBank = null;
+
+    protected WeakAudioStream weakstream = null;
+
+    protected Object control_mutex = this;
+
+    protected int voiceIDCounter = 0;
+
+    // 0: default
+    // 1: DLS Voice Allocation
+    protected int voice_allocation_mode = 0;
+
+    protected boolean reverb_light = true;
+    protected boolean reverb_on = true;
+    protected boolean chorus_on = true;
+    protected boolean agc_on = true;
+
+    protected SoftChannel[] channels;
+    protected SoftChannelProxy[] external_channels = null;
+
+    private boolean largemode = false;
+
+    // 0: GM Mode off (default)
+    // 1: GM Level 1
+    // 2: GM Level 2
+    private int gmmode = 0;
+
+    private int deviceid = 0;
+
+    private AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+
+    private SourceDataLine sourceDataLine = null;
+
+    private SoftAudioPusher pusher = null;
+    private AudioInputStream pusher_stream = null;
+
+    private float controlrate = 147f;
+
+    private boolean open = false;
+    private boolean implicitOpen = false;
+
+    private String resamplerType = "linear";
+    private SoftResampler resampler = new SoftLinearResampler();
+
+    private int number_of_midi_channels = 16;
+    private int maxpoly = 64;
+    private long latency = 200000; // 200 msec
+    private boolean jitter_correction = false;
+
+    private SoftMainMixer mainmixer;
+    private SoftVoice[] voices;
+
+    private Map<String, SoftTuning> tunings
+            = new HashMap<String, SoftTuning>();
+    private Map<String, SoftInstrument> inslist
+            = new HashMap<String, SoftInstrument>();
+    private Map<String, ModelInstrument> availlist
+            = new HashMap<String, ModelInstrument>();
+    private Map<String, ModelInstrument> loadedlist
+            = new HashMap<String, ModelInstrument>();
+
+    private ArrayList<Receiver> recvslist = new ArrayList<Receiver>();
+
+    private void getBuffers(ModelInstrument instrument,
+            List<ModelByteBuffer> buffers) {
+        for (ModelPerformer performer : instrument.getPerformers()) {
+            if (performer.getOscillators() != null) {
+                for (ModelOscillator osc : performer.getOscillators()) {
+                    if (osc instanceof ModelByteBufferWavetable) {
+                        ModelByteBufferWavetable w = (ModelByteBufferWavetable)osc;
+                        ModelByteBuffer buff = w.getBuffer();
+                        if (buff != null)
+                            buffers.add(buff);
+                        buff = w.get8BitExtensionBuffer();
+                        if (buff != null)
+                            buffers.add(buff);
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean loadSamples(List<ModelInstrument> instruments) {
+        if (largemode)
+            return true;
+        List<ModelByteBuffer> buffers = new ArrayList<ModelByteBuffer>();
+        for (ModelInstrument instrument : instruments)
+            getBuffers(instrument, buffers);
+        try {
+            ModelByteBuffer.loadAll(buffers);
+        } catch (IOException e) {
+            return false;
+        }
+        return true;
+    }
+
+    private boolean loadInstruments(List<ModelInstrument> instruments) {
+        if (!isOpen())
+            return false;
+        if (!loadSamples(instruments))
+            return false;
+
+        synchronized (control_mutex) {
+            if (channels != null)
+                for (SoftChannel c : channels)
+                    c.current_instrument = null;
+            for (Instrument instrument : instruments) {
+                String pat = patchToString(instrument.getPatch());
+                availlist.remove(pat);
+                SoftInstrument softins
+                        = new SoftInstrument((ModelInstrument) instrument);
+                inslist.put(pat, softins);
+                loadedlist.put(pat, (ModelInstrument) instrument);
+            }
+        }
+
+        return true;
+    }
+
+    private void processPropertyInfo(Map<String, Object> info) {
+        AudioSynthesizerPropertyInfo[] items = getPropertyInfo(info);
+
+        String resamplerType = (String)items[0].value;
+        if (resamplerType.equalsIgnoreCase("point"))
+        {
+            this.resampler = new SoftPointResampler();
+            this.resamplerType = "point";
+        }
+        else if (resamplerType.equalsIgnoreCase("linear"))
+        {
+            this.resampler = new SoftLinearResampler2();
+            this.resamplerType = "linear";
+        }
+        else if (resamplerType.equalsIgnoreCase("linear1"))
+        {
+            this.resampler = new SoftLinearResampler();
+            this.resamplerType = "linear1";
+        }
+        else if (resamplerType.equalsIgnoreCase("linear2"))
+        {
+            this.resampler = new SoftLinearResampler2();
+            this.resamplerType = "linear2";
+        }
+        else if (resamplerType.equalsIgnoreCase("cubic"))
+        {
+            this.resampler = new SoftCubicResampler();
+            this.resamplerType = "cubic";
+        }
+        else if (resamplerType.equalsIgnoreCase("lanczos"))
+        {
+            this.resampler = new SoftLanczosResampler();
+            this.resamplerType = "lanczos";
+        }
+        else if (resamplerType.equalsIgnoreCase("sinc"))
+        {
+            this.resampler = new SoftSincResampler();
+            this.resamplerType = "sinc";
+        }
+
+        setFormat((AudioFormat)items[2].value);
+        controlrate = (Float)items[1].value;
+        latency = (Long)items[3].value;
+        deviceid = (Integer)items[4].value;
+        maxpoly = (Integer)items[5].value;
+        reverb_on = (Boolean)items[6].value;
+        chorus_on = (Boolean)items[7].value;
+        agc_on = (Boolean)items[8].value;
+        largemode = (Boolean)items[9].value;
+        number_of_midi_channels = (Integer)items[10].value;
+        jitter_correction = (Boolean)items[11].value;
+        reverb_light = (Boolean)items[12].value;
+    }
+
+    private String patchToString(Patch patch) {
+        if (patch instanceof ModelPatch && ((ModelPatch) patch).isPercussion())
+            return "p." + patch.getProgram() + "." + patch.getBank();
+        else
+            return patch.getProgram() + "." + patch.getBank();
+    }
+
+    private void setFormat(AudioFormat format) {
+        if (format.getChannels() > 2) {
+            throw new IllegalArgumentException(
+                    "Only mono and stereo audio supported.");
+        }
+        if (AudioFloatConverter.getConverter(format) == null)
+            throw new IllegalArgumentException("Audio format not supported.");
+        this.format = format;
+    }
+
+    protected void removeReceiver(Receiver recv) {
+        boolean perform_close = false;
+        synchronized (control_mutex) {
+            if (recvslist.remove(recv)) {
+                if (implicitOpen && recvslist.isEmpty())
+                    perform_close = true;
+            }
+        }
+        if (perform_close)
+            close();
+    }
+
+    protected SoftMainMixer getMainMixer() {
+        if (!isOpen())
+            return null;
+        return mainmixer;
+    }
+
+    protected SoftInstrument findInstrument(int program, int bank, int channel) {
+
+        // Add support for GM2 banks 0x78 and 0x79
+        // as specified in DLS 2.2 in Section 1.4.6
+        // which allows using percussion and melodic instruments
+        // on all channels
+        if (bank >> 7 == 0x78 || bank >> 7 == 0x79) {
+            SoftInstrument current_instrument
+                    = inslist.get(program + "." + bank);
+            if (current_instrument != null)
+                return current_instrument;
+
+            String p_plaf;
+            if (bank >> 7 == 0x78)
+                p_plaf = "p.";
+            else
+                p_plaf = "";
+
+            // Instrument not found fallback to MSB:bank, LSB:0
+            current_instrument = inslist.get(p_plaf + program + "."
+                    + ((bank & 128) << 7));
+            if (current_instrument != null)
+                return current_instrument;
+            // Instrument not found fallback to MSB:0, LSB:bank
+            current_instrument = inslist.get(p_plaf + program + "."
+                    + (bank & 128));
+            if (current_instrument != null)
+                return current_instrument;
+            // Instrument not found fallback to MSB:0, LSB:0
+            current_instrument = inslist.get(p_plaf + program + ".0");
+            if (current_instrument != null)
+                return current_instrument;
+            // Instrument not found fallback to MSB:0, LSB:0, program=0
+            current_instrument = inslist.get(p_plaf + program + "0.0");
+            if (current_instrument != null)
+                return current_instrument;
+            return null;
+        }
+
+        // Channel 10 uses percussion instruments
+        String p_plaf;
+        if (channel == 9)
+            p_plaf = "p.";
+        else
+            p_plaf = "";
+
+        SoftInstrument current_instrument
+                = inslist.get(p_plaf + program + "." + bank);
+        if (current_instrument != null)
+            return current_instrument;
+        // Instrument not found fallback to MSB:0, LSB:0
+        current_instrument = inslist.get(p_plaf + program + ".0");
+        if (current_instrument != null)
+            return current_instrument;
+        // Instrument not found fallback to MSB:0, LSB:0, program=0
+        current_instrument = inslist.get(p_plaf + "0.0");
+        if (current_instrument != null)
+            return current_instrument;
+        return null;
+    }
+
+    protected int getVoiceAllocationMode() {
+        return voice_allocation_mode;
+    }
+
+    protected int getGeneralMidiMode() {
+        return gmmode;
+    }
+
+    protected void setGeneralMidiMode(int gmmode) {
+        this.gmmode = gmmode;
+    }
+
+    protected int getDeviceID() {
+        return deviceid;
+    }
+
+    protected float getControlRate() {
+        return controlrate;
+    }
+
+    protected SoftVoice[] getVoices() {
+        return voices;
+    }
+
+    protected SoftTuning getTuning(Patch patch) {
+        String t_id = patchToString(patch);
+        SoftTuning tuning = tunings.get(t_id);
+        if (tuning == null) {
+            tuning = new SoftTuning(patch);
+            tunings.put(t_id, tuning);
+        }
+        return tuning;
+    }
+
+    public long getLatency() {
+        synchronized (control_mutex) {
+            return latency;
+        }
+    }
+
+    public AudioFormat getFormat() {
+        synchronized (control_mutex) {
+            return format;
+        }
+    }
+
+    public int getMaxPolyphony() {
+        synchronized (control_mutex) {
+            return maxpoly;
+        }
+    }
+
+    public MidiChannel[] getChannels() {
+
+        synchronized (control_mutex) {
+            // if (external_channels == null) => the synthesizer is not open,
+            // create 16 proxy channels
+            // otherwise external_channels has the same length as channels array
+            if (external_channels == null) {
+                external_channels = new SoftChannelProxy[16];
+                for (int i = 0; i < external_channels.length; i++)
+                    external_channels[i] = new SoftChannelProxy();
+            }
+            MidiChannel[] ret;
+            if (isOpen())
+                ret = new MidiChannel[channels.length];
+            else
+                ret = new MidiChannel[16];
+            for (int i = 0; i < ret.length; i++)
+                ret[i] = external_channels[i];
+            return ret;
+        }
+    }
+
+    public VoiceStatus[] getVoiceStatus() {
+        if (!isOpen()) {
+            VoiceStatus[] tempVoiceStatusArray
+                    = new VoiceStatus[getMaxPolyphony()];
+            for (int i = 0; i < tempVoiceStatusArray.length; i++) {
+                VoiceStatus b = new VoiceStatus();
+                b.active = false;
+                b.bank = 0;
+                b.channel = 0;
+                b.note = 0;
+                b.program = 0;
+                b.volume = 0;
+                tempVoiceStatusArray[i] = b;
+            }
+            return tempVoiceStatusArray;
+        }
+
+        synchronized (control_mutex) {
+            VoiceStatus[] tempVoiceStatusArray = new VoiceStatus[voices.length];
+            for (int i = 0; i < voices.length; i++) {
+                VoiceStatus a = voices[i];
+                VoiceStatus b = new VoiceStatus();
+                b.active = a.active;
+                b.bank = a.bank;
+                b.channel = a.channel;
+                b.note = a.note;
+                b.program = a.program;
+                b.volume = a.volume;
+                tempVoiceStatusArray[i] = b;
+            }
+            return tempVoiceStatusArray;
+        }
+    }
+
+    public boolean isSoundbankSupported(Soundbank soundbank) {
+        for (Instrument ins: soundbank.getInstruments())
+            if (!(ins instanceof ModelInstrument))
+                return false;
+        return true;
+    }
+
+    public boolean loadInstrument(Instrument instrument) {
+        if (instrument == null || (!(instrument instanceof ModelInstrument))) {
+            throw new IllegalArgumentException("Unsupported instrument: " +
+                    instrument);
+        }
+        List<ModelInstrument> instruments = new ArrayList<ModelInstrument>();
+        instruments.add((ModelInstrument)instrument);
+        return loadInstruments(instruments);
+    }
+
+    public void unloadInstrument(Instrument instrument) {
+        if (instrument == null || (!(instrument instanceof ModelInstrument))) {
+            throw new IllegalArgumentException("Unsupported instrument: " +
+                    instrument);
+        }
+        if (!isOpen())
+            return;
+
+        String pat = patchToString(instrument.getPatch());
+        synchronized (control_mutex) {
+            for (SoftChannel c: channels)
+                c.current_instrument = null;
+            inslist.remove(pat);
+            loadedlist.remove(pat);
+            availlist.remove(pat);
+        }
+    }
+
+    public boolean remapInstrument(Instrument from, Instrument to) {
+
+        if (from == null)
+            throw new NullPointerException();
+        if (to == null)
+            throw new NullPointerException();
+        if (!(from instanceof ModelInstrument)) {
+            throw new IllegalArgumentException("Unsupported instrument: " +
+                    from.toString());
+        }
+        if (!(to instanceof ModelInstrument)) {
+            throw new IllegalArgumentException("Unsupported instrument: " +
+                    to.toString());
+        }
+        if (!isOpen())
+            return false;
+
+        synchronized (control_mutex) {
+            if (!loadedlist.containsValue(to) && !availlist.containsValue(to))
+                throw new IllegalArgumentException("Instrument to is not loaded.");
+            unloadInstrument(from);
+            ModelMappedInstrument mfrom = new ModelMappedInstrument(
+                    (ModelInstrument)to, from.getPatch());
+            return loadInstrument(mfrom);
+        }
+    }
+
+    public synchronized Soundbank getDefaultSoundbank() {
+        if (defaultSoundBank == null) {
+            try {
+                File javahome = new File(System.getProperties().getProperty(
+                        "java.home"));
+                File libaudio = new File(new File(javahome, "lib"), "audio");
+
+                if (libaudio.exists()) {
+                    File foundfile = null;
+                    File[] files = libaudio.listFiles();
+                    if (files != null) {
+                        for (int i = 0; i < files.length; i++) {
+                            File file = files[i];
+                            if (file.isFile()) {
+                                String lname = file.getName().toLowerCase();
+                                if (lname.endsWith(".sf2") ||
+                                        lname.endsWith(".dls")) {
+                                    if (foundfile == null || (file.length() >
+                                            foundfile.length())) {
+                                        foundfile = file;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    if (foundfile != null) {
+                        try {
+                            Soundbank sbk = MidiSystem.getSoundbank(foundfile);
+                            defaultSoundBank = sbk;
+                            return defaultSoundBank;
+                        } catch (Exception e) {
+                            //e.printStackTrace();
+                        }
+                    }
+                }
+
+                if (System.getProperties().getProperty("os.name")
+                        .startsWith("Windows")) {
+                    File gm_dls = new File(System.getenv("SystemRoot")
+                            + "\\system32\\drivers\\gm.dls");
+                    if (gm_dls.exists()) {
+                        try {
+                            Soundbank sbk = MidiSystem.getSoundbank(gm_dls);
+                            defaultSoundBank = sbk;
+                            return defaultSoundBank;
+                        } catch (Exception e) {
+                            //e.printStackTrace();
+                        }
+                    }
+                }
+            } catch (AccessControlException e) {
+            } catch (Exception e) {
+                //e.printStackTrace();
+            }
+
+            File userhome = null;
+            File emg_soundbank_file = null;
+
+            /*
+             *  Try to load saved generated soundbank
+             */
+            try {
+                userhome = new File(System.getProperty("user.home"),
+                     ".gervill");
+                emg_soundbank_file = new File(userhome, "soundbank-emg.sf2");
+                Soundbank sbk = MidiSystem.getSoundbank(emg_soundbank_file);
+                defaultSoundBank = sbk;
+                return defaultSoundBank;
+            } catch (AccessControlException e) {
+            } catch (Exception e) {
+                //e.printStackTrace();
+            }
+
+            try {
+
+                /*
+                 *  Generate emergency soundbank
+                 */
+                defaultSoundBank = EmergencySoundbank.createSoundbank();
+
+                /*
+                 *  Save generated soundbank to disk for faster future use.
+                 */
+                if(defaultSoundBank != null)
+                {
+                    if(!userhome.exists()) userhome.mkdirs();
+                    if(!emg_soundbank_file.exists())
+                        ((SF2Soundbank)defaultSoundBank).save(emg_soundbank_file);
+                }
+            } catch (Exception e) {
+                //e.printStackTrace();
+            }
+
+        }
+        return defaultSoundBank;
+    }
+
+    public Instrument[] getAvailableInstruments() {
+        if (!isOpen()) {
+            Soundbank defsbk = getDefaultSoundbank();
+            if (defsbk == null)
+                return new Instrument[0];
+            return defsbk.getInstruments();
+        }
+
+        synchronized (control_mutex) {
+            ModelInstrument[] inslist_array =
+                    new ModelInstrument[availlist.values().size()];
+            availlist.values().toArray(inslist_array);
+            Arrays.sort(inslist_array, new ModelInstrumentComparator());
+            return inslist_array;
+        }
+    }
+
+    public Instrument[] getLoadedInstruments() {
+        if (!isOpen())
+            return new Instrument[0];
+
+        synchronized (control_mutex) {
+            ModelInstrument[] inslist_array =
+                    new ModelInstrument[loadedlist.values().size()];
+            loadedlist.values().toArray(inslist_array);
+            Arrays.sort(inslist_array, new ModelInstrumentComparator());
+            return inslist_array;
+        }
+    }
+
+    public boolean loadAllInstruments(Soundbank soundbank) {
+        List<ModelInstrument> instruments = new ArrayList<ModelInstrument>();
+        for (Instrument ins: soundbank.getInstruments()) {
+            if (ins == null || !(ins instanceof ModelInstrument)) {
+                throw new IllegalArgumentException(
+                        "Unsupported instrument: " + ins);
+            }
+            instruments.add((ModelInstrument)ins);
+        }
+        return loadInstruments(instruments);
+    }
+
+    public void unloadAllInstruments(Soundbank soundbank) {
+        if (soundbank == null || !isSoundbankSupported(soundbank))
+            throw new IllegalArgumentException("Unsupported soundbank: " + soundbank);
+
+        if (!isOpen())
+            return;
+
+        for (Instrument ins: soundbank.getInstruments()) {
+            if (ins instanceof ModelInstrument) {
+                unloadInstrument(ins);
+            }
+        }
+    }
+
+    public boolean loadInstruments(Soundbank soundbank, Patch[] patchList) {
+        List<ModelInstrument> instruments = new ArrayList<ModelInstrument>();
+        for (Patch patch: patchList) {
+            Instrument ins = soundbank.getInstrument(patch);
+            if (ins == null || !(ins instanceof ModelInstrument)) {
+                throw new IllegalArgumentException(
+                        "Unsupported instrument: " + ins);
+            }
+            instruments.add((ModelInstrument)ins);
+        }
+        return loadInstruments(instruments);
+    }
+
+    public void unloadInstruments(Soundbank soundbank, Patch[] patchList) {
+        if (soundbank == null || !isSoundbankSupported(soundbank))
+            throw new IllegalArgumentException("Unsupported soundbank: " + soundbank);
+
+        if (!isOpen())
+            return;
+
+        for (Patch pat: patchList) {
+            Instrument ins = soundbank.getInstrument(pat);
+            if (ins instanceof ModelInstrument) {
+                unloadInstrument(ins);
+            }
+        }
+    }
+
+    public MidiDevice.Info getDeviceInfo() {
+        return info;
+    }
+
+    public AudioSynthesizerPropertyInfo[] getPropertyInfo(Map<String, Object> info) {
+        List<AudioSynthesizerPropertyInfo> list =
+                new ArrayList<AudioSynthesizerPropertyInfo>();
+
+        AudioSynthesizerPropertyInfo item;
+
+        // If info != null or synthesizer is closed
+        //   we return how the synthesizer will be set on next open
+        // If info == null and synthesizer is open
+        //   we return current synthesizer properties.
+        boolean o = info == null && open;
+
+        item = new AudioSynthesizerPropertyInfo("interpolation", o?resamplerType:"linear");
+        item.choices = new String[]{"linear", "linear1", "linear2", "cubic",
+                                    "lanczos", "sinc", "point"};
+        item.description = "Interpolation method";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("control rate", o?controlrate:147f);
+        item.description = "Control rate";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("format",
+                o?format:new AudioFormat(44100, 16, 2, true, false));
+        item.description = "Default audio format";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("latency", o?latency:120000L);
+        item.description = "Default latency";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("device id", o?deviceid:0);
+        item.description = "Device ID for SysEx Messages";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("max polyphony", o?maxpoly:64);
+        item.description = "Maximum polyphony";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("reverb", o?reverb_on:true);
+        item.description = "Turn reverb effect on or off";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("chorus", o?chorus_on:true);
+        item.description = "Turn chorus effect on or off";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("auto gain control", o?agc_on:true);
+        item.description = "Turn auto gain control on or off";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("large mode", o?largemode:false);
+        item.description = "Turn large mode on or off.";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("midi channels", o?channels.length:16);
+        item.description = "Number of midi channels.";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("jitter correction", o?jitter_correction:true);
+        item.description = "Turn jitter correction on or off.";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("light reverb", o?reverb_light:true);
+        item.description = "Turn light reverb mode on or off";
+        list.add(item);
+
+        AudioSynthesizerPropertyInfo[] items;
+        items = list.toArray(new AudioSynthesizerPropertyInfo[list.size()]);
+
+        if (info != null)
+            for (AudioSynthesizerPropertyInfo item2: items) {
+                Object v = info.get(item2.name);
+                Class c = (item2.valueClass);
+                if (v != null)
+                    if (c.isInstance(v))
+                        item2.value = v;
+            }
+
+        return items;
+    }
+
+    public void open() throws MidiUnavailableException {
+        if (isOpen()) {
+            synchronized (control_mutex) {
+                implicitOpen = false;
+            }
+            return;
+        }
+        open(null, null);
+    }
+
+    public void open(SourceDataLine line, Map<String, Object> info) throws MidiUnavailableException {
+        if (isOpen()) {
+            synchronized (control_mutex) {
+                implicitOpen = false;
+            }
+            return;
+        }
+        synchronized (control_mutex) {
+            try {
+                if (line != null)
+                    setFormat(line.getFormat());
+
+                AudioInputStream ais = openStream(getFormat(), info);
+
+                weakstream = new WeakAudioStream(ais);
+                ais = weakstream.getAudioInputStream();
+
+                if (line == null)
+                {
+                    if(testline != null)
+                        line = testline;
+                    else
+                        line = AudioSystem.getSourceDataLine(getFormat());
+                }
+
+                double latency = this.latency;
+
+                if (!line.isOpen()) {
+                    int bufferSize = getFormat().getFrameSize()
+                        * (int)(getFormat().getFrameRate() * (latency/1000000f));
+                    line.open(getFormat(), bufferSize);
+
+                    // Remember that we opened that line
+                    // so we can close again in SoftSynthesizer.close()
+                    sourceDataLine = line;
+                }
+                if (!line.isActive())
+                    line.start();
+
+                int controlbuffersize = 512;
+                try {
+                    controlbuffersize = ais.available();
+                } catch (IOException e) {
+                }
+
+                // Tell mixer not fill read buffers fully.
+                // This lowers latency, and tells DataPusher
+                // to read in smaller amounts.
+                //mainmixer.readfully = false;
+                //pusher = new DataPusher(line, ais);
+
+                int buffersize = line.getBufferSize();
+                buffersize -= buffersize % controlbuffersize;
+
+                if (buffersize < 3 * controlbuffersize)
+                    buffersize = 3 * controlbuffersize;
+
+                if (jitter_correction) {
+                    ais = new SoftJitterCorrector(ais, buffersize,
+                            controlbuffersize);
+                    if(weakstream != null)
+                        weakstream.jitter_stream = ais;
+                }
+                pusher = new SoftAudioPusher(line, ais, controlbuffersize);
+                pusher_stream = ais;
+                pusher.start();
+
+                if(weakstream != null)
+                {
+                    weakstream.pusher = pusher;
+                    weakstream.sourceDataLine = sourceDataLine;
+                }
+
+
+
+            } catch (LineUnavailableException e) {
+                if (isOpen())
+                    close();
+                // am: need MidiUnavailableException(Throwable) ctor!
+                throw new MidiUnavailableException(e.toString());
+            }
+
+        }
+    }
+
+    public AudioInputStream openStream(AudioFormat targetFormat,
+            Map<String, Object> info) throws MidiUnavailableException {
+
+        if (isOpen())
+            throw new MidiUnavailableException("Synthesizer is already open");
+
+        synchronized (control_mutex) {
+
+            gmmode = 0;
+            voice_allocation_mode = 0;
+
+            processPropertyInfo(info);
+
+            open = true;
+            implicitOpen = false;
+
+            if (targetFormat != null)
+                setFormat(targetFormat);
+
+            Soundbank defbank = getDefaultSoundbank();
+            if (defbank != null) {
+                loadAllInstruments(defbank);
+                availlist.putAll(loadedlist);
+                loadedlist.clear();
+            }
+
+            voices = new SoftVoice[maxpoly];
+            for (int i = 0; i < maxpoly; i++)
+                voices[i] = new SoftVoice(this);
+
+            mainmixer = new SoftMainMixer(this);
+
+            channels = new SoftChannel[number_of_midi_channels];
+            for (int i = 0; i < channels.length; i++)
+                channels[i] = new SoftChannel(this, i);
+
+            if (external_channels == null) {
+                // Always create external_channels array
+                // with 16 or more channels
+                // so getChannels works correctly
+                // when the synhtesizer is closed.
+                if (channels.length < 16)
+                    external_channels = new SoftChannelProxy[16];
+                else
+                    external_channels = new SoftChannelProxy[channels.length];
+                for (int i = 0; i < external_channels.length; i++)
+                    external_channels[i] = new SoftChannelProxy();
+            } else {
+                // We must resize external_channels array
+                // but we must also copy the old SoftChannelProxy
+                // into the new one
+                if (channels.length > external_channels.length) {
+                    SoftChannelProxy[] new_external_channels
+                            = new SoftChannelProxy[channels.length];
+                    for (int i = 0; i < external_channels.length; i++)
+                        new_external_channels[i] = external_channels[i];
+                    for (int i = external_channels.length;
+                            i < new_external_channels.length; i++) {
+                        new_external_channels[i] = new SoftChannelProxy();
+                    }
+                }
+            }
+
+            for (int i = 0; i < channels.length; i++)
+                external_channels[i].setChannel(channels[i]);
+
+            for (SoftVoice voice: getVoices())
+                voice.resampler = resampler.openStreamer();
+
+            for (Receiver recv: getReceivers()) {
+                SoftReceiver srecv = ((SoftReceiver)recv);
+                srecv.open = open;
+                srecv.mainmixer = mainmixer;
+                srecv.midimessages = mainmixer.midimessages;
+            }
+
+            return mainmixer.getInputStream();
+        }
+    }
+
+    public void close() {
+
+        if (!isOpen())
+            return;
+
+        SoftAudioPusher pusher_to_be_closed = null;
+        AudioInputStream pusher_stream_to_be_closed = null;
+        synchronized (control_mutex) {
+            if (pusher != null) {
+                pusher_to_be_closed = pusher;
+                pusher_stream_to_be_closed = pusher_stream;
+                pusher = null;
+                pusher_stream = null;
+            }
+        }
+
+        if (pusher_to_be_closed != null) {
+            // Pusher must not be closed synchronized against control_mutex,
+            // this may result in synchronized conflict between pusher
+            // and current thread.
+            pusher_to_be_closed.stop();
+
+            try {
+                pusher_stream_to_be_closed.close();
+            } catch (IOException e) {
+                //e.printStackTrace();
+            }
+        }
+
+        synchronized (control_mutex) {
+
+            if (mainmixer != null)
+                mainmixer.close();
+            open = false;
+            implicitOpen = false;
+            mainmixer = null;
+            voices = null;
+            channels = null;
+
+            if (external_channels != null)
+                for (int i = 0; i < external_channels.length; i++)
+                    external_channels[i].setChannel(null);
+
+            if (sourceDataLine != null) {
+                sourceDataLine.close();
+                sourceDataLine = null;
+            }
+
+            inslist.clear();
+            availlist.clear();
+            loadedlist.clear();
+            tunings.clear();
+
+            while (recvslist.size() != 0)
+                recvslist.get(recvslist.size() - 1).close();
+
+        }
+    }
+
+    public boolean isOpen() {
+        synchronized (control_mutex) {
+            return open;
+        }
+    }
+
+    public long getMicrosecondPosition() {
+
+        if (!isOpen())
+            return 0;
+
+        synchronized (control_mutex) {
+            return mainmixer.getMicrosecondPosition();
+        }
+    }
+
+    public int getMaxReceivers() {
+        return -1;
+    }
+
+    public int getMaxTransmitters() {
+        return 0;
+    }
+
+    public Receiver getReceiver() throws MidiUnavailableException {
+
+        synchronized (control_mutex) {
+            SoftReceiver receiver = new SoftReceiver(this);
+            receiver.open = open;
+            recvslist.add(receiver);
+            return receiver;
+        }
+    }
+
+    public List<Receiver> getReceivers() {
+
+        synchronized (control_mutex) {
+            ArrayList<Receiver> recvs = new ArrayList<Receiver>();
+            recvs.addAll(recvslist);
+            return recvs;
+        }
+    }
+
+    public Transmitter getTransmitter() throws MidiUnavailableException {
+
+        throw new MidiUnavailableException("No transmitter available");
+    }
+
+    public List<Transmitter> getTransmitters() {
+
+        return new ArrayList<Transmitter>();
+    }
+
+    public Receiver getReceiverReferenceCounting()
+            throws MidiUnavailableException {
+
+        if (!isOpen()) {
+            open();
+            synchronized (control_mutex) {
+                implicitOpen = true;
+            }
+        }
+
+        return getReceiver();
+    }
+
+    public Transmitter getTransmitterReferenceCounting()
+            throws MidiUnavailableException {
+
+        throw new MidiUnavailableException("No transmitter available");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftTuning.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.UnsupportedEncodingException;
+
+import javax.sound.midi.Patch;
+
+/**
+ * A tuning program container, for use with MIDI Tuning.
+ * See: http://www.midi.org
+ *
+ * @author Karl Helgason
+ */
+public class SoftTuning {
+
+    private String name = null;
+    private double[] tuning = new double[128];
+    private Patch patch = null;
+
+    public SoftTuning() {
+        name = "12-TET";
+        for (int i = 0; i < tuning.length; i++)
+            tuning[i] = i * 100;
+    }
+
+    public SoftTuning(byte[] data) {
+        for (int i = 0; i < tuning.length; i++)
+            tuning[i] = i * 100;
+        load(data);
+    }
+
+    public SoftTuning(Patch patch) {
+        this.patch = patch;
+        name = "12-TET";
+        for (int i = 0; i < tuning.length; i++)
+            tuning[i] = i * 100;
+    }
+
+    public SoftTuning(Patch patch, byte[] data) {
+        this.patch = patch;
+        for (int i = 0; i < tuning.length; i++)
+            tuning[i] = i * 100;
+        load(data);
+    }
+
+    private boolean checksumOK(byte[] data) {
+        int x = data[1] & 0xFF;
+        for (int i = 2; i < data.length - 2; i++)
+            x = x ^ (data[i] & 0xFF);
+        return (data[data.length - 2] & 0xFF) == (x & 127);
+    }
+
+    /*
+    private boolean checksumOK2(byte[] data) {
+        int x = data[1] & 0xFF; // 7E
+        x = x ^ (data[2] & 0xFF); // <device ID>
+        x = x ^ (data[4] & 0xFF); // nn
+        x = x ^ (data[5] & 0xFF); // tt
+        for (int i = 22; i < data.length - 2; i++)
+            x = x ^ (data[i] & 0xFF);
+        return (data[data.length - 2] & 0xFF) == (x & 127);
+    }
+     */
+    public void load(byte[] data) {
+        // Universal Non-Real-Time / Real-Time SysEx
+        if ((data[1] & 0xFF) == 0x7E || (data[1] & 0xFF) == 0x7F) {
+            int subid1 = data[3] & 0xFF;
+            switch (subid1) {
+            case 0x08: // MIDI Tuning Standard
+                int subid2 = data[4] & 0xFF;
+                switch (subid2) {
+                case 0x01: // BULK TUNING DUMP (NON-REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning.shtml
+                    //if (!checksumOK2(data))
+                    //    break;
+                    try {
+                        name = new String(data, 6, 16, "ascii");
+                    } catch (UnsupportedEncodingException e) {
+                        name = null;
+                    }
+                    int r = 22;
+                    for (int i = 0; i < 128; i++) {
+                        int xx = data[r++] & 0xFF;
+                        int yy = data[r++] & 0xFF;
+                        int zz = data[r++] & 0xFF;
+                        if (!(xx == 127 && yy == 127 && zz == 127))
+                            tuning[i] = 100.0 *
+                                    (((xx * 16384) + (yy * 128) + zz) / 16384.0);
+                    }
+                    break;
+                }
+                case 0x02: // SINGLE NOTE TUNING CHANGE (REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning.shtml
+                    int ll = data[6] & 0xFF;
+                    int r = 7;
+                    for (int i = 0; i < ll; i++) {
+                        int kk = data[r++] & 0xFF;
+                        int xx = data[r++] & 0xFF;
+                        int yy = data[r++] & 0xFF;
+                        int zz = data[r++] & 0xFF;
+                        if (!(xx == 127 && yy == 127 && zz == 127))
+                            tuning[kk] = 100.0*(((xx*16384) + (yy*128) + zz)/16384.0);
+                    }
+                    break;
+                }
+                case 0x04: // KEY-BASED TUNING DUMP (NON-REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning_extens.shtml
+                    if (!checksumOK(data))
+                        break;
+                    try {
+                        name = new String(data, 7, 16, "ascii");
+                    } catch (UnsupportedEncodingException e) {
+                        name = null;
+                    }
+                    int r = 23;
+                    for (int i = 0; i < 128; i++) {
+                        int xx = data[r++] & 0xFF;
+                        int yy = data[r++] & 0xFF;
+                        int zz = data[r++] & 0xFF;
+                        if (!(xx == 127 && yy == 127 && zz == 127))
+                            tuning[i] = 100.0*(((xx*16384) + (yy*128) + zz)/16384.0);
+                    }
+                    break;
+                }
+                case 0x05: // SCALE/OCTAVE TUNING DUMP, 1 byte format
+                           // (NON-REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning_extens.shtml
+                    if (!checksumOK(data))
+                        break;
+                    try {
+                        name = new String(data, 7, 16, "ascii");
+                    } catch (UnsupportedEncodingException e) {
+                        name = null;
+                    }
+                    int[] octave_tuning = new int[12];
+                    for (int i = 0; i < 12; i++)
+                        octave_tuning[i] = (data[i + 23] & 0xFF) - 64;
+                    for (int i = 0; i < tuning.length; i++)
+                        tuning[i] = i * 100 + octave_tuning[i % 12];
+                    break;
+                }
+                case 0x06: // SCALE/OCTAVE TUNING DUMP, 2 byte format
+                           // (NON-REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning_extens.shtml
+                    if (!checksumOK(data))
+                        break;
+                    try {
+                        name = new String(data, 7, 16, "ascii");
+                    } catch (UnsupportedEncodingException e) {
+                        name = null;
+                    }
+                    double[] octave_tuning = new double[12];
+                    for (int i = 0; i < 12; i++) {
+                        int v = (data[i * 2 + 23] & 0xFF) * 128
+                                + (data[i * 2 + 24] & 0xFF);
+                        octave_tuning[i] = (v / 8192.0 - 1) * 100.0;
+                    }
+                    for (int i = 0; i < tuning.length; i++)
+                        tuning[i] = i * 100 + octave_tuning[i % 12];
+                    break;
+                }
+                case 0x07: // SINGLE NOTE TUNING CHANGE (NON
+                           // REAL-TIME/REAL-TIME) (BANK)
+                    // http://www.midi.org/about-midi/tuning_extens.shtml
+                    int ll = data[7] & 0xFF;
+                    int r = 8;
+                    for (int i = 0; i < ll; i++) {
+                        int kk = data[r++] & 0xFF;
+                        int xx = data[r++] & 0xFF;
+                        int yy = data[r++] & 0xFF;
+                        int zz = data[r++] & 0xFF;
+                        if (!(xx == 127 && yy == 127 && zz == 127))
+                            tuning[kk] = 100.0
+                                    * (((xx*16384) + (yy*128) + zz) / 16384.0);
+                    }
+                    break;
+                case 0x08: // scale/octave tuning 1-byte form (Non
+                           // Real-Time/REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning-scale.shtml
+                    int[] octave_tuning = new int[12];
+                    for (int i = 0; i < 12; i++)
+                        octave_tuning[i] = (data[i + 8] & 0xFF) - 64;
+                    for (int i = 0; i < tuning.length; i++)
+                        tuning[i] = i * 100 + octave_tuning[i % 12];
+                    break;
+                }
+                case 0x09: // scale/octave tuning 2-byte form (Non
+                           // Real-Time/REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning-scale.shtml
+                    double[] octave_tuning = new double[12];
+                    for (int i = 0; i < 12; i++) {
+                        int v = (data[i * 2 + 8] & 0xFF) * 128
+                                + (data[i * 2 + 9] & 0xFF);
+                        octave_tuning[i] = (v / 8192.0 - 1) * 100.0;
+                    }
+                    for (int i = 0; i < tuning.length; i++)
+                        tuning[i] = i * 100 + octave_tuning[i % 12];
+                    break;
+                }
+                default:
+                    break;
+                }
+            }
+        }
+    }
+
+    public double[] getTuning() {
+        return tuning;
+    }
+
+    public double getTuning(int noteNumber) {
+        return tuning[noteNumber];
+    }
+
+    public Patch getPatch() {
+        return patch;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftVoice.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,841 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.sound.midi.VoiceStatus;
+
+/**
+ * Software synthesizer voice class.
+ *
+ * @author Karl Helgason
+ */
+public class SoftVoice extends VoiceStatus {
+
+    public int exclusiveClass = 0;
+    public boolean releaseTriggered = false;
+    private int noteOn_noteNumber = 0;
+    private int noteOn_velocity = 0;
+    private int noteOff_velocity = 0;
+    protected ModelChannelMixer channelmixer = null;
+    protected double tunedKey = 0;
+    protected SoftTuning tuning = null;
+    protected SoftChannel stealer_channel = null;
+    protected ModelConnectionBlock[] stealer_extendedConnectionBlocks = null;
+    protected SoftPerformer stealer_performer = null;
+    protected ModelChannelMixer stealer_channelmixer = null;
+    protected int stealer_voiceID = -1;
+    protected int stealer_noteNumber = 0;
+    protected int stealer_velocity = 0;
+    protected boolean stealer_releaseTriggered = false;
+    protected int voiceID = -1;
+    protected boolean sustain = false;
+    protected boolean sostenuto = false;
+    protected boolean portamento = false;
+    private SoftFilter filter_left;
+    private SoftFilter filter_right;
+    private SoftProcess eg = new SoftEnvelopeGenerator();
+    private SoftProcess lfo = new SoftLowFrequencyOscillator();
+    protected Map<String, SoftControl> objects =
+            new HashMap<String, SoftControl>();
+    protected SoftSynthesizer synthesizer;
+    protected SoftInstrument instrument;
+    protected SoftPerformer performer;
+    protected SoftChannel softchannel = null;
+    protected boolean on = false;
+    private boolean audiostarted = false;
+    private boolean started = false;
+    private boolean stopping = false;
+    private float osc_attenuation = 0.0f;
+    private ModelOscillatorStream osc_stream;
+    private int osc_stream_nrofchannels;
+    private float[][] osc_buff = new float[2][];
+    private boolean osc_stream_off_transmitted = false;
+    private boolean out_mixer_end = false;
+    private float out_mixer_left = 0;
+    private float out_mixer_right = 0;
+    private float out_mixer_effect1 = 0;
+    private float out_mixer_effect2 = 0;
+    private float last_out_mixer_left = 0;
+    private float last_out_mixer_right = 0;
+    private float last_out_mixer_effect1 = 0;
+    private float last_out_mixer_effect2 = 0;
+    protected ModelConnectionBlock[] extendedConnectionBlocks = null;
+    private ModelConnectionBlock[] connections;
+    // Last value added to destination
+    private double[] connections_last = new double[50];
+    // Pointer to source value
+    private double[][][] connections_src = new double[50][3][];
+    // Key-based override (if any)
+    private int[][] connections_src_kc = new int[50][3];
+    // Pointer to destination value
+    private double[][] connections_dst = new double[50][];
+    private boolean soundoff = false;
+    private float lastMuteValue = 0;
+    private float lastSoloMuteValue = 0;
+    protected double[] co_noteon_keynumber = new double[1];
+    protected double[] co_noteon_velocity = new double[1];
+    protected double[] co_noteon_on = new double[1];
+    private SoftControl co_noteon = new SoftControl() {
+        double[] keynumber = co_noteon_keynumber;
+        double[] velocity = co_noteon_velocity;
+        double[] on = co_noteon_on;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            if (name.equals("keynumber"))
+                return keynumber;
+            if (name.equals("velocity"))
+                return velocity;
+            if (name.equals("on"))
+                return on;
+            return null;
+        }
+    };
+    private double[] co_mixer_active = new double[1];
+    private double[] co_mixer_gain = new double[1];
+    private double[] co_mixer_pan = new double[1];
+    private double[] co_mixer_balance = new double[1];
+    private double[] co_mixer_reverb = new double[1];
+    private double[] co_mixer_chorus = new double[1];
+    private SoftControl co_mixer = new SoftControl() {
+        double[] active = co_mixer_active;
+        double[] gain = co_mixer_gain;
+        double[] pan = co_mixer_pan;
+        double[] balance = co_mixer_balance;
+        double[] reverb = co_mixer_reverb;
+        double[] chorus = co_mixer_chorus;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            if (name.equals("active"))
+                return active;
+            if (name.equals("gain"))
+                return gain;
+            if (name.equals("pan"))
+                return pan;
+            if (name.equals("balance"))
+                return balance;
+            if (name.equals("reverb"))
+                return reverb;
+            if (name.equals("chorus"))
+                return chorus;
+            return null;
+        }
+    };
+    private double[] co_osc_pitch = new double[1];
+    private SoftControl co_osc = new SoftControl() {
+        double[] pitch = co_osc_pitch;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            if (name.equals("pitch"))
+                return pitch;
+            return null;
+        }
+    };
+    private double[] co_filter_freq = new double[1];
+    private double[] co_filter_type = new double[1];
+    private double[] co_filter_q = new double[1];
+    private SoftControl co_filter = new SoftControl() {
+        double[] freq = co_filter_freq;
+        double[] ftype = co_filter_type;
+        double[] q = co_filter_q;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            if (name.equals("freq"))
+                return freq;
+            if (name.equals("type"))
+                return ftype;
+            if (name.equals("q"))
+                return q;
+            return null;
+        }
+    };
+    protected SoftResamplerStreamer resampler;
+    private int nrofchannels;
+
+    public SoftVoice(SoftSynthesizer synth) {
+        synthesizer = synth;
+        filter_left = new SoftFilter(synth.getFormat().getSampleRate());
+        filter_right = new SoftFilter(synth.getFormat().getSampleRate());
+        nrofchannels = synth.getFormat().getChannels();
+    }
+
+    private int getValueKC(ModelIdentifier id) {
+        if (id.getObject().equals("midi_cc")) {
+            int ic = Integer.parseInt(id.getVariable());
+            if (ic != 0 && ic != 32) {
+                if (ic < 120)
+                    return ic;
+            }
+        } else if (id.getObject().equals("midi_rpn")) {
+            if (id.getVariable().equals("1"))
+                return 120; // Fine tuning
+            if (id.getVariable().equals("2"))
+                return 121; // Coarse tuning
+        }
+        return -1;
+    }
+
+    private double[] getValue(ModelIdentifier id) {
+        SoftControl o = objects.get(id.getObject());
+        if (o == null)
+            return null;
+        return o.get(id.getInstance(), id.getVariable());
+    }
+
+    private double transformValue(double value, ModelSource src) {
+        if (src.getTransform() != null)
+            return src.getTransform().transform(value);
+        else
+            return value;
+    }
+
+    private double transformValue(double value, ModelDestination dst) {
+        if (dst.getTransform() != null)
+            return dst.getTransform().transform(value);
+        else
+            return value;
+    }
+
+    private double processKeyBasedController(double value, int keycontrol) {
+        if (keycontrol == -1)
+            return value;
+        if (softchannel.keybasedcontroller_active != null)
+            if (softchannel.keybasedcontroller_active[note] != null)
+                if (softchannel.keybasedcontroller_active[note][keycontrol]) {
+                    double key_controlvalue =
+                            softchannel.keybasedcontroller_value[note][keycontrol];
+                    if (keycontrol == 10 || keycontrol == 91 || keycontrol == 93)
+                        return key_controlvalue;
+                    value += key_controlvalue * 2.0 - 1.0;
+                    if (value > 1)
+                        value = 1;
+                    else if (value < 0)
+                        value = 0;
+                }
+        return value;
+    }
+
+    private void processConnection(int ix) {
+        ModelConnectionBlock conn = connections[ix];
+        double[][] src = connections_src[ix];
+        double[] dst = connections_dst[ix];
+        if (dst == null || Double.isInfinite(dst[0]))
+            return;
+
+        double value = conn.getScale();
+        if (softchannel.keybasedcontroller_active == null) {
+            ModelSource[] srcs = conn.getSources();
+            for (int i = 0; i < srcs.length; i++) {
+                value *= transformValue(src[i][0], srcs[i]);
+                if (value == 0)
+                    break;
+            }
+        } else {
+            ModelSource[] srcs = conn.getSources();
+            int[] src_kc = connections_src_kc[ix];
+            for (int i = 0; i < srcs.length; i++) {
+                value *= transformValue(processKeyBasedController(src[i][0],
+                        src_kc[i]), srcs[i]);
+                if (value == 0)
+                    break;
+            }
+        }
+
+        value = transformValue(value, conn.getDestination());
+        dst[0] = dst[0] - connections_last[ix] + value;
+        connections_last[ix] = value;
+        // co_mixer_gain[0] = 0;
+    }
+
+    protected void updateTuning(SoftTuning newtuning) {
+        tunedKey = tuning.getTuning(note) / 100.0;
+        if (!portamento) {
+            co_noteon_keynumber[0] = tunedKey * (1.0 / 128.0);
+            int[] c = performer.midi_connections[4];
+            if (c == null)
+                return;
+            for (int i = 0; i < c.length; i++)
+                processConnection(c[i]);
+        }
+    }
+
+    protected void setNote(int noteNumber) {
+        note = noteNumber;
+        tunedKey = tuning.getTuning(noteNumber) / 100.0;
+    }
+
+    protected void noteOn(int noteNumber, int velocity) {
+
+        sustain = false;
+        sostenuto = false;
+        portamento = false;
+
+        soundoff = false;
+        on = true;
+        active = true;
+        started = true;
+        // volume = velocity;
+
+        noteOn_noteNumber = noteNumber;
+        noteOn_velocity = velocity;
+
+        lastMuteValue = 0;
+        lastSoloMuteValue = 0;
+
+        setNote(noteNumber);
+
+        if (performer.forcedKeynumber)
+            co_noteon_keynumber[0] = 0;
+        else
+            co_noteon_keynumber[0] = tunedKey * (1f / 128f);
+        if (performer.forcedVelocity)
+            co_noteon_velocity[0] = 0;
+        else
+            co_noteon_velocity[0] = velocity * (1f / 128f);
+        co_mixer_active[0] = 0;
+        co_mixer_gain[0] = 0;
+        co_mixer_pan[0] = 0;
+        co_mixer_balance[0] = 0;
+        co_mixer_reverb[0] = 0;
+        co_mixer_chorus[0] = 0;
+        co_osc_pitch[0] = 0;
+        co_filter_freq[0] = 0;
+        co_filter_q[0] = 0;
+        co_filter_type[0] = 0;
+        co_noteon_on[0] = 1;
+
+        eg.reset();
+        lfo.reset();
+        filter_left.reset();
+        filter_right.reset();
+
+        objects.put("master", synthesizer.getMainMixer().co_master);
+        objects.put("eg", eg);
+        objects.put("lfo", lfo);
+        objects.put("noteon", co_noteon);
+        objects.put("osc", co_osc);
+        objects.put("mixer", co_mixer);
+        objects.put("filter", co_filter);
+
+        connections = performer.connections;
+
+        if (connections_last == null
+                || connections_last.length < connections.length) {
+            connections_last = new double[connections.length];
+        }
+        if (connections_src == null
+                || connections_src.length < connections.length) {
+            connections_src = new double[connections.length][][];
+            connections_src_kc = new int[connections.length][];
+        }
+        if (connections_dst == null
+                || connections_dst.length < connections.length) {
+            connections_dst = new double[connections.length][];
+        }
+        for (int i = 0; i < connections.length; i++) {
+            ModelConnectionBlock conn = connections[i];
+            connections_last[i] = 0;
+            if (conn.getSources() != null) {
+                ModelSource[] srcs = conn.getSources();
+                if (connections_src[i] == null
+                        || connections_src[i].length < srcs.length) {
+                    connections_src[i] = new double[srcs.length][];
+                    connections_src_kc[i] = new int[srcs.length];
+                }
+                double[][] src = connections_src[i];
+                int[] src_kc = connections_src_kc[i];
+                connections_src[i] = src;
+                for (int j = 0; j < srcs.length; j++) {
+                    src_kc[j] = getValueKC(srcs[j].getIdentifier());
+                    src[j] = getValue(srcs[j].getIdentifier());
+                }
+            }
+
+            if (conn.getDestination() != null)
+                connections_dst[i] = getValue(conn.getDestination()
+                        .getIdentifier());
+            else
+                connections_dst[i] = null;
+        }
+
+        for (int i = 0; i < connections.length; i++)
+            processConnection(i);
+
+        if (extendedConnectionBlocks != null) {
+            for (ModelConnectionBlock connection: extendedConnectionBlocks) {
+                double value = 0;
+
+                if (softchannel.keybasedcontroller_active == null) {
+                    for (ModelSource src: connection.getSources()) {
+                        double x = getValue(src.getIdentifier())[0];
+                        ModelTransform t = src.getTransform();
+                        if (t == null)
+                            value += x;
+                        else
+                            value += t.transform(x);
+                    }
+                } else {
+                    for (ModelSource src: connection.getSources()) {
+                        double x = getValue(src.getIdentifier())[0];
+                        x = processKeyBasedController(x,
+                                getValueKC(src.getIdentifier()));
+                        ModelTransform t = src.getTransform();
+                        if (t == null)
+                            value += x;
+                        else
+                            value += t.transform(x);
+                    }
+                }
+
+                ModelDestination dest = connection.getDestination();
+                ModelTransform t = dest.getTransform();
+                if (t != null)
+                    value = t.transform(value);
+                getValue(dest.getIdentifier())[0] += value;
+            }
+        }
+
+        eg.init(synthesizer);
+        lfo.init(synthesizer);
+
+    }
+
+    protected void setPolyPressure(int pressure) {
+        int[] c = performer.midi_connections[2];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void setChannelPressure(int pressure) {
+        int[] c = performer.midi_connections[1];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void controlChange(int controller, int value) {
+        int[] c = performer.midi_ctrl_connections[controller];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void nrpnChange(int controller, int value) {
+        int[] c = performer.midi_nrpn_connections.get(controller);
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void rpnChange(int controller, int value) {
+        int[] c = performer.midi_rpn_connections.get(controller);
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void setPitchBend(int bend) {
+        int[] c = performer.midi_connections[0];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void setMute(boolean mute) {
+        co_mixer_gain[0] -= lastMuteValue;
+        lastMuteValue = mute ? -960 : 0;
+        co_mixer_gain[0] += lastMuteValue;
+    }
+
+    protected void setSoloMute(boolean mute) {
+        co_mixer_gain[0] -= lastSoloMuteValue;
+        lastSoloMuteValue = mute ? -960 : 0;
+        co_mixer_gain[0] += lastSoloMuteValue;
+    }
+
+    protected void shutdown() {
+        if (co_noteon_on[0] < -0.5)
+            return;
+        on = false;
+
+        co_noteon_on[0] = -1;
+
+        int[] c = performer.midi_connections[3];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void soundOff() {
+        on = false;
+        soundoff = true;
+    }
+
+    protected void noteOff(int velocity) {
+        if (!on)
+            return;
+        on = false;
+
+        noteOff_velocity = velocity;
+
+        if (softchannel.sustain) {
+            sustain = true;
+            return;
+        }
+        if (sostenuto)
+            return;
+
+        co_noteon_on[0] = 0;
+
+        int[] c = performer.midi_connections[3];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void redamp() {
+        if (co_noteon_on[0] > 0.5)
+            return;
+        if (co_noteon_on[0] < -0.5)
+            return; // don't redamp notes in shutdown stage
+
+        sustain = true;
+        co_noteon_on[0] = 1;
+
+        int[] c = performer.midi_connections[3];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void processControlLogic() {
+        if (stopping) {
+            active = false;
+            stopping = false;
+            audiostarted = false;
+            if (osc_stream != null)
+                try {
+                    osc_stream.close();
+                } catch (IOException e) {
+                    //e.printStackTrace();
+                }
+
+            if (stealer_channel != null) {
+                stealer_channel.initVoice(this, stealer_performer,
+                        stealer_voiceID, stealer_noteNumber, stealer_velocity,
+                        stealer_extendedConnectionBlocks, stealer_channelmixer,
+                        stealer_releaseTriggered);
+                stealer_releaseTriggered = false;
+                stealer_channel = null;
+                stealer_performer = null;
+                stealer_voiceID = -1;
+                stealer_noteNumber = 0;
+                stealer_velocity = 0;
+                stealer_extendedConnectionBlocks = null;
+                stealer_channelmixer = null;
+            }
+        }
+        if (started) {
+            audiostarted = true;
+
+            ModelOscillator osc = performer.oscillators[0];
+
+            osc_stream_off_transmitted = false;
+            if (osc instanceof ModelWavetable) {
+                try {
+                    resampler.open((ModelWavetable)osc,
+                            synthesizer.getFormat().getSampleRate());
+                    osc_stream = resampler;
+                } catch (IOException e) {
+                    //e.printStackTrace();
+                }
+            } else {
+                osc_stream = osc.open(synthesizer.getFormat().getSampleRate());
+            }
+            osc_attenuation = osc.getAttenuation();
+            osc_stream_nrofchannels = osc.getChannels();
+            if (osc_buff == null || osc_buff.length < osc_stream_nrofchannels)
+                osc_buff = new float[osc_stream_nrofchannels][];
+
+            if (osc_stream != null)
+                osc_stream.noteOn(softchannel, this, noteOn_noteNumber,
+                        noteOn_velocity);
+
+
+        }
+        if (audiostarted) {
+            if (portamento) {
+                double note_delta = tunedKey - (co_noteon_keynumber[0] * 128);
+                double note_delta_a = Math.abs(note_delta);
+                if (note_delta_a < 0.0000000001) {
+                    co_noteon_keynumber[0] = tunedKey * (1.0 / 128.0);
+                    portamento = false;
+                } else {
+                    if (note_delta_a > softchannel.portamento_time)
+                        note_delta = Math.signum(note_delta)
+                                * softchannel.portamento_time;
+                    co_noteon_keynumber[0] += note_delta * (1.0 / 128.0);
+                }
+
+                int[] c = performer.midi_connections[4];
+                if (c == null)
+                    return;
+                for (int i = 0; i < c.length; i++)
+                    processConnection(c[i]);
+            }
+
+            eg.processControlLogic();
+            lfo.processControlLogic();
+
+            for (int i = 0; i < performer.ctrl_connections.length; i++)
+                processConnection(performer.ctrl_connections[i]);
+
+            osc_stream.setPitch((float)co_osc_pitch[0]);
+
+            int filter_type = (int)co_filter_type[0];
+            double filter_freq;
+
+            if (co_filter_freq[0] == 13500.0)
+                filter_freq = 19912.126958213175;
+            else
+                filter_freq = 440.0 * Math.exp(
+                        ((co_filter_freq[0]) - 6900.0) *
+                        (Math.log(2.0) / 1200.0));
+            /*
+            filter_freq = 440.0 * Math.pow(2.0,
+            ((co_filter_freq[0]) - 6900.0) / 1200.0);*/
+            /*
+             * double velocity = co_noteon_velocity[0]; if(velocity < 0.5)
+             * filter_freq *= ((velocity * 2)*0.75 + 0.25);
+             */
+
+            double q = co_filter_q[0] / 10.0;
+            filter_left.setFilterType(filter_type);
+            filter_left.setFrequency(filter_freq);
+            filter_left.setResonance(q);
+            filter_right.setFilterType(filter_type);
+            filter_right.setFrequency(filter_freq);
+            filter_right.setResonance(q);
+            /*
+            float gain = (float) Math.pow(10,
+            (-osc_attenuation + co_mixer_gain[0]) / 200.0);
+             */
+            float gain = (float)Math.exp(
+                    (-osc_attenuation + co_mixer_gain[0])*(Math.log(10) / 200.0));
+
+            if (co_mixer_gain[0] <= -960)
+                gain = 0;
+
+            if (soundoff) {
+                stopping = true;
+                gain = 0;
+                /*
+                 * if(co_mixer_gain[0] > -960)
+                 *   co_mixer_gain[0] -= 960;
+                 */
+            }
+
+            volume = (int)(Math.sqrt(gain) * 128);
+
+            // gain *= 0.2;
+
+            double pan = co_mixer_pan[0] * (1.0 / 1000.0);
+            // System.out.println("pan = " + pan);
+            if (pan < 0)
+                pan = 0;
+            else if (pan > 1)
+                pan = 1;
+
+            if (pan == 0.5) {
+                out_mixer_left = gain * 0.7071067811865476f;
+                out_mixer_right = out_mixer_left;
+            } else {
+                out_mixer_left = gain * (float)Math.cos(pan * Math.PI * 0.5);
+                out_mixer_right = gain * (float)Math.sin(pan * Math.PI * 0.5);
+            }
+
+            double balance = co_mixer_balance[0] * (1.0 / 1000.0);
+            if (balance != 0.5) {
+                if (balance > 0.5)
+                    out_mixer_left *= (1 - balance) * 2;
+                else
+                    out_mixer_right *= balance * 2;
+            }
+
+            if (synthesizer.reverb_on) {
+                out_mixer_effect1 = (float)(co_mixer_reverb[0] * (1.0 / 1000.0));
+                out_mixer_effect1 *= gain;
+            } else
+                out_mixer_effect1 = 0;
+            if (synthesizer.chorus_on) {
+                out_mixer_effect2 = (float)(co_mixer_chorus[0] * (1.0 / 1000.0));
+                out_mixer_effect2 *= gain;
+            } else
+                out_mixer_effect2 = 0;
+            out_mixer_end = co_mixer_active[0] < 0.5;
+
+            if (!on)
+                if (!osc_stream_off_transmitted) {
+                    osc_stream_off_transmitted = true;
+                    if (osc_stream != null)
+                        osc_stream.noteOff(noteOff_velocity);
+                }
+
+        }
+        if (started) {
+            last_out_mixer_left = out_mixer_left;
+            last_out_mixer_right = out_mixer_right;
+            last_out_mixer_effect1 = out_mixer_effect1;
+            last_out_mixer_effect2 = out_mixer_effect2;
+            started = false;
+        }
+
+    }
+
+    protected void mixAudioStream(SoftAudioBuffer in, SoftAudioBuffer out,
+            float amp_from, float amp_to) {
+        int bufferlen = in.getSize();
+        if (amp_from < 0.000000001 && amp_to < 0.000000001)
+            return;
+        if (amp_from == amp_to) {
+            float[] fout = out.array();
+            float[] fin = in.array();
+            for (int i = 0; i < bufferlen; i++)
+                fout[i] += fin[i] * amp_to;
+        } else {
+            float amp = amp_from;
+            float amp_delta = (amp_to - amp_from) / bufferlen;
+            float[] fout = out.array();
+            float[] fin = in.array();
+            for (int i = 0; i < bufferlen; i++) {
+                amp += amp_delta;
+                fout[i] += fin[i] * amp;
+            }
+        }
+
+    }
+
+    protected void processAudioLogic(SoftAudioBuffer[] buffer) {
+        if (!audiostarted)
+            return;
+
+        int bufferlen = buffer[0].getSize();
+
+        try {
+            osc_buff[0] = buffer[SoftMainMixer.CHANNEL_LEFT_DRY].array();
+            if (nrofchannels != 1)
+                osc_buff[1] = buffer[SoftMainMixer.CHANNEL_RIGHT_DRY].array();
+            int ret = osc_stream.read(osc_buff, 0, bufferlen);
+            if (ret == -1) {
+                stopping = true;
+                return;
+            }
+            if (ret != bufferlen) {
+                Arrays.fill(osc_buff[0], ret, bufferlen, 0f);
+                if (nrofchannels != 1)
+                    Arrays.fill(osc_buff[1], ret, bufferlen, 0f);
+            }
+
+        } catch (IOException e) {
+            //e.printStackTrace();
+        }
+
+        SoftAudioBuffer left = buffer[SoftMainMixer.CHANNEL_LEFT];
+        SoftAudioBuffer right = buffer[SoftMainMixer.CHANNEL_RIGHT];
+        SoftAudioBuffer eff1 = buffer[SoftMainMixer.CHANNEL_EFFECT1];
+        SoftAudioBuffer eff2 = buffer[SoftMainMixer.CHANNEL_EFFECT2];
+        SoftAudioBuffer leftdry = buffer[SoftMainMixer.CHANNEL_LEFT_DRY];
+        SoftAudioBuffer rightdry = buffer[SoftMainMixer.CHANNEL_RIGHT_DRY];
+
+        if (osc_stream_nrofchannels == 1)
+            rightdry = null;
+
+        if (!Double.isInfinite(co_filter_freq[0])) {
+            filter_left.processAudio(leftdry);
+            if (rightdry != null)
+                filter_right.processAudio(rightdry);
+        }
+
+        if (nrofchannels == 1) {
+            out_mixer_left = (out_mixer_left + out_mixer_right) / 2;
+            mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left);
+            if (rightdry != null)
+                mixAudioStream(rightdry, left, last_out_mixer_left,
+                        out_mixer_left);
+        } else {
+            mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left);
+            if (rightdry != null)
+                mixAudioStream(rightdry, right, last_out_mixer_right,
+                        out_mixer_right);
+            else
+                mixAudioStream(leftdry, right, last_out_mixer_right,
+                        out_mixer_right);
+        }
+
+        if (rightdry == null) {
+            mixAudioStream(leftdry, eff1, last_out_mixer_effect1,
+                    out_mixer_effect1);
+            mixAudioStream(leftdry, eff2, last_out_mixer_effect2,
+                    out_mixer_effect2);
+        } else {
+            mixAudioStream(leftdry, eff1, last_out_mixer_effect1 * 0.5f,
+                    out_mixer_effect1 * 0.5f);
+            mixAudioStream(leftdry, eff2, last_out_mixer_effect2 * 0.5f,
+                    out_mixer_effect2 * 0.5f);
+            mixAudioStream(rightdry, eff1, last_out_mixer_effect1 * 0.5f,
+                    out_mixer_effect1 * 0.5f);
+            mixAudioStream(rightdry, eff2, last_out_mixer_effect2 * 0.5f,
+                    out_mixer_effect2 * 0.5f);
+        }
+
+        last_out_mixer_left = out_mixer_left;
+        last_out_mixer_right = out_mixer_right;
+        last_out_mixer_effect1 = out_mixer_effect1;
+        last_out_mixer_effect2 = out_mixer_effect2;
+
+        if (out_mixer_end) {
+            stopping = true;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/WaveExtensibleFileReader.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import javax.sound.sampled.AudioFormat.Encoding;
+import javax.sound.sampled.spi.AudioFileReader;
+
+/**
+ * WAVE file reader for files using format WAVE_FORMAT_EXTENSIBLE (0xFFFE).
+ *
+ * @author Karl Helgason
+ */
+public class WaveExtensibleFileReader extends AudioFileReader {
+
+    static private class GUID {
+        long i1;
+
+        int s1;
+
+        int s2;
+
+        int x1;
+
+        int x2;
+
+        int x3;
+
+        int x4;
+
+        int x5;
+
+        int x6;
+
+        int x7;
+
+        int x8;
+
+        private GUID() {
+        }
+
+        public GUID(long i1, int s1, int s2, int x1, int x2, int x3, int x4,
+                int x5, int x6, int x7, int x8) {
+            this.i1 = i1;
+            this.s1 = s1;
+            this.s2 = s2;
+            this.x1 = x1;
+            this.x2 = x2;
+            this.x3 = x3;
+            this.x4 = x4;
+            this.x5 = x5;
+            this.x6 = x6;
+            this.x7 = x7;
+            this.x8 = x8;
+        }
+
+        public static GUID read(RIFFReader riff) throws IOException {
+            GUID d = new GUID();
+            d.i1 = riff.readUnsignedInt();
+            d.s1 = riff.readUnsignedShort();
+            d.s2 = riff.readUnsignedShort();
+            d.x1 = riff.readUnsignedByte();
+            d.x2 = riff.readUnsignedByte();
+            d.x3 = riff.readUnsignedByte();
+            d.x4 = riff.readUnsignedByte();
+            d.x5 = riff.readUnsignedByte();
+            d.x6 = riff.readUnsignedByte();
+            d.x7 = riff.readUnsignedByte();
+            d.x8 = riff.readUnsignedByte();
+            return d;
+        }
+
+        public int hashCode() {
+            return (int) i1;
+        }
+
+        public boolean equals(Object obj) {
+            if (!(obj instanceof GUID))
+                return false;
+            GUID t = (GUID) obj;
+            if (i1 != t.i1)
+                return false;
+            if (s1 != t.s1)
+                return false;
+            if (s2 != t.s2)
+                return false;
+            if (x1 != t.x1)
+                return false;
+            if (x2 != t.x2)
+                return false;
+            if (x3 != t.x3)
+                return false;
+            if (x4 != t.x4)
+                return false;
+            if (x5 != t.x5)
+                return false;
+            if (x6 != t.x6)
+                return false;
+            if (x7 != t.x7)
+                return false;
+            if (x8 != t.x8)
+                return false;
+            return true;
+        }
+
+    }
+
+    private static String[] channelnames = { "FL", "FR", "FC", "LF",
+            "BL",
+            "BR", // 5.1
+            "FLC", "FLR", "BC", "SL", "SR", "TC", "TFL", "TFC", "TFR", "TBL",
+            "TBC", "TBR" };
+
+    private static String[] allchannelnames = { "w1", "w2", "w3", "w4", "w5",
+            "w6", "w7", "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15",
+            "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23", "w24",
+            "w25", "w26", "w27", "w28", "w29", "w30", "w31", "w32", "w33",
+            "w34", "w35", "w36", "w37", "w38", "w39", "w40", "w41", "w42",
+            "w43", "w44", "w45", "w46", "w47", "w48", "w49", "w50", "w51",
+            "w52", "w53", "w54", "w55", "w56", "w57", "w58", "w59", "w60",
+            "w61", "w62", "w63", "w64" };
+
+    private static GUID SUBTYPE_PCM = new GUID(0x00000001, 0x0000, 0x0010,
+            0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
+
+    private static GUID SUBTYPE_IEEE_FLOAT = new GUID(0x00000003, 0x0000,
+            0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
+
+    private String decodeChannelMask(long channelmask) {
+        StringBuffer sb = new StringBuffer();
+        long m = 1;
+        for (int i = 0; i < allchannelnames.length; i++) {
+            if ((channelmask & m) != 0L) {
+                if (i < channelnames.length) {
+                    sb.append(channelnames[i] + " ");
+                } else {
+                    sb.append(allchannelnames[i] + " ");
+                }
+            }
+            m *= 2L;
+        }
+        if (sb.length() == 0)
+            return null;
+        return sb.substring(0, sb.length() - 1);
+
+    }
+
+    public AudioFileFormat getAudioFileFormat(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+
+        stream.mark(200);
+        AudioFileFormat format;
+        try {
+            format = internal_getAudioFileFormat(stream);
+        } finally {
+            stream.reset();
+        }
+        return format;
+    }
+
+    private AudioFileFormat internal_getAudioFileFormat(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+
+        RIFFReader riffiterator = new RIFFReader(stream);
+        if (!riffiterator.getFormat().equals("RIFF"))
+            throw new UnsupportedAudioFileException();
+        if (!riffiterator.getType().equals("WAVE"))
+            throw new UnsupportedAudioFileException();
+
+        boolean fmt_found = false;
+        boolean data_found = false;
+
+        int channels = 1;
+        long samplerate = 1;
+        // long framerate = 1;
+        int framesize = 1;
+        int bits = 1;
+        int validBitsPerSample = 1;
+        long channelMask = 0;
+        GUID subFormat = null;
+
+        while (riffiterator.hasNextChunk()) {
+            RIFFReader chunk = riffiterator.nextChunk();
+
+            if (chunk.getFormat().equals("fmt ")) {
+                fmt_found = true;
+
+                int format = chunk.readUnsignedShort();
+                if (format != 0xFFFE)
+                    throw new UnsupportedAudioFileException(); // WAVE_FORMAT_EXTENSIBLE
+                // only
+                channels = chunk.readUnsignedShort();
+                samplerate = chunk.readUnsignedInt();
+                /* framerate = */chunk.readUnsignedInt();
+                framesize = chunk.readUnsignedShort();
+                bits = chunk.readUnsignedShort();
+                int cbSize = chunk.readUnsignedShort();
+                if (cbSize != 22)
+                    throw new UnsupportedAudioFileException();
+                validBitsPerSample = chunk.readUnsignedShort();
+                if (validBitsPerSample > bits)
+                    throw new UnsupportedAudioFileException();
+                channelMask = chunk.readUnsignedInt();
+                subFormat = GUID.read(chunk);
+
+            }
+            if (chunk.getFormat().equals("data")) {
+                data_found = true;
+                break;
+            }
+        }
+
+        if (!fmt_found)
+            throw new UnsupportedAudioFileException();
+        if (!data_found)
+            throw new UnsupportedAudioFileException();
+
+        Map<String, Object> p = new HashMap<String, Object>();
+        String s_channelmask = decodeChannelMask(channelMask);
+        if (s_channelmask != null)
+            p.put("channelOrder", s_channelmask);
+        if (channelMask != 0)
+            p.put("channelMask", channelMask);
+        // validBitsPerSample is only informational for PCM data,
+        // data is still encode according to SampleSizeInBits.
+        p.put("validBitsPerSample", validBitsPerSample);
+
+        AudioFormat audioformat = null;
+        if (subFormat.equals(SUBTYPE_PCM)) {
+            if (bits == 8) {
+                audioformat = new AudioFormat(Encoding.PCM_UNSIGNED,
+                        samplerate, bits, channels, framesize, samplerate,
+                        false, p);
+            } else {
+                audioformat = new AudioFormat(Encoding.PCM_SIGNED, samplerate,
+                        bits, channels, framesize, samplerate, false, p);
+            }
+        } else if (subFormat.equals(SUBTYPE_IEEE_FLOAT)) {
+            audioformat = new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    samplerate, bits, channels, framesize, samplerate, false, p);
+        } else
+            throw new UnsupportedAudioFileException();
+
+        AudioFileFormat fileformat = new AudioFileFormat(
+                AudioFileFormat.Type.WAVE, audioformat,
+                AudioSystem.NOT_SPECIFIED);
+        return fileformat;
+    }
+
+    public AudioInputStream getAudioInputStream(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+
+        AudioFileFormat format = getAudioFileFormat(stream);
+        RIFFReader riffiterator = new RIFFReader(stream);
+        if (!riffiterator.getFormat().equals("RIFF"))
+            throw new UnsupportedAudioFileException();
+        if (!riffiterator.getType().equals("WAVE"))
+            throw new UnsupportedAudioFileException();
+        while (riffiterator.hasNextChunk()) {
+            RIFFReader chunk = riffiterator.nextChunk();
+            if (chunk.getFormat().equals("data")) {
+                return new AudioInputStream(chunk, format.getFormat(), chunk
+                        .getSize());
+            }
+        }
+        throw new UnsupportedAudioFileException();
+    }
+
+    public AudioFileFormat getAudioFileFormat(URL url)
+            throws UnsupportedAudioFileException, IOException {
+        InputStream stream = url.openStream();
+        AudioFileFormat format;
+        try {
+            format = getAudioFileFormat(new BufferedInputStream(stream));
+        } finally {
+            stream.close();
+        }
+        return format;
+    }
+
+    public AudioFileFormat getAudioFileFormat(File file)
+            throws UnsupportedAudioFileException, IOException {
+        InputStream stream = new FileInputStream(file);
+        AudioFileFormat format;
+        try {
+            format = getAudioFileFormat(new BufferedInputStream(stream));
+        } finally {
+            stream.close();
+        }
+        return format;
+    }
+
+    public AudioInputStream getAudioInputStream(URL url)
+            throws UnsupportedAudioFileException, IOException {
+        return getAudioInputStream(new BufferedInputStream(url.openStream()));
+    }
+
+    public AudioInputStream getAudioInputStream(File file)
+            throws UnsupportedAudioFileException, IOException {
+        return getAudioInputStream(new BufferedInputStream(new FileInputStream(
+                file)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/WaveFloatFileReader.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import javax.sound.sampled.spi.AudioFileReader;
+
+/**
+ * Floating-point encoded (format 3) WAVE file loader.
+ *
+ * @author Karl Helgason
+ */
+public class WaveFloatFileReader extends AudioFileReader {
+
+    public AudioFileFormat getAudioFileFormat(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+
+        stream.mark(200);
+        AudioFileFormat format;
+        try {
+            format = internal_getAudioFileFormat(stream);
+        } finally {
+            stream.reset();
+        }
+        return format;
+    }
+
+    private AudioFileFormat internal_getAudioFileFormat(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+
+        RIFFReader riffiterator = new RIFFReader(stream);
+        if (!riffiterator.getFormat().equals("RIFF"))
+            throw new UnsupportedAudioFileException();
+        if (!riffiterator.getType().equals("WAVE"))
+            throw new UnsupportedAudioFileException();
+
+        boolean fmt_found = false;
+        boolean data_found = false;
+
+        int channels = 1;
+        long samplerate = 1;
+        int framesize = 1;
+        int bits = 1;
+
+        while (riffiterator.hasNextChunk()) {
+            RIFFReader chunk = riffiterator.nextChunk();
+
+            if (chunk.getFormat().equals("fmt ")) {
+                fmt_found = true;
+
+                int format = chunk.readUnsignedShort();
+                if (format != 3) // WAVE_FORMAT_IEEE_FLOAT only
+                    throw new UnsupportedAudioFileException();
+                channels = chunk.readUnsignedShort();
+                samplerate = chunk.readUnsignedInt();
+                /* framerate = */chunk.readUnsignedInt();
+                framesize = chunk.readUnsignedShort();
+                bits = chunk.readUnsignedShort();
+            }
+            if (chunk.getFormat().equals("data")) {
+                data_found = true;
+                break;
+            }
+        }
+
+        if (!fmt_found)
+            throw new UnsupportedAudioFileException();
+        if (!data_found)
+            throw new UnsupportedAudioFileException();
+
+        AudioFormat audioformat = new AudioFormat(
+                AudioFloatConverter.PCM_FLOAT, samplerate, bits, channels,
+                framesize, samplerate, false);
+        AudioFileFormat fileformat = new AudioFileFormat(
+                AudioFileFormat.Type.WAVE, audioformat,
+                AudioSystem.NOT_SPECIFIED);
+        return fileformat;
+    }
+
+    public AudioInputStream getAudioInputStream(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+
+        AudioFileFormat format = getAudioFileFormat(stream);
+        RIFFReader riffiterator = new RIFFReader(stream);
+        if (!riffiterator.getFormat().equals("RIFF"))
+            throw new UnsupportedAudioFileException();
+        if (!riffiterator.getType().equals("WAVE"))
+            throw new UnsupportedAudioFileException();
+        while (riffiterator.hasNextChunk()) {
+            RIFFReader chunk = riffiterator.nextChunk();
+            if (chunk.getFormat().equals("data")) {
+                return new AudioInputStream(chunk, format.getFormat(),
+                        chunk.getSize());
+            }
+        }
+        throw new UnsupportedAudioFileException();
+    }
+
+    public AudioFileFormat getAudioFileFormat(URL url)
+            throws UnsupportedAudioFileException, IOException {
+        InputStream stream = url.openStream();
+        AudioFileFormat format;
+        try {
+            format = getAudioFileFormat(new BufferedInputStream(stream));
+        } finally {
+            stream.close();
+        }
+        return format;
+    }
+
+    public AudioFileFormat getAudioFileFormat(File file)
+            throws UnsupportedAudioFileException, IOException {
+        InputStream stream = new FileInputStream(file);
+        AudioFileFormat format;
+        try {
+            format = getAudioFileFormat(new BufferedInputStream(stream));
+        } finally {
+            stream.close();
+        }
+        return format;
+    }
+
+    public AudioInputStream getAudioInputStream(URL url)
+            throws UnsupportedAudioFileException, IOException {
+        return getAudioInputStream(new BufferedInputStream(url.openStream()));
+    }
+
+    public AudioInputStream getAudioInputStream(File file)
+            throws UnsupportedAudioFileException, IOException {
+        return getAudioInputStream(new BufferedInputStream(new FileInputStream(
+                file)));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/WaveFloatFileWriter.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.AudioFileFormat.Type;
+import javax.sound.sampled.spi.AudioFileWriter;
+
+/**
+ * Floating-point encoded (format 3) WAVE file writer.
+ *
+ * @author Karl Helgason
+ */
+public class WaveFloatFileWriter extends AudioFileWriter {
+
+    public Type[] getAudioFileTypes() {
+        return new Type[] { Type.WAVE };
+    }
+
+    public Type[] getAudioFileTypes(AudioInputStream stream) {
+
+        if (!stream.getFormat().getEncoding().equals(
+                AudioFloatConverter.PCM_FLOAT))
+            return new Type[0];
+        return new Type[] { Type.WAVE };
+    }
+
+    private void checkFormat(AudioFileFormat.Type type, AudioInputStream stream) {
+        if (!Type.WAVE.equals(type))
+            throw new IllegalArgumentException("File type " + type
+                    + " not supported.");
+        if (!stream.getFormat().getEncoding().equals(
+                AudioFloatConverter.PCM_FLOAT))
+            throw new IllegalArgumentException("File format "
+                    + stream.getFormat() + " not supported.");
+    }
+
+    public void write(AudioInputStream stream, RIFFWriter writer)
+            throws IOException {
+
+        RIFFWriter fmt_chunk = writer.writeChunk("fmt ");
+
+        AudioFormat format = stream.getFormat();
+        fmt_chunk.writeUnsignedShort(3); // WAVE_FORMAT_IEEE_FLOAT
+        fmt_chunk.writeUnsignedShort(format.getChannels());
+        fmt_chunk.writeUnsignedInt((int) format.getSampleRate());
+        fmt_chunk.writeUnsignedInt(((int) format.getFrameRate())
+                * format.getFrameSize());
+        fmt_chunk.writeUnsignedShort(format.getFrameSize());
+        fmt_chunk.writeUnsignedShort(format.getSampleSizeInBits());
+        fmt_chunk.close();
+        RIFFWriter data_chunk = writer.writeChunk("data");
+        byte[] buff = new byte[1024];
+        int len;
+        while ((len = stream.read(buff, 0, buff.length)) != -1)
+            data_chunk.write(buff, 0, len);
+        data_chunk.close();
+    }
+
+    private static class NoCloseOutputStream extends OutputStream {
+        OutputStream out;
+
+        public NoCloseOutputStream(OutputStream out) {
+            this.out = out;
+        }
+
+        public void write(int b) throws IOException {
+            out.write(b);
+        }
+
+        public void flush() throws IOException {
+            out.flush();
+        }
+
+        public void write(byte[] b, int off, int len) throws IOException {
+            out.write(b, off, len);
+        }
+
+        public void write(byte[] b) throws IOException {
+            out.write(b);
+        }
+    }
+
+    private AudioInputStream toLittleEndian(AudioInputStream ais) {
+        AudioFormat format = ais.getFormat();
+        AudioFormat targetFormat = new AudioFormat(format.getEncoding(), format
+                .getSampleRate(), format.getSampleSizeInBits(), format
+                .getChannels(), format.getFrameSize(), format.getFrameRate(),
+                false);
+        return AudioSystem.getAudioInputStream(targetFormat, ais);
+    }
+
+    public int write(AudioInputStream stream, Type fileType, OutputStream out)
+            throws IOException {
+
+        checkFormat(fileType, stream);
+        if (stream.getFormat().isBigEndian())
+            stream = toLittleEndian(stream);
+        RIFFWriter writer = new RIFFWriter(new NoCloseOutputStream(out), "WAVE");
+        write(stream, writer);
+        int fpointer = (int) writer.getFilePointer();
+        writer.close();
+        return fpointer;
+    }
+
+    public int write(AudioInputStream stream, Type fileType, File out)
+            throws IOException {
+        checkFormat(fileType, stream);
+        if (stream.getFormat().isBigEndian())
+            stream = toLittleEndian(stream);
+        RIFFWriter writer = new RIFFWriter(out, "WAVE");
+        write(stream, writer);
+        int fpointer = (int) writer.getFilePointer();
+        writer.close();
+        return fpointer;
+    }
+
+}
--- a/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.midi.spi.MidiDeviceProvider	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.midi.spi.MidiDeviceProvider	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,5 @@
 # Providers for midi devices
-com.sun.media.sound.MixerSynthProvider
 com.sun.media.sound.RealTimeSequencerProvider
 com.sun.media.sound.MidiOutDeviceProvider
 com.sun.media.sound.MidiInDeviceProvider
+com.sun.media.sound.SoftProvider
--- a/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.midi.spi.MidiFileReader	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.midi.spi.MidiFileReader	Wed Jul 05 16:46:22 2017 +0200
@@ -1,3 +1,2 @@
 # Providers for midi sequences
 com.sun.media.sound.StandardMidiFileReader
-com.sun.media.sound.RmfFileReader
--- a/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.midi.spi.SoundbankReader	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.midi.spi.SoundbankReader	Wed Jul 05 16:46:22 2017 +0200
@@ -1,2 +1,5 @@
 # Providers for Soundbanks
-com.sun.media.sound.HsbParser
+com.sun.media.sound.SF2SoundbankReader
+com.sun.media.sound.DLSSoundbankReader
+com.sun.media.sound.AudioFileSoundbankReader
+com.sun.media.sound.JARSoundbankReader
--- a/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.sampled.spi.AudioFileReader	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.sampled.spi.AudioFileReader	Wed Jul 05 16:46:22 2017 +0200
@@ -2,3 +2,5 @@
 com.sun.media.sound.AuFileReader
 com.sun.media.sound.AiffFileReader
 com.sun.media.sound.WaveFileReader
+com.sun.media.sound.WaveFloatFileReader
+com.sun.media.sound.SoftMidiAudioFileReader
--- a/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.sampled.spi.FormatConversionProvider	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.sampled.spi.FormatConversionProvider	Wed Jul 05 16:46:22 2017 +0200
@@ -2,3 +2,4 @@
 com.sun.media.sound.UlawCodec
 com.sun.media.sound.AlawCodec
 com.sun.media.sound.PCMtoPCMCodec
+com.sun.media.sound.AudioFloatFormatConverter
--- a/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.sampled.spi.MixerProvider	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.sampled.spi.MixerProvider	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,3 @@
 # last mixer is default mixer
 com.sun.media.sound.PortMixerProvider
-com.sun.media.sound.SimpleInputDeviceProvider
-com.sun.media.sound.HeadspaceMixerProvider
 com.sun.media.sound.DirectAudioDeviceProvider
--- a/jdk/src/share/classes/java/beans/EventHandler.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/beans/EventHandler.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, 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
@@ -385,16 +385,16 @@
         try {
             Method getter = null;
             if (target != null) {
-                getter = ReflectionUtils.getMethod(target.getClass(),
+                getter = Statement.getMethod(target.getClass(),
                                       "get" + NameGenerator.capitalize(first),
                                       new Class[]{});
                 if (getter == null) {
-                    getter = ReflectionUtils.getMethod(target.getClass(),
+                    getter = Statement.getMethod(target.getClass(),
                                    "is" + NameGenerator.capitalize(first),
                                    new Class[]{});
                 }
                 if (getter == null) {
-                    getter = ReflectionUtils.getMethod(target.getClass(), first, new Class[]{});
+                    getter = Statement.getMethod(target.getClass(), first, new Class[]{});
                 }
             }
             if (getter == null) {
@@ -462,10 +462,10 @@
                     target = applyGetters(target, action.substring(0, lastDot));
                     action = action.substring(lastDot + 1);
                 }
-                Method targetMethod = ReflectionUtils.getMethod(
+                Method targetMethod = Statement.getMethod(
                              target.getClass(), action, argTypes);
                 if (targetMethod == null) {
-                    targetMethod = ReflectionUtils.getMethod(target.getClass(),
+                    targetMethod = Statement.getMethod(target.getClass(),
                              "set" + NameGenerator.capitalize(action), argTypes);
                 }
                 if (targetMethod == null) {
--- a/jdk/src/share/classes/java/beans/MetaData.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/beans/MetaData.java	Wed Jul 05 16:46:22 2017 +0200
@@ -24,6 +24,8 @@
  */
 package java.beans;
 
+import com.sun.beans.finder.PrimitiveWrapperMap;
+
 import java.awt.AWTKeyStroke;
 import java.awt.BorderLayout;
 import java.awt.Dimension;
@@ -204,7 +206,7 @@
         if (c.isPrimitive()) {
             Field field = null;
             try {
-                field = ReflectionUtils.typeToClass(c).getDeclaredField("TYPE");
+                field = PrimitiveWrapperMap.getType(c.getName()).getDeclaredField("TYPE");
             } catch (NoSuchFieldException ex) {
                 System.err.println("Unknown primitive type: " + c);
             }
--- a/jdk/src/share/classes/java/beans/ReflectionUtils.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/beans/ReflectionUtils.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, 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
@@ -24,20 +24,7 @@
  */
 package java.beans;
 
-import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
-
-import java.util.*;
-
-import com.sun.beans.ObjectHandler;
-import sun.reflect.misc.MethodUtil;
-import sun.reflect.misc.ConstructorUtil;
-import sun.reflect.misc.ReflectUtil;
 
 /**
  * A utility class for reflectively finding methods, constuctors and fields
@@ -45,12 +32,6 @@
  */
 class ReflectionUtils {
 
-    private static Reference methodCacheRef;
-
-    public static Class typeToClass(Class type) {
-        return type.isPrimitive() ? ObjectHandler.typeNameToClass(type.getName()) : type;
-    }
-
     public static boolean isPrimitive(Class type) {
         return primitiveTypeFor(type) != null;
     }
@@ -69,346 +50,6 @@
     }
 
     /**
-     * Tests each element on the class arrays for assignability.
-     *
-     * @param argClasses arguments to be tested
-     * @param argTypes arguments from Method
-     * @return true if each class in argTypes is assignable from the
-     *         corresponding class in argClasses.
-     */
-    private static boolean matchArguments(Class[] argClasses, Class[] argTypes) {
-        return matchArguments(argClasses, argTypes, false);
-    }
-
-    /**
-     * Tests each element on the class arrays for equality.
-     *
-     * @param argClasses arguments to be tested
-     * @param argTypes arguments from Method
-     * @return true if each class in argTypes is equal to the
-     *         corresponding class in argClasses.
-     */
-    private static boolean matchExplicitArguments(Class[] argClasses, Class[] argTypes) {
-        return matchArguments(argClasses, argTypes, true);
-    }
-
-    private static boolean matchArguments(Class[] argClasses,
-                                          Class[] argTypes, boolean explicit) {
-
-        boolean match = (argClasses.length == argTypes.length);
-        for(int j = 0; j < argClasses.length && match; j++) {
-            Class argType = argTypes[j];
-            if (argType.isPrimitive()) {
-                argType = typeToClass(argType);
-            }
-            if (explicit) {
-                // Test each element for equality
-                if (argClasses[j] != argType) {
-                    match = false;
-                }
-            } else {
-                // Consider null an instance of all classes.
-                if (argClasses[j] != null &&
-                    !(argType.isAssignableFrom(argClasses[j]))) {
-                    match = false;
-                }
-            }
-        }
-        return match;
-    }
-
-    /**
-     * @return the method which best matches the signature or throw an exception
-     *         if it can't be found or the method is ambiguous.
-     */
-    static Method getPublicMethod(Class declaringClass, String methodName,
-                                           Class[] argClasses) throws NoSuchMethodException {
-        Method m;
-
-        m = findPublicMethod(declaringClass, methodName, argClasses);
-        if (m == null)
-            throw new NoSuchMethodException(declaringClass.getName() + "." + methodName);
-        return m;
-    }
-
-    /**
-     * @return the method which best matches the signature or null if it cant be found or
-     *         the method is ambiguous.
-     */
-    public static Method findPublicMethod(Class declaringClass, String methodName,
-                                           Class[] argClasses) {
-        // Many methods are "getters" which take no arguments.
-        // This permits the following optimisation which
-        // avoids the expensive call to getMethods().
-        if (argClasses.length == 0) {
-            try {
-                return MethodUtil.getMethod(declaringClass, methodName, argClasses);
-            }
-            catch (NoSuchMethodException e) {
-                  return null;
-            } catch (SecurityException se) {
-                // fall through
-            }
-        }
-        Method[] methods = MethodUtil.getPublicMethods(declaringClass);
-        List list = new ArrayList();
-        for(int i = 0; i < methods.length; i++) {
-            // Collect all the methods which match the signature.
-            Method method = methods[i];
-            if (method.getName().equals(methodName)) {
-                if (matchArguments(argClasses, method.getParameterTypes())) {
-                    list.add(method);
-                }
-            }
-        }
-        if (list.size() > 0) {
-            if (list.size() == 1) {
-                return (Method)list.get(0);
-            }
-            else {
-                ListIterator iterator = list.listIterator();
-                Method method;
-                while (iterator.hasNext()) {
-                    method = (Method)iterator.next();
-                    if (matchExplicitArguments(argClasses, method.getParameterTypes())) {
-                        return method;
-                    }
-                }
-                // There are more than one method which matches this signature.
-                // try to return the most specific method.
-                return getMostSpecificMethod(list, argClasses);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return the most specific method from the list of methods which
-     * matches the args. The most specific method will have the most
-     * number of equal parameters or will be closest in the inheritance
-     * heirarchy to the runtime execution arguments.
-     * <p>
-     * See the JLS section 15.12
-     * http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#20448
-     *
-     * @param methods List of methods which already have the same param length
-     *                and arg types are assignable to param types
-     * @param args an array of param types to match
-     * @return method or null if a specific method cannot be determined
-     */
-    private static Method getMostSpecificMethod(List methods, Class[] args) {
-        Method method = null;
-
-        int matches = 0;
-        int lastMatch = matches;
-
-        ListIterator iterator = methods.listIterator();
-        while (iterator.hasNext()) {
-            Method m = (Method)iterator.next();
-            Class[] mArgs = m.getParameterTypes();
-            matches = 0;
-            for (int i = 0; i < args.length; i++) {
-                Class mArg = mArgs[i];
-                if (mArg.isPrimitive()) {
-                    mArg = typeToClass(mArg);
-                }
-                if (args[i] == mArg) {
-                    matches++;
-                }
-            }
-            if (matches == 0 && lastMatch == 0) {
-                if (method == null) {
-                    method = m;
-                } else {
-                    // Test existing method. We already know that the args can
-                    // be assigned to all the method params. However, if the
-                    // current method parameters is higher in the inheritance
-                    // hierarchy then replace it.
-                    if (!matchArguments(method.getParameterTypes(),
-                                        m.getParameterTypes())) {
-                        method = m;
-                    }
-                }
-            } else if (matches > lastMatch) {
-                lastMatch = matches;
-                method = m;
-            } else if (matches == lastMatch) {
-                // ambiguous method selection.
-                method = null;
-            }
-        }
-        return method;
-    }
-
-    /**
-     * @return the method or null if it can't be found or is ambiguous.
-     */
-    public static Method findMethod(Class targetClass, String methodName,
-                                    Class[] argClasses) {
-        Method m = findPublicMethod(targetClass, methodName, argClasses);
-        if (m != null && Modifier.isPublic(m.getDeclaringClass().getModifiers())) {
-            return m;
-        }
-
-        /*
-        Search the interfaces for a public version of this method.
-
-        Example: the getKeymap() method of a JTextField
-        returns a package private implementation of the
-        of the public Keymap interface. In the Keymap
-        interface there are a number of "properties" one
-        being the "resolveParent" property implied by the
-        getResolveParent() method. This getResolveParent()
-        cannot be called reflectively because the class
-        itself is not public. Instead we search the class's
-        interfaces and find the getResolveParent()
-        method of the Keymap interface - on which invoke
-        may be applied without error.
-
-        So in :-
-
-            JTextField o = new JTextField("Hello, world");
-            Keymap km = o.getKeymap();
-            Method m1 = km.getClass().getMethod("getResolveParent", new Class[0]);
-            Method m2 = Keymap.class.getMethod("getResolveParent", new Class[0]);
-
-        Methods m1 and m2 are different. The invocation of method
-        m1 unconditionally throws an IllegalAccessException where
-        the invocation of m2 will invoke the implementation of the
-        method. Note that (ignoring the overloading of arguments)
-        there is only one implementation of the named method which
-        may be applied to this target.
-        */
-        for(Class type = targetClass; type != null; type = type.getSuperclass()) {
-            Class[] interfaces = type.getInterfaces();
-            for(int i = 0; i < interfaces.length; i++) {
-                m = findPublicMethod(interfaces[i], methodName, argClasses);
-                if (m != null) {
-                    return m;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * A class that represents the unique elements of a method that will be a
-     * key in the method cache.
-     */
-    private static class Signature {
-        private Class targetClass;
-        private String methodName;
-        private Class[] argClasses;
-
-        private volatile int hashCode = 0;
-
-        public Signature(Class targetClass, String methodName, Class[] argClasses) {
-            this.targetClass = targetClass;
-            this.methodName = methodName;
-            this.argClasses = argClasses;
-        }
-
-        public boolean equals(Object o2) {
-            if (this == o2) {
-                return true;
-            }
-            Signature that = (Signature)o2;
-            if (!(targetClass == that.targetClass)) {
-                return false;
-            }
-            if (!(methodName.equals(that.methodName))) {
-                return false;
-            }
-            if (argClasses.length != that.argClasses.length) {
-                return false;
-            }
-            for (int i = 0; i < argClasses.length; i++) {
-                if (!(argClasses[i] == that.argClasses[i])) {
-                  return false;
-                }
-            }
-            return true;
-        }
-
-        /**
-         * Hash code computed using algorithm suggested in
-         * Effective Java, Item 8.
-         */
-        public int hashCode() {
-            if (hashCode == 0) {
-                int result = 17;
-                result = 37 * result + targetClass.hashCode();
-                result = 37 * result + methodName.hashCode();
-                if (argClasses != null) {
-                    for (int i = 0; i < argClasses.length; i++) {
-                        result = 37 * result + ((argClasses[i] == null) ? 0 :
-                            argClasses[i].hashCode());
-                    }
-                }
-                hashCode = result;
-            }
-            return hashCode;
-        }
-    }
-
-    /**
-     * A wrapper to findMethod(), which will search or populate the method
-     * in a cache.
-     * @throws exception if the method is ambiguios.
-     */
-    public static synchronized Method getMethod(Class targetClass,
-                                                String methodName,
-                                                Class[] argClasses) {
-        Object signature = new Signature(targetClass, methodName, argClasses);
-
-        Method method = null;
-        Map methodCache = null;
-        boolean cache = false;
-        if (ReflectUtil.isPackageAccessible(targetClass)) {
-            cache = true;
-        }
-
-        if (cache && methodCacheRef != null &&
-            (methodCache = (Map)methodCacheRef.get()) != null) {
-            method = (Method)methodCache.get(signature);
-            if (method != null) {
-                return method;
-            }
-        }
-        method = findMethod(targetClass, methodName, argClasses);
-        if (cache && method != null) {
-            if (methodCache == null) {
-                methodCache = new HashMap();
-                methodCacheRef = new SoftReference(methodCache);
-            }
-            methodCache.put(signature, method);
-        }
-        return method;
-    }
-
-    /**
-     * Return a constructor on the class with the arguments.
-     *
-     * @throws exception if the method is ambiguios.
-     */
-    public static Constructor getConstructor(Class cls, Class[] args) {
-        Constructor constructor = null;
-
-        // PENDING: Implement the resolutuion of ambiguities properly.
-        Constructor[] ctors = ConstructorUtil.getConstructors(cls);
-        for(int i = 0; i < ctors.length; i++) {
-            if (matchArguments(args, ctors[i].getParameterTypes())) {
-                constructor = ctors[i];
-            }
-        }
-        return constructor;
-    }
-
-    public static Object getPrivateField(Object instance, Class cls, String name) {
-        return getPrivateField(instance, cls, name, null);
-    }
-
-    /**
      * Returns the value of a private field.
      *
      * @param instance object instance
--- a/jdk/src/share/classes/java/beans/Statement.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/beans/Statement.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, 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
@@ -31,6 +31,8 @@
 import java.lang.reflect.Method;
 
 import com.sun.beans.finder.ClassFinder;
+import com.sun.beans.finder.ConstructorFinder;
+import com.sun.beans.finder.MethodFinder;
 import sun.reflect.misc.MethodUtil;
 
 /**
@@ -195,13 +197,18 @@
                     argClasses[0] == String.class) {
                     return new Character(((String)arguments[0]).charAt(0));
                 }
-                m = ReflectionUtils.getConstructor((Class)target, argClasses);
+                try {
+                    m = ConstructorFinder.findConstructor((Class)target, argClasses);
+                }
+                catch (NoSuchMethodException exception) {
+                    m = null;
+                }
             }
             if (m == null && target != Class.class) {
-                m = ReflectionUtils.getMethod((Class)target, methodName, argClasses);
+                m = getMethod((Class)target, methodName, argClasses);
             }
             if (m == null) {
-                m = ReflectionUtils.getMethod(Class.class, methodName, argClasses);
+                m = getMethod(Class.class, methodName, argClasses);
             }
         }
         else {
@@ -224,7 +231,7 @@
                     return null;
                 }
             }
-            m = ReflectionUtils.getMethod(target.getClass(), methodName, argClasses);
+            m = getMethod(target.getClass(), methodName, argClasses);
         }
         if (m != null) {
             try {
@@ -289,4 +296,13 @@
         result.append(");");
         return result.toString();
     }
+
+    static Method getMethod(Class<?> type, String name, Class<?>... args) {
+        try {
+            return MethodFinder.findMethod(type, name, args);
+        }
+        catch (NoSuchMethodException exception) {
+            return null;
+        }
+    }
 }
--- a/jdk/src/share/classes/java/beans/XMLDecoder.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/beans/XMLDecoder.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, 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
@@ -24,19 +24,14 @@
  */
 package java.beans;
 
-import com.sun.beans.ObjectHandler;
+import com.sun.beans.decoder.DocumentHandler;
 
+import java.io.Closeable;
 import java.io.InputStream;
 import java.io.IOException;
 
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.SAXParserFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
 
 /**
  * The <code>XMLDecoder</code> class is used to read XML documents
@@ -66,11 +61,11 @@
  * @author Philip Milne
  */
 public class XMLDecoder {
-    private InputStream in;
+    private final DocumentHandler handler = new DocumentHandler();
+    private final InputSource input;
     private Object owner;
-    private ExceptionListener exceptionListener;
-    private ObjectHandler handler;
-    private Reference clref;
+    private Object[] array;
+    private int index;
 
     /**
      * Creates a new input stream for reading archives
@@ -126,36 +121,45 @@
      */
     public XMLDecoder(InputStream in, Object owner,
                       ExceptionListener exceptionListener, ClassLoader cl) {
-        this.in = in;
-        setOwner(owner);
-        setExceptionListener(exceptionListener);
-        setClassLoader(cl);
+        this(new InputSource(in), owner, exceptionListener, cl);
     }
 
 
     /**
-     * Set the class loader used to instantiate objects for this stream.
+     * Creates a new decoder to parse XML archives
+     * created by the {@code XMLEncoder} class.
+     * If the input source {@code is} is {@code null},
+     * no exception is thrown and no parsing is performed.
+     * This behavior is similar to behavior of other constructors
+     * that use {@code InputStream} as a parameter.
      *
-     * @param cl a classloader to use; if null then the default class loader
-     *           will be used
+     * @param is  the input source to parse
+     *
+     * @since 1.7
      */
-    private void setClassLoader(ClassLoader cl) {
-        if (cl != null) {
-            this.clref = new WeakReference(cl);
-        }
+    public XMLDecoder(InputSource is) {
+        this(is, null, null, null);
     }
 
     /**
-     * Return the class loader used to instantiate objects. If the class loader
-     * has not been explicitly set then null is returned.
+     * Creates a new decoder to parse XML archives
+     * created by the {@code XMLEncoder} class.
      *
-     * @return the class loader used to instantiate objects
+     * @param is     the input source to parse
+     * @param owner  the owner of this decoder
+     * @param el     the exception handler for the parser,
+     *               or {@code null} to use the default exception handler
+     * @param cl     the class loader used for instantiating objects,
+     *               or {@code null} to use the default class loader
+     *
+     * @since 1.7
      */
-    private ClassLoader getClassLoader() {
-        if (clref != null) {
-            return (ClassLoader)clref.get();
-        }
-        return null;
+    private XMLDecoder(InputSource is, Object owner, ExceptionListener el, ClassLoader cl) {
+        this.input = is;
+        this.owner = owner;
+        setExceptionListener(el);
+        this.handler.setClassLoader(cl);
+        this.handler.setOwner(this);
     }
 
     /**
@@ -163,8 +167,14 @@
      * with this stream.
      */
     public void close() {
+        if (parsingComplete()) {
+            close(this.input.getCharacterStream());
+            close(this.input.getByteStream());
+        }
+    }
+
+    private void close(Closeable in) {
         if (in != null) {
-            getHandler();
             try {
                 in.close();
             }
@@ -174,6 +184,17 @@
         }
     }
 
+    private boolean parsingComplete() {
+        if (this.input == null) {
+            return false;
+        }
+        if (this.array == null) {
+            this.handler.parse(this.input);
+            this.array = this.handler.getObjects();
+        }
+        return true;
+    }
+
     /**
      * Sets the exception handler for this stream to <code>exceptionListener</code>.
      * The exception handler is notified when this stream catches recoverable
@@ -185,7 +206,10 @@
      * @see #getExceptionListener
      */
     public void setExceptionListener(ExceptionListener exceptionListener) {
-        this.exceptionListener = exceptionListener;
+        if (exceptionListener == null) {
+            exceptionListener = Statement.defaultExceptionListener;
+        }
+        this.handler.setExceptionListener(exceptionListener);
     }
 
     /**
@@ -197,8 +221,7 @@
      * @see #setExceptionListener
      */
     public ExceptionListener getExceptionListener() {
-        return (exceptionListener != null) ? exceptionListener :
-            Statement.defaultExceptionListener;
+        return this.handler.getExceptionListener();
     }
 
     /**
@@ -212,10 +235,9 @@
      * @see XMLEncoder#writeObject
      */
     public Object readObject() {
-        if (in == null) {
-            return null;
-        }
-        return getHandler().dequeueResult();
+        return (parsingComplete())
+                ? this.array[this.index++]
+                : null;
     }
 
     /**
@@ -241,33 +263,32 @@
     }
 
     /**
-     * Returns the object handler for input stream.
-     * The object handler is created if necessary.
+     * Creates a new handler for SAX parser
+     * that can be used to parse embedded XML archives
+     * created by the {@code XMLEncoder} class.
      *
-     * @return  the object handler
+     * The {@code owner} should be used if parsed XML document contains
+     * the method call within context of the &lt;java&gt; element.
+     * The {@code null} value may cause illegal parsing in such case.
+     * The same problem may occur, if the {@code owner} class
+     * does not contain expected method to call. See details <a
+     * href="http://java.sun.com/products/jfc/tsc/articles/persistence3/">here</a>.
+     *
+     * @param owner  the owner of the default handler
+     *               that can be used as a value of &lt;java&gt; element
+     * @param el     the exception handler for the parser,
+     *               or {@code null} to use the default exception handler
+     * @param cl     the class loader used for instantiating objects,
+     *               or {@code null} to use the default class loader
+     * @return an instance of {@code DefaultHandler} for SAX parser
+     *
+     * @since 1.7
      */
-    private ObjectHandler getHandler() {
-        if ( handler == null ) {
-            SAXParserFactory factory = SAXParserFactory.newInstance();
-            try {
-                SAXParser parser = factory.newSAXParser();
-                handler = new ObjectHandler( this, getClassLoader() );
-                parser.parse( in, handler );
-            }
-            catch ( ParserConfigurationException e ) {
-                getExceptionListener().exceptionThrown( e );
-            }
-            catch ( SAXException se ) {
-                Exception e = se.getException();
-                if ( e == null ) {
-                    e = se;
-                }
-                getExceptionListener().exceptionThrown( e );
-            }
-            catch ( IOException ioe ) {
-                getExceptionListener().exceptionThrown( ioe );
-            }
-        }
+    public static DefaultHandler createHandler(Object owner, ExceptionListener el, ClassLoader cl) {
+        DocumentHandler handler = new DocumentHandler();
+        handler.setOwner(owner);
+        handler.setExceptionListener(el);
+        handler.setClassLoader(cl);
         return handler;
     }
 }
--- a/jdk/src/share/classes/java/lang/Double.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/lang/Double.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1994-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1994-2009 Sun Microsystems, 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
@@ -404,8 +404,19 @@
      * binary value that is then rounded to type {@code double}
      * by the usual round-to-nearest rule of IEEE 754 floating-point
      * arithmetic, which includes preserving the sign of a zero
-     * value. Finally, a {@code Double} object representing this
-     * {@code double} value is returned.
+     * value.
+     *
+     * Note that the round-to-nearest rule also implies overflow and
+     * underflow behaviour; if the exact value of {@code s} is large
+     * enough in magnitude (greater than or equal to ({@link
+     * #MAX_VALUE} + {@link Math#ulp(double) ulp(MAX_VALUE)}/2),
+     * rounding to {@code double} will result in an infinity and if the
+     * exact value of {@code s} is small enough in magnitude (less
+     * than or equal to {@link #MIN_VALUE}/2), rounding to float will
+     * result in a zero.
+     *
+     * Finally, after rounding a {@code Double} object representing
+     * this {@code double} value is returned.
      *
      * <p> To interpret localized string representations of a
      * floating-point value, use subclasses of {@link
--- a/jdk/src/share/classes/java/lang/Float.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/lang/Float.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1994-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1994-2009 Sun Microsystems, 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
@@ -365,8 +365,19 @@
      * binary value that is then rounded to type {@code float}
      * by the usual round-to-nearest rule of IEEE 754 floating-point
      * arithmetic, which includes preserving the sign of a zero
-     * value. Finally, a {@code Float} object representing this
-     * {@code float} value is returned.
+     * value.
+     *
+     * Note that the round-to-nearest rule also implies overflow and
+     * underflow behaviour; if the exact value of {@code s} is large
+     * enough in magnitude (greater than or equal to ({@link
+     * #MAX_VALUE} + {@link Math#ulp(float) ulp(MAX_VALUE)}/2),
+     * rounding to {@code float} will result in an infinity and if the
+     * exact value of {@code s} is small enough in magnitude (less
+     * than or equal to {@link #MIN_VALUE}/2), rounding to float will
+     * result in a zero.
+     *
+     * Finally, after rounding a {@code Float} object representing
+     * this {@code float} value is returned.
      *
      * <p>To interpret localized string representations of a
      * floating-point value, use subclasses of {@link
--- a/jdk/src/share/classes/java/net/DatagramSocket.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/net/DatagramSocket.java	Wed Jul 05 16:46:22 2017 +0200
@@ -41,10 +41,11 @@
  * one machine to another may be routed differently, and may arrive in
  * any order.
  *
- * <p>UDP broadcasts sends are always enabled on a DatagramSocket.
- * In order to receive broadcast packets a DatagramSocket
- * should be bound to the wildcard address. In some
- * implementations, broadcast packets may also be received when
+ * <p> Where possible, a newly constructed {@code DatagramSocket} has the
+ * {@link SocketOptions#SO_BROADCAST SO_BROADCAST} socket option enabled so as
+ * to allow the transmission of broadcast datagrams. In order to receive
+ * broadcast packets a DatagramSocket should be bound to the wildcard address.
+ * In some implementations, broadcast packets may also be received when
  * a DatagramSocket is bound to a more specific address.
  * <p>
  * Example:
@@ -1017,9 +1018,18 @@
 
     /**
      * Enable/disable SO_BROADCAST.
-     * @param on     whether or not to have broadcast turned on.
-     * @exception SocketException if there is an error
-     * in the underlying protocol, such as an UDP error.
+     *
+     * <p> Some operating systems may require that the Java virtual machine be
+     * started with implementation specific privileges to enable this option or
+     * send broadcast datagrams.
+     *
+     * @param  on
+     *         whether or not to have broadcast turned on.
+     *
+     * @throws  SocketException
+     *          if there is an error in the underlying protocol, such as an UDP
+     *          error.
+     *
      * @since 1.4
      * @see #getBroadcast()
      */
--- a/jdk/src/share/classes/java/util/Calendar.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/util/Calendar.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1190,7 +1190,9 @@
      */
     public void set(int field, int value)
     {
-        if (isLenient() && areFieldsSet && !areAllFieldsSet) {
+        // If the fields are partially normalized, calculate all the
+        // fields before changing any fields.
+        if (areFieldsSet && !areAllFieldsSet) {
             computeFields();
         }
         internalSet(field, value);
--- a/jdk/src/share/classes/java/util/Collection.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/util/Collection.java	Wed Jul 05 16:46:22 2017 +0200
@@ -427,7 +427,7 @@
      * contract for the <tt>Object.hashCode</tt> method, programmers should
      * take note that any class that overrides the <tt>Object.equals</tt>
      * method must also override the <tt>Object.hashCode</tt> method in order
-     * to satisfy the general contract for the <tt>Object.hashCode</tt>method.
+     * to satisfy the general contract for the <tt>Object.hashCode</tt> method.
      * In particular, <tt>c1.equals(c2)</tt> implies that
      * <tt>c1.hashCode()==c2.hashCode()</tt>.
      *
--- a/jdk/src/share/classes/java/util/CurrencyData.properties	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/util/CurrencyData.properties	Wed Jul 05 16:46:22 2017 +0200
@@ -441,12 +441,16 @@
 RU=RUB
 # RWANDA
 RW=RWF
+# SAINT BARTHELEMY
+BL=EUR
 # SAINT HELENA
 SH=SHP
 # SAINT KITTS AND NEVIS
 KN=XCD
 # SAINT LUCIA
 LC=XCD
+# SAINT MARTIN
+MF=EUR
 # SAINT PIERRE AND MIQUELON
 PM=EUR
 # SAINT VINCENT AND THE GRENADINES
--- a/jdk/src/share/classes/java/util/Formatter.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/util/Formatter.java	Wed Jul 05 16:46:22 2017 +0200
@@ -39,6 +39,7 @@
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.MathContext;
+import java.math.RoundingMode;
 import java.nio.charset.Charset;
 import java.text.DateFormatSymbols;
 import java.text.DecimalFormat;
@@ -1252,7 +1253,7 @@
  *     Double#toString(double)} respectively, then the value will be rounded
  *     using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
  *     algorithm}.  Otherwise, zeros may be appended to reach the precision.
- *     For a canonical representation of the value,use {@link
+ *     For a canonical representation of the value, use {@link
  *     Float#toString(float)} or {@link Double#toString(double)} as
  *     appropriate.
  *
@@ -3569,15 +3570,23 @@
                 // Create a new BigDecimal with the desired precision.
                 int prec = (precision == -1 ? 6 : precision);
                 int scale = value.scale();
-                int compPrec = value.precision();
-                if (scale > prec)
-                    compPrec -= (scale - prec);
-                MathContext mc = new MathContext(compPrec);
-                BigDecimal v
-                    = new BigDecimal(value.unscaledValue(), scale, mc);
-
-                BigDecimalLayout bdl
-                    = new BigDecimalLayout(v.unscaledValue(), v.scale(),
+
+                if (scale > prec) {
+                    // more "scale" digits than the requested "precision
+                    int compPrec = value.precision();
+                    if (compPrec <= scale) {
+                        // case of 0.xxxxxx
+                        value = value.setScale(prec, RoundingMode.HALF_UP);
+                    } else {
+                        compPrec -= (scale - prec);
+                        value = new BigDecimal(value.unscaledValue(),
+                                               scale,
+                                               new MathContext(compPrec));
+                    }
+                }
+                BigDecimalLayout bdl = new BigDecimalLayout(
+                                           value.unscaledValue(),
+                                           value.scale(),
                                            BigDecimalLayoutForm.DECIMAL_FLOAT);
 
                 char mant[] = bdl.mantissa();
--- a/jdk/src/share/classes/java/util/LocaleISOData.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/util/LocaleISOData.java	Wed Jul 05 16:46:22 2017 +0200
@@ -250,6 +250,7 @@
         + "BH" + "BHR"  // Bahrain, Kingdom of
         + "BI" + "BDI"  // Burundi, Republic of
         + "BJ" + "BEN"  // Benin, People's Republic of
+        + "BL" + "BLM"  // Saint Barth\u00e9lemy
         + "BM" + "BMU"  // Bermuda
         + "BN" + "BRN"  // Brunei Darussalam
         + "BO" + "BOL"  // Bolivia, Republic of
@@ -273,7 +274,7 @@
         + "CN" + "CHN"  // China, People's Republic of
         + "CO" + "COL"  // Colombia, Republic of
         + "CR" + "CRI"  // Costa Rica, Republic of
-        + "CS" + "SCG"  // Serbia and Montenegro
+//      + "CS" + "SCG"  // Serbia and Montenegro
         + "CU" + "CUB"  // Cuba, Republic of
         + "CV" + "CPV"  // Cape Verde, Republic of
         + "CX" + "CXR"  // Christmas Island
@@ -363,6 +364,7 @@
         + "MC" + "MCO"  // Monaco, Principality of
         + "MD" + "MDA"  // Moldova, Republic of
         + "ME" + "MNE"  // Montenegro, Republic of
+        + "MF" + "MAF"  // Saint Martin
         + "MG" + "MDG"  // Madagascar, Republic of
         + "MH" + "MHL"  // Marshall Islands
         + "MK" + "MKD"  // Macedonia, the former Yugoslav Republic of
--- a/jdk/src/share/classes/java/util/Random.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/java/util/Random.java	Wed Jul 05 16:46:22 2017 +0200
@@ -32,7 +32,7 @@
  * An instance of this class is used to generate a stream of
  * pseudorandom numbers. The class uses a 48-bit seed, which is
  * modified using a linear congruential formula. (See Donald Knuth,
- * <i>The Art of Computer Programming, Volume 3</i>, Section 3.2.1.)
+ * <i>The Art of Computer Programming, Volume 2</i>, Section 3.2.1.)
  * <p>
  * If two instances of {@code Random} are created with the same
  * seed, and the same sequence of method calls is made for each, they
--- a/jdk/src/share/classes/javax/swing/ImageIcon.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/ImageIcon.java	Wed Jul 05 16:46:22 2017 +0200
@@ -86,7 +86,7 @@
 
     static {
         component = new Component() {};
-        AccessController.doPrivileged(new PrivilegedAction() {
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
             public Object run() {
                 try {
                     // 6482575 - clear the appContext field so as not to leak it
--- a/jdk/src/share/classes/javax/swing/ProgressMonitor.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/ProgressMonitor.java	Wed Jul 05 16:46:22 2017 +0200
@@ -78,7 +78,7 @@
  * @author James Gosling
  * @author Lynn Monsanto (accessibility)
  */
-public class ProgressMonitor extends Object implements Accessible
+public class ProgressMonitor implements Accessible
 {
     private ProgressMonitor root;
     private JDialog         dialog;
@@ -186,7 +186,7 @@
             }
             if (window instanceof SwingUtilities.SharedOwnerFrame) {
                 WindowListener ownerShutdownListener =
-                    (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener();
+                        SwingUtilities.getSharedOwnerFrameShutdownListener();
                 dialog.addWindowListener(ownerShutdownListener);
             }
             Container contentPane = dialog.getContentPane();
@@ -273,7 +273,7 @@
                 if (dT >= millisToDecideToPopup) {
                     int predictedCompletionTime;
                     if (nv > min) {
-                        predictedCompletionTime = (int)((long)dT *
+                        predictedCompletionTime = (int)(dT *
                                                         (max - min) /
                                                         (nv - min));
                     }
@@ -691,10 +691,7 @@
          * object does not have an Accessible parent
          */
         public Accessible getAccessibleParent() {
-            if (dialog != null) {
-                return (Accessible)dialog;
-            }
-            return null;
+            return dialog;
         }
 
         /*
@@ -768,7 +765,7 @@
             if (myBar != null) {
                 Component c = myBar.getParent();
                 if (c instanceof Accessible) {
-                    return ((Accessible)c).getAccessibleContext();
+                    return c.getAccessibleContext();
                 }
             }
             return null;
--- a/jdk/src/share/classes/javax/swing/RepaintManager.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/RepaintManager.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1305,9 +1305,12 @@
             if (doubleBufferingEnabled && !nativeDoubleBuffering) {
                 switch (bufferStrategyType) {
                 case BUFFER_STRATEGY_NOT_SPECIFIED:
-                    if (((SunToolkit)Toolkit.getDefaultToolkit()).
-                                                useBufferPerWindow()) {
-                        paintManager = new BufferStrategyPaintManager();
+                    Toolkit tk = Toolkit.getDefaultToolkit();
+                    if (tk instanceof SunToolkit) {
+                        SunToolkit stk = (SunToolkit) tk;
+                        if (stk.useBufferPerWindow()) {
+                            paintManager = new BufferStrategyPaintManager();
+                        }
                     }
                     break;
                 case BUFFER_STRATEGY_SPECIFIED_ON:
@@ -1329,9 +1332,16 @@
 
     private void scheduleProcessingRunnable(AppContext context) {
         if (processingRunnable.markPending()) {
-            SunToolkit.getSystemEventQueueImplPP(context).
-                postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(),
-                                              processingRunnable));
+            Toolkit tk = Toolkit.getDefaultToolkit();
+            if (tk instanceof SunToolkit) {
+                SunToolkit.getSystemEventQueueImplPP(context).
+                  postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(),
+                                                processingRunnable));
+            } else {
+                Toolkit.getDefaultToolkit().getSystemEventQueue().
+                      postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(),
+                                                    processingRunnable));
+            }
         }
     }
 
--- a/jdk/src/share/classes/javax/swing/SwingWorker.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/SwingWorker.java	Wed Jul 05 16:46:22 2017 +0200
@@ -282,7 +282,7 @@
          * is finished.
          */
         DONE
-    };
+    }
 
     /**
      * Constructs this {@code SwingWorker}.
@@ -825,7 +825,7 @@
     }
     private static class DoSubmitAccumulativeRunnable
           extends AccumulativeRunnable<Runnable> implements ActionListener {
-        private final static int DELAY = (int) (1000 / 30);
+        private final static int DELAY = 1000 / 30;
         @Override
         protected void run(List<Runnable> args) {
             for (Runnable runnable : args) {
--- a/jdk/src/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/colorchooser/AbstractColorChooserPanel.java	Wed Jul 05 16:46:22 2017 +0200
@@ -26,6 +26,8 @@
 package javax.swing.colorchooser;
 
 import java.awt.*;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import javax.swing.*;
 
 /**
@@ -47,6 +49,15 @@
  */
 public abstract class AbstractColorChooserPanel extends JPanel {
 
+    private final PropertyChangeListener enabledListener = new PropertyChangeListener() {
+        public void propertyChange(PropertyChangeEvent event) {
+            Object value = event.getNewValue();
+            if (value instanceof Boolean) {
+                setEnabled((Boolean) value);
+            }
+        }
+    };
+
     /**
      *
      */
@@ -142,6 +153,8 @@
             throw new RuntimeException ("This chooser panel is already installed");
         }
         chooser = enclosingChooser;
+        chooser.addPropertyChangeListener("enabled", enabledListener);
+        setEnabled(chooser.isEnabled());
         buildChooser();
         updateChooser();
     }
@@ -151,6 +164,7 @@
      * If override this, be sure to call <code>super</code>.
      */
   public void uninstallChooserPanel(JColorChooser enclosingChooser) {
+        chooser.removePropertyChangeListener("enabled", enabledListener);
         chooser = null;
     }
 
--- a/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserPanel.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserPanel.java	Wed Jul 05 16:46:22 2017 +0200
@@ -26,6 +26,8 @@
 package javax.swing.colorchooser;
 
 import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.beans.PropertyChangeEvent;
@@ -57,6 +59,21 @@
     }
 
     @Override
+    public void setEnabled(boolean enabled) {
+        super.setEnabled(enabled);
+        setEnabled(this, enabled);
+    }
+
+    private static void setEnabled(Container container, boolean enabled) {
+        for (Component component : container.getComponents()) {
+            component.setEnabled(enabled);
+            if (component instanceof Container) {
+                setEnabled((Container) component, enabled);
+            }
+        }
+    }
+
+    @Override
     public void updateChooser() {
         Color color = getColorFromModel();
         if (color != null) {
--- a/jdk/src/share/classes/javax/swing/colorchooser/DefaultColorSelectionModel.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/colorchooser/DefaultColorSelectionModel.java	Wed Jul 05 16:46:22 2017 +0200
@@ -128,8 +128,7 @@
      * @since 1.4
      */
     public ChangeListener[] getChangeListeners() {
-        return (ChangeListener[])listenerList.getListeners(
-                ChangeListener.class);
+        return listenerList.getListeners(ChangeListener.class);
     }
 
     /**
--- a/jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java	Wed Jul 05 16:46:22 2017 +0200
@@ -170,7 +170,6 @@
         superHolder.add(mainHolder, gbc);
         gbc.insets = oldInsets;
 
-        recentSwatchPanel.addMouseListener(recentSwatchListener);
         recentSwatchPanel.setInheritsPopupMenu(true);
         JPanel recentHolder = new JPanel( new BorderLayout() );
         recentHolder.setBorder(border);
@@ -212,16 +211,20 @@
 
     class RecentSwatchListener extends MouseAdapter implements Serializable {
         public void mousePressed(MouseEvent e) {
-            Color color = recentSwatchPanel.getColorForLocation(e.getX(), e.getY());
-            setSelectedColor(color);
+            if (isEnabled()) {
+                Color color = recentSwatchPanel.getColorForLocation(e.getX(), e.getY());
+                setSelectedColor(color);
+            }
         }
     }
 
     class MainSwatchListener extends MouseAdapter implements Serializable {
         public void mousePressed(MouseEvent e) {
-            Color color = swatchPanel.getColorForLocation(e.getX(), e.getY());
-            setSelectedColor(color);
-            recentSwatchPanel.setMostRecentColor(color);
+            if (isEnabled()) {
+                Color color = swatchPanel.getColorForLocation(e.getX(), e.getY());
+                setSelectedColor(color);
+                recentSwatchPanel.setMostRecentColor(color);
+            }
         }
     }
 
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1132,13 +1132,18 @@
     private void changeDirectory(File dir) {
         JFileChooser fc = getFileChooser();
         // Traverse shortcuts on Windows
-        if (dir != null && File.separatorChar == '\\' && dir.getPath().endsWith(".lnk")) {
+        if (dir != null && FilePane.usesShellFolder(fc)) {
             try {
-                File linkedTo = ShellFolder.getShellFolder(dir).getLinkLocation();
-                if (linkedTo != null && fc.isTraversable(linkedTo)) {
-                    dir = linkedTo;
-                } else {
-                    return;
+                ShellFolder shellFolder = ShellFolder.getShellFolder(dir);
+
+                if (shellFolder.isLink()) {
+                    File linkedTo = shellFolder.getLinkLocation();
+
+                    if (linkedTo != null && fc.isTraversable(linkedTo)) {
+                        dir = linkedTo;
+                    } else {
+                        return;
+                    }
                 }
             } catch (FileNotFoundException ex) {
                 return;
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java	Wed Jul 05 16:46:22 2017 +0200
@@ -836,18 +836,24 @@
      */
     protected Integer getHighestValue() {
         Dictionary dictionary = slider.getLabelTable();
-        if (dictionary != null) {
-            Enumeration keys = dictionary.keys();
-            int max = slider.getMinimum() - 1;
-            while (keys.hasMoreElements()) {
-                max = Math.max(max, ((Integer)keys.nextElement()).intValue());
+
+        if (dictionary == null) {
+            return null;
+        }
+
+        Enumeration keys = dictionary.keys();
+
+        Integer max = null;
+
+        while (keys.hasMoreElements()) {
+            Integer i = (Integer) keys.nextElement();
+
+            if (max == null || i > max) {
+                max = i;
             }
-            if (max == slider.getMinimum() - 1) {
-                return null;
-            }
-            return max;
         }
-        return null;
+
+        return max;
     }
 
     /**
@@ -859,18 +865,24 @@
      */
     protected Integer getLowestValue() {
         Dictionary dictionary = slider.getLabelTable();
-        if (dictionary != null) {
-            Enumeration keys = dictionary.keys();
-            int min = slider.getMaximum() + 1;
-            while (keys.hasMoreElements()) {
-                min = Math.min(min, ((Integer)keys.nextElement()).intValue());
+
+        if (dictionary == null) {
+            return null;
+        }
+
+        Enumeration keys = dictionary.keys();
+
+        Integer min = null;
+
+        while (keys.hasMoreElements()) {
+            Integer i = (Integer) keys.nextElement();
+
+            if (min == null || i < min) {
+                min = i;
             }
-            if (min == slider.getMaximum() + 1) {
-                return null;
-            }
-            return min;
         }
-        return null;
+
+        return min;
     }
 
 
--- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java	Wed Jul 05 16:46:22 2017 +0200
@@ -68,8 +68,6 @@
     private JToggleButton listViewButton;
     private JToggleButton detailsViewButton;
 
-    private boolean useShellFolder;
-
     private JButton approveButton;
     private JButton cancelButton;
 
@@ -204,10 +202,6 @@
         public ListSelectionListener createListSelectionListener() {
             return MetalFileChooserUI.this.createListSelectionListener(getFileChooser());
         }
-
-        public boolean usesShellFolder() {
-            return useShellFolder;
-        }
     }
 
     public void installComponents(JFileChooser fc) {
@@ -219,8 +213,6 @@
         filePane = new FilePane(new MetalFileChooserUIAccessor());
         fc.addPropertyChangeListener(filePane);
 
-        updateUseShellFolder();
-
         // ********************************* //
         // **** Construct the top panel **** //
         // ********************************* //
@@ -448,19 +440,6 @@
         groupLabels(new AlignedLabel[] { fileNameLabel, filesOfTypeLabel });
     }
 
-    private void updateUseShellFolder() {
-        // Decide whether to use the ShellFolder class to populate shortcut
-        // panel and combobox.
-        JFileChooser fc = getFileChooser();
-        Boolean prop =
-            (Boolean)fc.getClientProperty("FileChooser.useShellFolder");
-        if (prop != null) {
-            useShellFolder = prop.booleanValue();
-        } else {
-            useShellFolder = fc.getFileSystemView().equals(FileSystemView.getFileSystemView());
-        }
-    }
-
     protected JPanel getButtonPanel() {
         if (buttonPanel == null) {
             buttonPanel = new JPanel();
@@ -786,7 +765,6 @@
                         cc.applyComponentOrientation(o);
                     }
                 } else if (s == "FileChooser.useShellFolder") {
-                    updateUseShellFolder();
                     doDirectoryChanged(e);
                 } else if (s.equals("ancestor")) {
                     if (e.getOldValue() == null && e.getNewValue() != null) {
@@ -953,6 +931,8 @@
                 return;
             }
 
+            boolean useShellFolder = FilePane.usesShellFolder(chooser);
+
             directories.clear();
 
             File[] baseFolders;
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthParser.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthParser.java	Wed Jul 05 16:46:22 2017 +0200
@@ -59,16 +59,16 @@
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 
-import org.xml.sax.AttributeList;
-import org.xml.sax.HandlerBase;
+import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
 import org.xml.sax.Locator;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
 
-import com.sun.beans.ObjectHandler;
+import com.sun.beans.decoder.DocumentHandler;
 
-class SynthParser extends HandlerBase {
+class SynthParser extends DefaultHandler {
     //
     // Known element names
     //
@@ -119,7 +119,7 @@
     /**
      * Lazily created, used for anything we don't understand.
      */
-    private ObjectHandler _handler;
+    private DocumentHandler _handler;
 
     /**
      * Indicates the depth of how many elements we've encountered but don't
@@ -292,8 +292,9 @@
     /**
      * Handles beans persistance.
      */
-    private ObjectHandler getHandler() {
+    private DocumentHandler getHandler() {
         if (_handler == null) {
+            _handler = new DocumentHandler();
             if (_urlResourceBase != null) {
                 // getHandler() is never called before parse() so it is safe
                 // to create a URLClassLoader with _resourceBase.
@@ -304,14 +305,13 @@
                 URL[] urls = new URL[] { getResource(".") };
                 ClassLoader parent = Thread.currentThread().getContextClassLoader();
                 ClassLoader urlLoader = new URLClassLoader(urls, parent);
-                _handler = new ObjectHandler(null, urlLoader);
+                _handler.setClassLoader(urlLoader);
             } else {
-                _handler = new ObjectHandler(null,
-                    _classResourceBase.getClassLoader());
+                _handler.setClassLoader(_classResourceBase.getClassLoader());
             }
 
             for (String key : _mapping.keySet()) {
-                _handler.register(key, _mapping.get(key));
+                _handler.setVariable(key, _mapping.get(key));
             }
         }
         return _handler;
@@ -336,8 +336,8 @@
     private Object lookup(String key, Class type) throws SAXException {
         Object value;
         if (_handler != null) {
-            if ((value = _handler.lookup(key)) != null) {
-                return checkCast(value, type);
+            if (_handler.hasVariable(key)) {
+                return checkCast(_handler.getVariable(key), type);
             }
         }
         value = _mapping.get(key);
@@ -354,11 +354,11 @@
     private void register(String key, Object value) throws SAXException {
         if (key != null) {
             if (_mapping.get(key) != null ||
-                     (_handler != null && _handler.lookup(key) != null)) {
+                     (_handler != null && _handler.hasVariable(key))) {
                 throw new SAXException("ID " + key + " is already defined");
             }
             if (_handler != null) {
-                _handler.register(key, value);
+                _handler.setVariable(key, value);
             }
             else {
                 _mapping.put(key, value);
@@ -400,12 +400,12 @@
     // The following methods are invoked from startElement/stopElement
     //
 
-    private void startStyle(AttributeList attributes) throws SAXException {
+    private void startStyle(Attributes attributes) throws SAXException {
         String id = null;
 
         _style = null;
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
             if (key.equals(ATTRIBUTE_CLONE)) {
                 _style = (ParsedSynthStyle)((ParsedSynthStyle)lookup(
                          attributes.getValue(i), ParsedSynthStyle.class)).
@@ -421,7 +421,7 @@
         register(id, _style);
     }
 
-    private void endStyle() throws SAXException {
+    private void endStyle() {
         int size = _stylePainters.size();
         if (size > 0) {
             _style.setPainters(_stylePainters.toArray(new ParsedSynthStyle.PainterInfo[size]));
@@ -435,14 +435,14 @@
         _style = null;
     }
 
-    private void startState(AttributeList attributes) throws SAXException {
+    private void startState(Attributes attributes) throws SAXException {
         ParsedSynthStyle.StateInfo stateInfo = null;
         int state = 0;
         String id = null;
 
         _stateInfo = null;
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
             if (key.equals(ATTRIBUTE_ID)) {
                 id = attributes.getValue(i);
             }
@@ -496,7 +496,7 @@
         _stateInfos.add(_stateInfo);
     }
 
-    private void endState() throws SAXException {
+    private void endState() {
         int size = _statePainters.size();
         if (size > 0) {
             _stateInfo.setPainters(_statePainters.toArray(new ParsedSynthStyle.PainterInfo[size]));
@@ -505,7 +505,7 @@
         _stateInfo = null;
     }
 
-    private void startFont(AttributeList attributes) throws SAXException {
+    private void startFont(Attributes attributes) throws SAXException {
         Font font = null;
         int style = Font.PLAIN;
         int size = 0;
@@ -513,7 +513,7 @@
         String name = null;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
             if (key.equals(ATTRIBUTE_ID)) {
                 id = attributes.getValue(i);
             }
@@ -568,13 +568,13 @@
         }
     }
 
-    private void startColor(AttributeList attributes) throws SAXException {
+    private void startColor(Attributes attributes) throws SAXException {
         Color color = null;
         String id = null;
 
         _colorTypes.clear();
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
             if (key.equals(ATTRIBUTE_ID)) {
                 id = attributes.getValue(i);
             }
@@ -697,7 +697,7 @@
         }
     }
 
-    private void startProperty(AttributeList attributes,
+    private void startProperty(Attributes attributes,
                                Object property) throws SAXException {
         Object value = null;
         String key = null;
@@ -707,7 +707,7 @@
         String aValue = null;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String aName = attributes.getName(i);
+            String aName = attributes.getQName(i);
             if (aName.equals(ATTRIBUTE_TYPE)) {
                 String type = attributes.getValue(i).toUpperCase();
                 if (type.equals("IDREF")) {
@@ -795,11 +795,11 @@
         }
     }
 
-    private void startGraphics(AttributeList attributes) throws SAXException {
+    private void startGraphics(Attributes attributes) throws SAXException {
         SynthGraphicsUtils graphics = null;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
             if (key.equals(ATTRIBUTE_IDREF)) {
                 graphics = (SynthGraphicsUtils)lookup(attributes.getValue(i),
                                                  SynthGraphicsUtils.class);
@@ -813,7 +813,7 @@
         }
     }
 
-    private void startInsets(AttributeList attributes) throws SAXException {
+    private void startInsets(Attributes attributes) throws SAXException {
         int top = 0;
         int bottom = 0;
         int left = 0;
@@ -822,7 +822,7 @@
         String id = null;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
 
             try {
                 if (key.equals(ATTRIBUTE_IDREF)) {
@@ -858,13 +858,13 @@
         }
     }
 
-    private void startBind(AttributeList attributes) throws SAXException {
+    private void startBind(Attributes attributes) throws SAXException {
         ParsedSynthStyle style = null;
         String path = null;
         int type = -1;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
 
             if (key.equals(ATTRIBUTE_STYLE)) {
                 style = (ParsedSynthStyle)lookup(attributes.getValue(i),
@@ -899,7 +899,7 @@
         }
     }
 
-    private void startPainter(AttributeList attributes, String type) throws SAXException {
+    private void startPainter(Attributes attributes, String type) throws SAXException {
         Insets sourceInsets = null;
         Insets destInsets = null;
         String path = null;
@@ -915,7 +915,7 @@
         boolean paintCenterSpecified = false;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
             String value = attributes.getValue(i);
 
             if (key.equals(ATTRIBUTE_ID)) {
@@ -1042,12 +1042,12 @@
         painters.add(painterInfo);
     }
 
-    private void startImageIcon(AttributeList attributes) throws SAXException {
+    private void startImageIcon(Attributes attributes) throws SAXException {
         String path = null;
         String id = null;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
 
             if (key.equals(ATTRIBUTE_ID)) {
                 id = attributes.getValue(i);
@@ -1062,12 +1062,11 @@
         register(id, new LazyImageIcon(getResource(path)));
        }
 
-    private void startOpaque(AttributeList attributes) throws
-                      SAXException {
+    private void startOpaque(Attributes attributes) {
         if (_style != null) {
             _style.setOpaque(true);
             for(int i = attributes.getLength() - 1; i >= 0; i--) {
-                String key = attributes.getName(i);
+                String key = attributes.getQName(i);
 
                 if (key.equals(ATTRIBUTE_VALUE)) {
                     _style.setOpaque("true".equals(attributes.getValue(i).
@@ -1077,12 +1076,12 @@
         }
     }
 
-    private void startInputMap(AttributeList attributes) throws SAXException {
+    private void startInputMap(Attributes attributes) throws SAXException {
         _inputMapBindings.clear();
         _inputMapID = null;
         if (_style != null) {
             for(int i = attributes.getLength() - 1; i >= 0; i--) {
-                String key = attributes.getName(i);
+                String key = attributes.getQName(i);
 
                 if (key.equals(ATTRIBUTE_ID)) {
                     _inputMapID = attributes.getValue(i);
@@ -1101,7 +1100,7 @@
         _inputMapID = null;
     }
 
-    private void startBindKey(AttributeList attributes) throws SAXException {
+    private void startBindKey(Attributes attributes) throws SAXException {
         if (_inputMapID == null) {
             // Not in an inputmap, bail.
             return;
@@ -1110,7 +1109,7 @@
             String key = null;
             String value = null;
             for(int i = attributes.getLength() - 1; i >= 0; i--) {
-                String aKey = attributes.getName(i);
+                String aKey = attributes.getQName(i);
 
                 if (aKey.equals(ATTRIBUTE_KEY)) {
                     key = attributes.getValue(i);
@@ -1129,26 +1128,26 @@
     }
 
     //
-    // SAX methods, these forward to the ObjectHandler if we don't know
+    // SAX methods, these forward to the DocumentHandler if we don't know
     // the element name.
     //
 
     public InputSource resolveEntity(String publicId, String systemId)
-                              throws SAXException {
+                              throws IOException, SAXException {
         if (isForwarding()) {
             return getHandler().resolveEntity(publicId, systemId);
         }
         return null;
     }
 
-    public void notationDecl(String name, String publicId, String systemId) {
+    public void notationDecl(String name, String publicId, String systemId) throws SAXException {
         if (isForwarding()) {
             getHandler().notationDecl(name, publicId, systemId);
         }
     }
 
     public void unparsedEntityDecl(String name, String publicId,
-                                   String systemId, String notationName) {
+                                   String systemId, String notationName) throws SAXException {
         if (isForwarding()) {
             getHandler().unparsedEntityDecl(name, publicId, systemId,
                                             notationName);
@@ -1173,7 +1172,7 @@
         }
     }
 
-    public void startElement(String name, AttributeList attributes)
+    public void startElement(String uri, String local, String name, Attributes attributes)
                      throws SAXException {
         name = name.intern();
         if (name == ELEMENT_STYLE) {
@@ -1223,18 +1222,18 @@
         }
         else if (name != ELEMENT_SYNTH) {
             if (_depth++ == 0) {
-                getHandler().reset();
+                getHandler().startDocument();
             }
-            getHandler().startElement(name, attributes);
+            getHandler().startElement(uri, local, name, attributes);
         }
     }
 
-    public void endElement(String name) throws SAXException {
+    public void endElement(String uri, String local, String name) throws SAXException {
         if (isForwarding()) {
-            getHandler().endElement(name);
+            getHandler().endElement(uri, local, name);
             _depth--;
             if (!isForwarding()) {
-                getHandler().reset();
+                getHandler().startDocument();
             }
         }
         else {
--- a/jdk/src/share/classes/javax/swing/table/DefaultTableColumnModel.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/table/DefaultTableColumnModel.java	Wed Jul 05 16:46:22 2017 +0200
@@ -190,7 +190,7 @@
             fireColumnMoved(new TableColumnModelEvent(this, columnIndex, newIndex));
             return;
         }
-        aColumn = (TableColumn)tableColumns.elementAt(columnIndex);
+        aColumn = tableColumns.elementAt(columnIndex);
 
         tableColumns.removeElementAt(columnIndex);
         boolean selected = selectionModel.isSelectedIndex(columnIndex);
@@ -291,7 +291,7 @@
      *                          at <code>columnIndex</code>
      */
     public TableColumn getColumn(int columnIndex) {
-        return (TableColumn)tableColumns.elementAt(columnIndex);
+        return tableColumns.elementAt(columnIndex);
     }
 
     /**
@@ -504,8 +504,7 @@
      * @since 1.4
      */
     public TableColumnModelListener[] getColumnModelListeners() {
-        return (TableColumnModelListener[])listenerList.getListeners(
-                TableColumnModelListener.class);
+        return listenerList.getListeners(TableColumnModelListener.class);
     }
 
 //
--- a/jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java	Wed Jul 05 16:46:22 2017 +0200
@@ -84,7 +84,7 @@
  *
  * @author Rob Davis
  */
-public class DefaultMutableTreeNode extends Object implements Cloneable,
+public class DefaultMutableTreeNode implements Cloneable,
        MutableTreeNode, Serializable
 {
     private static final long serialVersionUID = -4298474751201349152L;
@@ -1251,7 +1251,7 @@
      * @return  a copy of this node
      */
     public Object clone() {
-        DefaultMutableTreeNode newNode = null;
+        DefaultMutableTreeNode newNode;
 
         try {
             newNode = (DefaultMutableTreeNode)super.clone();
@@ -1297,24 +1297,22 @@
             userObject = tValues[1];
     }
 
-    final class PreorderEnumeration implements Enumeration<TreeNode> {
-        protected Stack stack;
+    private final class PreorderEnumeration implements Enumeration<TreeNode> {
+        private final Stack<Enumeration> stack = new Stack<Enumeration>();
 
         public PreorderEnumeration(TreeNode rootNode) {
             super();
-            Vector v = new Vector(1);
+            Vector<TreeNode> v = new Vector<TreeNode>(1);
             v.addElement(rootNode);     // PENDING: don't really need a vector
-            stack = new Stack();
             stack.push(v.elements());
         }
 
         public boolean hasMoreElements() {
-            return (!stack.empty() &&
-                    ((Enumeration)stack.peek()).hasMoreElements());
+            return (!stack.empty() && stack.peek().hasMoreElements());
         }
 
         public TreeNode nextElement() {
-            Enumeration enumer = (Enumeration)stack.peek();
+            Enumeration enumer = stack.peek();
             TreeNode    node = (TreeNode)enumer.nextElement();
             Enumeration children = node.children();
 
@@ -1353,8 +1351,7 @@
             if (subtree.hasMoreElements()) {
                 retval = subtree.nextElement();
             } else if (children.hasMoreElements()) {
-                subtree = new PostorderEnumeration(
-                                (TreeNode)children.nextElement());
+                subtree = new PostorderEnumeration(children.nextElement());
                 retval = subtree.nextElement();
             } else {
                 retval = root;
@@ -1373,7 +1370,7 @@
 
         public BreadthFirstEnumeration(TreeNode rootNode) {
             super();
-            Vector v = new Vector(1);
+            Vector<TreeNode> v = new Vector<TreeNode>(1);
             v.addElement(rootNode);     // PENDING: don't really need a vector
             queue = new Queue();
             queue.enqueue(v.elements());
--- a/jdk/src/share/classes/javax/swing/undo/CompoundEdit.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/undo/CompoundEdit.java	Wed Jul 05 16:46:22 2017 +0200
@@ -59,7 +59,7 @@
         super.undo();
         int i = edits.size();
         while (i-- > 0) {
-            UndoableEdit e = (UndoableEdit)edits.elementAt(i);
+            UndoableEdit e = edits.elementAt(i);
             e.undo();
         }
     }
@@ -85,7 +85,7 @@
     protected UndoableEdit lastEdit() {
         int count = edits.size();
         if (count > 0)
-            return (UndoableEdit)edits.elementAt(count-1);
+            return edits.elementAt(count-1);
         else
             return null;
     }
@@ -98,7 +98,7 @@
         int size = edits.size();
         for (int i = size-1; i >= 0; i--)
         {
-            UndoableEdit e = (UndoableEdit)edits.elementAt(i);
+            UndoableEdit e = edits.elementAt(i);
 //          System.out.println("CompoundEdit(" + i + "): Discarding " +
 //                             e.getUndoPresentationName());
             e.die();
--- a/jdk/src/share/classes/sun/beans/editors/EnumEditor.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/beans/editors/EnumEditor.java	Wed Jul 05 16:46:22 2017 +0200
@@ -67,7 +67,7 @@
     }
 
     public void setValue( Object value ) {
-        if ( ( value != null ) && ( this.type != value.getClass() ) ) {
+        if ( ( value != null ) && !this.type.isInstance( value ) ) {
             throw new IllegalArgumentException( "Unsupported value: " + value );
         }
         Object oldValue;
--- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java	Wed Jul 05 16:46:22 2017 +0200
@@ -60,9 +60,6 @@
     // Memory allocation size for mapping buffers
     private static final long allocationGranularity;
 
-    // Cached field for MappedByteBuffer.isAMappedBuffer
-    private static final Field isAMappedBufferField;
-
     // File descriptor
     private final FileDescriptor fd;
 
@@ -1315,8 +1312,6 @@
         Util.load();
         allocationGranularity = initIDs();
         nd = new FileDispatcher();
-        isAMappedBufferField = Reflect.lookupField("java.nio.MappedByteBuffer",
-                                          "isAMappedBuffer");
     }
 
 }
--- a/jdk/src/share/classes/sun/security/krb5/Config.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/security/krb5/Config.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Portions Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Portions Copyright 2000-2009 Sun Microsystems, 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
@@ -74,7 +74,7 @@
     private String defaultRealm;   // default kdc realm.
 
     // used for native interface
-    private static native String getWindowsDirectory();
+    private static native String getWindowsDirectory(boolean isSystem);
 
 
     /**
@@ -661,38 +661,37 @@
     }
 
     /**
-     * Gets the default configuration file name. The file will be searched
-     * in a list of possible loations in the following order:
-     * 1. the location and file name defined by system property
-     * "java.security.krb5.conf",
-     * 2. at Java home lib\security directory with "krb5.conf" name,
-     * 3. "krb5.ini" at Java home,
-     * 4. at windows directory with the name of "krb5.ini" for Windows,
-     * /etc/krb5/krb5.conf for Solaris, /etc/krb5.conf for Linux.
+     * Gets the default configuration file name. This method will never
+     * return null.
+     *
+     * If the system property "java.security.krb5.conf" is defined, we'll
+     * use its value, no matter if the file exists or not. Otherwise,
+     * the file will be searched in a list of possible loations in the
+     * following order:
+     *
+     * 1. at Java home lib\security directory with "krb5.conf" name,
+     * 2. at windows directory with the name of "krb5.ini" for Windows,
+     * /etc/krb5/krb5.conf for Solaris, /etc/krb5.conf otherwise.
+     *
+     * Note: When the Terminal Service is started in Windows (from 2003),
+     * there are two kinds of Windows directories: A system one (say,
+     * C:\Windows), and a user-private one (say, C:\Users\Me\Windows).
+     * We will first look for krb5.ini in the user-private one. If not
+     * found, try the system one instead.
      */
     private String getFileName() {
         String name =
             java.security.AccessController.doPrivileged(
                                 new sun.security.action.
                                 GetPropertyAction("java.security.krb5.conf"));
-        if (name != null) {
-            boolean temp =
-                java.security.AccessController.doPrivileged(
-                                new FileExistsAction(name));
-            if (temp)
-                return name;
-        } else {
+        if (name == null) {
             name = java.security.AccessController.doPrivileged(
                         new sun.security.action.
                         GetPropertyAction("java.home")) + File.separator +
                                 "lib" + File.separator + "security" +
                                 File.separator + "krb5.conf";
-            boolean temp =
-                java.security.AccessController.doPrivileged(
-                                new FileExistsAction(name));
-            if (temp) {
-                return name;
-            } else {
+            if (!fileExists(name)) {
+                name = null;
                 String osname =
                         java.security.AccessController.doPrivileged(
                         new sun.security.action.GetPropertyAction("os.name"));
@@ -703,19 +702,35 @@
                         // ignore exceptions
                     }
                     if (Credentials.alreadyLoaded) {
-                        if ((name = getWindowsDirectory()) == null) {
-                            name = "c:\\winnt\\krb5.ini";
-                        } else if (name.endsWith("\\")) {
-                            name += "krb5.ini";
-                        } else {
-                            name += "\\krb5.ini";
+                        String path = getWindowsDirectory(false);
+                        if (path != null) {
+                            if (path.endsWith("\\")) {
+                                path = path + "krb5.ini";
+                            } else {
+                                path = path + "\\krb5.ini";
+                            }
+                            if (fileExists(path)) {
+                                name = path;
+                            }
                         }
-                    } else {
+                        if (name == null) {
+                            path = getWindowsDirectory(true);
+                            if (path != null) {
+                                if (path.endsWith("\\")) {
+                                    path = path + "krb5.ini";
+                                } else {
+                                    path = path + "\\krb5.ini";
+                                }
+                                name = path;
+                            }
+                        }
+                    }
+                    if (name == null) {
                         name = "c:\\winnt\\krb5.ini";
                     }
                 } else if (osname.startsWith("SunOS")) {
                     name =  "/etc/krb5/krb5.conf";
-                } else if (osname.startsWith("Linux")) {
+                } else {
                     name =  "/etc/krb5.conf";
                 }
             }
@@ -1171,6 +1186,11 @@
         return kdcs;
     }
 
+    private boolean fileExists(String name) {
+        return java.security.AccessController.doPrivileged(
+                                new FileExistsAction(name));
+    }
+
     static class FileExistsAction
         implements java.security.PrivilegedAction<Boolean> {
 
--- a/jdk/src/share/classes/sun/swing/FilePane.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/swing/FilePane.java	Wed Jul 05 16:46:22 2017 +0200
@@ -689,7 +689,7 @@
 
         void updateColumnInfo() {
             File dir = chooser.getCurrentDirectory();
-            if (dir != null && fileChooserUIAccessor.usesShellFolder()) {
+            if (dir != null && usesShellFolder(chooser)) {
                 try {
                     dir = ShellFolder.getShellFolder(dir);
                 } catch (FileNotFoundException e) {
@@ -1947,7 +1947,7 @@
         if (f instanceof ShellFolder) {
             return ((ShellFolder) f).isFileSystem();
         } else {
-            if (fileChooserUIAccessor.usesShellFolder()) {
+            if (usesShellFolder(getFileChooser())) {
                 try {
                     return ShellFolder.getShellFolder(f).isFileSystem();
                 } catch (FileNotFoundException ex) {
@@ -1961,6 +1961,16 @@
         }
     }
 
+    /**
+     * Returns true if specified FileChooser should use ShellFolder
+     */
+    public static boolean usesShellFolder(JFileChooser chooser) {
+        Boolean prop = (Boolean) chooser.getClientProperty("FileChooser.useShellFolder");
+
+        return prop == null ? chooser.getFileSystemView().equals(FileSystemView.getFileSystemView())
+                : prop.booleanValue();
+    }
+
     // This interface is used to access methods in the FileChooserUI
     // that are not public.
     public interface FileChooserUIAccessor {
@@ -1975,6 +1985,5 @@
         public Action getNewFolderAction();
         public MouseListener createDoubleClickListener(JList list);
         public ListSelectionListener createListSelectionListener();
-        public boolean usesShellFolder();
     }
 }
--- a/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java	Wed Jul 05 16:46:22 2017 +0200
@@ -71,8 +71,6 @@
     private JToggleButton listViewButton;
     private JToggleButton detailsViewButton;
 
-    private boolean useShellFolder;
-
     private boolean readOnly;
 
     private JPanel buttonPanel;
@@ -185,10 +183,6 @@
         public ListSelectionListener createListSelectionListener() {
             return SynthFileChooserUIImpl.this.createListSelectionListener(getFileChooser());
         }
-
-        public boolean usesShellFolder() {
-            return useShellFolder;
-        }
     }
 
     protected void installDefaults(JFileChooser fc) {
@@ -201,8 +195,6 @@
 
         SynthContext context = getContext(fc, ENABLED);
 
-        updateUseShellFolder();
-
         fc.setLayout(new BorderLayout(0, 11));
 
         // ********************************* //
@@ -432,20 +424,6 @@
         super.uninstallListeners(fc);
     }
 
-    private void updateUseShellFolder() {
-        // Decide whether to use the ShellFolder class to populate shortcut
-        // panel and combobox.
-        JFileChooser fc = getFileChooser();
-        Boolean prop =
-            (Boolean)fc.getClientProperty("FileChooser.useShellFolder");
-        if (prop != null) {
-            useShellFolder = prop.booleanValue();
-        } else {
-            useShellFolder = fc.getFileSystemView().equals(FileSystemView.getFileSystemView());
-        }
-    }
-
-
     private String fileNameString(File file) {
         if (file == null) {
             return null;
@@ -761,6 +739,8 @@
                 return;
             }
 
+            boolean useShellFolder = FilePane.usesShellFolder(chooser);
+
             int oldSize = directories.size();
             directories.clear();
             if (oldSize > 0) {
--- a/jdk/src/share/classes/sun/text/resources/FormatData_th.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/text/resources/FormatData_th.java	Wed Jul 05 16:46:22 2017 +0200
@@ -47,6 +47,19 @@
      * Overrides ListResourceBundle
      */
     protected final Object[][] getContents() {
+        String[] dateTimePatterns = new String[] {
+            "H' \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 'm' \u0e19\u0e32\u0e17\u0e35 'ss' \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35'", // full time pattern
+            "H' \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 'm' \u0e19\u0e32\u0e17\u0e35'", // long time pattern
+            "H:mm:ss", // medium time pattern
+            "H:mm' \u0e19.'",  // short time pattern (modified)  -- add ' \u0e19.'
+                               // (it means something like "o'clock" in english)
+            "EEEE'\u0e17\u0e35\u0e48 'd MMMM G yyyy", // full date pattern
+            "d MMMM yyyy", // long date pattern
+            "d MMM yyyy", // medium date pattern
+            "d/M/yyyy", // short date pattern
+            "{1}, {0}" // date-time pattern
+        };
+
         return new Object[][] {
             { "MonthNames",
                 new String[] {
@@ -129,18 +142,10 @@
                 }
             },
             { "sun.util.BuddhistCalendar.DateTimePatterns",
-                new String[] {
-                    "H' \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 'm' \u0e19\u0e32\u0e17\u0e35 'ss' \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35'", // full time pattern
-                    "H' \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 'm' \u0e19\u0e32\u0e17\u0e35'", // long time pattern
-                    "H:mm:ss", // medium time pattern
-                    "H:mm' \u0e19.'",  // short time pattern (modified)  -- add ' \u0e19.'
-                                                                            // (it means something like "o'clock" in english)
-                    "EEEE'\u0e17\u0e35\u0e48 'd MMMM G yyyy", // full date pattern
-                    "d MMMM yyyy", // long date pattern
-                    "d MMM yyyy", // medium date pattern
-                    "d/M/yyyy", // short date pattern
-                    "{1}, {0}" // date-time pattern
-                }
+                dateTimePatterns
+            },
+            { "DateTimePatterns",
+                dateTimePatterns
             },
             { "DateTimePatternChars", "GanjkHmsSEDFwWxhKzZ" },
         };
--- a/jdk/src/share/classes/sun/tools/jar/Main.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/tools/jar/Main.java	Wed Jul 05 16:46:22 2017 +0200
@@ -74,7 +74,6 @@
     static final String MANIFEST = JarFile.MANIFEST_NAME;
     static final String MANIFEST_DIR = "META-INF/";
     static final String VERSION = "1.0";
-    static final char SEPARATOR = File.separatorChar;
     static final String INDEX = JarIndex.INDEX_NAME;
 
     private static ResourceBundle rsrc;
@@ -227,19 +226,32 @@
                     }
                     tmpFile.delete();
                 }
-            } else if (xflag || tflag) {
-                InputStream in;
+            } else if (tflag) {
+                replaceFSC(files);
                 if (fname != null) {
-                    in = new FileInputStream(fname);
+                    list(fname, files);
                 } else {
-                    in = new FileInputStream(FileDescriptor.in);
+                    InputStream in = new FileInputStream(FileDescriptor.in);
+                    try{
+                        list(new BufferedInputStream(in), files);
+                    } finally {
+                        in.close();
+                    }
                 }
-                if (xflag) {
-                    extract(new BufferedInputStream(in), files);
+            } else if (xflag) {
+                replaceFSC(files);
+                if (fname != null && files != null) {
+                    extract(fname, files);
                 } else {
-                    list(new BufferedInputStream(in), files);
+                    InputStream in = (fname == null)
+                        ? new FileInputStream(FileDescriptor.in)
+                        : new FileInputStream(fname);
+                    try {
+                        extract(new BufferedInputStream(in), files);
+                    } finally {
+                        in.close();
+                    }
                 }
-                in.close();
             } else if (iflag) {
                 genIndex(rootjar, files);
             }
@@ -760,6 +772,31 @@
         e.setCrc(crc32.getValue());
     }
 
+    void replaceFSC(String files[]) {
+        if (files != null) {
+            for (String file : files) {
+                file = file.replace(File.separatorChar, '/');
+            }
+        }
+    }
+
+    Set<ZipEntry> newDirSet() {
+        return new HashSet<ZipEntry>() {
+            public boolean add(ZipEntry e) {
+                return ((e == null || useExtractionTime) ? false : super.add(e));
+            }};
+    }
+
+    void updateLastModifiedTime(Set<ZipEntry> zes) throws IOException {
+        for (ZipEntry ze : zes) {
+            long lastModified = ze.getTime();
+            if (lastModified != -1) {
+                File f = new File(ze.getName().replace('/', File.separatorChar));
+                f.setLastModified(lastModified);
+            }
+        }
+    }
+
     /*
      * Extracts specified entries from JAR file.
      */
@@ -768,19 +805,13 @@
         ZipEntry e;
         // Set of all directory entries specified in archive.  Disallows
         // null entries.  Disallows all entries if using pre-6.0 behavior.
-        Set<ZipEntry> dirs = new HashSet<ZipEntry>() {
-            public boolean add(ZipEntry e) {
-                return ((e == null || useExtractionTime) ? false : super.add(e));
-            }};
-
+        Set<ZipEntry> dirs = newDirSet();
         while ((e = zis.getNextEntry()) != null) {
             if (files == null) {
                 dirs.add(extractFile(zis, e));
-
             } else {
                 String name = e.getName();
-                for (int i = 0; i < files.length; i++) {
-                    String file = files[i].replace(File.separatorChar, '/');
+                for (String file : files) {
                     if (name.startsWith(file)) {
                         dirs.add(extractFile(zis, e));
                         break;
@@ -793,13 +824,33 @@
         // timestamps as given in the archive.  We do this after extraction,
         // instead of during, because creating a file in a directory changes
         // that directory's timestamp.
-        for (ZipEntry dirEntry : dirs) {
-            long lastModified = dirEntry.getTime();
-            if (lastModified != -1) {
-                File dir = new File(dirEntry.getName().replace('/', File.separatorChar));
-                dir.setLastModified(lastModified);
+        updateLastModifiedTime(dirs);
+    }
+
+    /*
+     * Extracts specified entries from JAR file, via ZipFile.
+     */
+    void extract(String fname, String files[]) throws IOException {
+        ZipFile zf = new ZipFile(fname);
+        Set<ZipEntry> dirs = newDirSet();
+        Enumeration<? extends ZipEntry> zes = zf.entries();
+        while (zes.hasMoreElements()) {
+            ZipEntry e = zes.nextElement();
+            InputStream is;
+            if (files == null) {
+                dirs.add(extractFile(zf.getInputStream(e), e));
+            } else {
+                String name = e.getName();
+                for (String file : files) {
+                    if (name.startsWith(file)) {
+                        dirs.add(extractFile(zf.getInputStream(e), e));
+                        break;
+                    }
+                }
             }
         }
+        zf.close();
+        updateLastModifiedTime(dirs);
     }
 
     /*
@@ -807,7 +858,7 @@
      * the entry is for a directory which doesn't exist prior to this
      * invocation, returns that entry, otherwise returns null.
      */
-    ZipEntry extractFile(ZipInputStream zis, ZipEntry e) throws IOException {
+    ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException {
         ZipEntry rc = null;
         String name = e.getName();
         File f = new File(e.getName().replace('/', File.separatorChar));
@@ -838,13 +889,19 @@
                 }
             }
             OutputStream os = new FileOutputStream(f);
-            byte[] b = new byte[512];
+            byte[] b = new byte[8192];
             int len;
-            while ((len = zis.read(b, 0, b.length)) != -1) {
-                os.write(b, 0, len);
+            try {
+                while ((len = is.read(b, 0, b.length)) != -1) {
+                    os.write(b, 0, len);
+                }
+            } finally {
+                if (is instanceof ZipInputStream)
+                    ((ZipInputStream)is).closeEntry();
+                else
+                    is.close();
+                os.close();
             }
-            zis.closeEntry();
-            os.close();
             if (vflag) {
                 if (e.getMethod() == ZipEntry.DEFLATED) {
                     output(formatMsg("out.inflated", name));
@@ -869,7 +926,6 @@
         ZipInputStream zis = new ZipInputStream(in);
         ZipEntry e;
         while ((e = zis.getNextEntry()) != null) {
-            String name = e.getName();
             /*
              * In the case of a compressed (deflated) entry, the entry size
              * is stored immediately following the entry data and cannot be
@@ -877,20 +933,22 @@
              * the entry first before printing out its attributes.
              */
             zis.closeEntry();
-            if (files == null) {
-                printEntry(e);
-            } else {
-                for (int i = 0; i < files.length; i++) {
-                    String file = files[i].replace(File.separatorChar, '/');
-                    if (name.startsWith(file)) {
-                        printEntry(e);
-                        break;
-                    }
-                }
-            }
+            printEntry(e, files);
         }
     }
 
+    /*
+     * Lists contents of JAR file, via ZipFile.
+     */
+    void list(String fname, String files[]) throws IOException {
+        ZipFile zf = new ZipFile(fname);
+        Enumeration<? extends ZipEntry> zes = zf.entries();
+        while (zes.hasMoreElements()) {
+            printEntry(zes.nextElement(), files);
+        }
+        zf.close();
+    }
+
     /**
      * Output the class index table to the INDEX.LIST file of the
      * root jar file.
@@ -974,13 +1032,29 @@
         dumpIndex(rootjar, index);
     }
 
+    /*
+     * Prints entry information, if requested.
+     */
+    void printEntry(ZipEntry e, String[] files) throws IOException {
+        if (files == null) {
+            printEntry(e);
+        } else {
+            String name = e.getName();
+            for (String file : files) {
+                if (name.startsWith(file)) {
+                    printEntry(e);
+                    return;
+                }
+            }
+        }
+    }
 
     /*
      * Prints entry information.
      */
     void printEntry(ZipEntry e) throws IOException {
         if (vflag) {
-            StringBuffer sb = new StringBuffer();
+            StringBuilder sb = new StringBuilder();
             String s = Long.toString(e.getSize());
             for (int i = 6 - s.length(); i > 0; --i) {
                 sb.append(' ');
--- a/jdk/src/share/classes/sun/util/resources/LocaleNames.properties	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/LocaleNames.properties	Wed Jul 05 16:46:22 2017 +0200
@@ -257,6 +257,7 @@
 BH=Bahrain
 BI=Burundi
 BJ=Benin
+BL=Saint Barth\u00e9lemy
 BM=Bermuda
 BN=Brunei
 BO=Bolivia
@@ -370,6 +371,7 @@
 MC=Monaco
 MD=Moldova
 ME=Montenegro
+MF=Saint Martin
 MG=Madagascar
 MH=Marshall Islands
 MK=Macedonia
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java	Wed Jul 05 16:46:22 2017 +0200
@@ -141,6 +141,8 @@
                                      "Malaysia Summer Time", "MYST"};
         String NORONHA[] = new String[] {"Fernando de Noronha Time", "FNT",
                                          "Fernando de Noronha Summer Time", "FNST"};
+        String NPT[] = new String[] {"Nepal Time", "NPT",
+                                     "Nepal Summer Time", "NPST"};
         String NST[] = new String[] {"Newfoundland Standard Time", "NST",
                                      "Newfoundland Daylight Time", "NDT"};
         String NZST[] = new String[] {"New Zealand Standard Time", "NZST",
@@ -151,6 +153,8 @@
                                      "Pakistan Summer Time", "PKST"};
         String PST[] = new String[] {"Pacific Standard Time", "PST",
                                      "Pacific Daylight Time", "PDT"};
+        String RST[] = new String[] {"Eastern Standard Time", "EST",
+                                     "Central Daylight Time", "CDT"};
         String SAST[] = new String[] {"South Africa Standard Time", "SAST",
                                       "South Africa Summer Time", "SAST"};
         String SBT[] = new String[] {"Solomon Is. Time", "SBT",
@@ -290,6 +294,7 @@
             {"America/Argentina/La_Rioja", AGT},
             {"America/Argentina/Mendoza", AGT},
             {"America/Argentina/Rio_Gallegos", AGT},
+            {"America/Argentina/Salta", AGT},
             {"America/Argentina/San_Juan", AGT},
             {"America/Argentina/San_Luis", AGT},
             {"America/Argentina/Tucuman", AGT},
@@ -407,7 +412,7 @@
             {"America/Rankin_Inlet", CST},
             {"America/Recife", BRT},
             {"America/Regina", CST},
-            {"America/Resolute", EST},
+            {"America/Resolute", RST},
             {"America/Rio_Branco", AMT},
             {"America/Rosario", AGT},
             {"America/Santarem", BRT},
@@ -505,8 +510,8 @@
                                              "Petropavlovsk-Kamchatski Summer Time", "PETST"}},
             {"Asia/Karachi", PKT},
             {"Asia/Kashgar", CTT},
-            {"Asia/Katmandu", new String[] {"Nepal Time", "NPT",
-                                            "Nepal Summer Time", "NPST"}},
+            {"Asia/Kathmandu", NPT},
+            {"Asia/Katmandu", NPT},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"Krasnoyarsk Time", "KRAT",
                                                "Krasnoyarsk Summer Time", "KRAST"}},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java	Wed Jul 05 16:46:22 2017 +0200
@@ -141,6 +141,8 @@
                                      "Malaysische Sommerzeit", "MYST"};
         String NORONHA[] = new String[] {"Fernando de Noronha Zeit", "FNT",
                                          "Fernando de Noronha Sommerzeit", "FNST"};
+        String NPT[] = new String[] {"Nepalesische Zeit", "NPT",
+                                     "Nepalesische Sommerzeit", "NPST"};
         String NST[] = new String[] {"Neufundland Normalzeit", "NST",
                                      "Neufundland Sommerzeit", "NDT"};
         String NZST[] = new String[] {"Neuseeland Normalzeit", "NZST",
@@ -151,6 +153,8 @@
                                      "Pakistanische Sommerzeit", "PKST"};
         String PST[] = new String[] {"Pazifische Normalzeit", "PST",
                                      "Pazifische Sommerzeit", "PDT"};
+        String RST[] = new String[] {"\u00d6stliche Normalzeit", "EST",
+                                     "Zentrale Sommerzeit", "CDT"};
         String SAST[] = new String[] {"S\u00fcdafrikanische Normalzeit", "SAST",
                                       "S\u00fcdafrikanische Sommerzeit", "SAST"};
         String SBT[] = new String[] {"Salomoninseln Zeit", "SBT",
@@ -290,6 +294,7 @@
             {"America/Argentina/La_Rioja", AGT},
             {"America/Argentina/Mendoza", AGT},
             {"America/Argentina/Rio_Gallegos", AGT},
+            {"America/Argentina/Salta", AGT},
             {"America/Argentina/San_Juan", AGT},
             {"America/Argentina/San_Luis", AGT},
             {"America/Argentina/Tucuman", AGT},
@@ -407,7 +412,7 @@
             {"America/Rankin_Inlet", CST},
             {"America/Recife", BRT},
             {"America/Regina", CST},
-            {"America/Resolute", EST},
+            {"America/Resolute", RST},
             {"America/Rio_Branco", AMT},
             {"America/Rosario", AGT},
             {"America/Santarem", BRT},
@@ -505,8 +510,8 @@
                                              "Petropawlowsk-Kamtschatkische Sommerzeit", "PETST"}},
             {"Asia/Karachi", PKT},
             {"Asia/Kashgar", CTT},
-            {"Asia/Katmandu", new String[] {"Nepalesische Zeit", "NPT",
-                                            "Nepalesische Sommerzeit", "NPST"}},
+            {"Asia/Kathmandu", NPT},
+            {"Asia/Katmandu", NPT},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"Krasnojarsker Zeit", "KRAT",
                                                "Krasnojarsker Sommerzeit", "KRAST"}},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java	Wed Jul 05 16:46:22 2017 +0200
@@ -141,6 +141,8 @@
                                      "Hora de verano de Malasia", "MYST"};
         String NORONHA[] = new String[] {"Hora de Fernando de Noronha", "FNT",
                                          "Hora de verano de Fernando de Noronha", "FNST"};
+        String NPT[] = new String[] {"Hora de Nepal", "NPT",
+                                     "Hora de verano de Nepal", "NPST"};
         String NST[] = new String[] {"Hora est\u00e1ndar de Terranova", "NST",
                                      "Hora de verano de Terranova", "NDT"};
         String NZST[] = new String[] {"Hora est\u00e1ndar de Nueva Zelanda", "NZST",
@@ -151,6 +153,8 @@
                                      "Hora de verano de Pakist\u00e1n", "PKST"};
         String PST[] = new String[] {"Hora est\u00e1ndar del Pac\u00edfico", "PST",
                                      "Hora de verano del Pac\u00edfico", "PDT"};
+        String RST[] = new String[] {"Hora est\u00e1ndar Oriental", "EST",
+                                     "Hora de verano Central", "CDT"};
         String SAST[] = new String[] {"Hora est\u00e1ndar de Sud\u00e1frica", "SAST",
                                       "Hora de verano de Sud\u00e1frica", "SAST"};
         String SBT[] = new String[] {"Hora de las Islas Solomon", "SBT",
@@ -290,6 +294,7 @@
             {"America/Argentina/La_Rioja", AGT},
             {"America/Argentina/Mendoza", AGT},
             {"America/Argentina/Rio_Gallegos", AGT},
+            {"America/Argentina/Salta", AGT},
             {"America/Argentina/San_Juan", AGT},
             {"America/Argentina/San_Luis", AGT},
             {"America/Argentina/Tucuman", AGT},
@@ -407,7 +412,7 @@
             {"America/Rankin_Inlet", CST},
             {"America/Recife", BRT},
             {"America/Regina", CST},
-            {"America/Resolute", EST},
+            {"America/Resolute", RST},
             {"America/Rio_Branco", AMT},
             {"America/Rosario", AGT},
             {"America/Santarem", BRT},
@@ -505,8 +510,8 @@
                                              "Hora de verano de Petropavlovsk-Kamchatski", "PETST"}},
             {"Asia/Karachi", PKT},
             {"Asia/Kashgar", CTT},
-            {"Asia/Katmandu", new String[] {"Hora de Nepal", "NPT",
-                                            "Hora de verano de Nepal", "NPST"}},
+            {"Asia/Kathmandu", NPT},
+            {"Asia/Katmandu", NPT},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"Hora de Krasnoyarsk", "KRAT",
                                                "Hora de verano de Krasnoyarsk", "KRAST"}},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java	Wed Jul 05 16:46:22 2017 +0200
@@ -141,6 +141,8 @@
                                      "Heure d'\u00e9t\u00e9 de Malaisie", "MYST"};
         String NORONHA[] = new String[] {"Heure de Fernando de Noronha", "FNT",
                                          "Heure d'\u00e9t\u00e9 de Fernando de Noronha", "FNST"};
+        String NPT[] = new String[] {"Heure du N\u00e9pal", "NPT",
+                                     "Heure d'\u00e9t\u00e9 du N\u00e9pal", "NPST"};
         String NST[] = new String[] {"Heure normale de Terre-Neuve", "NST",
                                      "Heure avanc\u00e9e de Terre-Neuve", "NDT"} ;
         String NZST[] = new String[] {"Heure normale de Nouvelle-Z\u00e9lande", "NZST",
@@ -151,6 +153,8 @@
                                      "Heure d'\u00e9t\u00e9 du Pakistan", "PKST"} ;
         String PST[] = new String[] {"Heure normale du Pacifique", "PST",
                                      "Heure avanc\u00e9e du Pacifique", "PDT"} ;
+        String RST[] = new String[] {"Heure normale de l'Est", "EST",
+                                     "Heure avanc\u00e9e du Centre", "CDT"} ;
         String SAST[] = new String[] {"Heure normale d'Afrique du Sud", "SAST",
                                       "Heure d'\u00e9t\u00e9 d'Afrique du Sud", "SAST"} ;
         String SBT[] = new String[] {"Heure des \u00celes Salomon", "SBT",
@@ -290,6 +294,7 @@
             {"America/Argentina/La_Rioja", AGT},
             {"America/Argentina/Mendoza", AGT},
             {"America/Argentina/Rio_Gallegos", AGT},
+            {"America/Argentina/Salta", AGT},
             {"America/Argentina/San_Juan", AGT},
             {"America/Argentina/San_Luis", AGT},
             {"America/Argentina/Tucuman", AGT},
@@ -407,7 +412,7 @@
             {"America/Rankin_Inlet", CST},
             {"America/Recife", BRT},
             {"America/Regina", CST},
-            {"America/Resolute", EST},
+            {"America/Resolute", RST},
             {"America/Rio_Branco", AMT},
             {"America/Rosario", AGT},
             {"America/Santarem", BRT},
@@ -505,8 +510,8 @@
                                              "Heure d'\u00e9t\u00e9 de Petropavlovsk-Kamchatski", "PETST"}},
             {"Asia/Karachi", PKT},
             {"Asia/Kashgar", CTT},
-            {"Asia/Katmandu", new String[] {"Heure du N\u00e9pal", "NPT",
-                                            "Heure d'\u00e9t\u00e9 du N\u00e9pal", "NPST"}},
+            {"Asia/Kathmandu", NPT},
+            {"Asia/Katmandu", NPT},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"Heure de Krasno\u00efarsk", "KRAT",
                                                "Heure d'\u00e9t\u00e9 de Krasno\u00efarsk", "KRAST"}},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java	Wed Jul 05 16:46:22 2017 +0200
@@ -141,6 +141,8 @@
                                      "Ora estiva della Malaysia", "MYST"};
         String NORONHA[] = new String[] {"Ora di Fernando de Noronha", "FNT",
                                          "Ora estiva di Fernando de Noronha", "FNST"};
+        String NPT[] = new String[] {"Ora del Nepal", "NPT",
+                                     "Ora estiva del Nepal", "NPST"};
         String NST[] = new String[] {"Ora solare di Terranova", "NST",
                                      "Ora legale di Terranova", "NDT"};
         String NZST[] = new String[] {"Ora solare della Nuova Zelanda", "NZST",
@@ -151,6 +153,8 @@
                                      "Ora estiva del Pakistan", "PKST"};
         String PST[] = new String[] {"Ora solare della costa occidentale USA", "PST",
                                      "Ora legale della costa occidentale USA", "PDT"};
+        String RST[] = new String[] {"Ora solare USA orientale", "EST",
+                                     "Ora legale USA centrale", "CDT"};
         String SAST[] = new String[] {"Ora solare del Sudafrica", "SAST",
                                       "Ora estiva del Sudafrica", "SAST"};
         String SBT[] = new String[] {"Ora delle Isole Salomone", "SBT",
@@ -290,6 +294,7 @@
             {"America/Argentina/La_Rioja", AGT},
             {"America/Argentina/Mendoza", AGT},
             {"America/Argentina/Rio_Gallegos", AGT},
+            {"America/Argentina/Salta", AGT},
             {"America/Argentina/San_Juan", AGT},
             {"America/Argentina/San_Luis", AGT},
             {"America/Argentina/Tucuman", AGT},
@@ -407,7 +412,7 @@
             {"America/Rankin_Inlet", CST},
             {"America/Recife", BRT},
             {"America/Regina", CST},
-            {"America/Resolute", EST},
+            {"America/Resolute", RST},
             {"America/Rio_Branco", AMT},
             {"America/Rosario", AGT},
             {"America/Santarem", BRT},
@@ -505,8 +510,8 @@
                                              "Ora estiva di Petropavlovsk-Kamchatski", "PETST"}},
             {"Asia/Karachi", PKT},
             {"Asia/Kashgar", CTT},
-            {"Asia/Katmandu", new String[] {"Ora del Nepal", "NPT",
-                                            "Ora estiva del Nepal", "NPST"}},
+            {"Asia/Kathmandu", NPT},
+            {"Asia/Katmandu", NPT},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"Ora di Krasnojarsk", "KRAT",
                                                "Ora estiva di Krasnojarsk", "KRAST"}},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java	Wed Jul 05 16:46:22 2017 +0200
@@ -141,6 +141,8 @@
                                      "\u30de\u30ec\u30fc\u30b7\u30a2\u590f\u6642\u9593", "MYST"};
         String NORONHA[] = new String[] {"\u30d5\u30a7\u30eb\u30ca\u30f3\u30c9\u30fb\u30c7\u30fb\u30ce\u30ed\u30fc\u30cb\u30e3\u6642\u9593", "FNT",
                                          "\u30d5\u30a7\u30eb\u30ca\u30f3\u30c9\u30fb\u30c7\u30fb\u30ce\u30ed\u30fc\u30cb\u30e3\u590f\u6642\u9593", "FNST"};
+        String NPT[] = new String[] {"\u30cd\u30d1\u30fc\u30eb\u6642\u9593", "NPT",
+                                      "\u30cd\u30d1\u30fc\u30eb\u590f\u6642\u9593", "NPST"};
         String NST[] = new String[] {"\u30cb\u30e5\u30fc\u30d5\u30a1\u30f3\u30c9\u30e9\u30f3\u30c9\u6a19\u6e96\u6642", "NST",
                                      "\u30cb\u30e5\u30fc\u30d5\u30a1\u30f3\u30c9\u30e9\u30f3\u30c9\u590f\u6642\u9593", "NDT"};
         String NZST[] = new String[] {"\u30cb\u30e5\u30fc\u30b8\u30fc\u30e9\u30f3\u30c9\u6a19\u6e96\u6642", "NZST",
@@ -151,6 +153,8 @@
                                      "\u30d1\u30ad\u30b9\u30bf\u30f3\u590f\u6642\u9593", "PKST"};
         String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6a19\u6e96\u6642", "PST",
                                      "\u592a\u5e73\u6d0b\u590f\u6642\u9593", "PDT"};
+        String RST[] = new String[] {"\u6771\u90e8\u6a19\u6e96\u6642", "EST",
+                                     "\u4e2d\u90e8\u590f\u6642\u9593", "CDT"};
         String SAST[] = new String[] {"\u5357\u30a2\u30d5\u30ea\u30ab\u6a19\u6e96\u6642", "SAST",
                                       "\u5357\u30a2\u30d5\u30ea\u30ab\u590f\u6642\u9593", "SAST"};
         String SBT[] = new String[] {"\u30bd\u30ed\u30e2\u30f3\u8af8\u5cf6\u6642\u9593", "SBT",
@@ -290,6 +294,7 @@
             {"America/Argentina/La_Rioja", AGT},
             {"America/Argentina/Mendoza", AGT},
             {"America/Argentina/Rio_Gallegos", AGT},
+            {"America/Argentina/Salta", AGT},
             {"America/Argentina/San_Juan", AGT},
             {"America/Argentina/San_Luis", AGT},
             {"America/Argentina/Tucuman", AGT},
@@ -407,7 +412,7 @@
             {"America/Rankin_Inlet", CST},
             {"America/Recife", BRT},
             {"America/Regina", CST},
-            {"America/Resolute", EST},
+            {"America/Resolute", RST},
             {"America/Rio_Branco", AMT},
             {"America/Rosario", AGT},
             {"America/Santarem", BRT},
@@ -505,8 +510,8 @@
                                              "\u30da\u30c8\u30ed\u30d1\u30d6\u30ed\u30d5\u30b9\u30af\u30ab\u30e0\u30c1\u30e3\u30c4\u30ad\u30fc\u590f\u6642\u9593", "PETST"}},
             {"Asia/Karachi", PKT},
             {"Asia/Kashgar", CTT},
-            {"Asia/Katmandu", new String[] {"\u30cd\u30d1\u30fc\u30eb\u6642\u9593", "NPT",
-                                            "\u30cd\u30d1\u30fc\u30eb\u590f\u6642\u9593", "NPST"}},
+            {"Asia/Kathmandu", NPT},
+            {"Asia/Katmandu", NPT},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"\u30af\u30e9\u30b9\u30ce\u30e4\u30eb\u30b9\u30af\u6642\u9593", "KRAT",
                                                "\u30af\u30e9\u30b9\u30ce\u30e4\u30eb\u30b9\u30af\u590f\u6642\u9593", "KRAST"}},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java	Wed Jul 05 16:46:22 2017 +0200
@@ -141,6 +141,8 @@
                                      "\ub9d0\ub808\uc774\uc2dc\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MYST"};
         String NORONHA[] = new String[] {"Fernando de Noronha \uc2dc\uac04", "FNT",
                                          "Fernando de Noronha \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "FNST"};
+        String NPT[] = new String[] {"\ub124\ud314 \uc2dc\uac04", "NPT",
+                                      "\ub124\ud314 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NPST"};
         String NST[] = new String[] {"\ub274\ud380\ub4e4\ub79c\ub4dc \ud45c\uc900\uc2dc", "NST",
                                      "\ub274\ud380\ub4e4\ub79c\ub4dc \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NDT"};
         String NZST[] = new String[] {"\ub274\uc9c8\ub79c\ub4dc \ud45c\uc900\uc2dc", "NZST",
@@ -151,6 +153,8 @@
                                      "\ud30c\ud0a4\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PKST"};
         String PST[] = new String[] {"\ud0dc\ud3c9\uc591 \ud45c\uc900\uc2dc", "PST",
                                      "\ud0dc\ud3c9\uc591 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PDT"};
+        String RST[] = new String[] {"\ub3d9\ubd80 \ud45c\uc900\uc2dc", "EST",
+                                     "\uc911\ubd80 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CDT"};
         String SAST[] = new String[] {"\ub0a8\uc544\ud504\ub9ac\uce74 \ud45c\uc900\uc2dc", "SAST",
                                       "\ub0a8\uc544\ud504\ub9ac\uce74 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "SAST"};
         String SBT[] = new String[] {"\uc194\ub85c\ubaac \uad70\ub3c4 \uc2dc\uac04", "SBT",
@@ -290,6 +294,7 @@
             {"America/Argentina/La_Rioja", AGT},
             {"America/Argentina/Mendoza", AGT},
             {"America/Argentina/Rio_Gallegos", AGT},
+            {"America/Argentina/Salta", AGT},
             {"America/Argentina/San_Juan", AGT},
             {"America/Argentina/San_Luis", AGT},
             {"America/Argentina/Tucuman", AGT},
@@ -407,7 +412,7 @@
             {"America/Rankin_Inlet", CST},
             {"America/Recife", BRT},
             {"America/Regina", CST},
-            {"America/Resolute", EST},
+            {"America/Resolute", RST},
             {"America/Rio_Branco", AMT},
             {"America/Rosario", AGT},
             {"America/Santarem", BRT},
@@ -505,8 +510,8 @@
                                             "\ud398\ud2b8\ub85c\ud30c\ube14\ub85c\ud504\uc2a4\ud06c-\uce84\ucc28\uce20\ud0a4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PETST"}},
             {"Asia/Karachi", PKT},
             {"Asia/Kashgar", CTT},
-            {"Asia/Katmandu", new String[] {"\ub124\ud314 \uc2dc\uac04", "NPT",
-                                            "\ub124\ud314 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NPST"}},
+            {"Asia/Kathmandu", NPT},
+            {"Asia/Katmandu", NPT},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"\ud06c\ub77c\uc2a4\ub178\uc57c\ub974\uc2a4\ud06c \uc2dc\uac04", "KRAT",
                                                "\ud06c\ub77c\uc2a4\ub178\uc57c\ub974\uc2a4\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "KRAST"}},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java	Wed Jul 05 16:46:22 2017 +0200
@@ -141,6 +141,8 @@
                                      "Malaysia, sommartid", "MYST"};
         String NORONHA[] = new String[] {"Fernando de Noronha, normaltid", "FNT",
                                          "Fernando de Noronha, sommartid", "FNST"};
+        String NPT[] = new String[] {"Nepal, normaltid", "NPT",
+                                     "Nepal, sommartid", "NPST"};
         String NST[] = new String[] {"Newfoundland, normaltid", "NST",
                                      "Newfoundland, sommartid", "NDT"};
         String NZST[] = new String[] {"Nya Zeeland, normaltid", "NZST",
@@ -151,6 +153,8 @@
                                      "Pakistan, sommartid", "PKST"};
         String PST[] = new String[] {"Stilla havet, normaltid", "PST",
                                      "Stilla havet, sommartid", "PDT"};
+        String RST[] = new String[] {"Eastern, normaltid", "EST",
+                                     "Central sommartid", "CDT"};
         String SAST[] = new String[] {"Sydafrika, normaltid", "SAST",
                                       "Sydafrika, sommartid", "SAST"};
         String SBT[] = new String[] {"Salomon\u00f6arna, normaltid", "SBT",
@@ -290,6 +294,7 @@
             {"America/Argentina/La_Rioja", AGT},
             {"America/Argentina/Mendoza", AGT},
             {"America/Argentina/Rio_Gallegos", AGT},
+            {"America/Argentina/Salta", AGT},
             {"America/Argentina/San_Juan", AGT},
             {"America/Argentina/San_Luis", AGT},
             {"America/Argentina/Tucuman", AGT},
@@ -407,7 +412,7 @@
             {"America/Rankin_Inlet", CST},
             {"America/Recife", BRT},
             {"America/Regina", CST},
-            {"America/Resolute", EST},
+            {"America/Resolute", RST},
             {"America/Rio_Branco", AMT},
             {"America/Rosario", AGT},
             {"America/Santarem", BRT},
@@ -505,8 +510,8 @@
                                              "Petropavlovsk-Kamtjatka, sommartid", "PETST"}},
             {"Asia/Karachi", PKT},
             {"Asia/Kashgar", CTT},
-            {"Asia/Katmandu", new String[] {"Nepal, normaltid", "NPT",
-                                            "Nepal, sommartid", "NPST"}},
+            {"Asia/Kathmandu", NPT},
+            {"Asia/Katmandu", NPT},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"Krasnojarsk, normaltid", "KRAT",
                                                "Krasnojarsk, sommartid", "KRAST"}},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java	Wed Jul 05 16:46:22 2017 +0200
@@ -141,6 +141,8 @@
                                      "\u9a6c\u6765\u897f\u4e9a\u590f\u4ee4\u65f6", "MYST"};
         String NORONHA[] = new String[] {"\u8d39\u5c14\u5357\u591a\u5fb7\u8bfa\u7f57\u5c3c\u4e9a\u65f6\u95f4", "FNT",
                                          "\u8d39\u5c14\u5357\u591a\u5fb7\u8bfa\u7f57\u5c3c\u4e9a\u590f\u4ee4\u65f6", "FNST"};
+        String NPT[] = new String[] {"\u5c3c\u6cca\u5c14\u65f6\u95f4", "NPT",
+                                     "\u5c3c\u6cca\u5c14\u590f\u4ee4\u65f6", "NPST"};
         String NST[] = new String[] {"\u7ebd\u82ac\u5170\u6807\u51c6\u65f6\u95f4", "NST",
                                      "\u7ebd\u82ac\u5170\u590f\u4ee4\u65f6", "NDT"};
         String NZST[] = new String[] {"\u65b0\u897f\u5170\u6807\u51c6\u65f6\u95f4", "NZST",
@@ -151,6 +153,8 @@
                                      "\u5df4\u57fa\u65af\u5766\u590f\u4ee4\u65f6", "PKST"};
         String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6807\u51c6\u65f6\u95f4", "PST",
                                      "\u592a\u5e73\u6d0b\u590f\u4ee4\u65f6", "PDT"};
+        String RST[] = new String[] {"\u4e1c\u90e8\u6807\u51c6\u65f6\u95f4", "EST",
+                                     "\u4e2d\u592e\u590f\u4ee4\u65f6", "CDT"};
         String SAST[] = new String[] {"\u5357\u975e\u6807\u51c6\u65f6\u95f4", "SAST",
                                       "\u5357\u975e\u590f\u4ee4\u65f6", "SAST"};
         String SBT[] = new String[] {"\u6240\u7f57\u95e8\u7fa4\u5c9b\u65f6\u95f4", "SBT",
@@ -290,6 +294,7 @@
             {"America/Argentina/La_Rioja", AGT},
             {"America/Argentina/Mendoza", AGT},
             {"America/Argentina/Rio_Gallegos", AGT},
+            {"America/Argentina/Salta", AGT},
             {"America/Argentina/San_Juan", AGT},
             {"America/Argentina/San_Luis", AGT},
             {"America/Argentina/Tucuman", AGT},
@@ -407,7 +412,7 @@
             {"America/Rankin_Inlet", CST},
             {"America/Recife", BRT},
             {"America/Regina", CST},
-            {"America/Resolute", EST},
+            {"America/Resolute", RST},
             {"America/Rio_Branco", AMT},
             {"America/Rosario", AGT},
             {"America/Santarem", BRT},
@@ -505,8 +510,8 @@
                                              "\u5f7c\u5f97\u7f57\u5df4\u752b\u6d1b\u592b\u65af\u514b\u590f\u4ee4\u65f6", "PETST"}},
             {"Asia/Karachi", PKT},
             {"Asia/Kashgar", CTT},
-            {"Asia/Katmandu", new String[] {"\u5c3c\u6cca\u5c14\u65f6\u95f4", "NPT",
-                                            "\u5c3c\u6cca\u5c14\u590f\u4ee4\u65f6", "NPST"}},
+            {"Asia/Kathmandu", NPT},
+            {"Asia/Katmandu", NPT},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"\u514b\u62c9\u65af\u8bfa\u4e9a\u5c14\u65af\u514b\u65f6\u95f4", "KRAT",
                                                "\u514b\u62c9\u65af\u8bfa\u4e9a\u5c14\u65af\u514b\u590f\u4ee4\u65f6", "KRAST"}},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java	Wed Jul 05 16:46:22 2017 +0200
@@ -141,6 +141,8 @@
                                      "\u99ac\u4f86\u897f\u4e9e\u590f\u4ee4\u6642\u9593", "MYST"};
         String NORONHA[] = new String[] {"\u8cbb\u723e\u5357\u591a-\u8fea\u8afe\u7f85\u5c3c\u4e9e\u6642\u9593", "FNT",
                                          "\u8cbb\u723e\u5357\u591a-\u8fea\u8afe\u7f85\u5c3c\u4e9e\u590f\u4ee4\u6642\u9593", "FNST"};
+        String NPT[] = new String[] {"\u5c3c\u6cca\u723e\u6642\u9593", "NPT",
+                                     "\u5c3c\u6cca\u723e\u590f\u4ee4\u6642\u9593", "NPST"};
         String NST[] = new String[] {"\u7d10\u82ac\u862d\u6a19\u6e96\u6642\u9593", "NST",
                                      "\u7d10\u82ac\u862d\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "NDT"};
         String NZST[] = new String[] {"\u7d10\u897f\u862d\u6a19\u6e96\u6642\u9593", "NZST",
@@ -151,6 +153,8 @@
                                      "\u5df4\u57fa\u65af\u5766\u590f\u4ee4\u6642\u9593", "PKST"};
         String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6a19\u6e96\u6642\u9593", "PST",
                                      "\u592a\u5e73\u6d0b\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "PDT"};
+        String RST[] = new String[] {"\u6771\u65b9\u6a19\u6e96\u6642\u9593", "EST",
+                                     "\u4e2d\u592e\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "CDT"};
         String SAST[] = new String[] {"\u5357\u975e\u6a19\u6e96\u6642\u9593", "SAST",
                                       "\u5357\u975e\u590f\u4ee4\u6642\u9593", "SAST"};
         String SBT[] = new String[] {"\u6240\u7f85\u9580\u7fa4\u5cf6\u6642\u9593", "SBT",
@@ -290,6 +294,7 @@
             {"America/Argentina/La_Rioja", AGT},
             {"America/Argentina/Mendoza", AGT},
             {"America/Argentina/Rio_Gallegos", AGT},
+            {"America/Argentina/Salta", AGT},
             {"America/Argentina/San_Juan", AGT},
             {"America/Argentina/San_Luis", AGT},
             {"America/Argentina/Tucuman", AGT},
@@ -407,7 +412,7 @@
             {"America/Rankin_Inlet", CST},
             {"America/Recife", BRT},
             {"America/Regina", CST},
-            {"America/Resolute", EST},
+            {"America/Resolute", RST},
             {"America/Rio_Branco", AMT},
             {"America/Rosario", AGT},
             {"America/Santarem", BRT},
@@ -505,8 +510,8 @@
                                              "Petropavlovsk-Kamchatski \u590f\u4ee4\u6642\u9593", "PETST"}},
             {"Asia/Karachi", PKT},
             {"Asia/Kashgar", CTT},
-            {"Asia/Katmandu", new String[] {"\u5c3c\u6cca\u723e\u6642\u9593", "NPT",
-                                            "\u5c3c\u6cca\u723e\u590f\u4ee4\u6642\u9593", "NPST"}},
+            {"Asia/Kathmandu", NPT},
+            {"Asia/Katmandu", NPT},
             {"Asia/Kolkata", IST},
             {"Asia/Krasnoyarsk", new String[] {"\u514b\u62c9\u65af\u8afe\u4e9e\u723e\u65af\u514b\u6642\u9593", "KRAT",
                                                "\u514b\u62c9\u65af\u8afe\u4e9e\u723e\u65af\u514b\u590f\u4ee4\u6642\u9593", "KRAST"}},
Binary file jdk/src/share/lib/audio/soundbank.gm has changed
--- a/jdk/src/windows/native/sun/security/krb5/WindowsDirectory.c	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/src/windows/native/sun/security/krb5/WindowsDirectory.c	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, 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
@@ -23,6 +23,7 @@
  * have any questions.
  */
 
+#define UNICODE
 #include <jni.h>
 #include <windows.h>
 #include <stdlib.h>
@@ -30,22 +31,20 @@
 /*
  * Class:     sun_security_krb5_Config
  * Method:    getWindowsDirectory
- * Signature: ()Ljava/lang/String;
+ * Signature: (Z)Ljava/lang/String;
  */
 JNIEXPORT jstring JNICALL Java_sun_security_krb5_Config_getWindowsDirectory(
-    JNIEnv* env, jclass configClass) {
-    LPTSTR lpPath = NULL;
-    UINT uLength ;
-    jstring path = NULL;
-
-    if (uLength = GetWindowsDirectory(lpPath, 0)) {
-        lpPath = (LPTSTR)malloc(sizeof(TCHAR) * uLength);
-        if (lpPath != NULL) {
-            if (GetWindowsDirectory(lpPath, uLength)) {
-                path = (*env)->NewStringUTF(env, lpPath);
-            }
-            free(lpPath);
-        }
+        JNIEnv* env, jclass configClass, jboolean isSystem) {
+    TCHAR lpPath[MAX_PATH+1];
+    UINT len;
+    if (isSystem) {
+        len = GetSystemWindowsDirectory(lpPath, MAX_PATH);
+    } else {
+        len = GetWindowsDirectory(lpPath, MAX_PATH);
     }
-    return path;
+    if (len) {
+        return (*env)->NewString(env, lpPath, len);
+    } else {
+        return NULL;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/EventHandler/Test6788531.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6788531
+ * @summary Tests public method lookup problem in EventHandler
+ * @author Sergey Malenkov
+ */
+
+import javax.swing.JButton;
+import java.awt.event.ActionListener;
+import java.beans.EventHandler;
+
+public class Test6788531 {
+    public static void main(String[] args) throws Exception {
+        JButton button = new JButton("hi");
+        button.addActionListener(EventHandler.create(ActionListener.class, new Private(), "run"));
+        button.addActionListener(EventHandler.create(ActionListener.class, new PrivateGeneric(), "run", "generic"));
+        button.doClick();
+    }
+
+    public static class Public {
+        public void run() {
+            throw new Error("method is overridden");
+        }
+    }
+
+    static class Private extends Public {
+        public void run() {
+            System.out.println("default");
+        }
+    }
+
+    public static class PublicGeneric<T> {
+        public void run(T object) {
+            throw new Error("method is overridden");
+        }
+    }
+
+    static class PrivateGeneric extends PublicGeneric<String> {
+        public void run(String string) {
+            System.out.println(string);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/PropertyEditor/TestEnumSubclass.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6736248
+ * @summary Tests PropertyEditor for value of subtype Enum with security manager
+ * @author Sergey Malenkov
+ */
+
+public class TestEnumSubclass {
+    public static void main(String[] args) {
+        System.setSecurityManager(new SecurityManager());
+        new TestEditor(Operation.class);
+    }
+
+    public enum Operation {
+        PLUS {
+            public int run(int i, int j) {
+                return i + j;
+            }
+        },
+        MINUS {
+            public int run(int i, int j) {
+                return i - j;
+            }
+        };
+        public abstract int run(int i, int j);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/PropertyEditor/TestEnumSubclassJava.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6736248
+ * @summary Tests PropertyEditor for value of subtype Enum
+ * @author Sergey Malenkov
+ */
+
+public class TestEnumSubclassJava {
+    public static void main(String[] args) {
+        new TestEditor(Operation.class).testJava(Operation.PLUS);
+    }
+
+    public enum Operation {
+        PLUS {
+            public int run(int i, int j) {
+                return i + j;
+            }
+        },
+        MINUS {
+            public int run(int i, int j) {
+                return i - j;
+            }
+        };
+        public abstract int run(int i, int j);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/PropertyEditor/TestEnumSubclassNull.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6736248
+ * @summary Tests PropertyEditor for null value of subtype Enum
+ * @author Sergey Malenkov
+ */
+
+public class TestEnumSubclassNull {
+    public static void main(String[] args) {
+        new TestEditor(Operation.class).testJava(null);
+    }
+
+    public enum Operation {
+        PLUS {
+            public int run(int i, int j) {
+                return i + j;
+            }
+        },
+        MINUS {
+            public int run(int i, int j) {
+                return i - j;
+            }
+        };
+        public abstract int run(int i, int j);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/PropertyEditor/TestEnumSubclassValue.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6736248
+ * @summary Tests PropertyEditor for value of subtype Enum
+ * @author Sergey Malenkov
+ */
+
+public class TestEnumSubclassValue {
+    public static void main(String[] args) {
+        TestEditor test = new TestEditor(Operation.class);
+        test.testValue(Operation.PLUS, "PLUS");
+        test.testValue(null, null);
+        test.testText("MINUS", Operation.MINUS);
+        test.testText(null, null);
+    }
+
+    public enum Operation {
+        PLUS {
+            public int run(int i, int j) {
+                return i + j;
+            }
+        },
+        MINUS {
+            public int run(int i, int j) {
+                return i - j;
+            }
+        };
+        public abstract int run(int i, int j);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Statement/Test6788531.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6788531
+ * @summary Tests public method lookup problem in Statement
+ * @author Sergey Malenkov
+ */
+
+import java.beans.Statement;
+
+public class Test6788531 {
+    public static void main(String[] args) throws Exception {
+        new Statement(new Private(), "run", null).execute();
+        new Statement(new PrivateGeneric(), "run", new Object[] {"generic"}).execute();
+    }
+
+    public static class Public {
+        public void run() {
+            throw new Error("method is overridden");
+        }
+    }
+
+    static class Private extends Public {
+        public void run() {
+            System.out.println("default");
+        }
+    }
+
+    public static class PublicGeneric<T> {
+        public void run(T object) {
+            throw new Error("method is overridden");
+        }
+    }
+
+    static class PrivateGeneric extends PublicGeneric<String> {
+        public void run(String string) {
+            System.out.println(string);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/Test4864117.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4864117
+ * @summary Tests XMLDecoder within another DefaultHandler for SAX parser
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+import java.beans.ExceptionListener;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public final class Test4864117 extends DefaultHandler implements ExceptionListener {
+    private static final String TEST = "test";
+    private static final String DATA
+            = "<test>\n"
+            + " <void property=\"message\">\n"
+            + "  <string>Hello, world!</string>\n"
+            + " </void>\n"
+            + "</test>";
+
+    public static void main(String[] args) {
+        Test4864117 test = new Test4864117();
+        InputStream input = new ByteArrayInputStream(DATA.getBytes());
+        Exception error = null;
+        try {
+            SAXParserFactory.newInstance().newSAXParser().parse(input, test);
+        }
+        catch (ParserConfigurationException exception) {
+            error = exception;
+        }
+        catch (SAXException exception) {
+            error = exception.getException();
+            if (error == null) {
+                error = exception;
+            }
+        }
+        catch (IOException exception) {
+            error = exception;
+        }
+        if (error != null) {
+            throw new Error("unexpected error", error);
+        }
+        test.print('?', test.getMessage());
+    }
+
+    private String message;
+
+    public String getMessage() {
+        if (this.message == null) {
+            throw new Error("owner's method is not called");
+        }
+        return this.message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+        print(':', this.message);
+    }
+
+    // DefaultHandler implementation
+
+    private DefaultHandler handler;
+    private int depth;
+
+    @Override
+    public void startDocument() throws SAXException {
+        this.handler = XMLDecoder.createHandler(this, this, null);
+        this.handler.startDocument();
+    }
+
+    @Override
+    public void endDocument() {
+        this.handler = null;
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+        print('>', qName);
+        if (this.depth > 0) {
+            this.handler.startElement(uri, localName, qName, attributes);
+        } else if (!TEST.equals(qName)) {
+            throw new SAXException("unexpected element name: " + qName);
+        }
+        this.depth++;
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        this.depth--;
+        print('<', qName);
+        if (this.depth > 0) {
+            this.handler.endElement(uri, localName, qName);
+        } else if (!TEST.equals(qName)) {
+            throw new SAXException("unexpected element name: " + qName);
+        }
+    }
+
+    @Override
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        this.handler.characters(ch, start, length);
+    }
+
+    public void exceptionThrown(Exception exception) {
+        throw new Error("unexpected exception", exception);
+    }
+
+    private void print(char ch, String name) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < this.depth; i++) sb.append(' ');
+        sb.append(ch).append(' ').append(name);
+        System.out.println(sb.toString());
+    }
+}
--- a/jdk/test/java/beans/XMLDecoder/Test6341798.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/beans/XMLDecoder/Test6341798.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2008 Sun Microsystems, 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
@@ -39,7 +39,7 @@
 
     private static final String DATA
             = "<java>\n"
-            + " <object class=\"TestTurkishLocale$DataBean\">\n"
+            + " <object class=\"Test6341798$DataBean\">\n"
             + "  <void property=\"illegal\">\n"
             + "   <boolean>true</boolean>\n"
             + "  </void>\n"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/AbstractTest.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.beans.ExceptionListener;
+import java.beans.XMLDecoder;
+
+import java.io.ByteArrayInputStream;
+
+abstract class AbstractTest implements ExceptionListener {
+    public void exceptionThrown(Exception exception) {
+        throw new Error("unexpected exception", exception);
+    }
+
+    /**
+     * Validates the XML decoder for XML archive
+     * that defined in the public field of the subclass.
+     *
+     * @param decoder  the initialized XML decoder
+     * @throws Error if validation failed
+     */
+    protected abstract void validate(XMLDecoder decoder);
+
+    /**
+     * This is entry point to start testing.
+     *
+     * @param security  use {@code true} to start
+     *                  second pass in secure context
+     */
+    final void test(boolean security) {
+        byte[] array = getFieldValue("XML").getBytes(); // NON-NLS: the field name
+        ByteArrayInputStream input = new ByteArrayInputStream(array);
+        XMLDecoder decoder = new XMLDecoder(input);
+        decoder.setExceptionListener(this);
+        validate(decoder);
+        try {
+            throw new Error("unexpected object" + decoder.readObject());
+        } catch (ArrayIndexOutOfBoundsException exception) {
+            // expected exception
+        }
+        decoder.close();
+        if (security) {
+            System.setSecurityManager(new SecurityManager());
+            test(false);
+        }
+    }
+
+    private String getFieldValue(String field) {
+        try {
+            return getClass().getField(field).get(this).toString();
+        } catch (NoSuchFieldException exception) {
+            throw new Error("unexpected exception", exception);
+        } catch (IllegalAccessException exception) {
+            throw new Error("unexpected exception", exception);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestArray.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <array> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+import java.lang.reflect.Array;
+
+public final class TestArray extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <array class=\"java.lang.Number\">\n"
+            + "  <byte>-111</byte>\n"
+            + "  <long>1111</long>\n"
+            + " </array>\n"
+            + " <array length=\"3\">\n"
+            + "  <void index=\"1\">\n"
+            + "   <string>Hello, world!</string>\n"
+            + "  </void>\n"
+            + " </array>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestArray().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        Number[] numbers = getArray(Number.class, 2, decoder.readObject());
+        if (!numbers[0].equals(Byte.valueOf("-111"))) { // NON-NLS: hardcoded in XML
+            throw new Error("unexpected byte value");
+        }
+        if (!numbers[1].equals(Long.valueOf("1111"))) { // NON-NLS: hardcoded in XML
+            throw new Error("unexpected long value");
+        }
+
+        Object[] objects = getArray(Object.class, 3, decoder.readObject());
+        if (objects[0] != null) {
+            throw new Error("unexpected first value");
+        }
+        if (!objects[1].equals("Hello, world!")) { // NON-NLS: hardcoded in XML
+            throw new Error("unexpected string value");
+        }
+        if (objects[2] != null) {
+            throw new Error("unexpected last value");
+        }
+    }
+
+    private static <T> T[] getArray(Class<T> component, int length, Object object) {
+        Class type = object.getClass();
+        if (!type.isArray()) {
+            throw new Error("array expected");
+        }
+        if (!type.getComponentType().equals(component)) {
+            throw new Error("unexpected component type");
+        }
+        if (length != Array.getLength(object)) {
+            throw new Error("unexpected array length");
+        }
+        return (T[]) object;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestBoolean.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <boolean> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestBoolean extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <boolean>true</boolean>\n"
+            + " <boolean>false</boolean>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestBoolean().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        if (!Boolean.TRUE.equals(decoder.readObject())) {
+            throw new Error("true expected");
+        }
+        if (!Boolean.FALSE.equals(decoder.readObject())) {
+            throw new Error("false expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestByte.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <byte> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestByte extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <byte>0</byte>\n"
+            + " <byte>127</byte>\n"
+            + " <byte>-128</byte>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestByte().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate((byte) 0, decoder.readObject());
+        validate(Byte.MAX_VALUE, decoder.readObject());
+        validate(Byte.MIN_VALUE, decoder.readObject());
+    }
+
+    private static void validate(byte value, Object object) {
+        if (!object.equals(Byte.valueOf(value))) {
+            throw new Error("byte " + value + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestChar.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <char> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestChar extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <char>X</char>\n"
+            + " <char code=\"#20\"/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestChar().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        if (!decoder.readObject().equals(Character.valueOf('X'))) {
+            throw new Error("unexpected character");
+        }
+        if (!decoder.readObject().equals(Character.valueOf((char) 0x20))) {
+            throw new Error("unexpected character code");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestClass.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <class> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestClass extends AbstractTest {
+    public static final String PREFIX = "javax.swing.colorchooser.";
+    public static final String INTERFACE = "ColorSelectionModel";
+    public static final String PUBLIC_CLASS = "DefaultColorSelectionModel";
+    public static final String PRIVATE_CLASS = "DiagramComponent";
+    public static final String XML
+            = "<java>\n"
+            + " <class>" + PREFIX + INTERFACE + "</class>\n"
+            + " <class>" + PREFIX + PUBLIC_CLASS + "</class>\n"
+            + " <class>" + PREFIX + PRIVATE_CLASS + "</class>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestClass().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(PREFIX + INTERFACE, decoder.readObject());
+        validate(PREFIX + PUBLIC_CLASS, decoder.readObject());
+        validate(PREFIX + PRIVATE_CLASS, decoder.readObject());
+    }
+
+    private static void validate(String name, Object object) {
+        Class type = (Class) object;
+        if (!type.getName().equals(name)) {
+            throw new Error(name + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestDouble.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <double> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestDouble extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <double>0</double>\n"
+            + " <double>1000</double>\n"
+            + " <double>-1.1e15</double>\n"
+            + " <double>10.11e-123</double>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestDouble().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(0.0, decoder.readObject());
+        validate(1000.0, decoder.readObject());
+        validate(-1.1e15, decoder.readObject());
+        validate(10.11e-123, decoder.readObject());
+    }
+
+    private static void validate(double value, Object object) {
+        if (!object.equals(Double.valueOf(value))) {
+            throw new Error("double " + value + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestFalse.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <false> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestFalse extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <false/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestFalse().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        if (!Boolean.FALSE.equals(decoder.readObject())) {
+            throw new Error("false expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestField.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <field> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestField extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <field name=\"FIELD\" class=\"TestField\"/>\n"
+            + " <field name=\"FIELD\" class=\"TestField\">\n"
+            + "  <string>static postfix</string>\n"
+            + " </field>\n"
+            + " <field name=\"FIELD\" class=\"TestField\"/>\n"
+            + " <property name=\"owner\">\n"
+            + "  <field id=\"prefix\" name=\"field\"/>\n"
+            + "  <field name=\"field\">\n"
+            + "   <string>postfix</string>\n"
+            + "  </field>\n"
+            + "  <field id=\"postfix\" name=\"field\"/>\n"
+            + " </property>\n"
+            + " <var idref=\"prefix\"/>\n"
+            + " <var idref=\"postfix\"/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestField().test(true);
+    }
+
+    public static String FIELD;
+    public String field;
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        FIELD = "static prefix";
+        field = "prefix";
+        decoder.setOwner(this);
+        validate(decoder, "static prefix");
+        validate(decoder, "static postfix");
+        validate(decoder, "prefix");
+        validate(decoder, "postfix");
+    }
+
+    private static void validate(XMLDecoder decoder, String name) {
+        if (!decoder.readObject().equals(name)) {
+            throw new Error(name + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestFloat.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <float> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestFloat extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <float>0</float>\n"
+            + " <float>100</float>\n"
+            + " <float>-1e15</float>\n"
+            + " <float>100e-20</float>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestFloat().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(0.0f, decoder.readObject());
+        validate(100.0f, decoder.readObject());
+        validate(-1e15f, decoder.readObject());
+        validate(100e-20f, decoder.readObject());
+    }
+
+    private static void validate(float value, Object object) {
+        if (!object.equals(Float.valueOf(value))) {
+            throw new Error("float " + value + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <int> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestInt extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <int>0</int>\n"
+            + " <int>127</int>\n"
+            + " <int>-128</int>\n"
+            + " <int>32767</int>\n"
+            + " <int>-32768</int>\n"
+            + " <int>2147483647</int>\n"
+            + " <int>-2147483648</int>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestInt().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(0, decoder.readObject());
+        validate((int) Byte.MAX_VALUE, decoder.readObject());
+        validate((int) Byte.MIN_VALUE, decoder.readObject());
+        validate((int) Short.MAX_VALUE, decoder.readObject());
+        validate((int) Short.MIN_VALUE, decoder.readObject());
+        validate(Integer.MAX_VALUE, decoder.readObject());
+        validate(Integer.MIN_VALUE, decoder.readObject());
+    }
+
+    private static void validate(int value, Object object) {
+        if (!object.equals(Integer.valueOf(value))) {
+            throw new Error("int " + value + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestJava.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <java> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestJava extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <void id=\"owner\" method=\"getOwner\">\n"
+            + "  <void method=\"init\">\n"
+            + "   <string>Hello, world!</string>\n"
+            + "  </void>\n"
+            + " </void>\n"
+            + " <object idref=\"owner\"/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestJava().test(true);
+    }
+
+    private String message;
+
+    public void init(String message) {
+        this.message = message;
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        decoder.setOwner(this);
+        if (this != decoder.readObject()) {
+            throw new Error("owner should be the same");
+        }
+        if (this.message == null) {
+            throw new Error("owner's method is not called");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestLong.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <long> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestLong extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <long>0</long>\n"
+            + " <long>127</long>\n"
+            + " <long>-128</long>\n"
+            + " <long>32767</long>\n"
+            + " <long>-32768</long>\n"
+            + " <long>2147483647</long>\n"
+            + " <long>-2147483648</long>\n"
+            + " <long>9223372036854775807</long>\n"
+            + " <long>-9223372036854775808</long>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestLong().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(0L, decoder.readObject());
+        validate((long) Byte.MAX_VALUE, decoder.readObject());
+        validate((long) Byte.MIN_VALUE, decoder.readObject());
+        validate((long) Short.MAX_VALUE, decoder.readObject());
+        validate((long) Short.MIN_VALUE, decoder.readObject());
+        validate((long) Integer.MAX_VALUE, decoder.readObject());
+        validate((long) Integer.MIN_VALUE, decoder.readObject());
+        validate(Long.MAX_VALUE, decoder.readObject());
+        validate(Long.MIN_VALUE, decoder.readObject());
+    }
+
+    private static void validate(long value, Object object) {
+        if (!object.equals(Long.valueOf(value))) {
+            throw new Error("long " + value + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestMethod.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <method> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestMethod extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <new class=\"TestMethod$A\">\n"
+            + "  <method name=\"m\">\n"
+            + "   <new class=\"TestMethod$Y\"/>\n"
+            + "   <new class=\"TestMethod$Y\"/>\n"
+            + "  </method>\n"
+            + " </new>\n"
+            + " <new class=\"TestMethod$B\">\n"
+            + "  <method name=\"m\">\n"
+            + "   <new class=\"TestMethod$Y\"/>\n"
+            + "   <new class=\"TestMethod$Y\"/>\n"
+            + "  </method>\n"
+            + " </new>\n"
+            + " <new class=\"TestMethod$C\">\n"
+            + "  <method name=\"m\">\n"
+            + "   <new class=\"TestMethod$Z\"/>\n"
+            + "   <new class=\"TestMethod$Z\"/>\n"
+            + "  </method>\n"
+            + " </new>\n"
+            + " <new class=\"TestMethod$D\">\n"
+            + "  <method name=\"m\">\n"
+            + "   <new class=\"TestMethod$Z\"/>\n"
+            + "   <new class=\"TestMethod$Z\"/>\n"
+            + "  </method>\n"
+            + " </new>\n"
+            + " <new class=\"TestMethod$E\">\n"
+            + "  <method name=\"m\">\n"
+            + "   <new class=\"TestMethod$Z\"/>\n"
+            + "   <new class=\"TestMethod$Z\"/>\n"
+            + "  </method>\n"
+            + " </new>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestMethod().test(true);
+    }
+
+    private NoSuchMethodException exception;
+
+    @Override
+    public void exceptionThrown(Exception exception) {
+        if (this.exception != null) {
+            // only one exception allowed
+            super.exceptionThrown(exception);
+        } else if (exception instanceof NoSuchMethodException) {
+            // expected exception: ambiguous methods are found
+            this.exception = (NoSuchMethodException) exception;
+        } else {
+            super.exceptionThrown(exception);
+        }
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        this.exception = null;
+        validate(decoder, A.class);
+        validate(decoder, B.class);
+        validate(decoder, C.class);
+        validate(decoder, D.class);
+        validate(decoder, E.class);
+        if (this.exception == null) {
+            throw new Error("NoSuchMethodException expected");
+        }
+    }
+
+    private static void validate(XMLDecoder decoder, Class type) {
+        if (!type.equals(decoder.readObject().getClass())) {
+            throw new Error("unexpected class");
+        }
+    }
+
+    /**
+     * All ambiguous method declarations should fail.
+     */
+    public static class A {
+        public void m(X x1, X x2) {
+            throw new Error("A.m(X,X) should not be called");
+        }
+
+        public void m(X x1, Y y2) {
+            throw new Error("A.m(X,Y) should not be called");
+        }
+
+        public void m(Y y1, X x2) {
+            throw new Error("A.m(Y,X) should not be called");
+        }
+    }
+
+    /**
+     * The most specific method in this case would be the second declaration.
+     */
+    public static class B {
+        public void m(X x1, X x2) {
+            throw new Error("B.m(X,X) should not be called");
+        }
+
+        public void m(X x1, Y y2) {
+            // expected: B.m(X,Y) should be called
+        }
+    }
+
+    /**
+     * The most specific method in this case would be the first declaration.
+     */
+    public static class C {
+        public void m(Y y1, Y y2) {
+            // expected: C.m(Y,Y) should be called
+        }
+
+        public void m(X x1, X x2) {
+            throw new Error("C.m(X,X) should not be called");
+        }
+    }
+
+    /**
+     * Same as the previous case but flip methods.
+     */
+    public static class D {
+        public void m(X x1, X x2) {
+            throw new Error("D.m(X,X) should not be called");
+        }
+
+        public void m(Y y1, Y y2) {
+            // expected: D.m(Y,Y) should be called
+        }
+    }
+
+    /**
+     * The method should be called with (Z,Z).
+     */
+    public static class E {
+        public void m(X x1, X x2) {
+            // expected: E.m(X,X) should be called
+        }
+    }
+
+    public static class X {
+    }
+
+    public static class Y extends X {
+    }
+
+    public static class Z extends Y {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestNew.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <new> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+import java.util.ArrayList;
+import java.util.List;
+
+public final class TestNew extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <new class=\"TestNew\"/>\n"
+            + " <new class=\"TestNew\">\n"
+            + "  <null/>\n"
+            + " </new>\n"
+            + " <new class=\"TestNew\">\n"
+            + "  <string>single</string>\n"
+            + " </new>\n"
+            + " <new class=\"TestNew\">\n"
+            + "  <string>first</string>\n"
+            + "  <string>second</string>\n"
+            + "  <string>third</string>\n"
+            + " </new>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestNew().test(true);
+    }
+
+    private List<String> list;
+
+    public TestNew(String...messages) {
+        if (messages != null) {
+            this.list = new ArrayList<String>();
+            for (String message : messages) {
+                this.list.add(message);
+            }
+        }
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (object instanceof TestNew) {
+            TestNew test = (TestNew) object;
+            return (test.list == null)
+                    ? this.list == null
+                    : test.list.equals(this.list);
+        }
+        return false;
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(decoder.readObject());
+        validate(decoder.readObject(), null);
+        validate(decoder.readObject(), "single");
+        validate(decoder.readObject(), "first", "second", "third");
+    }
+
+    private static void validate(Object object, String...messages) {
+        if (!object.equals(new TestNew(messages))) {
+            throw new Error("expected object");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestNull.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <null> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestNull extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <null/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestNull().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        if (null != decoder.readObject()) {
+            throw new Error("null value expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestObject.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <object> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+public final class TestObject extends AbstractTest {
+    public static final String XML // TODO
+            = "<java>\n"
+            + " <object class=\"javax.swing.JPanel\">\n"
+            + "  <void method=\"add\">\n"
+            + "   <object id=\"button\" class=\"javax.swing.JButton\">\n"
+            + "    <string>button</string>\n"
+            + "    <void property=\"verticalAlignment\">\n"
+            + "     <object field=\"CENTER\" class=\"javax.swing.SwingConstants\"/>\n"
+            + "    </void>\n"
+            + "   </object>\n"
+            + "  </void>\n"
+            + "  <void method=\"add\">\n"
+            + "   <object class=\"javax.swing.JLabel\">\n"
+            + "    <string>label</string>\n"
+            + "    <void property=\"labelFor\">\n"
+            + "     <object idref=\"button\"/>\n"
+            + "    </void>\n"
+            + "   </object>\n"
+            + "  </void>\n"
+            + " </object>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestObject().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        JPanel panel = (JPanel) decoder.readObject();
+        if (2 != panel.getComponents().length) {
+            throw new Error("unexpected component count");
+        }
+        JButton button = (JButton) panel.getComponents()[0];
+        if (!button.getText().equals("button")) { // NON-NLS: hardcoded in XML
+            throw new Error("unexpected button text");
+        }
+        if (SwingConstants.CENTER != button.getVerticalAlignment()) {
+            throw new Error("unexpected vertical alignment");
+        }
+        JLabel label = (JLabel) panel.getComponents()[1];
+        if (!label.getText().equals("label")) { // NON-NLS: hardcoded in XML
+            throw new Error("unexpected label text");
+        }
+        if (button != label.getLabelFor()) {
+            throw new Error("unexpected component");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestProperty.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <property> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestProperty extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <property name=\"owner\">\n"
+            + "  <property name=\"message\">\n"
+            + "   <string>message</string>\n"
+            + "  </property>\n"
+            + "  <property id=\"message\" name=\"message\"/>\n"
+            + "  <property name=\"indexed\" index=\"1\">\n"
+            + "   <string>indexed</string>\n"
+            + "  </property>\n"
+            + "  <property id=\"indexed\" name=\"indexed\" index=\"1\"/>\n"
+            + " </property>\n"
+            + " <var idref=\"message\"/>\n"
+            + " <var idref=\"indexed\"/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestProperty().test(true);
+    }
+
+    private int index;
+    private String message;
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getIndexed(int index) {
+        if (this.index != index) {
+            throw new Error("unexpected index");
+        }
+        return this.message;
+    }
+
+    public void setIndexed(int index, String message) {
+        this.index = index;
+        this.message = message;
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        decoder.setOwner(this);
+        validate(decoder, "message");
+        validate(decoder, "indexed");
+    }
+
+    private static void validate(XMLDecoder decoder, String name) {
+        if (!decoder.readObject().equals(name)) {
+            throw new Error(name + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestShort.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <short> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestShort extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <short>0</short>\n"
+            + " <short>127</short>\n"
+            + " <short>-128</short>\n"
+            + " <short>32767</short>\n"
+            + " <short>-32768</short>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestShort().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate((short) 0, decoder.readObject());
+        validate((short) Byte.MAX_VALUE, decoder.readObject());
+        validate((short) Byte.MIN_VALUE, decoder.readObject());
+        validate(Short.MAX_VALUE, decoder.readObject());
+        validate(Short.MIN_VALUE, decoder.readObject());
+    }
+
+    private static void validate(short value, Object object) {
+        if (!object.equals(Short.valueOf(value))) {
+            throw new Error("short " + value + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestString.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <string> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestString extends AbstractTest {
+    public static final String PREFIX = " prefix ";
+    public static final String POSTFIX = " postfix ";
+    public static final String XML
+            = "<java>\n"
+            + " <string>" + PREFIX + "</string>\n"
+            + " <string>" + POSTFIX + "</string>\n"
+            + " <string>" + PREFIX + POSTFIX + "</string>\n"
+            + " <string>" + PREFIX + "<char code=\"0\"/>" + POSTFIX + "</string>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestString().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(PREFIX, decoder.readObject());
+        validate(POSTFIX, decoder.readObject());
+        validate(PREFIX + POSTFIX, decoder.readObject());
+        validate(PREFIX + '\u0000' + POSTFIX, decoder.readObject());
+    }
+
+    private static void validate(String name, Object object) {
+        if (!object.equals(name)) {
+            throw new Error(name + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestTrue.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <true> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestTrue extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <true/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestTrue().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        if (!Boolean.TRUE.equals(decoder.readObject())) {
+            throw new Error("true expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/spec/TestVar.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <var> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestVar extends AbstractTest {
+    public static final String XML
+            = "<java id=\"decoder\">\n"
+            + " <var idref=\"decoder\"/>\n"
+            + " <var id=\"another\" idref=\"decoder\"/>\n"
+            + " <var idref=\"another\"/>\n"
+            + " <var id=\"decoder\" idref=\"another\"/>\n"
+            + " <var idref=\"decoder\"/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestVar().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        for (int i = 0; i < 3; i++) {
+            if (decoder != decoder.readObject()) {
+                throw new Error("decoder instance expected");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Boolean/Factory.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4262398
+ * @summary Basic test for Boolean.valueOf(boolean b).
+ */
+
+public class Factory {
+    public static void main(String[] args) throws Exception {
+        if (Boolean.valueOf(true) != Boolean.TRUE)
+            throw new Exception("Truth failure");
+        if (Boolean.valueOf(false) != Boolean.FALSE)
+            throw new Exception("Major fallacy");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Boolean/GetBoolean.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1999 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4252308
+ * @summary test Boolean.getBoolean method with empty key
+ */
+
+public class GetBoolean {
+    public static void main(String[] args) throws Exception {
+        Boolean.getBoolean("");
+        Boolean.getBoolean(null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Boolean/MakeBooleanComparable.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     4329937
+ * @summary Basic test for making Boolean implement Comparable
+ * @author  Josh Bloch
+ *
+ * @compile -source 1.5 MakeBooleanComparable.java
+ * @run main MakeBooleanComparable
+ */
+
+import java.util.*;
+
+public class MakeBooleanComparable {
+    public static void main(String args[]) {
+        Random rnd = new Random();
+        List<Boolean> list = new ArrayList<Boolean>();
+        int numFalse = 0;
+        for (int i = 0; i < 1000; i++) {
+            boolean element = rnd.nextBoolean();
+            if (!element)
+                numFalse++;
+            list.add(element); // Autoboxing!
+        }
+
+        Collections.sort(list);
+
+        for (int i = 0; i < numFalse; i++)
+            if (list.get(i).booleanValue())  // Autounboxing doesn't work yet!
+                throw new RuntimeException("False positive: " + i);
+        for (int i = numFalse; i < 1000; i++)
+            if (!list.get(i).booleanValue()) // Autounboxing doesn't work yet!
+                throw new RuntimeException("False negative: " + i);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Boolean/ParseBoolean.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4253773
+ * @summary test Boolean.parseBoolean
+ */
+
+public class ParseBoolean {
+    public static void main(String[] args) throws Exception {
+        checkTrue(Boolean.parseBoolean("TRUE"));
+        checkTrue(Boolean.parseBoolean("true"));
+        checkTrue(Boolean.parseBoolean("TrUe"));
+
+        checkFalse(Boolean.parseBoolean("false"));
+        checkFalse(Boolean.parseBoolean("FALSE"));
+        checkFalse(Boolean.parseBoolean("FaLse"));
+        checkFalse(Boolean.parseBoolean(null));
+        checkFalse(Boolean.parseBoolean("garbage"));
+        checkFalse(Boolean.parseBoolean("TRUEE"));
+    }
+
+    static void checkTrue(boolean b) {
+        if (!b)
+            throw new RuntimeException("test failed");
+    }
+
+    static void checkFalse(boolean b) {
+        if (b)
+            throw new RuntimeException("test failed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Byte/Decode.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4242173 5017980 6576055
+ * @summary Test Byte.decode method
+ * @author madbot
+ * @author Joseph D. Darcy
+ */
+
+/**
+ * There are six methods in java.lang.Byte which transform strings
+ * into a byte or Byte value:
+ *
+ * public Byte(String s)
+ * public static Byte decode(String nm)
+ * public static byte parseByte(String s, int radix)
+ * public static byte parseByte(String s)
+ * public static Byte valueOf(String s, int radix)
+ * public static Byte valueOf(String s)
+ *
+ * However, of these only decode has a nontrivial implementation
+ * in that class.
+ */
+public class Decode {
+
+    private static void check(String val, byte expected) {
+        byte n = (Byte.decode(val)).byteValue();
+        if (n != expected)
+            throw new RuntimeException("Byte.decode failed. String:" +
+                                                val + " Result:" + n);
+    }
+
+    private static void checkFailure(String val, String message) {
+        try {
+            byte n = (Byte.decode(val)).byteValue();
+            throw new RuntimeException(message);
+        } catch (NumberFormatException e) { /* Okay */}
+    }
+
+    public static void main(String[] args) throws Exception {
+        check(new String(""+Byte.MIN_VALUE), Byte.MIN_VALUE);
+        check(new String(""+Byte.MAX_VALUE), Byte.MAX_VALUE);
+
+        check("10",   (byte)10);
+        check("0x10", (byte)16);
+        check("0X10", (byte)16);
+        check("010",  (byte)8);
+        check("#10",  (byte)16);
+
+        check("+10",   (byte)10);
+        check("+0x10", (byte)16);
+        check("+0X10", (byte)16);
+        check("+010",  (byte)8);
+        check("+#10",  (byte)16);
+
+        check("-10",   (byte)-10);
+        check("-0x10", (byte)-16);
+        check("-0X10", (byte)-16);
+        check("-010",  (byte)-8);
+        check("-#10",  (byte)-16);
+
+        check(Integer.toString((int)Byte.MIN_VALUE), Byte.MIN_VALUE);
+        check(Integer.toString((int)Byte.MAX_VALUE), Byte.MAX_VALUE);
+
+        checkFailure("0x-10",   "Byte.decode allows negative sign in wrong position.");
+        checkFailure("0x+10",   "Byte.decode allows positive sign in wrong position.");
+
+        checkFailure("+",       "Raw plus sign allowed.");
+        checkFailure("-",       "Raw minus sign allowed.");
+
+        checkFailure(Integer.toString((int)Byte.MIN_VALUE - 1), "Out of range");
+        checkFailure(Integer.toString((int)Byte.MAX_VALUE + 1), "Out of range");
+
+        checkFailure("", "Empty String");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Double/BitwiseConversion.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 5037596
+ * @summary Verify bitwise conversion works for non-canonical NaN values
+ * @author Joseph D. Darcy
+ */
+
+import static java.lang.Double.*;
+import static sun.misc.DoubleConsts.*;
+
+public class BitwiseConversion {
+    static int testNanCase(long x) {
+        int errors  = 0;
+        // Strip out sign and exponent bits
+        long y = x & SIGNIF_BIT_MASK;
+
+        double values[] = {
+            longBitsToDouble(EXP_BIT_MASK | y),
+            longBitsToDouble(SIGN_BIT_MASK | EXP_BIT_MASK | y)
+        };
+
+        for(double value: values) {
+            if (!isNaN(value)) {
+                throw new RuntimeException("Invalid input " + y +
+                                           "yielded non-NaN" + value);
+            }
+            long converted = doubleToLongBits(value);
+            if (converted != 0x7ff8000000000000L) {
+                errors++;
+                System.err.format("Non-canoncial NaN bits returned: %x%n",
+                                  converted);
+            }
+        }
+        return errors;
+    }
+
+    public static void main(String... argv) {
+        int errors = 0;
+
+        for (int i = 0; i < SIGNIFICAND_WIDTH-1; i++) {
+            errors += testNanCase(1L<<i);
+        }
+
+        if (doubleToLongBits(Double.POSITIVE_INFINITY)
+                != 0x7ff0000000000000L) {
+            errors++;
+            System.err.println("Bad conversion for +infinity.");
+        }
+
+        if (doubleToLongBits(Double.NEGATIVE_INFINITY)
+                != 0xfff0000000000000L) {
+            errors++;
+            System.err.println("Bad conversion for -infinity.");
+        }
+
+        if (errors > 0)
+            throw new RuntimeException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Double/Constants.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2001-2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @compile Constants.java
+ * @bug 4397405 4826652
+ * @summary Testing constant-ness of Double.{MIN_VALUE, MAX_VALUE}, etc.
+ * @author Joseph D. Darcy
+ */
+
+public class Constants {
+    /*
+     * This compile-only test is to make sure that the primitive
+     * public static final fields in java.lang.Double are "constant
+     * expressions" as defined by "The Java Language Specification,
+     * 2nd edition" section 15.28; a different test checks the values
+     * of those fields.
+     */
+    public static void main(String[] args) throws Exception {
+        int i = 0;
+        switch (i) {
+        case (int)Double.NaN:                   // 0
+            System.out.println("Double.NaN is a constant!");
+            break;
+        case (int)Double.MIN_VALUE + 1:         // 0 + 1
+            System.out.println("Double.MIN_VALUE is a constant!");
+            break;
+        case (int)Double.MIN_NORMAL + 2:        // 0 + 2
+            System.out.println("Double.MIN_NORMAL is a constant!");
+            break;
+        case Double.MIN_EXPONENT:               // -1022
+            System.out.println("Double.MIN_EXPONENT is a constant!");
+            break;
+        case Double.MAX_EXPONENT:               // 1023
+            System.out.println("Double.MAX_EXPONENT is a constant!");
+            break;
+        case (int)Double.MAX_VALUE - 1:         // Integer.MAX_VALUE - 1
+            System.out.println("Double.MAX_VALUE is a constant!");
+            break;
+        case (int)Double.POSITIVE_INFINITY:     // Integer.MAX_VALUE
+            System.out.println("Double.POSITIVE_INFINITY is a constant!");
+            break;
+        case (int)Double.NEGATIVE_INFINITY:     // Integer.MIN_VALUE
+            System.out.println("Double.NEGATIVE_INFINITY is a constant!");
+            break;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Double/Extrema.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2001-2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4408489 4826652
+ * @summary Testing values of Double.{MIN_VALUE, MIN_NORMAL, MAX_VALUE}
+ * @author Joseph D. Darcy
+ */
+
+public class Extrema {
+    public static void main(String[] args) throws Exception {
+        if (Double.MIN_VALUE != Double.longBitsToDouble(0x1L))
+            throw new RuntimeException("Double.MIN_VALUE is not equal "+
+                                       "to longBitsToDouble(0x1L).");
+
+        if (Double.MIN_NORMAL != Double.longBitsToDouble(0x0010000000000000L))
+            throw new RuntimeException("Double.MIN_NORMAL is not equal "+
+                                       "to longBitsToDouble(0x0010000000000000L).");
+
+        if (Double.MAX_VALUE != Double.longBitsToDouble(0x7fefffffffffffffL))
+            throw new RuntimeException("Double.MAX_VALUE is not equal "+
+                                       "to longBitsToDouble(0x7fefffffffffffffL).");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Double/NaNInfinityParsing.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2001 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4428772
+ * @summary Testing recognition of "NaN" and "Infinity" strings
+ * @author Joseph D. Darcy
+ */
+
+
+public class NaNInfinityParsing {
+    /*
+     * Regression tests for:
+     * 4428772 -- Establish invariant for Float & Double classes and
+     * their string representations
+     *
+     * Added capability for parse{Float, Double} and related methods
+     * to recognize "NaN" and "Infinity" strings so that
+     * parseDouble(toString(d)) will always return the original
+     * floating-point value.
+     */
+
+    static String NaNStrings[] = {
+        "NaN",
+        "+NaN",
+        "-NaN"
+    };
+
+    static String infinityStrings[] = {
+        "Infinity",
+        "+Infinity",
+        "-Infinity",
+    };
+
+    static String invalidStrings[] = {
+        "+",
+        "-",
+        "@",
+        "N",
+        "Na",
+        "Nan",
+        "NaNf",
+        "NaNd",
+        "NaNF",
+        "NaND",
+        "+N",
+        "+Na",
+        "+Nan",
+        "+NaNf",
+        "+NaNd",
+        "+NaNF",
+        "+NaND",
+        "-N",
+        "-Na",
+        "-Nan",
+        "-NaNf",
+        "-NaNd",
+        "-NaNF",
+        "-NaND",
+        "I",
+        "In",
+        "Inf",
+        "Infi",
+        "Infin",
+        "Infini",
+        "Infinit",
+        "InfinitY",
+        "Infinityf",
+        "InfinityF",
+        "Infinityd",
+        "InfinityD",
+        "+I",
+        "+In",
+        "+Inf",
+        "+Infi",
+        "+Infin",
+        "+Infini",
+        "+Infinit",
+        "+InfinitY",
+        "+Infinityf",
+        "+InfinityF",
+        "+Infinityd",
+        "+InfinityD",
+        "-I",
+        "-In",
+        "-Inf",
+        "-Infi",
+        "-Infin",
+        "-Infini",
+        "-Infinit",
+        "-InfinitY",
+        "-Infinityf",
+        "-InfinityF",
+        "-Infinityd",
+        "-InfinityD",
+        "NaNInfinity",
+        "InfinityNaN",
+        "nan",
+        "infinity"
+    };
+
+    public static void main(String [] argv) throws Exception {
+        int i;
+        double d;
+
+        // Test valid NaN strings
+        for(i = 0; i < NaNStrings.length; i++) {
+            if(!Double.isNaN(d=Double.parseDouble(NaNStrings[i]))) {
+                throw new RuntimeException("NaN string ``" + NaNStrings[i]
+                                           + "'' did not parse as a NaN; returned " +
+                                           d + " instead.");
+            }
+        }
+
+        // Test valid Infinity strings
+        for(i = 0; i < infinityStrings.length; i++) {
+            if(!Double.isInfinite(d=Double.parseDouble(infinityStrings[i]))) {
+                throw new RuntimeException("Infinity string ``" +
+                                           infinityStrings[i] +
+                                           "'' did not parse as infinity; returned " +
+                                           d + "instead.");
+            }
+            // check sign of result
+
+            boolean negative = (infinityStrings[i].charAt(0) == '-');
+            if(d != (negative?Double.NEGATIVE_INFINITY:
+                          Double.POSITIVE_INFINITY))
+                throw new RuntimeException("Infinity has wrong sign;" +
+                                           (negative?"positive instead of negative.":
+                                            "negative instead of positive."));
+        }
+
+        // Test almost valid strings
+        for(i = 0; i < invalidStrings.length; i++) {
+            try {
+                double result;
+                d = Double.parseDouble(invalidStrings[i]);
+                throw new RuntimeException("Invalid string ``" +
+                                           invalidStrings[i]
+                                           +"'' parsed as " + d + ".");
+            }
+            catch(NumberFormatException e) {
+                // expected
+            }
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Double/ParseDouble.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,562 @@
+/*
+ * Copyright 2001-2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4160406 4705734 4707389 4826774 4895911
+ * @summary Test for Double.parseDouble method and acceptance regex
+ */
+
+import java.util.regex.*;
+
+public class ParseDouble {
+
+    private static void check(String val, double expected) {
+        double n = Double.parseDouble(val);
+        if (n != expected)
+            throw new RuntimeException("Double.parseDouble failed. String:" +
+                                                val + " Result:" + n);
+    }
+
+    private static void rudimentaryTest() {
+        check(new String(""+Double.MIN_VALUE), Double.MIN_VALUE);
+        check(new String(""+Double.MAX_VALUE), Double.MAX_VALUE);
+
+        check("10",     (double)  10.0);
+        check("10.0",   (double)  10.0);
+        check("10.01",  (double)  10.01);
+
+        check("-10",    (double) -10.0);
+        check("-10.00", (double) -10.0);
+        check("-10.01", (double) -10.01);
+    }
+
+
+    static  String badStrings[] = {
+        "",
+        "+",
+        "-",
+        "+e",
+        "-e",
+        "+e170",
+        "-e170",
+
+        // Make sure intermediate white space is not deleted.
+        "1234   e10",
+        "-1234   e10",
+
+        // Control characters in the interior of a string are not legal
+        "1\u0007e1",
+        "1e\u00071",
+
+        // NaN and infinity can't have trailing type suffices or exponents
+        "NaNf",
+        "NaNF",
+        "NaNd",
+        "NaND",
+        "-NaNf",
+        "-NaNF",
+        "-NaNd",
+        "-NaND",
+        "+NaNf",
+        "+NaNF",
+        "+NaNd",
+        "+NaND",
+        "Infinityf",
+        "InfinityF",
+        "Infinityd",
+        "InfinityD",
+        "-Infinityf",
+        "-InfinityF",
+        "-Infinityd",
+        "-InfinityD",
+        "+Infinityf",
+        "+InfinityF",
+        "+Infinityd",
+        "+InfinityD",
+
+        "NaNe10",
+        "-NaNe10",
+        "+NaNe10",
+        "Infinitye10",
+        "-Infinitye10",
+        "+Infinitye10",
+
+        // Non-ASCII digits are not recognized
+        "\u0661e\u0661", // 1e1 in Arabic-Indic digits
+        "\u06F1e\u06F1", // 1e1 in Extended Arabic-Indic digits
+        "\u0967e\u0967", // 1e1 in Devanagari digits
+
+        // JCK test lex03592m3
+        ".",
+
+        // JCK test lex03592m4
+        "e42",
+
+        // JCK test lex03592m5
+        ".e42",
+
+        // JCK test lex03592m6
+        "d",
+
+        // JCK test lex03592m7
+        ".d",
+
+        // JCK test lex03592m8
+        "e42d",
+
+        // JCK test lex03592m9
+        ".e42d",
+
+        // JCK test lex03593m10
+        "1A01.01125e-10d",
+
+        // JCK test lex03593m11
+        "2;3.01125e-10d",
+
+        // JCK test lex03593m12
+        "1_34.01125e-10d",
+
+        // JCK test lex03593m14
+        "202..01125e-10d",
+
+        // JCK test lex03593m15
+        "202,01125e-10d",
+
+        // JCK test lex03593m16
+        "202.03b4e-10d",
+
+        // JCK test lex03593m18
+        "202.06_3e-10d",
+
+        // JCK test lex03593m20
+        "202.01125e-f0d",
+
+        // JCK test lex03593m21
+        "202.01125e_3d",
+
+        // JCK test lex03593m22
+        "202.01125e -5d",
+
+        // JCK test lex03593m24
+        "202.01125e-10r",
+
+        // JCK test lex03593m25
+        "202.01125e-10ff",
+
+        // JCK test lex03593m26
+        "1234L.01",
+
+        // JCK test lex03593m27
+        "12ee-2",
+
+        // JCK test lex03593m28
+        "12e-2.2.2",
+
+        // JCK test lex03593m29
+        "12.01e+",
+
+        // JCK test lex03593m30
+        "12.01E",
+
+        // Bad hexadecimal-style strings
+
+        // Two leading zeros
+        "00x1.0p1",
+
+        // Must have hex specifier
+        "1.0p1",
+        "00010p1",
+        "deadbeefp1",
+
+        // Need an explicit fully-formed exponent
+        "0x1.0p",
+        "0x1.0",
+
+        // Exponent must be in decimal
+        "0x1.0pa",
+        "0x1.0pf",
+
+        // Exponent separated by "p"
+        "0x1.0e22",
+        "0x1.0e22",
+
+        // Need a signifcand
+        "0xp22"
+    };
+
+    static String goodStrings[] = {
+        "NaN",
+        "+NaN",
+        "-NaN",
+        "Infinity",
+        "+Infinity",
+        "-Infinity",
+        "1.1e-23f",
+        ".1e-23f",
+        "1e-23",
+        "1f",
+        "0",
+        "-0",
+        "+0",
+        "00",
+        "00",
+        "-00",
+        "+00",
+        "0000000000",
+        "-0000000000",
+        "+0000000000",
+        "1",
+        "2",
+        "1234",
+        "-1234",
+        "+1234",
+        "2147483647",   // Integer.MAX_VALUE
+        "2147483648",
+        "-2147483648",  // Integer.MIN_VALUE
+        "-2147483649",
+
+        "16777215",
+        "16777216",     // 2^24
+        "16777217",
+
+        "-16777215",
+        "-16777216",    // -2^24
+        "-16777217",
+
+        "9007199254740991",
+        "9007199254740992",     // 2^53
+        "9007199254740993",
+
+        "-9007199254740991",
+        "-9007199254740992",    // -2^53
+        "-9007199254740993",
+
+        "9223372036854775807",
+        "9223372036854775808",  // Long.MAX_VALUE
+        "9223372036854775809",
+
+        "-9223372036854775808",
+        "-9223372036854775809", // Long.MIN_VALUE
+        "-9223372036854775810",
+
+        // Culled from JCK test lex03591m1
+        "54.07140d",
+        "7.01e-324d",
+        "2147483647.01d",
+        "1.2147483647f",
+        "000000000000000000000000001.F",
+        "1.00000000000000000000000000e-2F",
+
+        // Culled from JCK test lex03592m2
+        "2.",
+        ".0909",
+        "122112217090.0",
+        "7090e-5",
+        "2.E-20",
+        ".0909e42",
+        "122112217090.0E+100",
+        "7090f",
+        "2.F",
+        ".0909d",
+        "122112217090.0D",
+        "7090e-5f",
+        "2.E-20F",
+        ".0909e42d",
+        "122112217090.0E+100D",
+
+        // Culled from JCK test lex03594m31 -- unicode escapes
+        "\u0035\u0031\u0034\u0039\u0032\u0033\u0036\u0037\u0038\u0030.1102E-209D",
+        "1290873\u002E12301e100",
+        "1.1E-10\u0066",
+
+        // Culled from JCK test lex03595m1
+        "0.0E-10",
+        "1E10",
+
+        // Culled from JCK test lex03691m1
+        "0.f",
+        "1f",
+        "0.F",
+        "1F",
+        "0.12d",
+        "1e-0d",
+        "12.e+1D",
+        "0e-0D",
+        "12.e+01",
+        "1e-01",
+
+        // Good hex strings
+        // Vary capitalization of separators.
+
+        "0x1p1",
+        "0X1p1",
+        "0x1P1",
+        "0X1P1",
+        "0x1p1f",
+        "0X1p1f",
+        "0x1P1f",
+        "0X1P1f",
+        "0x1p1F",
+        "0X1p1F",
+        "0x1P1F",
+        "0X1P1F",
+        "0x1p1d",
+        "0X1p1d",
+        "0x1P1d",
+        "0X1P1d",
+        "0x1p1D",
+        "0X1p1D",
+        "0x1P1D",
+        "0X1P1D",
+
+        "-0x1p1",
+        "-0X1p1",
+        "-0x1P1",
+        "-0X1P1",
+        "-0x1p1f",
+        "-0X1p1f",
+        "-0x1P1f",
+        "-0X1P1f",
+        "-0x1p1F",
+        "-0X1p1F",
+        "-0x1P1F",
+        "-0X1P1F",
+        "-0x1p1d",
+        "-0X1p1d",
+        "-0x1P1d",
+        "-0X1P1d",
+        "-0x1p1D",
+        "-0X1p1D",
+        "-0x1P1D",
+        "-0X1P1D",
+
+        "0x1p-1",
+        "0X1p-1",
+        "0x1P-1",
+        "0X1P-1",
+        "0x1p-1f",
+        "0X1p-1f",
+        "0x1P-1f",
+        "0X1P-1f",
+        "0x1p-1F",
+        "0X1p-1F",
+        "0x1P-1F",
+        "0X1P-1F",
+        "0x1p-1d",
+        "0X1p-1d",
+        "0x1P-1d",
+        "0X1P-1d",
+        "0x1p-1D",
+        "0X1p-1D",
+        "0x1P-1D",
+        "0X1P-1D",
+
+        "-0x1p-1",
+        "-0X1p-1",
+        "-0x1P-1",
+        "-0X1P-1",
+        "-0x1p-1f",
+        "-0X1p-1f",
+        "-0x1P-1f",
+        "-0X1P-1f",
+        "-0x1p-1F",
+        "-0X1p-1F",
+        "-0x1P-1F",
+        "-0X1P-1F",
+        "-0x1p-1d",
+        "-0X1p-1d",
+        "-0x1P-1d",
+        "-0X1P-1d",
+        "-0x1p-1D",
+        "-0X1p-1D",
+        "-0x1P-1D",
+        "-0X1P-1D",
+
+
+        // Try different significand combinations
+        "0xap1",
+        "0xbp1",
+        "0xcp1",
+        "0xdp1",
+        "0xep1",
+        "0xfp1",
+
+        "0x1p1",
+        "0x.1p1",
+        "0x1.1p1",
+
+        "0x001p23",
+        "0x00.1p1",
+        "0x001.1p1",
+
+        "0x100p1",
+        "0x.100p1",
+        "0x1.100p1",
+
+        "0x00100p1",
+        "0x00.100p1",
+        "0x001.100p1"
+    };
+
+    static String paddedBadStrings[];
+    static String paddedGoodStrings[];
+    static {
+        String pad = " \t\n\r\f\u0001\u000b\u001f";
+        paddedBadStrings = new String[badStrings.length];
+        for(int i = 0 ; i <  badStrings.length; i++)
+            paddedBadStrings[i] = pad + badStrings[i] + pad;
+
+        paddedGoodStrings = new String[goodStrings.length];
+        for(int i = 0 ; i <  goodStrings.length; i++)
+            paddedGoodStrings[i] = pad + goodStrings[i] + pad;
+
+    }
+
+
+    /*
+     * Throws an exception if <code>Input</code> is
+     * <code>exceptionalInput</code> and {@link Double.parseDouble
+     * parseDouble} does <em>not</em> throw an exception or if
+     * <code>Input</code> is not <code>exceptionalInput</code> and
+     * <code>parseDouble</code> throws an exception.  This method does
+     * not attempt to test whether the string is converted to the
+     * proper value; just whether the input is accepted appropriately
+     * or not.
+     */
+    private static void testParsing(String [] input,
+                                    boolean exceptionalInput) {
+        for(int i = 0; i < input.length; i++) {
+            double d;
+
+            try {
+                d = Double.parseDouble(input[i]);
+            }
+            catch (NumberFormatException e) {
+                if (! exceptionalInput) {
+                    throw new RuntimeException("Double.parseDouble rejected " +
+                                               "good string `" + input[i] +
+                                               "'.");
+                }
+                break;
+            }
+            if (exceptionalInput) {
+                throw new RuntimeException("Double.parseDouble accepted " +
+                                           "bad string `" + input[i] +
+                                           "'.");
+            }
+        }
+    }
+
+    /*
+     * Throws an exception if <code>Input</code> is
+     * <code>exceptionalInput</code> and the regular expression
+     * matches one of the strings or if <code>Input</code> is not
+     * <code>exceptionalInput</code> and the regular expression fails
+     * to match an input string.
+     */
+    private static void testRegex(String [] input, boolean exceptionalInput) {
+        /*
+         * The regex below is taken from the JavaDoc for
+         * Double.valueOf.
+         */
+
+        final String Digits     = "(\\p{Digit}+)";
+        final String HexDigits  = "(\\p{XDigit}+)";
+        // an exponent is 'e' or 'E' followed by an optionally
+        // signed decimal integer.
+        final String Exp        = "[eE][+-]?"+Digits;
+        final String fpRegex    =
+            ("[\\x00-\\x20]*"+  // Optional leading "whitespace"
+             "[+-]?(" + // Optional sign character
+             "NaN|" +           // "NaN" string
+             "Infinity|" +      // "Infinity" string
+
+             // A floating-point string representing a finite positive
+             // number without a leading sign has at most five basic pieces:
+             // Digits . Digits ExponentPart FloatTypeSuffix
+             //
+             // Since this method allows integer-only strings as input
+             // in addition to strings of floating-point literals, the
+             // two sub-patterns below are simplifications of the grammar
+             // productions from the Java Language Specification, 2nd
+             // edition, section 3.10.2.
+
+
+             // A decimal floating-point string representing a finite positive
+             // number without a leading sign has at most five basic pieces:
+             // Digits . Digits ExponentPart FloatTypeSuffix
+             //
+             // Since this method allows integer-only strings as input
+             // in addition to strings of floating-point literals, the
+             // two sub-patterns below are simplifications of the grammar
+             // productions from the Java Language Specification, 2nd
+             // edition, section 3.10.2.
+
+             // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
+             "(((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+
+
+             // . Digits ExponentPart_opt FloatTypeSuffix_opt
+             "(\\.("+Digits+")("+Exp+")?))|"+
+
+            // Hexadecimal strings
+            "((" +
+             // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
+             "(0[xX]" + HexDigits + "(\\.)?)|" +
+
+             // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt
+             "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +
+
+             ")[pP][+-]?" + Digits + "))" +
+             "[fFdD]?))" +
+             "[\\x00-\\x20]*");// Optional trailing "whitespace"
+        Pattern fpPattern = Pattern.compile(fpRegex);
+
+        for(int i = 0; i < input.length; i++) {
+             Matcher m = fpPattern.matcher(input[i]);
+             if (m.matches() != ! exceptionalInput) {
+                 throw new RuntimeException("Regular expression " +
+                                            (exceptionalInput?
+                                             "accepted bad":
+                                             "rejected good") +
+                                            " string `" +
+                                            input[i] + "'.");
+             }
+        }
+
+    }
+
+    public static void main(String[] args) throws Exception {
+        rudimentaryTest();
+
+        testParsing(goodStrings, false);
+        testParsing(paddedGoodStrings, false);
+        testParsing(badStrings, true);
+        testParsing(paddedBadStrings, true);
+
+        testRegex(goodStrings, false);
+        testRegex(paddedGoodStrings, false);
+        testRegex(badStrings, true);
+        testRegex(paddedBadStrings, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Double/ParseHexFloatingPoint.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,448 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4826774
+ * @summary Numerical tests for hexadecimal inputs to parseDouble, parseFloat
+ * @author Joseph D. Darcy
+ */
+
+
+import java.util.regex.*;
+import sun.misc.FpUtils;
+import sun.misc.DoubleConsts;
+
+public class ParseHexFloatingPoint {
+    private ParseHexFloatingPoint(){}
+
+    public static final double infinityD = Double.POSITIVE_INFINITY;
+    public static final double NaND = Double.NaN;
+
+    static int test(String testName, String input,
+                    double result, double expected) {
+        int failures =0;
+
+        if (Double.compare(result, expected) != 0 ) {
+            System.err.println("Failure for " + testName +
+                               ": For input " + input +
+                               " expected " + expected +
+                               " got " + result + ".");
+        }
+
+        return failures;
+    }
+
+    static int testCase(String input, double expected) {
+        int failures =0;
+
+
+        // Try different combination of letter components
+        input = input.toLowerCase(java.util.Locale.US);
+
+        String [] suffices = {"", "f", "F", "d", "D"};
+        String [] signs = {"", "-", "+"};
+
+        for(int i = 0; i < 2; i++) {
+            String s1 = input;
+            if(i == 1)
+                s1 = s1.replace('x', 'X');
+
+            for(int j = 0; j < 2; j++) {
+                String s2 = s1;
+                if(j == 1)
+                    s2 = s2.replace('p', 'P');
+
+                for(int k = 0; k < 2; k++) {
+                    String s3 = s2;
+                    if(k == 1)
+                        s3 = upperCaseHex(s3);
+
+
+                    for(int m = 0; m < suffices.length; m++) {
+                        String s4 = s3 + suffices[m];
+
+
+                        for(int n = 0; n < signs.length; n++) {
+                            String s5 = signs[n] + s4;
+
+                            double result = Double.parseDouble(s5);
+                            failures += test("Double.parseDouble",
+                                             s5, result, (signs[n].equals("-") ?
+                                                          -expected:
+                                                          expected));
+                        }
+                    }
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    static String upperCaseHex(String s) {
+        return s.replace('a', 'A').replace('b', 'B').replace('c', 'C').
+                 replace('d', 'D').replace('e','E').replace('f', 'F');
+    }
+
+    /*
+     * Test easy and tricky double rounding cases.
+     */
+    static int doubleTests() {
+
+        /*
+         * A String, double pair
+         */
+        class PairSD {
+            public String s;
+            public double d;
+            PairSD(String s, double d) {
+                this.s = s;
+                this.d = d;
+            }
+        }
+        int failures = 0;
+
+
+
+        // Hex strings that convert to three; test basic functionality
+        // of significand and exponent shift adjusts along with the
+        // no-op of adding leading zeros.  These cases don't exercise
+        // the rounding code.
+        String leadingZeros = "0x0000000000000000000";
+        String [] threeTests = {
+            "0x.003p12",
+            "0x.006p11",
+            "0x.00cp10",
+            "0x.018p9",
+
+            "0x.3p4",
+            "0x.6p3",
+            "0x.cp2",
+            "0x1.8p1",
+
+            "0x3p0",
+            "0x6.0p-1",
+            "0xc.0p-2",
+            "0x18.0p-3",
+
+            "0x3000000p-24",
+            "0x3.0p0",
+            "0x3.000000p0",
+        };
+        for(int i=0; i < threeTests.length; i++) {
+            String input = threeTests[i];
+            failures += testCase(input, 3.0);
+
+            input.replaceFirst("^0x", leadingZeros);
+            failures += testCase(input, 3.0);
+        }
+
+        long bigExponents [] = {
+            2*DoubleConsts.MAX_EXPONENT,
+            2*DoubleConsts.MIN_EXPONENT,
+
+            (long)Integer.MAX_VALUE-1,
+            (long)Integer.MAX_VALUE,
+            (long)Integer.MAX_VALUE+1,
+
+            (long)Integer.MIN_VALUE-1,
+            (long)Integer.MIN_VALUE,
+            (long)Integer.MIN_VALUE+1,
+
+            Long.MAX_VALUE-1,
+            Long.MAX_VALUE,
+
+            Long.MIN_VALUE+1,
+            Long.MIN_VALUE,
+        };
+
+        // Test zero significand with large exponents.
+        for(int i = 0; i < bigExponents.length; i++) {
+            failures += testCase("0x0.0p"+Long.toString(bigExponents[i]) , 0.0);
+        }
+
+        // Test nonzero significand with large exponents.
+        for(int i = 0; i < bigExponents.length; i++) {
+            long exponent = bigExponents[i];
+            failures += testCase("0x10000.0p"+Long.toString(exponent) ,
+                                 (exponent <0?0.0:infinityD));
+        }
+
+        // Test significands with different lengths and bit patterns.
+        {
+            long signif = 0;
+                for(int i = 1; i <= 0xe; i++) {
+                    signif = (signif <<4) | (long)i;
+                    failures += testCase("0x"+Long.toHexString(signif)+"p0", signif);
+                }
+        }
+
+        PairSD [] testCases = {
+            new PairSD("0x0.0p0",               0.0/16.0),
+            new PairSD("0x0.1p0",               1.0/16.0),
+            new PairSD("0x0.2p0",               2.0/16.0),
+            new PairSD("0x0.3p0",               3.0/16.0),
+            new PairSD("0x0.4p0",               4.0/16.0),
+            new PairSD("0x0.5p0",               5.0/16.0),
+            new PairSD("0x0.6p0",               6.0/16.0),
+            new PairSD("0x0.7p0",               7.0/16.0),
+            new PairSD("0x0.8p0",               8.0/16.0),
+            new PairSD("0x0.9p0",               9.0/16.0),
+            new PairSD("0x0.ap0",               10.0/16.0),
+            new PairSD("0x0.bp0",               11.0/16.0),
+            new PairSD("0x0.cp0",               12.0/16.0),
+            new PairSD("0x0.dp0",               13.0/16.0),
+            new PairSD("0x0.ep0",               14.0/16.0),
+            new PairSD("0x0.fp0",               15.0/16.0),
+
+            // Half-way case between zero and MIN_VALUE rounds down to
+            // zero
+            new PairSD("0x1.0p-1075",           0.0),
+
+            // Slighly more than half-way case between zero and
+            // MIN_VALUES rounds up to zero.
+            new PairSD("0x1.1p-1075",                   Double.MIN_VALUE),
+            new PairSD("0x1.000000000001p-1075",        Double.MIN_VALUE),
+            new PairSD("0x1.000000000000001p-1075",     Double.MIN_VALUE),
+
+            // More subnormal rounding tests
+            new PairSD("0x0.fffffffffffff7fffffp-1022", FpUtils.nextDown(DoubleConsts.MIN_NORMAL)),
+            new PairSD("0x0.fffffffffffff8p-1022",      DoubleConsts.MIN_NORMAL),
+            new PairSD("0x0.fffffffffffff800000001p-1022",DoubleConsts.MIN_NORMAL),
+            new PairSD("0x0.fffffffffffff80000000000000001p-1022",DoubleConsts.MIN_NORMAL),
+            new PairSD("0x1.0p-1022",                   DoubleConsts.MIN_NORMAL),
+
+
+            // Large value and overflow rounding tests
+            new PairSD("0x1.fffffffffffffp1023",        Double.MAX_VALUE),
+            new PairSD("0x1.fffffffffffff0000000p1023", Double.MAX_VALUE),
+            new PairSD("0x1.fffffffffffff4p1023",       Double.MAX_VALUE),
+            new PairSD("0x1.fffffffffffff7fffffp1023",  Double.MAX_VALUE),
+            new PairSD("0x1.fffffffffffff8p1023",       infinityD),
+            new PairSD("0x1.fffffffffffff8000001p1023", infinityD),
+
+            new PairSD("0x1.ffffffffffffep1023",        FpUtils.nextDown(Double.MAX_VALUE)),
+            new PairSD("0x1.ffffffffffffe0000p1023",    FpUtils.nextDown(Double.MAX_VALUE)),
+            new PairSD("0x1.ffffffffffffe8p1023",       FpUtils.nextDown(Double.MAX_VALUE)),
+            new PairSD("0x1.ffffffffffffe7p1023",       FpUtils.nextDown(Double.MAX_VALUE)),
+            new PairSD("0x1.ffffffffffffeffffffp1023",  Double.MAX_VALUE),
+            new PairSD("0x1.ffffffffffffe8000001p1023", Double.MAX_VALUE),
+        };
+
+        for (int i = 0; i < testCases.length; i++) {
+            failures += testCase(testCases[i].s,testCases[i].d);
+        }
+
+        failures += significandAlignmentTests();
+
+        {
+            java.util.Random rand = new java.util.Random();
+            // Consistency check; double => hexadecimal => double
+            // preserves the original value.
+            for(int i = 0; i < 1000; i++) {
+                double d = rand.nextDouble();
+                failures += testCase(Double.toHexString(d), d);
+            }
+        }
+
+        return failures;
+    }
+
+    /*
+     * Verify rounding works the same regardless of how the
+     * significand is aligned on input.  A useful extension could be
+     * to have this sort of test for strings near the overflow
+     * threshold.
+     */
+    static int significandAlignmentTests() {
+        int failures = 0;
+                // baseSignif * 2^baseExp = nextDown(2.0)
+        long [] baseSignifs = {
+            0x1ffffffffffffe00L,
+            0x1fffffffffffff00L
+        };
+
+        double [] answers = {
+            FpUtils.nextDown(FpUtils.nextDown(2.0)),
+            FpUtils.nextDown(2.0),
+            2.0
+        };
+
+        int baseExp = -60;
+        int count = 0;
+        for(int i = 0; i < 2; i++) {
+            for(long j = 0; j <= 0xfL; j++) {
+                for(long k = 0; k <= 8; k+= 4) { // k = {0, 4, 8}
+                    long base = baseSignifs[i];
+                    long testValue = base | (j<<4) | k;
+
+                    int offset = 0;
+                    // Calculate when significand should be incremented
+                    // see table 4.7 in Koren book
+
+                    if ((base & 0x100L) == 0L ) { // lsb is 0
+                        if ( (j >= 8L) &&         // round is 1
+                             ((j & 0x7L) != 0 || k != 0 ) ) // sticky is 1
+                            offset = 1;
+                    }
+                    else {                        // lsb is 1
+                        if (j >= 8L)              // round is 1
+                            offset = 1;
+                    }
+
+                    double expected = answers[i+offset];
+
+                    for(int m = -2; m <= 3; m++) {
+                        count ++;
+
+                        // Form equal value string and evaluate it
+                        String s = "0x" +
+                            Long.toHexString((m >=0) ?(testValue<<m):(testValue>>(-m))) +
+                            "p" + (baseExp - m);
+
+                        failures += testCase(s, expected);
+                    }
+                }
+            }
+        }
+
+        return failures;
+    }
+
+
+    /*
+     * Test tricky float rounding cases.  The code which
+     * reads in a hex string converts the string to a double value.
+     * If a float value is needed, the double value is cast to float.
+     * However, the cast be itself not always guaranteed to return the
+     * right result since:
+     *
+     * 1. hex string => double can discard a sticky bit which would
+     * influence a direct hex string => float conversion.
+     *
+     * 2. hex string => double => float can have a rounding to double
+     * precision which results in a larger float value while a direct
+     * hex string => float conversion would not round up.
+     *
+     * This method includes tests of the latter two possibilities.
+     */
+    static int floatTests(){
+        int failures = 0;
+
+        /*
+         * A String, float pair
+         */
+        class PairSD {
+            public String s;
+            public float f;
+            PairSD(String s, float f) {
+                this.s = s;
+                this.f = f;
+            }
+        }
+
+        String [][] roundingTestCases = {
+            // Target float value       hard rouding version
+
+            {"0x1.000000p0",    "0x1.0000000000001p0"},
+
+            // Try some values that should round up to nextUp(1.0f)
+            {"0x1.000002p0",    "0x1.0000010000001p0"},
+            {"0x1.000002p0",    "0x1.00000100000008p0"},
+            {"0x1.000002p0",    "0x1.0000010000000fp0"},
+            {"0x1.000002p0",    "0x1.00000100000001p0"},
+            {"0x1.000002p0",    "0x1.00000100000000000000000000000000000000001p0"},
+            {"0x1.000002p0",    "0x1.0000010000000fp0"},
+
+            // Potential double rounding cases
+            {"0x1.000002p0",    "0x1.000002fffffffp0"},
+            {"0x1.000002p0",    "0x1.000002fffffff8p0"},
+            {"0x1.000002p0",    "0x1.000002ffffffffp0"},
+
+            {"0x1.000002p0",    "0x1.000002ffff0ffp0"},
+            {"0x1.000002p0",    "0x1.000002ffff0ff8p0"},
+            {"0x1.000002p0",    "0x1.000002ffff0fffp0"},
+
+
+            {"0x1.000000p0",    "0x1.000000fffffffp0"},
+            {"0x1.000000p0",    "0x1.000000fffffff8p0"},
+            {"0x1.000000p0",    "0x1.000000ffffffffp0"},
+
+            {"0x1.000000p0",    "0x1.000000ffffffep0"},
+            {"0x1.000000p0",    "0x1.000000ffffffe8p0"},
+            {"0x1.000000p0",    "0x1.000000ffffffefp0"},
+
+            // Float subnormal cases
+            {"0x0.000002p-126", "0x0.0000010000001p-126"},
+            {"0x0.000002p-126", "0x0.00000100000000000001p-126"},
+
+            {"0x0.000006p-126", "0x0.0000050000001p-126"},
+            {"0x0.000006p-126", "0x0.00000500000000000001p-126"},
+
+            {"0x0.0p-149",      "0x0.7ffffffffffffffp-149"},
+            {"0x1.0p-148",      "0x1.3ffffffffffffffp-148"},
+            {"0x1.cp-147",      "0x1.bffffffffffffffp-147"},
+
+            {"0x1.fffffcp-127", "0x1.fffffdffffffffp-127"},
+        };
+
+        String [] signs = {"", "-"};
+
+        for(int i = 0; i < roundingTestCases.length; i++) {
+            for(int j = 0; j < signs.length; j++) {
+                String expectedIn = signs[j]+roundingTestCases[i][0];
+                String resultIn   = signs[j]+roundingTestCases[i][1];
+
+                float expected =  Float.parseFloat(expectedIn);
+                float result   =  Float.parseFloat(resultIn);
+
+                if( Float.compare(expected, result) != 0) {
+                    failures += 1;
+                    System.err.println("" + (i+1));
+                    System.err.println("Expected = " + Float.toHexString(expected));
+                    System.err.println("Rounded  = " + Float.toHexString(result));
+                    System.err.println("Double   = " + Double.toHexString(Double.parseDouble(resultIn)));
+                    System.err.println("Input    = " + resultIn);
+                    System.err.println("");
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += doubleTests();
+        failures += floatTests();
+
+        if (failures != 0) {
+            throw new RuntimeException("" + failures + " failures while " +
+                                       "testing hexadecimal floating-point " +
+                                       "parsing.");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Double/ToHexString.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4826774 4926547
+ * @summary Tests for {Float, Double}.toHexString methods
+ * @author Joseph D. Darcy
+ */
+
+import java.util.regex.*;
+import sun.misc.FpUtils;
+import sun.misc.DoubleConsts;
+
+public class ToHexString {
+    private ToHexString() {}
+
+    /*
+     * Given a double value, create a hexadecimal floating-point
+     * string via an intermediate long hex string.
+     */
+    static String doubleToHexString(double d) {
+        return hexLongStringtoHexDoubleString(Long.toHexString(Double.doubleToLongBits(d)));
+    }
+
+    /*
+     * Transform the hexadecimal long output into the equivalent
+     * hexadecimal double value.
+     */
+    static String hexLongStringtoHexDoubleString(String transString) {
+        transString = transString.toLowerCase();
+
+        String zeros = "";
+        StringBuffer result = new StringBuffer(24);
+
+        for(int i = 0; i < (16 - transString.length()); i++, zeros += "0");
+        transString = zeros + transString;
+
+        // assert transString.length == 16;
+
+            char topChar;
+            // Extract sign
+            if((topChar=transString.charAt(0)) >= '8' ) {// 8, 9, a, A, b, B, ...
+                result.append("-");
+                // clear sign bit
+                transString =
+                    Character.toString(Character.forDigit(Character.digit(topChar, 16) - 8, 16)) +
+                    transString.substring(1,16);
+            }
+
+            // check for NaN and infinity
+            String signifString = transString.substring(3,16);
+
+            if( transString.substring(0,3).equals("7ff") ) {
+                if(signifString.equals("0000000000000")) {
+                    result.append("Infinity");
+                }
+                else
+                    result.append("NaN");
+            }
+            else { // finite value
+                // Extract exponent
+                int exponent = Integer.parseInt(transString.substring(0,3), 16) -
+                    DoubleConsts.EXP_BIAS;
+                result.append("0x");
+
+                if (exponent == DoubleConsts.MIN_EXPONENT - 1) { // zero or subnormal
+                    if(signifString.equals("0000000000000")) {
+                        result.append("0.0p0");
+                    }
+                    else {
+                        result.append("0." + signifString.replaceFirst("0+$", "").replaceFirst("^$", "0") +
+                                      "p-1022");
+                    }
+                }
+                else {  // normal value
+                    result.append("1." + signifString.replaceFirst("0+$", "").replaceFirst("^$", "0") +
+                                  "p" + exponent);
+                }
+            }
+            return result.toString();
+    }
+
+    public static int toHexStringTests() {
+        int failures = 0;
+        String [][] testCases1 = {
+            {"Infinity",                "Infinity"},
+            {"-Infinity",               "-Infinity"},
+            {"NaN",                     "NaN"},
+            {"-NaN",                    "NaN"},
+            {"0.0",                     "0x0.0p0"},
+            {"-0.0",                    "-0x0.0p0"},
+            {"1.0",                     "0x1.0p0"},
+            {"-1.0",                    "-0x1.0p0"},
+            {"2.0",                     "0x1.0p1"},
+            {"3.0",                     "0x1.8p1"},
+            {"0.5",                     "0x1.0p-1"},
+            {"0.25",                    "0x1.0p-2"},
+            {"1.7976931348623157e+308", "0x1.fffffffffffffp1023"},      // MAX_VALUE
+            {"2.2250738585072014E-308", "0x1.0p-1022"},                 // MIN_NORMAL
+            {"2.225073858507201E-308",  "0x0.fffffffffffffp-1022"},     // MAX_SUBNORMAL
+            {"4.9e-324",                "0x0.0000000000001p-1022"}      // MIN_VALUE
+        };
+
+        // Compare decimal string -> double -> hex string to hex string
+        for (int i = 0; i < testCases1.length; i++) {
+            String result;
+            if(! (result=Double.toHexString(Double.parseDouble(testCases1[i][0]))).
+               equals(testCases1[i][1])) {
+                failures ++;
+                System.err.println("For floating-point string " + testCases1[i][0] +
+                                   ", expected hex output " + testCases1[i][1] + ", got " + result +".");
+            }
+        }
+
+
+        // Except for float subnormals, the output for numerically
+        // equal float and double values should be the same.
+        // Therefore, we will explicitly test float subnormal values.
+        String [][] floatTestCases = {
+            {"Infinity",                "Infinity"},
+            {"-Infinity",               "-Infinity"},
+            {"NaN",                     "NaN"},
+            {"-NaN",                    "NaN"},
+            {"0.0",                     "0x0.0p0"},
+            {"-0.0",                    "-0x0.0p0"},
+            {"1.0",                     "0x1.0p0"},
+            {"-1.0",                    "-0x1.0p0"},
+            {"2.0",                     "0x1.0p1"},
+            {"3.0",                     "0x1.8p1"},
+            {"0.5",                     "0x1.0p-1"},
+            {"0.25",                    "0x1.0p-2"},
+            {"3.4028235e+38f",          "0x1.fffffep127"},      // MAX_VALUE
+            {"1.17549435E-38f",         "0x1.0p-126"},          // MIN_NORMAL
+            {"1.1754942E-38",           "0x0.fffffep-126"},     // MAX_SUBNORMAL
+            {"1.4e-45f",                "0x0.000002p-126"}      // MIN_VALUE
+        };
+        // Compare decimal string -> double -> hex string to hex string
+        for (int i = 0; i < floatTestCases.length; i++) {
+            String result;
+            if(! (result=Float.toHexString(Float.parseFloat(floatTestCases[i][0]))).
+               equals(floatTestCases[i][1])) {
+                failures++;
+                System.err.println("For floating-point string " + floatTestCases[i][0] +
+                                   ", expected hex output\n" + floatTestCases[i][1] + ", got\n" + result +".");
+            }
+        }
+
+        // Particular floating-point values and hex equivalents, mostly
+        // taken from fdlibm source.
+        String [][] testCases2 = {
+            {"+0.0",                                    "0000000000000000"},
+            {"-0.0",                                    "8000000000000000"},
+            {"+4.9e-324",                               "0000000000000001"},
+            {"-4.9e-324",                               "8000000000000001"},
+
+            // fdlibm k_sin.c
+            {"+5.00000000000000000000e-01",             "3FE0000000000000"},
+            {"-1.66666666666666324348e-01",             "BFC5555555555549"},
+            {"+8.33333333332248946124e-03",             "3F8111111110F8A6"},
+            {"-1.98412698298579493134e-04",             "BF2A01A019C161D5"},
+            {"+2.75573137070700676789e-06",             "3EC71DE357B1FE7D"},
+            {"-2.50507602534068634195e-08",             "BE5AE5E68A2B9CEB"},
+            {"+1.58969099521155010221e-10",             "3DE5D93A5ACFD57C"},
+
+            // fdlibm k_cos.c
+            {"+4.16666666666666019037e-02",             "3FA555555555554C"},
+            {"-1.38888888888741095749e-03",             "BF56C16C16C15177"},
+            {"+2.48015872894767294178e-05",             "3EFA01A019CB1590"},
+            {"-2.75573143513906633035e-07",             "BE927E4F809C52AD"},
+            {"+2.08757232129817482790e-09",             "3E21EE9EBDB4B1C4"},
+            {"-1.13596475577881948265e-11",             "BDA8FAE9BE8838D4"},
+
+            // fdlibm e_rempio.c
+            {"1.67772160000000000000e+07",              "4170000000000000"},
+            {"6.36619772367581382433e-01",              "3FE45F306DC9C883"},
+            {"1.57079632673412561417e+00",              "3FF921FB54400000"},
+            {"6.07710050650619224932e-11",              "3DD0B4611A626331"},
+            {"6.07710050630396597660e-11",              "3DD0B4611A600000"},
+            {"2.02226624879595063154e-21",              "3BA3198A2E037073"},
+            {"2.02226624871116645580e-21",              "3BA3198A2E000000"},
+            {"8.47842766036889956997e-32",              "397B839A252049C1"},
+
+
+            // fdlibm s_cbrt.c
+            {"+5.42857142857142815906e-01",             "3FE15F15F15F15F1"},
+            {"-7.05306122448979611050e-01",             "BFE691DE2532C834"},
+            {"+1.41428571428571436819e+00",             "3FF6A0EA0EA0EA0F"},
+            {"+1.60714285714285720630e+00",             "3FF9B6DB6DB6DB6E"},
+            {"+3.57142857142857150787e-01",             "3FD6DB6DB6DB6DB7"},
+        };
+
+        // Compare decimal string -> double -> hex string to
+        // long hex string -> double hex string
+        for (int i = 0; i < testCases2.length; i++) {
+            String result;
+            String expected;
+            if(! (result=Double.toHexString(Double.parseDouble(testCases2[i][0]))).
+               equals( expected=hexLongStringtoHexDoubleString(testCases2[i][1]) )) {
+                failures ++;
+                System.err.println("For floating-point string " + testCases2[i][0] +
+                                   ", expected hex output " + expected + ", got " + result +".");
+            }
+        }
+
+        // Test random double values;
+        // compare double -> Double.toHexString with local doubleToHexString
+        java.util.Random rand = new java.util.Random(0);
+        for (int i = 0; i < 1000; i++) {
+            String result;
+            String expected;
+            double d = rand.nextDouble();
+            if(! (expected=doubleToHexString(d)).equals(result=Double.toHexString(d)) ) {
+                failures ++;
+                System.err.println("For floating-point value " + d +
+                                   ", expected hex output " + expected + ", got " + result +".");
+            }
+        }
+
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures = toHexStringTests();
+
+        if (failures != 0) {
+            throw new RuntimeException("" + failures + " failures while testing Double.toHexString");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Float/BitwiseConversion.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 5037596
+ * @summary Verify bitwise conversion works for non-canonical NaN values
+ * @author Joseph D. Darcy
+ */
+
+import static java.lang.Float.*;
+import static sun.misc.FloatConsts.*;
+
+public class BitwiseConversion {
+    static int testNanCase(int x) {
+        int errors  = 0;
+        // Strip out sign and exponent bits
+        int y = x & SIGNIF_BIT_MASK;
+
+        float values[] = {
+            intBitsToFloat(EXP_BIT_MASK | y),
+            intBitsToFloat(SIGN_BIT_MASK | EXP_BIT_MASK | y)
+        };
+
+        for(float value: values) {
+            if (!isNaN(value)) {
+                throw new RuntimeException("Invalid input " + y +
+                                           "yielded non-NaN" + value);
+            }
+            int converted = floatToIntBits(value);
+            if (converted != 0x7fc00000) {
+                errors++;
+                System.err.format("Non-canoncial NaN bits returned: %x%n",
+                                  converted);
+            }
+        }
+        return errors;
+    }
+
+    public static void main(String... argv) {
+        int errors = 0;
+
+        for (int i = 0; i < SIGNIFICAND_WIDTH-1; i++) {
+            errors += testNanCase(1<<i);
+        }
+
+        if (floatToIntBits(Float.POSITIVE_INFINITY)
+                != 0x7F800000) {
+            errors++;
+            System.err.println("Bad conversion for +infinity.");
+        }
+
+        if (floatToIntBits(Float.NEGATIVE_INFINITY)
+                != 0xFF800000) {
+            errors++;
+            System.err.println("Bad conversion for -infinity.");
+        }
+
+        if (errors > 0)
+            throw new RuntimeException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Float/Constants.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2001-2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @compile Constants.java
+ * @bug 4397405 4826652
+ * @summary Testing constant-ness of Float.{MIN_VALUE, MAX_VALUE}, etc.
+ * @author Joseph D. Darcy
+ */
+
+public class Constants {
+    /*
+     * This compile-only test is to make sure that the primitive
+     * public static final fields in java.lang.Float are "constant
+     * expressions" as defined by "The Java Language Specification,
+     * 2nd edition" section 15.28; a different test checks the values
+     * of those fields.
+     */
+    public static void main(String[] args) throws Exception {
+        int i = 0;
+        switch (i) {
+        case (int)Float.NaN:                    // 0
+            System.out.println("Float.NaN is a constant!");
+            break;
+        case (int)Float.MIN_VALUE + 1:          // 0 + 1
+            System.out.println("Float.MIN_VALUE is a constant!");
+            break;
+        case (int)Float.MIN_NORMAL + 2:         // 0 + 2
+            System.out.println("Float.MIN_NORMAL is a constant!");
+            break;
+        case Float.MIN_EXPONENT:                // -126
+            System.out.println("Float.MIN_EXPONENT is a constant!");
+            break;
+        case Float.MAX_EXPONENT:                // 127
+            System.out.println("Float.MAX_EXPONENT is a constant!");
+            break;
+        case (int)Float.MAX_VALUE - 1:          // Integer.MAX_VALUE - 1
+            System.out.println("Float.MAX_VALUE is a constant!");
+            break;
+        case (int)Float.POSITIVE_INFINITY:      // Integer.MAX_VALUE
+            System.out.println("Float.POSITIVE_INFINITY is a constant!");
+            break;
+        case (int)Float.NEGATIVE_INFINITY:      // Integer.MIN_VALUE
+            System.out.println("Float.NEGATIVE_INFINITY is a constant!");
+            break;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Float/Extrema.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2001-2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4408489 4826652
+ * @summary Testing values of Float.{MIN_VALUE, MIN_NORMAL, MAX_VALUE}
+ * @author Joseph D. Darcy
+ */
+
+public class Extrema {
+    public static void main(String[] args) throws Exception {
+        if (Float.MIN_VALUE != Float.intBitsToFloat(0x1))
+            throw new RuntimeException("Float.MIN_VALUE is not equal "+
+                                       "to intBitsToFloat(0x1).");
+
+        if (Float.MIN_NORMAL != Float.intBitsToFloat(0x00800000))
+            throw new RuntimeException("Float.MIN_NORMAL is not equal "+
+                                       "to intBitsToFloat(0x00800000).");
+
+        if (Float.MAX_VALUE != Float.intBitsToFloat(0x7f7fffff))
+            throw new RuntimeException("Float.MAX_VALUE is not equal "+
+                                       "to intBitsToFloat(0x7f7fffff).");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Float/NaNInfinityParsing.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2001 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4428772
+ * @summary Testing recognition of "NaN" and "Infinity" strings
+ * @author Joseph D. Darcy
+ */
+
+
+public class NaNInfinityParsing {
+    /*
+     * Regression tests for:
+     * 4428772 -- Establish invariant for Float & Double classes and
+     * their string representations
+     *
+     * Added capability for parse{Float, Double} and related methods
+     * to recognize "NaN" and "Infinity" strings so that
+     * parseFloat(toString(d)) will always return the original
+     * floating-point value.
+     */
+
+    static String NaNStrings[] = {
+        "NaN",
+        "+NaN",
+        "-NaN"
+    };
+
+    static String infinityStrings[] = {
+        "Infinity",
+        "+Infinity",
+        "-Infinity",
+    };
+
+    static String invalidStrings[] = {
+        "+",
+        "-",
+        "@",
+        "N",
+        "Na",
+        "Nan",
+        "NaNf",
+        "NaNd",
+        "NaNF",
+        "NaND",
+        "+N",
+        "+Na",
+        "+Nan",
+        "+NaNf",
+        "+NaNd",
+        "+NaNF",
+        "+NaND",
+        "-N",
+        "-Na",
+        "-Nan",
+        "-NaNf",
+        "-NaNd",
+        "-NaNF",
+        "-NaND",
+        "I",
+        "In",
+        "Inf",
+        "Infi",
+        "Infin",
+        "Infini",
+        "Infinit",
+        "InfinitY",
+        "Infinityf",
+        "InfinityF",
+        "Infinityd",
+        "InfinityD",
+        "+I",
+        "+In",
+        "+Inf",
+        "+Infi",
+        "+Infin",
+        "+Infini",
+        "+Infinit",
+        "+InfinitY",
+        "+Infinityf",
+        "+InfinityF",
+        "+Infinityd",
+        "+InfinityD",
+        "-I",
+        "-In",
+        "-Inf",
+        "-Infi",
+        "-Infin",
+        "-Infini",
+        "-Infinit",
+        "-InfinitY",
+        "-Infinityf",
+        "-InfinityF",
+        "-Infinityd",
+        "-InfinityD",
+        "NaNInfinity",
+        "InfinityNaN",
+        "nan",
+        "infinity"
+    };
+
+    public static void main(String [] argv) throws Exception {
+        int i;
+        float d;
+
+        // Test valid NaN strings
+        for(i = 0; i < NaNStrings.length; i++) {
+            if(!Float.isNaN(d=Float.parseFloat(NaNStrings[i]))) {
+                throw new RuntimeException("NaN string ``" + NaNStrings[i]
+                                           + "'' did not parse as a NaN; returned " +
+                                           d + " instead.");
+            }
+        }
+
+        // Test valid Infinity strings
+        for(i = 0; i < infinityStrings.length; i++) {
+            if(!Float.isInfinite(d=Float.parseFloat(infinityStrings[i]))) {
+                throw new RuntimeException("Infinity string ``" +
+                                           infinityStrings[i] +
+                                           "'' did not parse as infinity; returned " +
+                                           d + "instead.");
+            }
+            // check sign of result
+
+            boolean negative = (infinityStrings[i].charAt(0) == '-');
+            if(d != (negative?Float.NEGATIVE_INFINITY:
+                          Float.POSITIVE_INFINITY))
+                throw new RuntimeException("Infinity has wrong sign;" +
+                                           (negative?"positive instead of negative.":
+                                            "negative instead of positive."));
+        }
+
+        // Test almost valid strings
+        for(i = 0; i < invalidStrings.length; i++) {
+            try {
+                float result;
+                d = Float.parseFloat(invalidStrings[i]);
+                throw new RuntimeException("Invalid string ``" +
+                                           invalidStrings[i]
+                                           +"'' parsed as " + d + ".");
+            }
+            catch(NumberFormatException e) {
+                // expected
+            }
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Float/ParseFloat.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,210 @@
+/*
+ * Copyright 1998-2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4160406 4705734 4707389
+ * @summary Tests for Float.parseFloat method
+ */
+
+public class ParseFloat {
+
+    private static void check(String val, float expected) {
+        float n = Float.parseFloat(val);
+        if (n != expected)
+            throw new RuntimeException("Float.parseFloat failed. String:" +
+                                                val + " Result:" + n);
+    }
+
+    private static void rudimentaryTest() {
+        check(new String(""+Float.MIN_VALUE), Float.MIN_VALUE);
+        check(new String(""+Float.MAX_VALUE), Float.MAX_VALUE);
+
+        check("10",     (float)  10.0);
+        check("10.0",   (float)  10.0);
+        check("10.01",  (float)  10.01);
+
+        check("-10",    (float) -10.0);
+        check("-10.00", (float) -10.0);
+        check("-10.01", (float) -10.01);
+    }
+
+    static  String badStrings[] = {
+        "",
+        "+",
+        "-",
+        "+e",
+        "-e",
+        "+e170",
+        "-e170",
+
+        // Make sure intermediate white space is not deleted.
+        "1234   e10",
+        "-1234   e10",
+
+        // Control characters in the interior of a string are not legal
+        "1\u0007e1",
+        "1e\u00071",
+
+        // NaN and infinity can't have trailing type suffices or exponents
+        "NaNf",
+        "NaNF",
+        "NaNd",
+        "NaND",
+        "-NaNf",
+        "-NaNF",
+        "-NaNd",
+        "-NaND",
+        "+NaNf",
+        "+NaNF",
+        "+NaNd",
+        "+NaND",
+        "Infinityf",
+        "InfinityF",
+        "Infinityd",
+        "InfinityD",
+        "-Infinityf",
+        "-InfinityF",
+        "-Infinityd",
+        "-InfinityD",
+        "+Infinityf",
+        "+InfinityF",
+        "+Infinityd",
+        "+InfinityD",
+
+        "NaNe10",
+        "-NaNe10",
+        "+NaNe10",
+        "Infinitye10",
+        "-Infinitye10",
+        "+Infinitye10",
+
+        // Non-ASCII digits are not recognized
+        "\u0661e\u0661", // 1e1 in Arabic-Indic digits
+        "\u06F1e\u06F1", // 1e1 in Extended Arabic-Indic digits
+        "\u0967e\u0967" // 1e1 in Devanagari digits
+    };
+
+    static String goodStrings[] = {
+        "NaN",
+        "+NaN",
+        "-NaN",
+        "Infinity",
+        "+Infinity",
+        "-Infinity",
+        "1.1e-23f",
+        ".1e-23f",
+        "1e-23",
+        "1f",
+        "1",
+        "2",
+        "1234",
+        "-1234",
+        "+1234",
+        "2147483647",   // Integer.MAX_VALUE
+        "2147483648",
+        "-2147483648",  // Integer.MIN_VALUE
+        "-2147483649",
+
+        "16777215",
+        "16777216",     // 2^24
+        "16777217",
+
+        "-16777215",
+        "-16777216",    // -2^24
+        "-16777217",
+
+        "9007199254740991",
+        "9007199254740992",     // 2^53
+        "9007199254740993",
+
+        "-9007199254740991",
+        "-9007199254740992",    // -2^53
+        "-9007199254740993",
+
+        "9223372036854775807",
+        "9223372036854775808",  // Long.MAX_VALUE
+        "9223372036854775809",
+
+        "-9223372036854775808",
+        "-9223372036854775809", // Long.MIN_VALUE
+        "-9223372036854775810"
+    };
+
+    static String paddedBadStrings[];
+    static String paddedGoodStrings[];
+    static {
+        String pad = " \t\n\r\f\u0001\u000b\u001f";
+        paddedBadStrings = new String[badStrings.length];
+        for(int i = 0 ; i <  badStrings.length; i++)
+            paddedBadStrings[i] = pad + badStrings[i] + pad;
+
+        paddedGoodStrings = new String[goodStrings.length];
+        for(int i = 0 ; i <  goodStrings.length; i++)
+            paddedGoodStrings[i] = pad + goodStrings[i] + pad;
+
+    }
+
+    /*
+     * Throws an exception if <code>Input</code> is
+     * <code>exceptionalInput</code> and {@link Float.parseFloat
+     * parseFloat} does <em>not</em> throw an exception or if
+     * <code>Input</code> is not <code>exceptionalInput</code> and
+     * <code>parseFloat</code> throws an exception.  This method does
+     * not attempt to test whether the string is converted to the
+     * proper value; just whether the input is accepted appropriately
+     * or not.
+     */
+    private static void testParsing(String [] input,
+                                    boolean exceptionalInput) {
+        for(int i = 0; i < input.length; i++) {
+            double d;
+
+            try {
+                d = Float.parseFloat(input[i]);
+            }
+            catch (NumberFormatException e) {
+                if (! exceptionalInput) {
+                    throw new RuntimeException("Float.parseFloat rejected " +
+                                               "good string `" + input[i] +
+                                               "'.");
+                }
+                break;
+            }
+            if (exceptionalInput) {
+                throw new RuntimeException("Float.parseFloat accepted " +
+                                           "bad string `" + input[i] +
+                                           "'.");
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        rudimentaryTest();
+
+        testParsing(goodStrings, false);
+        testParsing(paddedGoodStrings, false);
+        testParsing(badStrings, true);
+        testParsing(paddedBadStrings, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Integer/BitTwiddle.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     4495754
+ * @summary Basic test for int bit twiddling
+ * @author  Josh Bloch
+ *
+ * @compile -source 1.5 BitTwiddle.java
+ * @run main BitTwiddle
+ */
+
+import java.util.Random;
+import static java.lang.Integer.*;
+
+public class BitTwiddle {
+    private static final int N = 1000; // # of repetitions per test
+
+    public static void main(String args[]) {
+        Random rnd = new Random();
+
+        if (highestOneBit(0) != 0)
+            throw new RuntimeException("a");
+        if (highestOneBit(-1) != MIN_VALUE)
+            throw new RuntimeException("b");
+        if (highestOneBit(1) != 1)
+            throw new RuntimeException("c");
+
+        if (lowestOneBit(0) != 0)
+            throw new RuntimeException("d");
+        if (lowestOneBit(-1) != 1)
+            throw new RuntimeException("e");
+        if (lowestOneBit(MIN_VALUE) != MIN_VALUE)
+            throw new RuntimeException("f");
+
+        for (int i = 0; i < N; i++) {
+            int x = rnd.nextInt();
+            if (highestOneBit(x) != reverse(lowestOneBit(reverse(x))))
+                throw new RuntimeException("g: " + toHexString(x));
+        }
+
+        if (numberOfLeadingZeros(0) != SIZE)
+            throw new RuntimeException("h");
+        if (numberOfLeadingZeros(-1) != 0)
+            throw new RuntimeException("i");
+        if (numberOfLeadingZeros(1) != (SIZE - 1))
+            throw new RuntimeException("j");
+
+        if (numberOfTrailingZeros(0) != SIZE)
+            throw new RuntimeException("k");
+        if (numberOfTrailingZeros(1) != 0)
+            throw new RuntimeException("l");
+        if (numberOfTrailingZeros(MIN_VALUE) != (SIZE - 1))
+            throw new RuntimeException("m");
+
+        for (int i = 0; i < N; i++) {
+            int x = rnd.nextInt();
+            if (numberOfLeadingZeros(x) != numberOfTrailingZeros(reverse(x)))
+                throw new RuntimeException("n: " + toHexString(x));
+        }
+
+        if (bitCount(0) != 0)
+                throw new RuntimeException("o");
+
+        for (int i = 0; i < SIZE; i++) {
+            int pow2 = 1 << i;
+            if (bitCount(pow2) != 1)
+                throw new RuntimeException("p: " + i);
+            if (bitCount(pow2 -1) != i)
+                throw new RuntimeException("q: " + i);
+        }
+
+        for (int i = 0; i < N; i++) {
+            int x = rnd.nextInt();
+            if (bitCount(x) != bitCount(reverse(x)))
+                throw new RuntimeException("r: " + toHexString(x));
+        }
+
+        for (int i = 0; i < N; i++) {
+            int x = rnd.nextInt();
+            int dist = rnd.nextInt();
+            if (bitCount(x) != bitCount(rotateRight(x, dist)))
+                throw new RuntimeException("s: " + toHexString(x) +
+                                           toHexString(dist));
+            if (bitCount(x) != bitCount(rotateLeft(x, dist)))
+                throw new RuntimeException("t: " + toHexString(x) +
+                                           toHexString(dist));
+            if (rotateRight(x, dist) != rotateLeft(x, -dist))
+                throw new RuntimeException("u: " + toHexString(x) +
+                                           toHexString(dist));
+            if (rotateRight(x, -dist) != rotateLeft(x, dist))
+                throw new RuntimeException("v: " + toHexString(x) +
+                                           toHexString(dist));
+        }
+
+        if (signum(0) != 0 || signum(1) != 1 || signum(-1) != -1
+            || signum(MIN_VALUE) != -1 || signum(MAX_VALUE) != 1)
+            throw new RuntimeException("w");
+
+        for (int i = 0; i < N; i++) {
+            int x = rnd.nextInt();
+            int sign = (x < 0 ? -1 : (x == 0 ? 0 : 1));
+            if (signum(x) != sign)
+                throw new RuntimeException("x: " + toHexString(x));
+        }
+
+        if(reverseBytes(0xaabbccdd) != 0xddccbbaa)
+            throw new RuntimeException("y");
+
+        for (int i = 0; i < N; i++) {
+            int x = rnd.nextInt();
+            if (bitCount(x) != bitCount(reverseBytes(x)))
+                throw new RuntimeException("z: " + toHexString(x));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Integer/Decode.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2006 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4136371 5017980 6576055
+ * @summary Test Integer.decode method
+ * @author madbot
+ * @author Joseph D. Darcy
+ */
+
+/**
+ * There are six methods in java.lang.Integer which transform strings
+ * into an int or Integer value:
+ *
+ * public Integer(String s)
+ * public static Integer decode(String nm)
+ * public static int parseInteger(String s, int radix)
+ * public static int parseInteger(String s)
+ * public static Integer valueOf(String s, int radix)
+ * public static Integer valueOf(String s)
+ *
+ * The other five methods are tested elsewhere.
+ */
+public class Decode {
+
+    private static void check(String val, int expected) {
+        int n = (Integer.decode(val)).intValue();
+        if (n != expected)
+            throw new RuntimeException("Integer.decode failed. String:" +
+                                                val + " Result:" + n);
+    }
+
+    private static void checkFailure(String val, String message) {
+        try {
+            int n = (Integer.decode(val)).intValue();
+            throw new RuntimeException(message);
+        } catch (NumberFormatException e) { /* Okay */}
+    }
+
+    public static void main(String[] args) throws Exception {
+        check(new String(""+Integer.MIN_VALUE), Integer.MIN_VALUE);
+        check(new String(""+Integer.MAX_VALUE), Integer.MAX_VALUE);
+
+        check("10",   10);
+        check("0x10", 16);
+        check("0X10", 16);
+        check("010",  8);
+        check("#10",  16);
+
+        check("+10",   10);
+        check("+0x10", 16);
+        check("+0X10", 16);
+        check("+010",  8);
+        check("+#10",  16);
+
+        check("-10",   -10);
+        check("-0x10", -16);
+        check("-0X10", -16);
+        check("-010",  -8);
+        check("-#10",  -16);
+
+        check(Long.toString(Integer.MIN_VALUE), Integer.MIN_VALUE);
+        check(Long.toString(Integer.MAX_VALUE), Integer.MAX_VALUE);
+
+        checkFailure("0x-10",   "Integer.decode allows negative sign in wrong position.");
+        checkFailure("0x+10",   "Integer.decode allows positive sign in wrong position.");
+
+        checkFailure("+",       "Raw plus sign allowed.");
+        checkFailure("-",       "Raw minus sign allowed.");
+
+        checkFailure(Long.toString((long)Integer.MIN_VALUE - 1L), "Out of range");
+        checkFailure(Long.toString((long)Integer.MAX_VALUE + 1L), "Out of range");
+
+        checkFailure("", "Empty String");
+
+        try {
+            Integer.decode(null);
+            throw new RuntimeException("Integer.decode(null) expected to throw NPE");
+        } catch (NullPointerException npe) {/* Okay */}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Integer/GetInteger.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1999 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4252315
+ * @summary test Integer.getInteger method with empty key
+ */
+
+public class GetInteger {
+    public static void main(String[] args) throws Exception {
+        Integer.getInteger("", 1);
+        Integer.getInteger(null, 1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Integer/ParsingTest.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2006-2007 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 5017980 6576055
+ * @summary Test parsing methods
+ * @author Joseph D. Darcy
+ */
+
+
+/**
+ * There are six methods in java.lang.Integer which transform strings
+ * into an int or Integer value:
+ *
+ * public Integer(String s)
+ * public static Integer decode(String nm)
+ * public static int parseInt(String s, int radix)
+ * public static int parseInt(String s)
+ * public static Integer valueOf(String s, int radix)
+ * public static Integer valueOf(String s)
+ *
+ * Besides decode, all the methods and constructor call down into
+ * parseInt(String, int) to do the actual work.  Therefore, the
+ * behavior of parseInt(String, int) will be tested here.
+ */
+
+public class ParsingTest {
+    public static void main(String... argv) {
+        check("+100", +100);
+        check("-100", -100);
+
+        check("+0", 0);
+        check("-0", 0);
+        check("+00000", 0);
+        check("-00000", 0);
+
+        check("0", 0);
+        check("1", 1);
+        check("9", 9);
+
+        checkFailure("\u0000");
+        checkFailure("\u002f");
+        checkFailure("+");
+        checkFailure("-");
+        checkFailure("++");
+        checkFailure("+-");
+        checkFailure("-+");
+        checkFailure("--");
+        checkFailure("++100");
+        checkFailure("--100");
+        checkFailure("+-6");
+        checkFailure("-+6");
+        checkFailure("*100");
+    }
+
+    private static void check(String val, int expected) {
+        int n = Integer.parseInt(val);
+        if (n != expected)
+            throw new RuntimeException("Integer.parsedInt failed. String:" +
+                                                val + " Result:" + n);
+    }
+
+    private static void checkFailure(String val) {
+        int n = 0;
+        try {
+            n = Integer.parseInt(val);
+            System.err.println("parseInt(" + val + ") incorrectly returned " + n);
+            throw new RuntimeException();
+        } catch (NumberFormatException nfe) {
+            ; // Expected
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Long/BitTwiddle.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     4495754
+ * @summary Basic test for long bit twiddling
+ * @author  Josh Bloch
+ *
+ * @compile -source 1.5 BitTwiddle.java
+ * @run main BitTwiddle
+ */
+
+import java.util.Random;
+import static java.lang.Long.*;
+
+public class BitTwiddle {
+    private static final int N = 1000; // # of repetitions per test
+
+    public static void main(String args[]) {
+        Random rnd = new Random();
+
+        if (highestOneBit(0) != 0)
+            throw new RuntimeException("a");
+        if (highestOneBit(-1) != MIN_VALUE)
+            throw new RuntimeException("b");
+        if (highestOneBit(1) != 1)
+            throw new RuntimeException("c");
+
+        if (lowestOneBit(0) != 0)
+            throw new RuntimeException("d");
+        if (lowestOneBit(-1) != 1)
+            throw new RuntimeException("e");
+        if (lowestOneBit(MIN_VALUE) != MIN_VALUE)
+            throw new RuntimeException("f");
+
+        for (int i = 0; i < N; i++) {
+            long x = rnd.nextLong();
+            if (highestOneBit(x) != reverse(lowestOneBit(reverse(x))))
+                throw new RuntimeException("g: " + toHexString(x));
+        }
+
+        if (numberOfLeadingZeros(0) != SIZE)
+            throw new RuntimeException("h");
+        if (numberOfLeadingZeros(-1) != 0)
+            throw new RuntimeException("i");
+        if (numberOfLeadingZeros(1) != (SIZE - 1))
+            throw new RuntimeException("j");
+
+        if (numberOfTrailingZeros(0) != SIZE)
+            throw new RuntimeException("k");
+        if (numberOfTrailingZeros(1) != 0)
+            throw new RuntimeException("l");
+        if (numberOfTrailingZeros(MIN_VALUE) != (SIZE - 1))
+            throw new RuntimeException("m");
+
+        for (int i = 0; i < N; i++) {
+            long x = rnd.nextLong();
+            if (numberOfLeadingZeros(x) != numberOfTrailingZeros(reverse(x)))
+                throw new RuntimeException("n: " + toHexString(x));
+        }
+
+        if (bitCount(0) != 0)
+                throw new RuntimeException("o");
+
+        for (int i = 0; i < SIZE; i++) {
+            long pow2 = 1L << i;
+            if (bitCount(pow2) != 1)
+                throw new RuntimeException("p: " + i);
+            if (bitCount(pow2 -1) != i)
+                throw new RuntimeException("q: " + i);
+        }
+
+        for (int i = 0; i < N; i++) {
+            long x = rnd.nextLong();
+            if (bitCount(x) != bitCount(reverse(x)))
+                throw new RuntimeException("r: " + toHexString(x));
+        }
+
+        for (int i = 0; i < N; i++) {
+            long x = rnd.nextLong();
+            int dist = rnd.nextInt();
+            if (bitCount(x) != bitCount(rotateRight(x, dist)))
+                throw new RuntimeException("s: " + toHexString(x) +
+                                           toHexString(dist));
+            if (bitCount(x) != bitCount(rotateLeft(x, dist)))
+                throw new RuntimeException("t: " + toHexString(x) +
+                                           toHexString(dist));
+            if (rotateRight(x, dist) != rotateLeft(x, -dist))
+                throw new RuntimeException("u: " + toHexString(x) +
+                                           toHexString(dist));
+            if (rotateRight(x, -dist) != rotateLeft(x, dist))
+                throw new RuntimeException("v: " + toHexString(x) +
+                                           toHexString(dist));
+        }
+
+        if (signum(0) != 0 || signum(1) != 1 || signum(-1) != -1
+            || signum(MIN_VALUE) != -1 || signum(MAX_VALUE) != 1)
+            throw new RuntimeException("w");
+
+        for (int i = 0; i < N; i++) {
+            long x = rnd.nextLong();
+            int sign = (x < 0 ? -1 : (x == 0 ? 0 : 1));
+            if (signum(x) != sign)
+                throw new RuntimeException("x: " + toHexString(x));
+        }
+
+        if(reverseBytes(0xaabbccdd11223344L) != 0x44332211ddccbbaaL)
+            throw new RuntimeException("y");
+
+        for (int i = 0; i < N; i++) {
+            long x = rnd.nextLong();
+            if (bitCount(x) != bitCount(reverseBytes(x)))
+                throw new RuntimeException("z: " + toHexString(x));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Long/Decode.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,106 @@
+/*
+ * Copyright 1998-2006 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4136371 5017980 6576055
+ * @summary Test Long.decode method
+ * @author madbot
+ * @author Joseph D. Darcy
+ */
+
+import java.math.BigInteger;
+
+/**
+ * There are six methods in java.lang.Integer which transform strings
+ * into a long or Long value:
+ *
+ * public Long(String s)
+ * public static Long decode(String nm)
+ * public static long parseLong(String s, int radix)
+ * public static long parseLong(String s)
+ * public static Long valueOf(String s, int radix)
+ * public static Long valueOf(String s)
+ *
+ * The other five methods are tested elsewhere.
+ */
+public class Decode {
+
+    private static void check(String val, long expected) {
+        long n = (Long.decode(val)).longValue();
+        if (n != expected)
+            throw new RuntimeException("Long.decode failed. String:" +
+                                                val + " Result:" + n);
+    }
+
+    private static void checkFailure(String val, String message) {
+        try {
+            long n = (Long.decode(val)).longValue();
+            throw new RuntimeException(message);
+        } catch (NumberFormatException e) { /* Okay */}
+    }
+
+    public static void main(String[] args) throws Exception {
+        check(new String(""+Long.MIN_VALUE), Long.MIN_VALUE);
+        check(new String(""+Long.MAX_VALUE), Long.MAX_VALUE);
+
+        check("10",   10L);
+        check("0x10", 16L);
+        check("0X10", 16L);
+        check("010",  8L);
+        check("#10",  16L);
+
+        check("+10",   10L);
+        check("+0x10", 16L);
+        check("+0X10", 16L);
+        check("+010",  8L);
+        check("+#10",  16L);
+
+        check("-10",   -10L);
+        check("-0x10", -16L);
+        check("-0X10", -16L);
+        check("-010",  -8L);
+        check("-#10",  -16L);
+
+        check(Long.toString(Long.MIN_VALUE), Long.MIN_VALUE);
+        check(Long.toString(Long.MAX_VALUE), Long.MAX_VALUE);
+
+        checkFailure("0x-10",   "Long.decode allows negative sign in wrong position.");
+        checkFailure("0x+10",   "Long.decode allows positive sign in wrong position.");
+
+        checkFailure("+",       "Raw plus sign allowed.");
+        checkFailure("-",       "Raw minus sign allowed.");
+
+        checkFailure(BigInteger.valueOf(Long.MIN_VALUE).subtract(BigInteger.ONE).toString(),
+                     "Out of range");
+        checkFailure(BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE).toString(),
+                     "Out of range");
+
+        checkFailure("", "Empty String");
+
+        try {
+            Long.decode(null);
+            throw new RuntimeException("Long.decode(null) expected to throw NPE");
+        } catch (NullPointerException npe) {/* Okay */}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Long/GetLong.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1999 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4252322
+ * @summary test Long.getLong method with empty key
+ */
+
+public class GetLong {
+    public static void main(String[] args) throws Exception {
+        Long.getLong("", 1);
+        Long.getLong(null, 1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Long/ParsingTest.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2006-2007 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 5017980 6576055
+ * @summary Test parsing methods
+ * @author Joseph D. Darcy
+ */
+
+
+/**
+ * There are six methods in java.lang.Long which transform strings
+ * into a long or Long value:
+ *
+ * public Long(String s)
+ * public static Long decode(String nm)
+ * public static long parseLong(String s, int radix)
+ * public static long parseLong(String s)
+ * public static Long valueOf(String s, int radix)
+ * public static Long valueOf(String s)
+ *
+ * Besides decode, all the methods and constructor call down into
+ * parseLong(String, int) to do the actual work.  Therefore, the
+ * behavior of parseLong(String, int) will be tested here.
+ */
+
+public class ParsingTest {
+    public static void main(String... argv) {
+        check("+100", +100L);
+        check("-100", -100L);
+
+        check("+0", 0L);
+        check("-0", 0L);
+        check("+00000", 0L);
+        check("-00000", 0L);
+
+        check("0", 0L);
+        check("1", 1L);
+        check("9", 9L);
+
+        checkFailure("\u0000");
+        checkFailure("\u002f");
+        checkFailure("+");
+        checkFailure("-");
+        checkFailure("++");
+        checkFailure("+-");
+        checkFailure("-+");
+        checkFailure("--");
+        checkFailure("++100");
+        checkFailure("--100");
+        checkFailure("+-6");
+        checkFailure("-+6");
+        checkFailure("*100");
+    }
+
+    private static void check(String val, long expected) {
+        long n = Long.parseLong(val);
+        if (n != expected)
+            throw new RuntimeException("Long.parsedLong failed. String:" +
+                                       val + " Result:" + n);
+    }
+
+    private static void checkFailure(String val) {
+        long n = 0L;
+        try {
+            n = Long.parseLong(val);
+            System.err.println("parseLong(" + val + ") incorrectly returned " + n);
+            throw new RuntimeException();
+        } catch (NumberFormatException nfe) {
+            ; // Expected
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/AbsPositiveZero.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1998 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @bug 4096278
+   @summary Math.abs(+0.0) wrong
+   @author Anand Palaniswamy
+ */
+public class AbsPositiveZero {
+    private static boolean isPositiveZero(float f) {
+        return Float.floatToIntBits(f) == Float.floatToIntBits(0.0f);
+    }
+
+    private static boolean isPositiveZero(double d) {
+        return Double.doubleToLongBits(d) == Double.doubleToLongBits(0.0d);
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (!isPositiveZero(Math.abs(-0.0d))) {
+            throw new Exception("abs(-0.0d) failed");
+        }
+        if (!isPositiveZero(Math.abs(+0.0d))) {
+            throw new Exception("abs(+0.0d) failed");
+        }
+        if (Math.abs(Double.POSITIVE_INFINITY) != Double.POSITIVE_INFINITY) {
+            throw new Exception("abs(+Inf) failed");
+        }
+        if (Math.abs(Double.NEGATIVE_INFINITY) != Double.POSITIVE_INFINITY) {
+            throw new Exception("abs(-Inf) failed");
+        }
+        double dnanval = Math.abs(Double.NaN);
+        if (dnanval == dnanval) {
+            throw new Exception("abs(NaN) failed");
+        }
+
+        if (!isPositiveZero(Math.abs(-0.0f))) {
+            throw new Exception("abs(-0.0f) failed");
+        }
+        if (!isPositiveZero(Math.abs(+0.0f))) {
+            throw new Exception("abs(+0.0f) failed");
+        }
+        if (Math.abs(Float.POSITIVE_INFINITY) != Float.POSITIVE_INFINITY) {
+            throw new Exception("abs(+Inf) failed");
+        }
+        if (Math.abs(Float.NEGATIVE_INFINITY) != Float.POSITIVE_INFINITY) {
+            throw new Exception("abs(-Inf) failed");
+        }
+        float fnanval = Math.abs(Float.NaN);
+        if (fnanval == fnanval) {
+            throw new Exception("abs(NaN) failed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/Atan2Tests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4984407
+ * @summary Tests for {Math, StrictMath}.atan2
+ * @compile -source 1.5 Atan2Tests.java
+ * @run main Atan2Tests
+ * @author Joseph D. Darcy
+ */
+
+public class Atan2Tests {
+    private Atan2Tests(){}
+
+    static int testAtan2Case(double input1, double input2, double expected) {
+        int failures = 0;
+        failures += Tests.test("StrictMath.atan2(double, double)", input1, input2,
+                               StrictMath.atan2(input1, input2), expected);
+        failures += Tests.test("Math.atan2(double, double)", input1, input2,
+                               Math.atan2(input1, input2), expected);
+
+        return failures;
+    }
+
+    static int testAtan2() {
+        int failures = 0;
+
+        double [][] testCases = {
+            {-3.0,      Double.POSITIVE_INFINITY,       -0.0},
+        };
+
+        for (double[] testCase : testCases) {
+            failures+=testAtan2Case(testCase[0], testCase[1], testCase[2]);
+        }
+
+        return failures;
+    }
+
+    public static void main(String [] argv) {
+        int failures = 0;
+
+        failures += testAtan2();
+
+        if (failures > 0) {
+            System.err.println("Testing atan2 incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/CubeRootTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4347132 4939441
+ * @summary Tests for {Math, StrictMath}.cbrt
+ * @author Joseph D. Darcy
+ */
+
+import sun.misc.FpUtils;
+import sun.misc.DoubleConsts;
+
+public class CubeRootTests {
+    private CubeRootTests(){}
+
+    static final double infinityD = Double.POSITIVE_INFINITY;
+    static final double NaNd = Double.NaN;
+
+    // Initialize shared random number generator
+    static java.util.Random rand = new java.util.Random();
+
+    static int testCubeRootCase(double input, double expected) {
+        int failures=0;
+
+        double minus_input = -input;
+        double minus_expected = -expected;
+
+        failures+=Tests.test("Math.cbrt(double)", input,
+                             Math.cbrt(input), expected);
+        failures+=Tests.test("Math.cbrt(double)", minus_input,
+                             Math.cbrt(minus_input), minus_expected);
+        failures+=Tests.test("StrictMath.cbrt(double)", input,
+                             StrictMath.cbrt(input), expected);
+        failures+=Tests.test("StrictMath.cbrt(double)", minus_input,
+                             StrictMath.cbrt(minus_input), minus_expected);
+
+        return failures;
+    }
+
+    static int testCubeRoot() {
+        int failures = 0;
+        double [][] testCases = {
+            {NaNd,                      NaNd},
+            {Double.longBitsToDouble(0x7FF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0xFFF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0x7FF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0xFFF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0x7FFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0x7FFCafeBabe00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFCafeBabe00000L),      NaNd},
+            {Double.POSITIVE_INFINITY,  Double.POSITIVE_INFINITY},
+            {Double.NEGATIVE_INFINITY,  Double.NEGATIVE_INFINITY},
+            {+0.0,                      +0.0},
+            {-0.0,                      -0.0},
+            {+1.0,                      +1.0},
+            {-1.0,                      -1.0},
+            {+8.0,                      +2.0},
+            {-8.0,                      -2.0}
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            failures += testCubeRootCase(testCases[i][0],
+                                         testCases[i][1]);
+        }
+
+        // Test integer perfect cubes less than 2^53.
+        for(int i = 0; i <= 208063; i++) {
+            double d = i;
+            failures += testCubeRootCase(d*d*d, (double)i);
+        }
+
+        // Test cbrt(2^(3n)) = 2^n.
+        for(int i = 18; i <= DoubleConsts.MAX_EXPONENT/3; i++) {
+            failures += testCubeRootCase(FpUtils.scalb(1.0, 3*i),
+                                         FpUtils.scalb(1.0, i) );
+        }
+
+        // Test cbrt(2^(-3n)) = 2^-n.
+        for(int i = -1; i >= FpUtils.ilogb(Double.MIN_VALUE)/3; i--) {
+            failures += testCubeRootCase(FpUtils.scalb(1.0, 3*i),
+                                         FpUtils.scalb(1.0, i) );
+        }
+
+        // Test random perfect cubes.  Create double values with
+        // modest exponents but only have at most the 17 most
+        // significant bits in the significand set; 17*3 = 51, which
+        // is less than the number of bits in a double's significand.
+        long exponentBits1 =
+            Double.doubleToLongBits(FpUtils.scalb(1.0, 55)) &
+            DoubleConsts.EXP_BIT_MASK;
+        long exponentBits2=
+            Double.doubleToLongBits(FpUtils.scalb(1.0, -55)) &
+            DoubleConsts.EXP_BIT_MASK;
+        for(int i = 0; i < 100; i++) {
+            // Take 16 bits since the 17th bit is implicit in the
+            // exponent
+           double input1 =
+               Double.longBitsToDouble(exponentBits1 |
+                                       // Significand bits
+                                       ((long) (rand.nextInt() & 0xFFFF))<<
+                                       (DoubleConsts.SIGNIFICAND_WIDTH-1-16));
+           failures += testCubeRootCase(input1*input1*input1, input1);
+
+           double input2 =
+               Double.longBitsToDouble(exponentBits2 |
+                                       // Significand bits
+                                       ((long) (rand.nextInt() & 0xFFFF))<<
+                                       (DoubleConsts.SIGNIFICAND_WIDTH-1-16));
+           failures += testCubeRootCase(input2*input2*input2, input2);
+        }
+
+        // Directly test quality of implementation properties of cbrt
+        // for values that aren't perfect cubes.  Verify returned
+        // result meets the 1 ulp test.  That is, we want to verify
+        // that for positive x > 1,
+        // y = cbrt(x),
+        //
+        // if (err1=x - y^3 ) < 0, abs((y_pp^3 -x )) < err1
+        // if (err1=x - y^3 ) > 0, abs((y_mm^3 -x )) < err1
+        //
+        // where y_mm and y_pp are the next smaller and next larger
+        // floating-point value to y.  In other words, if y^3 is too
+        // big, making y larger does not improve the result; likewise,
+        // if y^3 is too small, making y smaller does not improve the
+        // result.
+        //
+        // ...-----|--?--|--?--|-----... Where is the true result?
+        //         y_mm  y     y_pp
+        //
+        // The returned value y should be one of the floating-point
+        // values braketing the true result.  However, given y, a
+        // priori we don't know if the true result falls in [y_mm, y]
+        // or [y, y_pp].  The above test looks at the error in x-y^3
+        // to determine which region the true result is in; e.g. if
+        // y^3 is smaller than x, the true result should be in [y,
+        // y_pp].  Therefore, it would be an error for y_mm to be a
+        // closer approximation to x^(1/3).  In this case, it is
+        // permissible, although not ideal, for y_pp^3 to be a closer
+        // approximation to x^(1/3) than y^3.
+        //
+        // We will use pow(y,3) to compute y^3.  Although pow is not
+        // correctly rounded, StrictMath.pow should have at most 1 ulp
+        // error.  For y > 1, pow(y_mm,3) and pow(y_pp,3) will differ
+        // from pow(y,3) by more than one ulp so the comparision of
+        // errors should still be valid.
+
+        for(int i = 0; i < 1000; i++) {
+            double d = 1.0 + rand.nextDouble();
+            double err, err_adjacent;
+
+            double y1 = Math.cbrt(d);
+            double y2 = StrictMath.cbrt(d);
+
+            err = d - StrictMath.pow(y1, 3);
+            if (err != 0.0) {
+                if(FpUtils.isNaN(err)) {
+                    failures++;
+                    System.err.println("Encountered unexpected NaN value: d = " + d +
+                                       "\tcbrt(d) = " + y1);
+                } else {
+                    if (err < 0.0) {
+                        err_adjacent = StrictMath.pow(FpUtils.nextUp(y1), 3) - d;
+                    }
+                    else  { // (err > 0.0)
+                        err_adjacent = StrictMath.pow(FpUtils.nextAfter(y1,0.0), 3) - d;
+                    }
+
+                    if (Math.abs(err) > Math.abs(err_adjacent)) {
+                        failures++;
+                        System.err.println("For Math.cbrt(" + d + "), returned result " +
+                                           y1 + "is not as good as adjacent value.");
+                    }
+                }
+            }
+
+
+            err = d - StrictMath.pow(y2, 3);
+            if (err != 0.0) {
+                if(FpUtils.isNaN(err)) {
+                    failures++;
+                    System.err.println("Encountered unexpected NaN value: d = " + d +
+                                       "\tcbrt(d) = " + y2);
+                } else {
+                    if (err < 0.0) {
+                        err_adjacent = StrictMath.pow(FpUtils.nextUp(y2), 3) - d;
+                    }
+                    else  { // (err > 0.0)
+                        err_adjacent = StrictMath.pow(FpUtils.nextAfter(y2,0.0), 3) - d;
+                    }
+
+                    if (Math.abs(err) > Math.abs(err_adjacent)) {
+                        failures++;
+                        System.err.println("For StrictMath.cbrt(" + d + "), returned result " +
+                                           y2 + "is not as good as adjacent value.");
+                    }
+                }
+            }
+
+
+        }
+
+        // Test monotonicity properites near perfect cubes; test two
+        // numbers before and two numbers after; i.e. for
+        //
+        // pcNeighbors[] =
+        // {nextDown(nextDown(pc)),
+        // nextDown(pc),
+        // pc,
+        // nextUp(pc),
+        // nextUp(nextUp(pc))}
+        //
+        // test that cbrt(pcNeighbors[i]) <= cbrt(pcNeighbors[i+1])
+        {
+
+            double pcNeighbors[] = new double[5];
+            double pcNeighborsCbrt[] = new double[5];
+            double pcNeighborsStrictCbrt[] = new double[5];
+
+            // Test near cbrt(2^(3n)) = 2^n.
+            for(int i = 18; i <= DoubleConsts.MAX_EXPONENT/3; i++) {
+                double pc = FpUtils.scalb(1.0, 3*i);
+
+                pcNeighbors[2] = pc;
+                pcNeighbors[1] = FpUtils.nextDown(pc);
+                pcNeighbors[0] = FpUtils.nextDown(pcNeighbors[1]);
+                pcNeighbors[3] = FpUtils.nextUp(pc);
+                pcNeighbors[4] = FpUtils.nextUp(pcNeighbors[3]);
+
+                for(int j = 0; j < pcNeighbors.length; j++) {
+                    pcNeighborsCbrt[j] =           Math.cbrt(pcNeighbors[j]);
+                    pcNeighborsStrictCbrt[j] = StrictMath.cbrt(pcNeighbors[j]);
+                }
+
+                for(int j = 0; j < pcNeighborsCbrt.length-1; j++) {
+                    if(pcNeighborsCbrt[j] >  pcNeighborsCbrt[j+1] ) {
+                        failures++;
+                        System.err.println("Monotonicity failure for Math.cbrt on " +
+                                          pcNeighbors[j] + " and "  +
+                                          pcNeighbors[j+1] + "\n\treturned " +
+                                          pcNeighborsCbrt[j] + " and " +
+                                          pcNeighborsCbrt[j+1] );
+                    }
+
+                    if(pcNeighborsStrictCbrt[j] >  pcNeighborsStrictCbrt[j+1] ) {
+                        failures++;
+                        System.err.println("Monotonicity failure for StrictMath.cbrt on " +
+                                          pcNeighbors[j] + " and "  +
+                                          pcNeighbors[j+1] + "\n\treturned " +
+                                          pcNeighborsStrictCbrt[j] + " and " +
+                                          pcNeighborsStrictCbrt[j+1] );
+                    }
+
+
+                }
+
+            }
+
+            // Test near cbrt(2^(-3n)) = 2^-n.
+            for(int i = -1; i >= FpUtils.ilogb(Double.MIN_VALUE)/3; i--) {
+                double pc = FpUtils.scalb(1.0, 3*i);
+
+                pcNeighbors[2] = pc;
+                pcNeighbors[1] = FpUtils.nextDown(pc);
+                pcNeighbors[0] = FpUtils.nextDown(pcNeighbors[1]);
+                pcNeighbors[3] = FpUtils.nextUp(pc);
+                pcNeighbors[4] = FpUtils.nextUp(pcNeighbors[3]);
+
+                for(int j = 0; j < pcNeighbors.length; j++) {
+                    pcNeighborsCbrt[j] =           Math.cbrt(pcNeighbors[j]);
+                    pcNeighborsStrictCbrt[j] = StrictMath.cbrt(pcNeighbors[j]);
+                }
+
+                for(int j = 0; j < pcNeighborsCbrt.length-1; j++) {
+                    if(pcNeighborsCbrt[j] >  pcNeighborsCbrt[j+1] ) {
+                        failures++;
+                        System.err.println("Monotonicity failure for Math.cbrt on " +
+                                          pcNeighbors[j] + " and "  +
+                                          pcNeighbors[j+1] + "\n\treturned " +
+                                          pcNeighborsCbrt[j] + " and " +
+                                          pcNeighborsCbrt[j+1] );
+                    }
+
+                    if(pcNeighborsStrictCbrt[j] >  pcNeighborsStrictCbrt[j+1] ) {
+                        failures++;
+                        System.err.println("Monotonicity failure for StrictMath.cbrt on " +
+                                          pcNeighbors[j] + " and "  +
+                                          pcNeighbors[j+1] + "\n\treturned " +
+                                          pcNeighborsStrictCbrt[j] + " and " +
+                                          pcNeighborsStrictCbrt[j+1] );
+                    }
+
+
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += testCubeRoot();
+
+        if (failures > 0) {
+            System.err.println("Testing cbrt incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/Expm1Tests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4851638 4900189 4939441
+ * @summary Tests for {Math, StrictMath}.expm1
+ * @author Joseph D. Darcy
+ */
+
+import sun.misc.DoubleConsts;
+import sun.misc.FpUtils;
+
+/*
+ * The Taylor expansion of expxm1(x) = exp(x) -1 is
+ *
+ * 1 + x/1! + x^2/2! + x^3/3| + ... -1 =
+ *
+ * x + x^2/2! + x^3/3 + ...
+ *
+ * Therefore, for small values of x, expxm1 ~= x.
+ *
+ * For large values of x, expxm1(x) ~= exp(x)
+ *
+ * For large negative x, expxm1(x) ~= -1.
+ */
+
+public class Expm1Tests {
+
+    private Expm1Tests(){}
+
+    static final double infinityD = Double.POSITIVE_INFINITY;
+    static final double NaNd = Double.NaN;
+
+    static int testExpm1() {
+        int failures = 0;
+
+        double [][] testCases = {
+            {Double.NaN,                NaNd},
+            {Double.longBitsToDouble(0x7FF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0xFFF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0x7FF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0xFFF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0x7FFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0x7FFCafeBabe00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFCafeBabe00000L),      NaNd},
+            {infinityD,                 infinityD},
+            {-infinityD,                -1.0},
+            {-0.0,                      -0.0},
+            {+0.0,                      +0.0},
+        };
+
+        // Test special cases
+        for(int i = 0; i < testCases.length; i++) {
+            failures += testExpm1CaseWithUlpDiff(testCases[i][0],
+                                                 testCases[i][1], 0, null);
+        }
+
+
+        // For |x| < 2^-54 expm1(x) ~= x
+        for(int i = DoubleConsts.MIN_SUB_EXPONENT; i <= -54; i++) {
+            double d = FpUtils.scalb(2, i);
+            failures += testExpm1Case(d, d);
+            failures += testExpm1Case(-d, -d);
+        }
+
+
+        // For values of y where exp(y) > 2^54, expm1(x) ~= exp(x).
+        // The least such y is ln(2^54) ~= 37.42994775023705; exp(x)
+        // overflows for x > ~= 709.8
+
+        // Use a 2-ulp error threshold to account for errors in the
+        // exp implementation; the increments of d in the loop will be
+        // exact.
+        for(double d = 37.5; d <= 709.5; d += 1.0) {
+            failures += testExpm1CaseWithUlpDiff(d, StrictMath.exp(d), 2, null);
+        }
+
+        // For x > 710, expm1(x) should be infinity
+        for(int i = 10; i <= DoubleConsts.MAX_EXPONENT; i++) {
+            double d = FpUtils.scalb(2, i);
+            failures += testExpm1Case(d, infinityD);
+        }
+
+        // By monotonicity, once the limit is reached, the
+        // implemenation should return the limit for all smaller
+        // values.
+        boolean reachedLimit [] = {false, false};
+
+        // Once exp(y) < 0.5 * ulp(1), expm1(y) ~= -1.0;
+        // The greatest such y is ln(2^-53) ~= -36.7368005696771.
+        for(double d = -36.75; d >= -127.75; d -= 1.0) {
+            failures += testExpm1CaseWithUlpDiff(d, -1.0, 1,
+                                                 reachedLimit);
+        }
+
+        for(int i = 7; i <= DoubleConsts.MAX_EXPONENT; i++) {
+            double d = -FpUtils.scalb(2, i);
+            failures += testExpm1CaseWithUlpDiff(d, -1.0, 1, reachedLimit);
+        }
+
+        // Test for monotonicity failures near multiples of log(2).
+        // Test two numbers before and two numbers after each chosen
+        // value; i.e.
+        //
+        // pcNeighbors[] =
+        // {nextDown(nextDown(pc)),
+        // nextDown(pc),
+        // pc,
+        // nextUp(pc),
+        // nextUp(nextUp(pc))}
+        //
+        // and we test that expm1(pcNeighbors[i]) <= expm1(pcNeighbors[i+1])
+        {
+            double pcNeighbors[] = new double[5];
+            double pcNeighborsExpm1[] = new double[5];
+            double pcNeighborsStrictExpm1[] = new double[5];
+
+            for(int i = -50; i <= 50; i++) {
+                double pc = StrictMath.log(2)*i;
+
+                pcNeighbors[2] = pc;
+                pcNeighbors[1] = FpUtils.nextDown(pc);
+                pcNeighbors[0] = FpUtils.nextDown(pcNeighbors[1]);
+                pcNeighbors[3] = FpUtils.nextUp(pc);
+                pcNeighbors[4] = FpUtils.nextUp(pcNeighbors[3]);
+
+                for(int j = 0; j < pcNeighbors.length; j++) {
+                    pcNeighborsExpm1[j]       =       Math.expm1(pcNeighbors[j]);
+                    pcNeighborsStrictExpm1[j] = StrictMath.expm1(pcNeighbors[j]);
+                }
+
+                for(int j = 0; j < pcNeighborsExpm1.length-1; j++) {
+                    if(pcNeighborsExpm1[j] >  pcNeighborsExpm1[j+1] ) {
+                        failures++;
+                        System.err.println("Monotonicity failure for Math.expm1 on " +
+                                          pcNeighbors[j] + " and "  +
+                                          pcNeighbors[j+1] + "\n\treturned " +
+                                          pcNeighborsExpm1[j] + " and " +
+                                          pcNeighborsExpm1[j+1] );
+                    }
+
+                    if(pcNeighborsStrictExpm1[j] >  pcNeighborsStrictExpm1[j+1] ) {
+                        failures++;
+                        System.err.println("Monotonicity failure for StrictMath.expm1 on " +
+                                          pcNeighbors[j] + " and "  +
+                                          pcNeighbors[j+1] + "\n\treturned " +
+                                          pcNeighborsStrictExpm1[j] + " and " +
+                                          pcNeighborsStrictExpm1[j+1] );
+                    }
+
+
+                }
+
+            }
+        }
+
+        return failures;
+    }
+
+    public static int testExpm1Case(double input,
+                                    double expected) {
+        return testExpm1CaseWithUlpDiff(input, expected, 1, null);
+    }
+
+    public static int testExpm1CaseWithUlpDiff(double input,
+                                               double expected,
+                                               double ulps,
+                                               boolean [] reachedLimit) {
+        int failures = 0;
+        double mathUlps = ulps, strictUlps = ulps;
+        double mathOutput;
+        double strictOutput;
+
+        if (reachedLimit != null) {
+            if (reachedLimit[0])
+                mathUlps = 0;
+
+            if (reachedLimit[1])
+                strictUlps = 0;
+        }
+
+        failures += Tests.testUlpDiffWithLowerBound("Math.expm1(double)",
+                                                    input, mathOutput=Math.expm1(input),
+                                                    expected, mathUlps, -1.0);
+        failures += Tests.testUlpDiffWithLowerBound("StrictMath.expm1(double)",
+                                                    input, strictOutput=StrictMath.expm1(input),
+                                                    expected, strictUlps, -1.0);
+        if (reachedLimit != null) {
+            reachedLimit[0] |= (mathOutput   == -1.0);
+            reachedLimit[1] |= (strictOutput == -1.0);
+        }
+
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += testExpm1();
+
+        if (failures > 0) {
+            System.err.println("Testing expm1 incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/HyperbolicTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,1065 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4851625 4900189 4939441
+ * @summary Tests for {Math, StrictMath}.{sinh, cosh, tanh}
+ * @author Joseph D. Darcy
+ */
+
+import sun.misc.DoubleConsts;
+import sun.misc.FpUtils;
+
+public class HyperbolicTests {
+    private HyperbolicTests(){}
+
+    static final double NaNd = Double.NaN;
+
+    /**
+     * Test accuracy of {Math, StrictMath}.sinh.  The specified
+     * accuracy is 2.5 ulps.
+     *
+     * The defintion of sinh(x) is
+     *
+     * (e^x - e^(-x))/2
+     *
+     * The series expansion of sinh(x) =
+     *
+     * x + x^3/3! + x^5/5! + x^7/7! +...
+     *
+     * Therefore,
+     *
+     * 1. For large values of x sinh(x) ~= signum(x)*exp(|x|)/2
+     *
+     * 2. For small values of x, sinh(x) ~= x.
+     *
+     * Additionally, sinh is an odd function; sinh(-x) = -sinh(x).
+     *
+     */
+    static int testSinh() {
+        int failures = 0;
+        /*
+         * Array elements below generated using a quad sinh
+         * implementation.  Rounded to a double, the quad result
+         * *should* be correctly rounded, unless we are quite unlucky.
+         * Assuming the quad value is a correctly rounded double, the
+         * allowed error is 3.0 ulps instead of 2.5 since the quad
+         * value rounded to double can have its own 1/2 ulp error.
+         */
+        double [][] testCases = {
+            // x                sinh(x)
+            {0.0625,            0.06254069805219182172183988501029229},
+            {0.1250,            0.12532577524111545698205754229137154},
+            {0.1875,            0.18860056562029018382047025055167585},
+            {0.2500,            0.25261231680816830791412515054205787},
+            {0.3125,            0.31761115611357728583959867611490292},
+            {0.3750,            0.38385106791361456875429567642050245},
+            {0.4375,            0.45159088610312053032509815226723017},
+            {0.5000,            0.52109530549374736162242562641149155},
+            {0.5625,            0.59263591611468777373870867338492247},
+            {0.6250,            0.66649226445661608227260655608302908},
+            {0.6875,            0.74295294580567543571442036910465007},
+            {0.7500,            0.82231673193582998070366163444691386},
+            {0.8125,            0.90489373856606433650504536421491368},
+            {0.8750,            0.99100663714429475605317427568995231},
+            {0.9375,            1.08099191569306394011007867453992548},
+            {1.0000,            1.17520119364380145688238185059560082},
+            {1.0625,            1.27400259579739321279181130344911907},
+            {1.1250,            1.37778219077984075760379987065228373},
+            {1.1875,            1.48694549961380717221109202361777593},
+            {1.2500,            1.60191908030082563790283030151221415},
+            {1.3125,            1.72315219460596010219069206464391528},
+            {1.3750,            1.85111856355791532419998548438506416},
+            {1.4375,            1.98631821852425112898943304217629457},
+            {1.5000,            2.12927945509481749683438749467763195},
+            {1.5625,            2.28056089740825247058075476705718764},
+            {1.6250,            2.44075368098794353221372986997161132},
+            {1.6875,            2.61048376261693140366028569794027603},
+            {1.7500,            2.79041436627764265509289122308816092},
+            {1.8125,            2.98124857471401377943765253243875520},
+            {1.8750,            3.18373207674259205101326780071803724},
+            {1.9375,            3.39865608104779099764440244167531810},
+            {2.0000,            3.62686040784701876766821398280126192},
+            {2.0625,            3.86923677050642806693938384073620450},
+            {2.1250,            4.12673225993027252260441410537905269},
+            {2.1875,            4.40035304533919660406976249684469164},
+            {2.2500,            4.69116830589833069188357567763552003},
+            {2.3125,            5.00031440855811351554075363240262157},
+            {2.3750,            5.32899934843284576394645856548481489},
+            {2.4375,            5.67850746906785056212578751630266858},
+            {2.5000,            6.05020448103978732145032363835040319},
+            {2.5625,            6.44554279850040875063706020260185553},
+            {2.6250,            6.86606721451642172826145238779845813},
+            {2.6875,            7.31342093738196587585692115636603571},
+            {2.7500,            7.78935201149073201875513401029935330},
+            {2.8125,            8.29572014785741787167717932988491961},
+            {2.8750,            8.83450399097893197351853322827892144},
+            {2.9375,            9.40780885043076394429977972921690859},
+            {3.0000,            10.01787492740990189897459361946582867},
+            {3.0625,            10.66708606836969224165124519209968368},
+            {3.1250,            11.35797907995166028304704128775698426},
+            {3.1875,            12.09325364161259019614431093344260209},
+            {3.2500,            12.87578285468067003959660391705481220},
+            {3.3125,            13.70862446906136798063935858393686525},
+            {3.3750,            14.59503283146163690015482636921657975},
+            {3.4375,            15.53847160182039311025096666980558478},
+            {3.5000,            16.54262728763499762495673152901249743},
+            {3.5625,            17.61142364906941482858466494889121694},
+            {3.6250,            18.74903703113232171399165788088277979},
+            {3.6875,            19.95991268283598684128844120984214675},
+            {3.7500,            21.24878212710338697364101071825171163},
+            {3.8125,            22.62068164929685091969259499078125023},
+            {3.8750,            24.08097197661255803883403419733891573},
+            {3.9375,            25.63535922523855307175060244757748997},
+            {4.0000,            27.28991719712775244890827159079382096},
+            {4.0625,            29.05111111351106713777825462100160185},
+            {4.1250,            30.92582287788986031725487699744107092},
+            {4.1875,            32.92137796722343190618721270937061472},
+            {4.2500,            35.04557405638942942322929652461901154},
+            {4.3125,            37.30671148776788628118833357170042385},
+            {4.3750,            39.71362570500944929025069048612806024},
+            {4.4375,            42.27572177772344954814418332587050658},
+            {4.5000,            45.00301115199178562180965680564371424},
+            {4.5625,            47.90615077031205065685078058248081891},
+            {4.6250,            50.99648471383193131253995134526177467},
+            {4.6875,            54.28608852959281437757368957713936555},
+            {4.7500,            57.78781641599226874961859781628591635},
+            {4.8125,            61.51535145084362283008545918273109379},
+            {4.8750,            65.48325905829987165560146562921543361},
+            {4.9375,            69.70704392356508084094318094283346381},
+            {5.0000,            74.20321057778875897700947199606456364},
+            {5.0625,            78.98932788987998983462810080907521151},
+            {5.1250,            84.08409771724448958901392613147384951},
+            {5.1875,            89.50742798369883598816307922895346849},
+            {5.2500,            95.28051047011540739630959111303975956},
+            {5.3125,            101.42590362176666730633859252034238987},
+            {5.3750,            107.96762069594029162704530843962700133},
+            {5.4375,            114.93122359426386042048760580590182604},
+            {5.5000,            122.34392274639096192409774240457730721},
+            {5.5625,            130.23468343534638291488502321709913206},
+            {5.6250,            138.63433897999898233879574111119546728},
+            {5.6875,            147.57571121692522056519568264304815790},
+            {5.7500,            157.09373875244884423880085377625986165},
+            {5.8125,            167.22561348600435888568183143777868662},
+            {5.8750,            178.01092593829229887752609866133883987},
+            {5.9375,            189.49181995209921964640216682906501778},
+            {6.0000,            201.71315737027922812498206768797872263},
+            {6.0625,            214.72269333437984291483666459592578915},
+            {6.1250,            228.57126288889537420461281285729970085},
+            {6.1875,            243.31297962030799867970551767086092471},
+            {6.2500,            259.00544710710289911522315435345489966},
+            {6.3125,            275.70998400700299790136562219920451185},
+            {6.3750,            293.49186366095654566861661249898332253},
+            {6.4375,            312.42056915013535342987623229485223434},
+            {6.5000,            332.57006480258443156075705566965111346},
+            {6.5625,            354.01908521044116928437570109827956007},
+            {6.6250,            376.85144288706511933454985188849781703},
+            {6.6875,            401.15635576625530823119100750634165252},
+            {6.7500,            427.02879582326538080306830640235938517},
+            {6.8125,            454.56986017986077163530945733572724452},
+            {6.8750,            483.88716614351897894746751705315210621},
+            {6.9375,            515.09527172439720070161654727225752288},
+            {7.0000,            548.31612327324652237375611757601851598},
+            {7.0625,            583.67953198942753384680988096024373270},
+            {7.1250,            621.32368116099280160364794462812762880},
+            {7.1875,            661.39566611888784148449430491465857519},
+            {7.2500,            704.05206901515336623551137120663358760},
+            {7.3125,            749.45957067108712382864538206200700256},
+            {7.3750,            797.79560188617531521347351754559776282},
+            {7.4375,            849.24903675279739482863565789325699416},
+            {7.5000,            904.02093068584652953510919038935849651},
+            {7.5625,            962.32530605113249628368993221570636328},
+            {7.6250,            1024.38998846242707559349318193113614698},
+            {7.6875,            1090.45749701500081956792547346904792325},
+            {7.7500,            1160.78599193425808533255719118417856088},
+            {7.8125,            1235.65028334242796895820912936318532502},
+            {7.8750,            1315.34290508508890654067255740428824014},
+            {7.9375,            1400.17525781352742299995139486063802583},
+            {8.0000,            1490.47882578955018611587663903188144796},
+            {8.0625,            1586.60647216744061169450001100145859236},
+            {8.1250,            1688.93381781440241350635231605477507900},
+            {8.1875,            1797.86070905726094477721128358866360644},
+            {8.2500,            1913.81278009067446281883262689250118009},
+            {8.3125,            2037.24311615199935553277163192983440062},
+            {8.3750,            2168.63402396170125867037749369723761636},
+            {8.4375,            2308.49891634734644432370720900969004306},
+            {8.5000,            2457.38431841538268239359965370719928775},
+            {8.5625,            2615.87200310986940554256648824234335262},
+            {8.6250,            2784.58126450289932429469130598902487336},
+            {8.6875,            2964.17133769964321637973459949999057146},
+            {8.7500,            3155.34397481384944060352507473513108710},
+            {8.8125,            3358.84618707947841898217318996045550438},
+            {8.8750,            3575.47316381333288862617411467285480067},
+            {8.9375,            3806.07137963459383403903729660349293583},
+            {9.0000,            4051.54190208278996051522359589803425598},
+            {9.0625,            4312.84391255878980330955246931164633615},
+            {9.1250,            4590.99845434696991399363282718106006883},
+            {9.1875,            4887.09242236403719571363798584676797558},
+            {9.2500,            5202.28281022453561319352901552085348309},
+            {9.3125,            5537.80123121853803935727335892054791265},
+            {9.3750,            5894.95873086734181634245918412592155656},
+            {9.4375,            6275.15090986233399457103055108344546942},
+            {9.5000,            6679.86337740502119410058225086262108741},
+            {9.5625,            7110.67755625726876329967852256934334025},
+            {9.6250,            7569.27686218510919585241049433331592115},
+            {9.6875,            8057.45328194243077504648484392156371121},
+            {9.7500,            8577.11437549816065709098061006273039092},
+            {9.8125,            9130.29072986829727910801024120918114778},
+            {9.8750,            9719.14389367880274015504995181862860062},
+            {9.9375,            10345.97482346383208590278839409938269134},
+            {10.0000,           11013.23287470339337723652455484636420303},
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            double [] testCase = testCases[i];
+            failures += testSinhCaseWithUlpDiff(testCase[0],
+                                                testCase[1],
+                                                3.0);
+        }
+
+        double [][] specialTestCases = {
+            {0.0,                       0.0},
+            {NaNd,                      NaNd},
+            {Double.longBitsToDouble(0x7FF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0xFFF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0x7FF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0xFFF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0x7FFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0x7FFCafeBabe00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFCafeBabe00000L),      NaNd},
+            {Double.POSITIVE_INFINITY,  Double.POSITIVE_INFINITY}
+        };
+
+        for(int i = 0; i < specialTestCases.length; i++) {
+            failures += testSinhCaseWithUlpDiff(specialTestCases[i][0],
+                                                specialTestCases[i][1],
+                                                0.0);
+        }
+
+        // For powers of 2 less than 2^(-27), the second and
+        // subsequent terms of the Taylor series expansion will get
+        // rounded away since |n-n^3| > 53, the binary precision of a
+        // double significand.
+
+        for(int i = DoubleConsts.MIN_SUB_EXPONENT; i < -27; i++) {
+            double d = FpUtils.scalb(2.0, i);
+
+            // Result and expected are the same.
+            failures += testSinhCaseWithUlpDiff(d, d, 2.5);
+        }
+
+        // For values of x larger than 22, the e^(-x) term is
+        // insignificant to the floating-point result.  Util exp(x)
+        // overflows around 709.8, sinh(x) ~= exp(x)/2; will will test
+        // 10000 values in this range.
+
+        long trans22 = Double.doubleToLongBits(22.0);
+        // (approximately) largest value such that exp shouldn't
+        // overflow
+        long transExpOvfl = Double.doubleToLongBits(FpUtils.nextDown(709.7827128933841));
+
+        for(long i = trans22;
+            i < transExpOvfl;
+            i +=(transExpOvfl-trans22)/10000) {
+
+            double d = Double.longBitsToDouble(i);
+
+            // Allow 3.5 ulps of error to deal with error in exp.
+            failures += testSinhCaseWithUlpDiff(d, StrictMath.exp(d)*0.5, 3.5);
+        }
+
+        // (approximately) largest value such that sinh shouldn't
+        // overflow.
+        long transSinhOvfl = Double.doubleToLongBits(710.4758600739439);
+
+        // Make sure sinh(x) doesn't overflow as soon as exp(x)
+        // overflows.
+
+        /*
+         * For large values of x, sinh(x) ~= 0.5*(e^x).  Therefore,
+         *
+         * sinh(x) ~= e^(ln 0.5) * e^x = e^(x + ln 0.5)
+         *
+         * So, we can calculate the approximate expected result as
+         * exp(x + -0.693147186).  However, this sum suffers from
+         * roundoff, limiting the accuracy of the approximation.  The
+         * accuracy can be improved by recovering the rounded-off
+         * information.  Since x is larger than ln(0.5), the trailing
+         * bits of ln(0.5) get rounded away when the two values are
+         * added.  However, high-order bits of ln(0.5) that
+         * contribute to the sum can be found:
+         *
+         * offset = log(0.5);
+         * effective_offset = (x + offset) - x; // exact subtraction
+         * rounded_away_offset = offset - effective_offset; // exact subtraction
+         *
+         * Therefore, the product
+         *
+         * exp(x + offset)*exp(rounded_away_offset)
+         *
+         * will be a better approximation to the exact value of
+         *
+         * e^(x + offset)
+         *
+         * than exp(x+offset) alone.  (The expected result cannot be
+         * computed as exp(x)*exp(offset) since exp(x) by itself would
+         * overflow to infinity.)
+         */
+        double offset = StrictMath.log(0.5);
+        for(long i = transExpOvfl+1; i < transSinhOvfl;
+            i += (transSinhOvfl-transExpOvfl)/1000 ) {
+            double input = Double.longBitsToDouble(i);
+
+            double expected =
+                StrictMath.exp(input + offset) *
+                StrictMath.exp( offset - ((input + offset) - input) );
+
+            failures += testSinhCaseWithUlpDiff(input, expected, 4.0);
+        }
+
+        // sinh(x) overflows for values greater than 710; in
+        // particular, it overflows for all 2^i, i > 10.
+        for(int i = 10; i <= DoubleConsts.MAX_EXPONENT; i++) {
+            double d = FpUtils.scalb(2.0, i);
+
+            // Result and expected are the same.
+            failures += testSinhCaseWithUlpDiff(d,
+                                                Double.POSITIVE_INFINITY, 0.0);
+        }
+
+        return failures;
+    }
+
+    public static int testSinhCaseWithTolerance(double input,
+                                                double expected,
+                                                double tolerance) {
+        int failures = 0;
+        failures += Tests.testTolerance("Math.sinh(double)",
+                                        input, Math.sinh(input),
+                                        expected, tolerance);
+        failures += Tests.testTolerance("Math.sinh(double)",
+                                        -input, Math.sinh(-input),
+                                        -expected, tolerance);
+
+        failures += Tests.testTolerance("StrictMath.sinh(double)",
+                                        input, StrictMath.sinh(input),
+                                        expected, tolerance);
+        failures += Tests.testTolerance("StrictMath.sinh(double)",
+                                        -input, StrictMath.sinh(-input),
+                                        -expected, tolerance);
+        return failures;
+    }
+
+    public static int testSinhCaseWithUlpDiff(double input,
+                                              double expected,
+                                              double ulps) {
+        int failures = 0;
+        failures += Tests.testUlpDiff("Math.sinh(double)",
+                                      input, Math.sinh(input),
+                                      expected, ulps);
+        failures += Tests.testUlpDiff("Math.sinh(double)",
+                                      -input, Math.sinh(-input),
+                                      -expected, ulps);
+
+        failures += Tests.testUlpDiff("StrictMath.sinh(double)",
+                                      input, StrictMath.sinh(input),
+                                      expected, ulps);
+        failures += Tests.testUlpDiff("StrictMath.sinh(double)",
+                                      -input, StrictMath.sinh(-input),
+                                      -expected, ulps);
+        return failures;
+    }
+
+
+    /**
+     * Test accuracy of {Math, StrictMath}.cosh.  The specified
+     * accuracy is 2.5 ulps.
+     *
+     * The defintion of cosh(x) is
+     *
+     * (e^x + e^(-x))/2
+     *
+     * The series expansion of cosh(x) =
+     *
+     * 1 + x^2/2! + x^4/4! + x^6/6! +...
+     *
+     * Therefore,
+     *
+     * 1. For large values of x cosh(x) ~= exp(|x|)/2
+     *
+     * 2. For small values of x, cosh(x) ~= 1.
+     *
+     * Additionally, cosh is an even function; cosh(-x) = cosh(x).
+     *
+     */
+    static int testCosh() {
+        int failures = 0;
+        /*
+         * Array elements below generated using a quad cosh
+         * implementation.  Rounded to a double, the quad result
+         * *should* be correctly rounded, unless we are quite unlucky.
+         * Assuming the quad value is a correctly rounded double, the
+         * allowed error is 3.0 ulps instead of 2.5 since the quad
+         * value rounded to double can have its own 1/2 ulp error.
+         */
+        double [][] testCases = {
+            // x                cosh(x)
+            {0.0625,            1.001953760865667607841550709632597376},
+            {0.1250,            1.007822677825710859846949685520422223},
+            {0.1875,            1.017629683800690526835115759894757615},
+            {0.2500,            1.031413099879573176159295417520378622},
+            {0.3125,            1.049226785060219076999158096606305793},
+            {0.3750,            1.071140346704586767299498015567016002},
+            {0.4375,            1.097239412531012567673453832328262160},
+            {0.5000,            1.127625965206380785226225161402672030},
+            {0.5625,            1.162418740845610783505338363214045218},
+            {0.6250,            1.201753692975606324229229064105075301},
+            {0.6875,            1.245784523776616395403056980542275175},
+            {0.7500,            1.294683284676844687841708185390181730},
+            {0.8125,            1.348641048647144208352285714214372703},
+            {0.8750,            1.407868656822803158638471458026344506},
+            {0.9375,            1.472597542369862933336886403008640891},
+            {1.0000,            1.543080634815243778477905620757061497},
+            {1.0625,            1.619593348374367728682469968448090763},
+            {1.1250,            1.702434658138190487400868008124755757},
+            {1.1875,            1.791928268324866464246665745956119612},
+            {1.2500,            1.888423877161015738227715728160051696},
+            {1.3125,            1.992298543335143985091891077551921106},
+            {1.3750,            2.103958159362661802010972984204389619},
+            {1.4375,            2.223839037619709260803023946704272699},
+            {1.5000,            2.352409615243247325767667965441644201},
+            {1.5625,            2.490172284559350293104864895029231913},
+            {1.6250,            2.637665356192137582275019088061812951},
+            {1.6875,            2.795465162524235691253423614360562624},
+            {1.7500,            2.964188309728087781773608481754531801},
+            {1.8125,            3.144494087167972176411236052303565201},
+            {1.8750,            3.337087043587520514308832278928116525},
+            {1.9375,            3.542719740149244276729383650503145346},
+            {2.0000,            3.762195691083631459562213477773746099},
+            {2.0625,            3.996372503438463642260225717607554880},
+            {2.1250,            4.246165228196992140600291052990934410},
+            {2.1875,            4.512549935859540340856119781585096760},
+            {2.2500,            4.796567530460195028666793366876218854},
+            {2.3125,            5.099327816921939817643745917141739051},
+            {2.3750,            5.422013837643509250646323138888569746},
+            {2.4375,            5.765886495263270945949271410819116399},
+            {2.5000,            6.132289479663686116619852312817562517},
+            {2.5625,            6.522654518468725462969589397439224177},
+            {2.6250,            6.938506971550673190999796241172117288},
+            {2.6875,            7.381471791406976069645686221095397137},
+            {2.7500,            7.853279872697439591457564035857305647},
+            {2.8125,            8.355774815752725814638234943192709129},
+            {2.8750,            8.890920130482709321824793617157134961},
+            {2.9375,            9.460806908834119747071078865866737196},
+            {3.0000,            10.067661995777765841953936035115890343},
+            {3.0625,            10.713856690753651225304006562698007312},
+            {3.1250,            11.401916013575067700373788969458446177},
+            {3.1875,            12.134528570998387744547733730974713055},
+            {3.2500,            12.914557062512392049483503752322408761},
+            {3.3125,            13.745049466398732213877084541992751273},
+            {3.3750,            14.629250949773302934853381428660210721},
+            {3.4375,            15.570616549147269180921654324879141947},
+            {3.5000,            16.572824671057316125696517821376119469},
+            {3.5625,            17.639791465519127930722105721028711044},
+            {3.6250,            18.775686128468677200079039891415789429},
+            {3.6875,            19.984947192985946987799359614758598457},
+            {3.7500,            21.272299872959396081877161903352144126},
+            {3.8125,            22.642774526961913363958587775566619798},
+            {3.8750,            24.101726314486257781049388094955970560},
+            {3.9375,            25.654856121347151067170940701379544221},
+            {4.0000,            27.308232836016486629201989612067059978},
+            {4.0625,            29.068317063936918520135334110824828950},
+            {4.1250,            30.941986372478026192360480044849306606},
+            {4.1875,            32.936562165180269851350626768308756303},
+            {4.2500,            35.059838290298428678502583470475012235},
+            {4.3125,            37.320111495433027109832850313172338419},
+            {4.3750,            39.726213847251883288518263854094284091},
+            {4.4375,            42.287547242982546165696077854963452084},
+            {4.5000,            45.014120148530027928305799939930642658},
+            {4.5625,            47.916586706774825161786212701923307169},
+            {4.6250,            51.006288368867753140854830589583165950},
+            {4.6875,            54.295298211196782516984520211780624960},
+            {4.7500,            57.796468111195389383795669320243166117},
+            {4.8125,            61.523478966332915041549750463563672435},
+            {4.8750,            65.490894152518731617237739112888213645},
+            {4.9375,            69.714216430810089539924900313140922323},
+            {5.0000,            74.209948524787844444106108044487704798},
+            {5.0625,            78.995657605307475581204965926043112946},
+            {5.1250,            84.090043934600961683400343038519519678},
+            {5.1875,            89.513013937957834087706670952561002466},
+            {5.2500,            95.285757988514588780586084642381131013},
+            {5.3125,            101.430833209098212357990123684449846912},
+            {5.3750,            107.972251614673824873137995865940755392},
+            {5.4375,            114.935573939814969189535554289886848550},
+            {5.5000,            122.348009517829425991091207107262038316},
+            {5.5625,            130.238522601820409078244923165746295574},
+            {5.6250,            138.637945543134998069351279801575968875},
+            {5.6875,            147.579099269447055276899288971207106581},
+            {5.7500,            157.096921533245353905868840194264636395},
+            {5.8125,            167.228603431860671946045256541679445836},
+            {5.8750,            178.013734732486824390148614309727161925},
+            {5.9375,            189.494458570056311567917444025807275896},
+            {6.0000,            201.715636122455894483405112855409538488},
+            {6.0625,            214.725021906554080628430756558271312513},
+            {6.1250,            228.573450380013557089736092321068279231},
+            {6.1875,            243.315034578039208138752165587134488645},
+            {6.2500,            259.007377561239126824465367865430519592},
+            {6.3125,            275.711797500835732516530131577254654076},
+            {6.3750,            293.493567280752348242602902925987643443},
+            {6.4375,            312.422169552825597994104814531010579387},
+            {6.5000,            332.571568241777409133204438572983297292},
+            {6.5625,            354.020497560858198165985214519757890505},
+            {6.6250,            376.852769667496146326030849450983914197},
+            {6.6875,            401.157602161123700280816957271992998156},
+            {6.7500,            427.029966702886171977469256622451185850},
+            {6.8125,            454.570960119471524953536004647195906721},
+            {6.8750,            483.888199441157626584508920036981010995},
+            {6.9375,            515.096242417696720610477570797503766179},
+            {7.0000,            548.317035155212076889964120712102928484},
+            {7.0625,            583.680388623257719787307547662358502345},
+            {7.1250,            621.324485894002926216918634755431456031},
+            {7.1875,            661.396422095589629755266517362992812037},
+            {7.2500,            704.052779189542208784574955807004218856},
+            {7.3125,            749.460237818184878095966335081928645934},
+            {7.3750,            797.796228612873763671070863694973560629},
+            {7.4375,            849.249625508044731271830060572510241864},
+            {7.5000,            904.021483770216677368692292389446994987},
+            {7.5625,            962.325825625814651122171697031114091993},
+            {7.6250,            1024.390476557670599008492465853663578558},
+            {7.6875,            1090.457955538048482588540574008226583335},
+            {7.7500,            1160.786422676798661020094043586456606003},
+            {7.8125,            1235.650687987597295222707689125107720568},
+            {7.8750,            1315.343285214046776004329388551335841550},
+            {7.9375,            1400.175614911635999247504386054087931958},
+            {8.0000,            1490.479161252178088627715460421007179728},
+            {8.0625,            1586.606787305415349050508956232945539108},
+            {8.1250,            1688.934113859132470361718199038326340668},
+            {8.1875,            1797.860987165547537276364148450577336075},
+            {8.2500,            1913.813041349231764486365114317586148767},
+            {8.3125,            2037.243361581700856522236313401822532385},
+            {8.3750,            2168.634254521568851112005905503069409349},
+            {8.4375,            2308.499132938297821208734949028296170563},
+            {8.5000,            2457.384521883751693037774022640629666294},
+            {8.5625,            2615.872194250713123494312356053193077854},
+            {8.6250,            2784.581444063104750127653362960649823247},
+            {8.6875,            2964.171506380845754878370650565756538203},
+            {8.7500,            3155.344133275174556354775488913749659006},
+            {8.8125,            3358.846335940117183452010789979584950102},
+            {8.8750,            3575.473303654961482727206202358956274888},
+            {8.9375,            3806.071511003646460448021740303914939059},
+            {9.0000,            4051.542025492594047194773093534725371440},
+            {9.0625,            4312.844028491571841588188869958240355518},
+            {9.1250,            4590.998563255739769060078863130940205710},
+            {9.1875,            4887.092524674358252509551443117048351290},
+            {9.2500,            5202.282906336187674588222835339193136030},
+            {9.3125,            5537.801321507079474415176386655744387251},
+            {9.3750,            5894.958815685577062811620236195525504885},
+            {9.4375,            6275.150989541692149890530417987358096221},
+            {9.5000,            6679.863452256851081801173722051940058824},
+            {9.5625,            7110.677626574055535297758456126491707647},
+            {9.6250,            7569.276928241617224537226019600213961572},
+            {9.6875,            8057.453343996777301036241026375049070162},
+            {9.7500,            8577.114433792824387959788368429252257664},
+            {9.8125,            9130.290784631065880205118262838330689429},
+            {9.8750,            9719.143945123662919857326995631317996715},
+            {9.9375,            10345.974871791805753327922796701684092861},
+            {10.0000,           11013.232920103323139721376090437880844591},
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            double [] testCase = testCases[i];
+            failures += testCoshCaseWithUlpDiff(testCase[0],
+                                                testCase[1],
+                                                3.0);
+        }
+
+
+        double [][] specialTestCases = {
+            {0.0,                       1.0},
+            {NaNd,                      NaNd},
+            {Double.longBitsToDouble(0x7FF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0xFFF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0x7FF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0xFFF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0x7FFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0x7FFCafeBabe00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFCafeBabe00000L),      NaNd},
+            {Double.POSITIVE_INFINITY,  Double.POSITIVE_INFINITY}
+        };
+
+        for(int i = 0; i < specialTestCases.length; i++ ) {
+            failures += testCoshCaseWithUlpDiff(specialTestCases[i][0],
+                                                specialTestCases[i][1],
+                                                0.0);
+        }
+
+        // For powers of 2 less than 2^(-27), the second and
+        // subsequent terms of the Taylor series expansion will get
+        // rounded.
+
+        for(int i = DoubleConsts.MIN_SUB_EXPONENT; i < -27; i++) {
+            double d = FpUtils.scalb(2.0, i);
+
+            // Result and expected are the same.
+            failures += testCoshCaseWithUlpDiff(d, 1.0, 2.5);
+        }
+
+        // For values of x larger than 22, the e^(-x) term is
+        // insignificant to the floating-point result.  Util exp(x)
+        // overflows around 709.8, cosh(x) ~= exp(x)/2; will will test
+        // 10000 values in this range.
+
+        long trans22 = Double.doubleToLongBits(22.0);
+        // (approximately) largest value such that exp shouldn't
+        // overflow
+        long transExpOvfl = Double.doubleToLongBits(FpUtils.nextDown(709.7827128933841));
+
+        for(long i = trans22;
+            i < transExpOvfl;
+            i +=(transExpOvfl-trans22)/10000) {
+
+            double d = Double.longBitsToDouble(i);
+
+            // Allow 3.5 ulps of error to deal with error in exp.
+            failures += testCoshCaseWithUlpDiff(d, StrictMath.exp(d)*0.5, 3.5);
+        }
+
+        // (approximately) largest value such that cosh shouldn't
+        // overflow.
+        long transCoshOvfl = Double.doubleToLongBits(710.4758600739439);
+
+        // Make sure sinh(x) doesn't overflow as soon as exp(x)
+        // overflows.
+
+        /*
+         * For large values of x, cosh(x) ~= 0.5*(e^x).  Therefore,
+         *
+         * cosh(x) ~= e^(ln 0.5) * e^x = e^(x + ln 0.5)
+         *
+         * So, we can calculate the approximate expected result as
+         * exp(x + -0.693147186).  However, this sum suffers from
+         * roundoff, limiting the accuracy of the approximation.  The
+         * accuracy can be improved by recovering the rounded-off
+         * information.  Since x is larger than ln(0.5), the trailing
+         * bits of ln(0.5) get rounded away when the two values are
+         * added.  However, high-order bits of ln(0.5) that
+         * contribute to the sum can be found:
+         *
+         * offset = log(0.5);
+         * effective_offset = (x + offset) - x; // exact subtraction
+         * rounded_away_offset = offset - effective_offset; // exact subtraction
+         *
+         * Therefore, the product
+         *
+         * exp(x + offset)*exp(rounded_away_offset)
+         *
+         * will be a better approximation to the exact value of
+         *
+         * e^(x + offset)
+         *
+         * than exp(x+offset) alone.  (The expected result cannot be
+         * computed as exp(x)*exp(offset) since exp(x) by itself would
+         * overflow to infinity.)
+         */
+        double offset = StrictMath.log(0.5);
+        for(long i = transExpOvfl+1; i < transCoshOvfl;
+            i += (transCoshOvfl-transExpOvfl)/1000 ) {
+            double input = Double.longBitsToDouble(i);
+
+            double expected =
+                StrictMath.exp(input + offset) *
+                StrictMath.exp( offset - ((input + offset) - input) );
+
+            failures += testCoshCaseWithUlpDiff(input, expected, 4.0);
+        }
+
+        // cosh(x) overflows for values greater than 710; in
+        // particular, it overflows for all 2^i, i > 10.
+        for(int i = 10; i <= DoubleConsts.MAX_EXPONENT; i++) {
+            double d = FpUtils.scalb(2.0, i);
+
+            // Result and expected are the same.
+            failures += testCoshCaseWithUlpDiff(d,
+                                                Double.POSITIVE_INFINITY, 0.0);
+        }
+        return failures;
+    }
+
+    public static int testCoshCaseWithTolerance(double input,
+                                                double expected,
+                                                double tolerance) {
+        int failures = 0;
+        failures += Tests.testTolerance("Math.cosh(double)",
+                                        input, Math.cosh(input),
+                                        expected, tolerance);
+        failures += Tests.testTolerance("Math.cosh(double)",
+                                        -input, Math.cosh(-input),
+                                        expected, tolerance);
+
+        failures += Tests.testTolerance("StrictMath.cosh(double)",
+                                        input, StrictMath.cosh(input),
+                                        expected, tolerance);
+        failures += Tests.testTolerance("StrictMath.cosh(double)",
+                                        -input, StrictMath.cosh(-input),
+                                        expected, tolerance);
+        return failures;
+    }
+
+    public static int testCoshCaseWithUlpDiff(double input,
+                                              double expected,
+                                              double ulps) {
+        int failures = 0;
+        failures += Tests.testUlpDiff("Math.cosh(double)",
+                                      input, Math.cosh(input),
+                                      expected, ulps);
+        failures += Tests.testUlpDiff("Math.cosh(double)",
+                                      -input, Math.cosh(-input),
+                                      expected, ulps);
+
+        failures += Tests.testUlpDiff("StrictMath.cosh(double)",
+                                      input, StrictMath.cosh(input),
+                                      expected, ulps);
+        failures += Tests.testUlpDiff("StrictMath.cosh(double)",
+                                      -input, StrictMath.cosh(-input),
+                                      expected, ulps);
+        return failures;
+    }
+
+
+    /**
+     * Test accuracy of {Math, StrictMath}.tanh.  The specified
+     * accuracy is 2.5 ulps.
+     *
+     * The defintion of tanh(x) is
+     *
+     * (e^x - e^(-x))/(e^x + e^(-x))
+     *
+     * The series expansion of tanh(x) =
+     *
+     * x - x^3/3 + 2x^5/15 - 17x^7/315 + ...
+     *
+     * Therefore,
+     *
+     * 1. For large values of x tanh(x) ~= signum(x)
+     *
+     * 2. For small values of x, tanh(x) ~= x.
+     *
+     * Additionally, tanh is an odd function; tanh(-x) = -tanh(x).
+     *
+     */
+    static int testTanh() {
+        int failures = 0;
+        /*
+         * Array elements below generated using a quad sinh
+         * implementation.  Rounded to a double, the quad result
+         * *should* be correctly rounded, unless we are quite unlucky.
+         * Assuming the quad value is a correctly rounded double, the
+         * allowed error is 3.0 ulps instead of 2.5 since the quad
+         * value rounded to double can have its own 1/2 ulp error.
+         */
+        double [][] testCases = {
+            // x                tanh(x)
+            {0.0625,            0.06241874674751251449014289119421133},
+            {0.1250,            0.12435300177159620805464727580589271},
+            {0.1875,            0.18533319990813951753211997502482787},
+            {0.2500,            0.24491866240370912927780113149101697},
+            {0.3125,            0.30270972933210848724239738970991712},
+            {0.3750,            0.35835739835078594631936023155315807},
+            {0.4375,            0.41157005567402245143207555859415687},
+            {0.5000,            0.46211715726000975850231848364367256},
+            {0.5625,            0.50982997373525658248931213507053130},
+            {0.6250,            0.55459972234938229399903909532308371},
+            {0.6875,            0.59637355547924233984437303950726939},
+            {0.7500,            0.63514895238728731921443435731249638},
+            {0.8125,            0.67096707420687367394810954721913358},
+            {0.8750,            0.70390560393662106058763026963135371},
+            {0.9375,            0.73407151960434149263991588052503660},
+            {1.0000,            0.76159415595576488811945828260479366},
+            {1.0625,            0.78661881210869761781941794647736081},
+            {1.1250,            0.80930107020178101206077047354332696},
+            {1.1875,            0.82980190998595952708572559629034476},
+            {1.2500,            0.84828363995751289761338764670750445},
+            {1.3125,            0.86490661772074179125443141102709751},
+            {1.3750,            0.87982669965198475596055310881018259},
+            {1.4375,            0.89319334040035153149249598745889365},
+            {1.5000,            0.90514825364486643824230369645649557},
+            {1.5625,            0.91582454416876231820084311814416443},
+            {1.6250,            0.92534622531174107960457166792300374},
+            {1.6875,            0.93382804322259173763570528576138652},
+            {1.7500,            0.94137553849728736226942088377163687},
+            {1.8125,            0.94808528560440629971240651310180052},
+            {1.8750,            0.95404526017994877009219222661968285},
+            {1.9375,            0.95933529331468249183399461756952555},
+            {2.0000,            0.96402758007581688394641372410092317},
+            {2.0625,            0.96818721657637057702714316097855370},
+            {2.1250,            0.97187274591350905151254495374870401},
+            {2.1875,            0.97513669829362836159665586901156483},
+            {2.2500,            0.97802611473881363992272924300618321},
+            {2.3125,            0.98058304703705186541999427134482061},
+            {2.3750,            0.98284502917257603002353801620158861},
+            {2.4375,            0.98484551746427837912703608465407824},
+            {2.5000,            0.98661429815143028888127603923734964},
+            {2.5625,            0.98817786228751240824802592958012269},
+            {2.6250,            0.98955974861288320579361709496051109},
+            {2.6875,            0.99078085564125158320311117560719312},
+            {2.7500,            0.99185972456820774534967078914285035},
+            {2.8125,            0.99281279483715982021711715899682324},
+            {2.8750,            0.99365463431502962099607366282699651},
+            {2.9375,            0.99439814606575805343721743822723671},
+            {3.0000,            0.99505475368673045133188018525548849},
+            {3.0625,            0.99563456710930963835715538507891736},
+            {3.1250,            0.99614653067334504917102591131792951},
+            {3.1875,            0.99659855517712942451966113109487039},
+            {3.2500,            0.99699763548652601693227592643957226},
+            {3.3125,            0.99734995516557367804571991063376923},
+            {3.3750,            0.99766097946988897037219469409451602},
+            {3.4375,            0.99793553792649036103161966894686844},
+            {3.5000,            0.99817789761119870928427335245061171},
+            {3.5625,            0.99839182812874152902001617480606320},
+            {3.6250,            0.99858065920179882368897879066418294},
+            {3.6875,            0.99874733168378115962760304582965538},
+            {3.7500,            0.99889444272615280096784208280487888},
+            {3.8125,            0.99902428575443546808677966295308778},
+            {3.8750,            0.99913888583735077016137617231569011},
+            {3.9375,            0.99924003097049627100651907919688313},
+            {4.0000,            0.99932929973906704379224334434172499},
+            {4.0625,            0.99940808577297384603818654530731215},
+            {4.1250,            0.99947761936180856115470576756499454},
+            {4.1875,            0.99953898655601372055527046497863955},
+            {4.2500,            0.99959314604388958696521068958989891},
+            {4.3125,            0.99964094406130644525586201091350343},
+            {4.3750,            0.99968312756179494813069349082306235},
+            {4.4375,            0.99972035584870534179601447812936151},
+            {4.5000,            0.99975321084802753654050617379050162},
+            {4.5625,            0.99978220617994689112771768489030236},
+            {4.6250,            0.99980779516900105210240981251048167},
+            {4.6875,            0.99983037791655283849546303868853396},
+            {4.7500,            0.99985030754497877753787358852000255},
+            {4.8125,            0.99986789571029070417475400133989992},
+            {4.8750,            0.99988341746867772271011794614780441},
+            {4.9375,            0.99989711557251558205051185882773206},
+            {5.0000,            0.99990920426259513121099044753447306},
+            {5.0625,            0.99991987261554158551063867262784721},
+            {5.1250,            0.99992928749851651137225712249720606},
+            {5.1875,            0.99993759617721206697530526661105307},
+            {5.2500,            0.99994492861777083305830639416802036},
+            {5.3125,            0.99995139951851344080105352145538345},
+            {5.3750,            0.99995711010315817210152906092289064},
+            {5.4375,            0.99996214970350792531554669737676253},
+            {5.5000,            0.99996659715630380963848952941756868},
+            {5.5625,            0.99997052203605101013786592945475432},
+            {5.6250,            0.99997398574306704793434088941484766},
+            {5.6875,            0.99997704246374583929961850444364696},
+            {5.7500,            0.99997974001803825215761760428815437},
+            {5.8125,            0.99998212060739040166557477723121777},
+            {5.8750,            0.99998422147482750993344503195672517},
+            {5.9375,            0.99998607548749972326220227464612338},
+            {6.0000,            0.99998771165079557056434885235523206},
+            {6.0625,            0.99998915556205996764518917496149338},
+            {6.1250,            0.99999042981101021976277974520745310},
+            {6.1875,            0.99999155433311068015449574811497719},
+            {6.2500,            0.99999254672143162687722782398104276},
+            {6.3125,            0.99999342250186907900400800240980139},
+            {6.3750,            0.99999419537602957780612639767025158},
+            {6.4375,            0.99999487743557848265406225515388994},
+            {6.5000,            0.99999547935140419285107893831698753},
+            {6.5625,            0.99999601054055694588617385671796346},
+            {6.6250,            0.99999647931357331502887600387959900},
+            {6.6875,            0.99999689300449080997594368612277442},
+            {6.7500,            0.99999725808558628431084200832778748},
+            {6.8125,            0.99999758026863294516387464046135924},
+            {6.8750,            0.99999786459425991170635407313276785},
+            {6.9375,            0.99999811551081218572759991597586905},
+            {7.0000,            0.99999833694394467173571641595066708},
+            {7.0625,            0.99999853235803894918375164252059190},
+            {7.1250,            0.99999870481040359014665019356422927},
+            {7.1875,            0.99999885699910593255108365463415411},
+            {7.2500,            0.99999899130518359709674536482047025},
+            {7.3125,            0.99999910982989611769943303422227663},
+            {7.3750,            0.99999921442759946591163427422888252},
+            {7.4375,            0.99999930673475777603853435094943258},
+            {7.5000,            0.99999938819554614875054970643513124},
+            {7.5625,            0.99999946008444508183970109263856958},
+            {7.6250,            0.99999952352618001331402589096040117},
+            {7.6875,            0.99999957951331792817413683491979752},
+            {7.7500,            0.99999962892179632633374697389145081},
+            {7.8125,            0.99999967252462750190604116210421169},
+            {7.8750,            0.99999971100399253750324718031574484},
+            {7.9375,            0.99999974496191422474977283863588658},
+            {8.0000,            0.99999977492967588981001883295636840},
+            {8.0625,            0.99999980137613348259726597081723424},
+            {8.1250,            0.99999982471505097353529823063673263},
+            {8.1875,            0.99999984531157382142423402736529911},
+            {8.2500,            0.99999986348794179107425910499030547},
+            {8.3125,            0.99999987952853049895833839645847571},
+            {8.3750,            0.99999989368430056302584289932834041},
+            {8.4375,            0.99999990617672396471542088609051728},
+            {8.5000,            0.99999991720124905211338798152800748},
+            {8.5625,            0.99999992693035839516545287745322387},
+            {8.6250,            0.99999993551626733394129009365703767},
+            {8.6875,            0.99999994309330543951799157347876934},
+            {8.7500,            0.99999994978001814614368429416607424},
+            {8.8125,            0.99999995568102143535399207289008504},
+            {8.8750,            0.99999996088863858914831986187674522},
+            {8.9375,            0.99999996548434461974481685677429908},
+            {9.0000,            0.99999996954004097447930211118358244},
+            {9.0625,            0.99999997311918045901919121395899372},
+            {9.1250,            0.99999997627775997868467948564005257},
+            {9.1875,            0.99999997906519662964368381583648379},
+            {9.2500,            0.99999998152510084671976114264303159},
+            {9.3125,            0.99999998369595870397054673668361266},
+            {9.3750,            0.99999998561173404286033236040150950},
+            {9.4375,            0.99999998730239984852716512979473289},
+            {9.5000,            0.99999998879440718770812040917618843},
+            {9.5625,            0.99999999011109904501789298212541698},
+            {9.6250,            0.99999999127307553219220251303121960},
+            {9.6875,            0.99999999229851618412119275358396363},
+            {9.7500,            0.99999999320346438410630581726217930},
+            {9.8125,            0.99999999400207836827291739324060736},
+            {9.8750,            0.99999999470685273619047001387577653},
+            {9.9375,            0.99999999532881393331131526966058758},
+            {10.0000,           0.99999999587769276361959283713827574},
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            double [] testCase = testCases[i];
+            failures += testTanhCaseWithUlpDiff(testCase[0],
+                                                testCase[1],
+                                                3.0);
+        }
+
+
+        double [][] specialTestCases = {
+            {0.0,                       0.0},
+            {NaNd,                      NaNd},
+            {Double.longBitsToDouble(0x7FF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0xFFF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0x7FF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0xFFF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0x7FFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0x7FFCafeBabe00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFCafeBabe00000L),      NaNd},
+            {Double.POSITIVE_INFINITY,  1.0}
+        };
+
+        for(int i = 0; i < specialTestCases.length; i++) {
+            failures += testTanhCaseWithUlpDiff(specialTestCases[i][0],
+                                                specialTestCases[i][1],
+                                                0.0);
+        }
+
+        // For powers of 2 less than 2^(-27), the second and
+        // subsequent terms of the Taylor series expansion will get
+        // rounded away since |n-n^3| > 53, the binary precision of a
+        // double significand.
+
+        for(int i = DoubleConsts.MIN_SUB_EXPONENT; i < -27; i++) {
+            double d = FpUtils.scalb(2.0, i);
+
+            // Result and expected are the same.
+            failures += testTanhCaseWithUlpDiff(d, d, 2.5);
+        }
+
+        // For values of x larger than 22, tanh(x) is 1.0 in double
+        // floating-point arithmetic.
+
+        for(int i = 22; i < 32; i++) {
+            failures += testTanhCaseWithUlpDiff(i, 1.0, 2.5);
+        }
+
+        for(int i = 5; i <= DoubleConsts.MAX_EXPONENT; i++) {
+            double d = FpUtils.scalb(2.0, i);
+
+            failures += testTanhCaseWithUlpDiff(d, 1.0, 2.5);
+        }
+
+        return failures;
+    }
+
+    public static int testTanhCaseWithTolerance(double input,
+                                                double expected,
+                                                double tolerance) {
+        int failures = 0;
+        failures += Tests.testTolerance("Math.tanh(double",
+                                        input, Math.tanh(input),
+                                        expected, tolerance);
+        failures += Tests.testTolerance("Math.tanh(double",
+                                        -input, Math.tanh(-input),
+                                        -expected, tolerance);
+
+        failures += Tests.testTolerance("StrictMath.tanh(double",
+                                        input, StrictMath.tanh(input),
+                                        expected, tolerance);
+        failures += Tests.testTolerance("StrictMath.tanh(double",
+                                        -input, StrictMath.tanh(-input),
+                                        -expected, tolerance);
+        return failures;
+    }
+
+    public static int testTanhCaseWithUlpDiff(double input,
+                                              double expected,
+                                              double ulps) {
+        int failures = 0;
+
+        failures += Tests.testUlpDiffWithAbsBound("Math.tanh(double)",
+                                                  input, Math.tanh(input),
+                                                  expected, ulps, 1.0);
+        failures += Tests.testUlpDiffWithAbsBound("Math.tanh(double)",
+                                                  -input, Math.tanh(-input),
+                                                  -expected, ulps, 1.0);
+
+        failures += Tests.testUlpDiffWithAbsBound("StrictMath.tanh(double)",
+                                                  input, StrictMath.tanh(input),
+                                                  expected, ulps, 1.0);
+        failures += Tests.testUlpDiffWithAbsBound("StrictMath.tanh(double)",
+                                                  -input, StrictMath.tanh(-input),
+                                                  -expected, ulps, 1.0);
+        return failures;
+    }
+
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += testSinh();
+        failures += testCosh();
+        failures += testTanh();
+
+        if (failures > 0) {
+            System.err.println("Testing the hyperbolic functions incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/HypotTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4851638 4939441
+ * @summary Tests for {Math, StrictMath}.hypot
+ * @author Joseph D. Darcy
+ */
+
+import sun.misc.DoubleConsts;
+import sun.misc.FpUtils;
+
+public class HypotTests {
+    private HypotTests(){}
+
+    static final double infinityD = Double.POSITIVE_INFINITY;
+    static final double NaNd      = Double.NaN;
+
+    /**
+     * Given integers m and n, assuming m < n, the triple (n^2 - m^2,
+     * 2mn, and n^2 + m^2) is a Pythagorean triple with a^2 + b^2 =
+     * c^2.  This methods returns a long array holding the Pythagorean
+     * triple corresponding to the inputs.
+     */
+    static long [] pythagoreanTriple(int m, int n) {
+        long M = m;
+        long N = n;
+        long result[] = new long[3];
+
+
+        result[0] = Math.abs(M*M - N*N);
+        result[1] = Math.abs(2*M*N);
+        result[2] = Math.abs(M*M + N*N);
+
+        return result;
+    }
+
+    static int testHypot() {
+        int failures = 0;
+
+        double [][] testCases = {
+            // Special cases
+            {infinityD,         infinityD,              infinityD},
+            {infinityD,         0.0,                    infinityD},
+            {infinityD,         1.0,                    infinityD},
+            {infinityD,         NaNd,                   infinityD},
+            {NaNd,              NaNd,                   NaNd},
+            {0.0,               NaNd,                   NaNd},
+            {1.0,               NaNd,                   NaNd},
+            {Double.longBitsToDouble(0x7FF0000000000001L),      1.0,    NaNd},
+            {Double.longBitsToDouble(0xFFF0000000000001L),      1.0,    NaNd},
+            {Double.longBitsToDouble(0x7FF8555555555555L),      1.0,    NaNd},
+            {Double.longBitsToDouble(0xFFF8555555555555L),      1.0,    NaNd},
+            {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),      1.0,    NaNd},
+            {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),      1.0,    NaNd},
+            {Double.longBitsToDouble(0x7FFDeadBeef00000L),      1.0,    NaNd},
+            {Double.longBitsToDouble(0xFFFDeadBeef00000L),      1.0,    NaNd},
+            {Double.longBitsToDouble(0x7FFCafeBabe00000L),      1.0,    NaNd},
+            {Double.longBitsToDouble(0xFFFCafeBabe00000L),      1.0,    NaNd},
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            failures += testHypotCase(testCases[i][0], testCases[i][1],
+                                      testCases[i][2]);
+        }
+
+        // Verify hypot(x, 0.0) is close to x over the entire exponent
+        // range.
+        for(int i = DoubleConsts.MIN_SUB_EXPONENT;
+            i <= DoubleConsts.MAX_EXPONENT;
+            i++) {
+            double input = FpUtils.scalb(2, i);
+            failures += testHypotCase(input, 0.0, input);
+        }
+
+
+        // Test Pythagorean triples
+
+        // Small ones
+        for(int m = 1; m < 10; m++) {
+            for(int n = m+1; n < 11; n++) {
+                long [] result = pythagoreanTriple(m, n);
+                failures += testHypotCase(result[0], result[1], result[2]);
+            }
+        }
+
+        // Big ones
+        for(int m = 100000; m < 100100; m++) {
+            for(int n = m+100000; n < 200200; n++) {
+                long [] result = pythagoreanTriple(m, n);
+                failures += testHypotCase(result[0], result[1], result[2]);
+            }
+        }
+
+        // Approaching overflow tests
+
+        /*
+         * Create a random value r with an large-ish exponent.  The
+         * result of hypot(3*r, 4*r) should be approximately 5*r. (The
+         * computation of 4*r is exact since it just changes the
+         * exponent).  While the exponent of r is less than or equal
+         * to (MAX_EXPONENT - 3), the computation should not overflow.
+         */
+        java.util.Random rand = new java.util.Random();
+        for(int i = 0; i < 1000; i++) {
+            double d = rand.nextDouble();
+            // Scale d to have an exponent equal to MAX_EXPONENT -15
+            d = FpUtils.scalb(d, DoubleConsts.MAX_EXPONENT
+                                 -15 - FpUtils.ilogb(d));
+            for(int j = 0; j <= 13; j += 1) {
+                failures += testHypotCase(3*d, 4*d, 5*d, 2.5);
+                d *= 2.0; // increase exponent by 1
+            }
+        }
+
+        // Test for monotonicity failures.  Fix one argument and test
+        // two numbers before and two numbers after each chosen value;
+        // i.e.
+        //
+        // pcNeighbors[] =
+        // {nextDown(nextDown(pc)),
+        // nextDown(pc),
+        // pc,
+        // nextUp(pc),
+        // nextUp(nextUp(pc))}
+        //
+        // and we test that hypot(pcNeighbors[i]) <= hypot(pcNeighbors[i+1])
+        {
+            double pcNeighbors[] = new double[5];
+            double pcNeighborsHypot[] = new double[5];
+            double pcNeighborsStrictHypot[] = new double[5];
+
+
+            for(int i = -18; i <= 18; i++) {
+                double pc = FpUtils.scalb(1.0, i);
+
+                pcNeighbors[2] = pc;
+                pcNeighbors[1] = FpUtils.nextDown(pc);
+                pcNeighbors[0] = FpUtils.nextDown(pcNeighbors[1]);
+                pcNeighbors[3] = FpUtils.nextUp(pc);
+                pcNeighbors[4] = FpUtils.nextUp(pcNeighbors[3]);
+
+                for(int j = 0; j < pcNeighbors.length; j++) {
+                    pcNeighborsHypot[j]       =       Math.hypot(2.0, pcNeighbors[j]);
+                    pcNeighborsStrictHypot[j] = StrictMath.hypot(2.0, pcNeighbors[j]);
+                }
+
+                for(int j = 0; j < pcNeighborsHypot.length-1; j++) {
+                    if(pcNeighborsHypot[j] >  pcNeighborsHypot[j+1] ) {
+                        failures++;
+                        System.err.println("Monotonicity failure for Math.hypot on " +
+                                          pcNeighbors[j] + " and "  +
+                                          pcNeighbors[j+1] + "\n\treturned " +
+                                          pcNeighborsHypot[j] + " and " +
+                                          pcNeighborsHypot[j+1] );
+                    }
+
+                    if(pcNeighborsStrictHypot[j] >  pcNeighborsStrictHypot[j+1] ) {
+                        failures++;
+                        System.err.println("Monotonicity failure for StrictMath.hypot on " +
+                                          pcNeighbors[j] + " and "  +
+                                          pcNeighbors[j+1] + "\n\treturned " +
+                                          pcNeighborsStrictHypot[j] + " and " +
+                                          pcNeighborsStrictHypot[j+1] );
+                    }
+
+
+                }
+
+            }
+        }
+
+
+        return failures;
+    }
+
+    static int testHypotCase(double input1, double input2, double expected) {
+        return testHypotCase(input1,input2, expected, 1);
+    }
+
+    static int testHypotCase(double input1, double input2, double expected,
+                             double ulps) {
+        int failures = 0;
+        if (expected < 0.0) {
+            throw new AssertionError("Result of hypot must be greater than " +
+                                     "or equal to zero");
+        }
+
+        // Test Math and StrictMath methods with no inputs negated,
+        // each input negated singly, and both inputs negated.  Also
+        // test inputs in reversed order.
+
+        for(int i = -1; i <= 1; i+=2) {
+            for(int j = -1; j <= 1; j+=2) {
+                double x = i * input1;
+                double y = j * input2;
+                failures += Tests.testUlpDiff("Math.hypot", x, y,
+                                              Math.hypot(x, y), expected, ulps);
+                failures += Tests.testUlpDiff("Math.hypot", y, x,
+                                              Math.hypot(y, x ), expected, ulps);
+
+                failures += Tests.testUlpDiff("StrictMath.hypot", x, y,
+                                              StrictMath.hypot(x, y), expected, ulps);
+                failures += Tests.testUlpDiff("StrictMath.hypot", y, x,
+                                              StrictMath.hypot(y, x), expected, ulps);
+            }
+        }
+
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += testHypot();
+
+        if (failures > 0) {
+            System.err.println("Testing the hypot incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/IeeeRecommendedTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,1705 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4860891 4826732 4780454 4939441 4826652
+ * @summary Tests for IEEE 754[R] recommended functions and similar methods
+ * @author Joseph D. Darcy
+ * @compile -source 1.5 IeeeRecommendedTests.java
+ * @run main IeeeRecommendedTests
+ */
+
+import sun.misc.FpUtils;
+import sun.misc.DoubleConsts;
+import sun.misc.FloatConsts;
+
+public class IeeeRecommendedTests {
+    private IeeeRecommendedTests(){}
+
+    static final float  NaNf = Float.NaN;
+    static final double NaNd = Double.NaN;
+    static final float  infinityF = Float.POSITIVE_INFINITY;
+    static final double infinityD = Double.POSITIVE_INFINITY;
+
+    static final float  Float_MAX_VALUEmm       = 0x1.fffffcP+127f;
+    static final float  Float_MAX_SUBNORMAL     = 0x0.fffffeP-126f;
+    static final float  Float_MAX_SUBNORMALmm   = 0x0.fffffcP-126f;
+
+    static final double Double_MAX_VALUEmm      = 0x1.ffffffffffffeP+1023;
+    static final double Double_MAX_SUBNORMAL    = 0x0.fffffffffffffP-1022;
+    static final double Double_MAX_SUBNORMALmm  = 0x0.ffffffffffffeP-1022;
+
+    // Initialize shared random number generator
+    static java.util.Random rand = new java.util.Random();
+
+    /**
+     * Returns a floating-point power of two in the normal range.
+     */
+    static double powerOfTwoD(int n) {
+        return Double.longBitsToDouble((((long)n + (long)DoubleConsts.MAX_EXPONENT) <<
+                                        (DoubleConsts.SIGNIFICAND_WIDTH-1))
+                                       & DoubleConsts.EXP_BIT_MASK);
+    }
+
+    /**
+     * Returns a floating-point power of two in the normal range.
+     */
+    static float powerOfTwoF(int n) {
+        return Float.intBitsToFloat(((n + FloatConsts.MAX_EXPONENT) <<
+                                     (FloatConsts.SIGNIFICAND_WIDTH-1))
+                                    & FloatConsts.EXP_BIT_MASK);
+    }
+
+    /* ******************** getExponent tests ****************************** */
+
+    /*
+     * The tests for getExponent should test the special values (NaN, +/-
+     * infinity, etc.), test the endpoints of each binade (set of
+     * floating-point values with the same exponent), and for good
+     * measure, test some random values within each binade.  Testing
+     * the endpoints of each binade includes testing both positive and
+     * negative numbers.  Subnormal values with different normalized
+     * exponents should be tested too.  Both Math and StrictMath
+     * methods should return the same results.
+     */
+
+    /*
+     * Test Math.getExponent and StrictMath.getExponent with +d and -d.
+     */
+    static int testGetExponentCase(float f, int expected) {
+        float minus_f = -f;
+        int failures=0;
+
+        failures+=Tests.test("Math.getExponent(float)", f,
+                             Math.getExponent(f), expected);
+        failures+=Tests.test("Math.getExponent(float)", minus_f,
+                             Math.getExponent(minus_f), expected);
+
+        failures+=Tests.test("StrictMath.getExponent(float)", f,
+                             StrictMath.getExponent(f), expected);
+        failures+=Tests.test("StrictMath.getExponent(float)", minus_f,
+                             StrictMath.getExponent(minus_f), expected);
+        return failures;
+    }
+
+    /*
+     * Test Math.getExponent and StrictMath.getExponent with +d and -d.
+     */
+    static int testGetExponentCase(double d, int expected) {
+        double minus_d = -d;
+        int failures=0;
+
+        failures+=Tests.test("Math.getExponent(double)", d,
+                             Math.getExponent(d), expected);
+        failures+=Tests.test("Math.getExponent(double)", minus_d,
+                             Math.getExponent(minus_d), expected);
+
+        failures+=Tests.test("StrictMath.getExponent(double)", d,
+                             StrictMath.getExponent(d), expected);
+        failures+=Tests.test("StrictMath.getExponent(double)", minus_d,
+                             StrictMath.getExponent(minus_d), expected);
+        return failures;
+    }
+
+    public static int testFloatGetExponent() {
+        int failures = 0;
+        float [] specialValues = {NaNf,
+                                   Float.POSITIVE_INFINITY,
+                                   +0.0f,
+                                  +1.0f,
+                                  +2.0f,
+                                  +16.0f,
+                                  +Float.MIN_VALUE,
+                                  +Float_MAX_SUBNORMAL,
+                                  +FloatConsts.MIN_NORMAL,
+                                  +Float.MAX_VALUE
+        };
+
+        int [] specialResults = {Float.MAX_EXPONENT + 1, // NaN results
+                                 Float.MAX_EXPONENT + 1, // Infinite results
+                                 Float.MIN_EXPONENT - 1, // Zero results
+                                 0,
+                                 1,
+                                 4,
+                                 FloatConsts.MIN_EXPONENT - 1,
+                                 -FloatConsts.MAX_EXPONENT,
+                                 FloatConsts.MIN_EXPONENT,
+                                 FloatConsts.MAX_EXPONENT
+        };
+
+        // Special value tests
+        for(int i = 0; i < specialValues.length; i++) {
+            failures += testGetExponentCase(specialValues[i], specialResults[i]);
+        }
+
+
+        // Normal exponent tests
+        for(int i = FloatConsts.MIN_EXPONENT; i <= FloatConsts.MAX_EXPONENT; i++) {
+            int result;
+
+            // Create power of two
+            float po2 = powerOfTwoF(i);
+
+            failures += testGetExponentCase(po2, i);
+
+            // Generate some random bit patterns for the significand
+            for(int j = 0; j < 10; j++) {
+                int randSignif = rand.nextInt();
+                float randFloat;
+
+                randFloat = Float.intBitsToFloat( // Exponent
+                                                 (Float.floatToIntBits(po2)&
+                                                  (~FloatConsts.SIGNIF_BIT_MASK)) |
+                                                 // Significand
+                                                 (randSignif &
+                                                  FloatConsts.SIGNIF_BIT_MASK) );
+
+                failures += testGetExponentCase(randFloat, i);
+            }
+
+            if (i > FloatConsts.MIN_EXPONENT) {
+                float po2minus = FpUtils.nextAfter(po2,
+                                                 Float.NEGATIVE_INFINITY);
+                failures += testGetExponentCase(po2minus, i-1);
+            }
+        }
+
+        // Subnormal exponent tests
+
+        /*
+         * Start with MIN_VALUE, left shift, test high value, low
+         * values, and random in between.
+         *
+         * Use nextAfter to calculate, high value of previous binade,
+         * loop count i will indicate how many random bits, if any are
+         * needed.
+         */
+
+        float top=Float.MIN_VALUE;
+        for( int i = 1;
+            i < FloatConsts.SIGNIFICAND_WIDTH;
+            i++, top *= 2.0f) {
+
+            failures += testGetExponentCase(top,
+                                            FloatConsts.MIN_EXPONENT - 1);
+
+            // Test largest value in next smaller binade
+            if (i >= 3) {// (i == 1) would test 0.0;
+                         // (i == 2) would just retest MIN_VALUE
+                testGetExponentCase(FpUtils.nextAfter(top, 0.0f),
+                                    FloatConsts.MIN_EXPONENT - 1);
+
+                if( i >= 10) {
+                    // create a bit mask with (i-1) 1's in the low order
+                    // bits
+                    int mask = ~((~0)<<(i-1));
+                    float randFloat = Float.intBitsToFloat( // Exponent
+                                                 Float.floatToIntBits(top) |
+                                                 // Significand
+                                                 (rand.nextInt() & mask ) ) ;
+
+                    failures += testGetExponentCase(randFloat,
+                                                    FloatConsts.MIN_EXPONENT - 1);
+                }
+            }
+        }
+
+        return failures;
+    }
+
+
+    public static int testDoubleGetExponent() {
+        int failures = 0;
+        double [] specialValues = {NaNd,
+                                   infinityD,
+                                   +0.0,
+                                   +1.0,
+                                   +2.0,
+                                   +16.0,
+                                   +Double.MIN_VALUE,
+                                   +Double_MAX_SUBNORMAL,
+                                   +DoubleConsts.MIN_NORMAL,
+                                   +Double.MAX_VALUE
+        };
+
+        int [] specialResults = {Double.MAX_EXPONENT + 1, // NaN results
+                                 Double.MAX_EXPONENT + 1, // Infinite results
+                                 Double.MIN_EXPONENT - 1, // Zero results
+                                 0,
+                                 1,
+                                 4,
+                                 DoubleConsts.MIN_EXPONENT - 1,
+                                 -DoubleConsts.MAX_EXPONENT,
+                                 DoubleConsts.MIN_EXPONENT,
+                                 DoubleConsts.MAX_EXPONENT
+        };
+
+        // Special value tests
+        for(int i = 0; i < specialValues.length; i++) {
+            failures += testGetExponentCase(specialValues[i], specialResults[i]);
+        }
+
+
+        // Normal exponent tests
+        for(int i = DoubleConsts.MIN_EXPONENT; i <= DoubleConsts.MAX_EXPONENT; i++) {
+            int result;
+
+            // Create power of two
+            double po2 = powerOfTwoD(i);
+
+            failures += testGetExponentCase(po2, i);
+
+            // Generate some random bit patterns for the significand
+            for(int j = 0; j < 10; j++) {
+                long randSignif = rand.nextLong();
+                double randFloat;
+
+                randFloat = Double.longBitsToDouble( // Exponent
+                                                 (Double.doubleToLongBits(po2)&
+                                                  (~DoubleConsts.SIGNIF_BIT_MASK)) |
+                                                 // Significand
+                                                 (randSignif &
+                                                  DoubleConsts.SIGNIF_BIT_MASK) );
+
+                failures += testGetExponentCase(randFloat, i);
+            }
+
+            if (i > DoubleConsts.MIN_EXPONENT) {
+                double po2minus = FpUtils.nextAfter(po2,
+                                                    Double.NEGATIVE_INFINITY);
+                failures += testGetExponentCase(po2minus, i-1);
+            }
+        }
+
+        // Subnormal exponent tests
+
+        /*
+         * Start with MIN_VALUE, left shift, test high value, low
+         * values, and random in between.
+         *
+         * Use nextAfter to calculate, high value of previous binade;
+         * loop count i will indicate how many random bits, if any are
+         * needed.
+         */
+
+        double top=Double.MIN_VALUE;
+        for( int i = 1;
+            i < DoubleConsts.SIGNIFICAND_WIDTH;
+            i++, top *= 2.0f) {
+
+            failures += testGetExponentCase(top,
+                                            DoubleConsts.MIN_EXPONENT - 1);
+
+            // Test largest value in next smaller binade
+            if (i >= 3) {// (i == 1) would test 0.0;
+                         // (i == 2) would just retest MIN_VALUE
+                testGetExponentCase(FpUtils.nextAfter(top, 0.0),
+                                    DoubleConsts.MIN_EXPONENT - 1);
+
+                if( i >= 10) {
+                    // create a bit mask with (i-1) 1's in the low order
+                    // bits
+                    long mask = ~((~0L)<<(i-1));
+                    double randFloat = Double.longBitsToDouble( // Exponent
+                                                 Double.doubleToLongBits(top) |
+                                                 // Significand
+                                                 (rand.nextLong() & mask ) ) ;
+
+                    failures += testGetExponentCase(randFloat,
+                                                    DoubleConsts.MIN_EXPONENT - 1);
+                }
+            }
+        }
+
+        return failures;
+    }
+
+
+    /* ******************** nextAfter tests ****************************** */
+
+    static int testNextAfterCase(float start, double direction, float expected) {
+        int failures=0;
+        float minus_start = -start;
+        double minus_direction = -direction;
+        float minus_expected = -expected;
+
+        failures+=Tests.test("Math.nextAfter(float,double)", start, direction,
+                             Math.nextAfter(start, direction), expected);
+        failures+=Tests.test("Math.nextAfter(float,double)", minus_start, minus_direction,
+                             Math.nextAfter(minus_start, minus_direction), minus_expected);
+
+        failures+=Tests.test("StrictMath.nextAfter(float,double)", start, direction,
+                             StrictMath.nextAfter(start, direction), expected);
+        failures+=Tests.test("StrictMath.nextAfter(float,double)", minus_start, minus_direction,
+                             StrictMath.nextAfter(minus_start, minus_direction), minus_expected);
+        return failures;
+    }
+
+    static int testNextAfterCase(double start, double direction, double expected) {
+        int failures=0;
+
+        double minus_start = -start;
+        double minus_direction = -direction;
+        double minus_expected = -expected;
+
+        failures+=Tests.test("Math.nextAfter(double,double)", start, direction,
+                             Math.nextAfter(start, direction), expected);
+        failures+=Tests.test("Math.nextAfter(double,double)", minus_start, minus_direction,
+                             Math.nextAfter(minus_start, minus_direction), minus_expected);
+
+        failures+=Tests.test("StrictMath.nextAfter(double,double)", start, direction,
+                             StrictMath.nextAfter(start, direction), expected);
+        failures+=Tests.test("StrictMath.nextAfter(double,double)", minus_start, minus_direction,
+                             StrictMath.nextAfter(minus_start, minus_direction), minus_expected);
+        return failures;
+    }
+
+    public static int testFloatNextAfter() {
+        int failures=0;
+
+        /*
+         * Each row of the testCases matrix represents one test case
+         * for nexAfter; given the input of the first two columns, the
+         * result in the last column is expected.
+         */
+        float [][] testCases  = {
+            {NaNf,              NaNf,                   NaNf},
+            {NaNf,              0.0f,                   NaNf},
+            {0.0f,              NaNf,                   NaNf},
+            {NaNf,              infinityF,              NaNf},
+            {infinityF,         NaNf,                   NaNf},
+
+            {infinityF,         infinityF,              infinityF},
+            {infinityF,         -infinityF,             Float.MAX_VALUE},
+            {infinityF,         0.0f,                   Float.MAX_VALUE},
+
+            {Float.MAX_VALUE,   infinityF,              infinityF},
+            {Float.MAX_VALUE,   -infinityF,             Float_MAX_VALUEmm},
+            {Float.MAX_VALUE,   Float.MAX_VALUE,        Float.MAX_VALUE},
+            {Float.MAX_VALUE,   0.0f,                   Float_MAX_VALUEmm},
+
+            {Float_MAX_VALUEmm, Float.MAX_VALUE,        Float.MAX_VALUE},
+            {Float_MAX_VALUEmm, infinityF,              Float.MAX_VALUE},
+            {Float_MAX_VALUEmm, Float_MAX_VALUEmm,      Float_MAX_VALUEmm},
+
+            {FloatConsts.MIN_NORMAL,    infinityF,              FloatConsts.MIN_NORMAL+
+                                                                Float.MIN_VALUE},
+            {FloatConsts.MIN_NORMAL,    -infinityF,             Float_MAX_SUBNORMAL},
+            {FloatConsts.MIN_NORMAL,    1.0f,                   FloatConsts.MIN_NORMAL+
+                                                                Float.MIN_VALUE},
+            {FloatConsts.MIN_NORMAL,    -1.0f,                  Float_MAX_SUBNORMAL},
+            {FloatConsts.MIN_NORMAL,    FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL},
+
+            {Float_MAX_SUBNORMAL,       FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL},
+            {Float_MAX_SUBNORMAL,       Float_MAX_SUBNORMAL,    Float_MAX_SUBNORMAL},
+            {Float_MAX_SUBNORMAL,       0.0f,                   Float_MAX_SUBNORMALmm},
+
+            {Float_MAX_SUBNORMALmm,     Float_MAX_SUBNORMAL,    Float_MAX_SUBNORMAL},
+            {Float_MAX_SUBNORMALmm,     0.0f,                   Float_MAX_SUBNORMALmm-Float.MIN_VALUE},
+            {Float_MAX_SUBNORMALmm,     Float_MAX_SUBNORMALmm,  Float_MAX_SUBNORMALmm},
+
+            {Float.MIN_VALUE,   0.0f,                   0.0f},
+            {-Float.MIN_VALUE,  0.0f,                   -0.0f},
+            {Float.MIN_VALUE,   Float.MIN_VALUE,        Float.MIN_VALUE},
+            {Float.MIN_VALUE,   1.0f,                   2*Float.MIN_VALUE},
+
+            // Make sure zero behavior is tested
+            {0.0f,              0.0f,                   0.0f},
+            {0.0f,              -0.0f,                  -0.0f},
+            {-0.0f,             0.0f,                   0.0f},
+            {-0.0f,             -0.0f,                  -0.0f},
+            {0.0f,              infinityF,              Float.MIN_VALUE},
+            {0.0f,              -infinityF,             -Float.MIN_VALUE},
+            {-0.0f,             infinityF,              Float.MIN_VALUE},
+            {-0.0f,             -infinityF,             -Float.MIN_VALUE},
+            {0.0f,              Float.MIN_VALUE,        Float.MIN_VALUE},
+            {0.0f,              -Float.MIN_VALUE,       -Float.MIN_VALUE},
+            {-0.0f,             Float.MIN_VALUE,        Float.MIN_VALUE},
+            {-0.0f,             -Float.MIN_VALUE,       -Float.MIN_VALUE}
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            failures += testNextAfterCase(testCases[i][0], testCases[i][1],
+                                          testCases[i][2]);
+        }
+
+        return failures;
+    }
+
+    public static int testDoubleNextAfter() {
+        int failures =0;
+
+        /*
+         * Each row of the testCases matrix represents one test case
+         * for nexAfter; given the input of the first two columns, the
+         * result in the last column is expected.
+         */
+        double [][] testCases  = {
+            {NaNd,              NaNd,                   NaNd},
+            {NaNd,              0.0d,                   NaNd},
+            {0.0d,              NaNd,                   NaNd},
+            {NaNd,              infinityD,              NaNd},
+            {infinityD,         NaNd,                   NaNd},
+
+            {infinityD,         infinityD,              infinityD},
+            {infinityD,         -infinityD,             Double.MAX_VALUE},
+            {infinityD,         0.0d,                   Double.MAX_VALUE},
+
+            {Double.MAX_VALUE,  infinityD,              infinityD},
+            {Double.MAX_VALUE,  -infinityD,             Double_MAX_VALUEmm},
+            {Double.MAX_VALUE,  Double.MAX_VALUE,       Double.MAX_VALUE},
+            {Double.MAX_VALUE,  0.0d,                   Double_MAX_VALUEmm},
+
+            {Double_MAX_VALUEmm,        Double.MAX_VALUE,       Double.MAX_VALUE},
+            {Double_MAX_VALUEmm,        infinityD,              Double.MAX_VALUE},
+            {Double_MAX_VALUEmm,        Double_MAX_VALUEmm,     Double_MAX_VALUEmm},
+
+            {DoubleConsts.MIN_NORMAL,   infinityD,              DoubleConsts.MIN_NORMAL+
+                                                                Double.MIN_VALUE},
+            {DoubleConsts.MIN_NORMAL,   -infinityD,             Double_MAX_SUBNORMAL},
+            {DoubleConsts.MIN_NORMAL,   1.0f,                   DoubleConsts.MIN_NORMAL+
+                                                                Double.MIN_VALUE},
+            {DoubleConsts.MIN_NORMAL,   -1.0f,                  Double_MAX_SUBNORMAL},
+            {DoubleConsts.MIN_NORMAL,   DoubleConsts.MIN_NORMAL,DoubleConsts.MIN_NORMAL},
+
+            {Double_MAX_SUBNORMAL,      DoubleConsts.MIN_NORMAL,DoubleConsts.MIN_NORMAL},
+            {Double_MAX_SUBNORMAL,      Double_MAX_SUBNORMAL,   Double_MAX_SUBNORMAL},
+            {Double_MAX_SUBNORMAL,      0.0d,                   Double_MAX_SUBNORMALmm},
+
+            {Double_MAX_SUBNORMALmm,    Double_MAX_SUBNORMAL,   Double_MAX_SUBNORMAL},
+            {Double_MAX_SUBNORMALmm,    0.0d,                   Double_MAX_SUBNORMALmm-Double.MIN_VALUE},
+            {Double_MAX_SUBNORMALmm,    Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMALmm},
+
+            {Double.MIN_VALUE,  0.0d,                   0.0d},
+            {-Double.MIN_VALUE, 0.0d,                   -0.0d},
+            {Double.MIN_VALUE,  Double.MIN_VALUE,       Double.MIN_VALUE},
+            {Double.MIN_VALUE,  1.0f,                   2*Double.MIN_VALUE},
+
+            // Make sure zero behavior is tested
+            {0.0d,              0.0d,                   0.0d},
+            {0.0d,              -0.0d,                  -0.0d},
+            {-0.0d,             0.0d,                   0.0d},
+            {-0.0d,             -0.0d,                  -0.0d},
+            {0.0d,              infinityD,              Double.MIN_VALUE},
+            {0.0d,              -infinityD,             -Double.MIN_VALUE},
+            {-0.0d,             infinityD,              Double.MIN_VALUE},
+            {-0.0d,             -infinityD,             -Double.MIN_VALUE},
+            {0.0d,              Double.MIN_VALUE,       Double.MIN_VALUE},
+            {0.0d,              -Double.MIN_VALUE,      -Double.MIN_VALUE},
+            {-0.0d,             Double.MIN_VALUE,       Double.MIN_VALUE},
+            {-0.0d,             -Double.MIN_VALUE,      -Double.MIN_VALUE}
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            failures += testNextAfterCase(testCases[i][0], testCases[i][1],
+                                          testCases[i][2]);
+        }
+        return failures;
+    }
+
+    /* ******************** nextUp tests ********************************* */
+
+    public static int testFloatNextUp() {
+        int failures=0;
+
+        /*
+         * Each row of testCases represents one test case for nextUp;
+         * the first column is the input and the second column is the
+         * expected result.
+         */
+        float testCases [][] = {
+            {NaNf,                      NaNf},
+            {-infinityF,                -Float.MAX_VALUE},
+            {-Float.MAX_VALUE,          -Float_MAX_VALUEmm},
+            {-FloatConsts.MIN_NORMAL,   -Float_MAX_SUBNORMAL},
+            {-Float_MAX_SUBNORMAL,      -Float_MAX_SUBNORMALmm},
+            {-Float.MIN_VALUE,          -0.0f},
+            {-0.0f,                     Float.MIN_VALUE},
+            {+0.0f,                     Float.MIN_VALUE},
+            {Float.MIN_VALUE,           Float.MIN_VALUE*2},
+            {Float_MAX_SUBNORMALmm,     Float_MAX_SUBNORMAL},
+            {Float_MAX_SUBNORMAL,       FloatConsts.MIN_NORMAL},
+            {FloatConsts.MIN_NORMAL,    FloatConsts.MIN_NORMAL+Float.MIN_VALUE},
+            {Float_MAX_VALUEmm,         Float.MAX_VALUE},
+            {Float.MAX_VALUE,           infinityF},
+            {infinityF,                 infinityF}
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            failures+=Tests.test("Math.nextUp(float)",
+                                 testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]);
+
+            failures+=Tests.test("StrictMath.nextUp(float)",
+                                 testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]);
+        }
+
+        return failures;
+    }
+
+
+    public static int testDoubleNextUp() {
+        int failures=0;
+
+        /*
+         * Each row of testCases represents one test case for nextUp;
+         * the first column is the input and the second column is the
+         * expected result.
+         */
+        double testCases [][] = {
+            {NaNd,                      NaNd},
+            {-infinityD,                -Double.MAX_VALUE},
+            {-Double.MAX_VALUE,         -Double_MAX_VALUEmm},
+            {-DoubleConsts.MIN_NORMAL,  -Double_MAX_SUBNORMAL},
+            {-Double_MAX_SUBNORMAL,     -Double_MAX_SUBNORMALmm},
+            {-Double.MIN_VALUE,         -0.0d},
+            {-0.0d,                     Double.MIN_VALUE},
+            {+0.0d,                     Double.MIN_VALUE},
+            {Double.MIN_VALUE,          Double.MIN_VALUE*2},
+            {Double_MAX_SUBNORMALmm,    Double_MAX_SUBNORMAL},
+            {Double_MAX_SUBNORMAL,      DoubleConsts.MIN_NORMAL},
+            {DoubleConsts.MIN_NORMAL,   DoubleConsts.MIN_NORMAL+Double.MIN_VALUE},
+            {Double_MAX_VALUEmm,        Double.MAX_VALUE},
+            {Double.MAX_VALUE,          infinityD},
+            {infinityD,                 infinityD}
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            failures+=Tests.test("Math.nextUp(double)",
+                                 testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]);
+
+            failures+=Tests.test("StrictMath.nextUp(double)",
+                                 testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]);
+        }
+
+        return failures;
+    }
+
+    /* ******************** nextDown tests ********************************* */
+
+    public static int testFloatNextDown() {
+        int failures=0;
+
+        /*
+         * Each row of testCases represents one test case for nextDown;
+         * the first column is the input and the second column is the
+         * expected result.
+         */
+        float testCases [][] = {
+            {NaNf,                      NaNf},
+            {-infinityF,                -infinityF},
+            {-Float.MAX_VALUE,          -infinityF},
+            {-Float_MAX_VALUEmm,        -Float.MAX_VALUE},
+            {-Float_MAX_SUBNORMAL,      -FloatConsts.MIN_NORMAL},
+            {-Float_MAX_SUBNORMALmm,    -Float_MAX_SUBNORMAL},
+            {-0.0f,                     -Float.MIN_VALUE},
+            {+0.0f,                     -Float.MIN_VALUE},
+            {Float.MIN_VALUE,           0.0f},
+            {Float.MIN_VALUE*2,         Float.MIN_VALUE},
+            {Float_MAX_SUBNORMAL,       Float_MAX_SUBNORMALmm},
+            {FloatConsts.MIN_NORMAL,    Float_MAX_SUBNORMAL},
+            {FloatConsts.MIN_NORMAL+
+             Float.MIN_VALUE,           FloatConsts.MIN_NORMAL},
+            {Float.MAX_VALUE,           Float_MAX_VALUEmm},
+            {infinityF,                 Float.MAX_VALUE},
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            failures+=Tests.test("FpUtils.nextDown(float)",
+                                 testCases[i][0], FpUtils.nextDown(testCases[i][0]), testCases[i][1]);
+        }
+
+        return failures;
+    }
+
+
+    public static int testDoubleNextDown() {
+        int failures=0;
+
+        /*
+         * Each row of testCases represents one test case for nextDown;
+         * the first column is the input and the second column is the
+         * expected result.
+         */
+        double testCases [][] = {
+            {NaNd,                      NaNd},
+            {-infinityD,                -infinityD},
+            {-Double.MAX_VALUE,         -infinityD},
+            {-Double_MAX_VALUEmm,       -Double.MAX_VALUE},
+            {-Double_MAX_SUBNORMAL,     -DoubleConsts.MIN_NORMAL},
+            {-Double_MAX_SUBNORMALmm,   -Double_MAX_SUBNORMAL},
+            {-0.0d,                     -Double.MIN_VALUE},
+            {+0.0d,                     -Double.MIN_VALUE},
+            {Double.MIN_VALUE,          0.0d},
+            {Double.MIN_VALUE*2,        Double.MIN_VALUE},
+            {Double_MAX_SUBNORMAL,      Double_MAX_SUBNORMALmm},
+            {DoubleConsts.MIN_NORMAL,   Double_MAX_SUBNORMAL},
+            {DoubleConsts.MIN_NORMAL+
+             Double.MIN_VALUE,          DoubleConsts.MIN_NORMAL},
+            {Double.MAX_VALUE,          Double_MAX_VALUEmm},
+            {infinityD,                 Double.MAX_VALUE},
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            failures+=Tests.test("FpUtils.nextDown(double)",
+                                 testCases[i][0], FpUtils.nextDown(testCases[i][0]), testCases[i][1]);
+        }
+
+        return failures;
+    }
+
+
+    /* ********************** boolean tests ****************************** */
+
+    /*
+     * Combined tests for boolean functions, isFinite, isInfinite,
+     * isNaN, isUnordered.
+     */
+
+    public static int testFloatBooleanMethods() {
+        int failures = 0;
+
+        float testCases [] = {
+            NaNf,
+            -infinityF,
+            infinityF,
+            -Float.MAX_VALUE,
+            -3.0f,
+            -1.0f,
+            -FloatConsts.MIN_NORMAL,
+            -Float_MAX_SUBNORMALmm,
+            -Float_MAX_SUBNORMAL,
+            -Float.MIN_VALUE,
+            -0.0f,
+            +0.0f,
+            Float.MIN_VALUE,
+            Float_MAX_SUBNORMALmm,
+            Float_MAX_SUBNORMAL,
+            FloatConsts.MIN_NORMAL,
+            1.0f,
+            3.0f,
+            Float_MAX_VALUEmm,
+            Float.MAX_VALUE
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            // isNaN
+            failures+=Tests.test("FpUtils.isNaN(float)", testCases[i],
+                                 FpUtils.isNaN(testCases[i]), (i ==0));
+
+            // isFinite
+            failures+=Tests.test("FpUtils.isFinite(float)", testCases[i],
+                                 FpUtils.isFinite(testCases[i]), (i >= 3));
+
+            // isInfinite
+            failures+=Tests.test("FpUtils.isInfinite(float)", testCases[i],
+                                 FpUtils.isInfinite(testCases[i]), (i==1 || i==2));
+
+            // isUnorderd
+            for(int j = 0; j < testCases.length; j++) {
+                failures+=Tests.test("FpUtils.isUnordered(float, float)", testCases[i],testCases[j],
+                                     FpUtils.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));
+            }
+        }
+
+        return failures;
+    }
+
+    public static int testDoubleBooleanMethods() {
+        int failures = 0;
+        boolean result = false;
+
+        double testCases [] = {
+            NaNd,
+            -infinityD,
+            infinityD,
+            -Double.MAX_VALUE,
+            -3.0d,
+            -1.0d,
+            -DoubleConsts.MIN_NORMAL,
+            -Double_MAX_SUBNORMALmm,
+            -Double_MAX_SUBNORMAL,
+            -Double.MIN_VALUE,
+            -0.0d,
+            +0.0d,
+            Double.MIN_VALUE,
+            Double_MAX_SUBNORMALmm,
+            Double_MAX_SUBNORMAL,
+            DoubleConsts.MIN_NORMAL,
+            1.0d,
+            3.0d,
+            Double_MAX_VALUEmm,
+            Double.MAX_VALUE
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            // isNaN
+            failures+=Tests.test("FpUtils.isNaN(double)", testCases[i],
+                                 FpUtils.isNaN(testCases[i]), (i ==0));
+
+            // isFinite
+            failures+=Tests.test("FpUtils.isFinite(double)", testCases[i],
+                                 FpUtils.isFinite(testCases[i]), (i >= 3));
+
+            // isInfinite
+            failures+=Tests.test("FpUtils.isInfinite(double)", testCases[i],
+                                 FpUtils.isInfinite(testCases[i]), (i==1 || i==2));
+
+            // isUnorderd
+            for(int j = 0; j < testCases.length; j++) {
+                failures+=Tests.test("FpUtils.isUnordered(double, double)", testCases[i],testCases[j],
+                                     FpUtils.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));
+            }
+        }
+
+        return failures;
+    }
+
+    /* ******************** copySign tests******************************** */
+
+   public static int testFloatCopySign() {
+        int failures = 0;
+
+        // testCases[0] are logically positive numbers;
+        // testCases[1] are negative numbers.
+        float testCases [][] = {
+            {+0.0f,
+             Float.MIN_VALUE,
+             Float_MAX_SUBNORMALmm,
+             Float_MAX_SUBNORMAL,
+             FloatConsts.MIN_NORMAL,
+             1.0f,
+             3.0f,
+             Float_MAX_VALUEmm,
+             Float.MAX_VALUE,
+             infinityF,
+            },
+            {-infinityF,
+             -Float.MAX_VALUE,
+             -3.0f,
+             -1.0f,
+             -FloatConsts.MIN_NORMAL,
+             -Float_MAX_SUBNORMALmm,
+             -Float_MAX_SUBNORMAL,
+             -Float.MIN_VALUE,
+             -0.0f}
+        };
+
+        float NaNs[] = {Float.intBitsToFloat(0x7fc00000),       // "positive" NaN
+                        Float.intBitsToFloat(0xFfc00000)};      // "negative" NaN
+
+        // Tests shared between raw and non-raw versions
+        for(int i = 0; i < 2; i++) {
+            for(int j = 0; j < 2; j++) {
+                for(int m = 0; m < testCases[i].length; m++) {
+                    for(int n = 0; n < testCases[j].length; n++) {
+                        // copySign(magnitude, sign)
+                        failures+=Tests.test("Math.copySign(float,float)",
+                                             testCases[i][m],testCases[j][n],
+                                             Math.copySign(testCases[i][m], testCases[j][n]),
+                                             (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );
+
+                        failures+=Tests.test("StrictMath.copySign(float,float)",
+                                             testCases[i][m],testCases[j][n],
+                                             StrictMath.copySign(testCases[i][m], testCases[j][n]),
+                                             (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );
+                    }
+                }
+            }
+        }
+
+        // For rawCopySign, NaN may effectively have either sign bit
+        // while for copySign NaNs are treated as if they always have
+        // a zero sign bit (i.e. as positive numbers)
+        for(int i = 0; i < 2; i++) {
+            for(int j = 0; j < NaNs.length; j++) {
+                for(int m = 0; m < testCases[i].length; m++) {
+                    // copySign(magnitude, sign)
+
+                    failures += (Math.abs(Math.copySign(testCases[i][m], NaNs[j])) ==
+                                 Math.abs(testCases[i][m])) ? 0:1;
+
+
+                    failures+=Tests.test("StrictMath.copySign(float,float)",
+                                         testCases[i][m], NaNs[j],
+                                         StrictMath.copySign(testCases[i][m], NaNs[j]),
+                                         Math.abs(testCases[i][m]) );
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    public static int testDoubleCopySign() {
+        int failures = 0;
+
+        // testCases[0] are logically positive numbers;
+        // testCases[1] are negative numbers.
+        double testCases [][] = {
+            {+0.0d,
+             Double.MIN_VALUE,
+             Double_MAX_SUBNORMALmm,
+             Double_MAX_SUBNORMAL,
+             DoubleConsts.MIN_NORMAL,
+             1.0d,
+             3.0d,
+             Double_MAX_VALUEmm,
+             Double.MAX_VALUE,
+             infinityD,
+            },
+            {-infinityD,
+             -Double.MAX_VALUE,
+             -3.0d,
+             -1.0d,
+             -DoubleConsts.MIN_NORMAL,
+             -Double_MAX_SUBNORMALmm,
+             -Double_MAX_SUBNORMAL,
+             -Double.MIN_VALUE,
+             -0.0d}
+        };
+
+        double NaNs[] = {Double.longBitsToDouble(0x7ff8000000000000L),  // "positive" NaN
+                         Double.longBitsToDouble(0xfff8000000000000L),  // "negative" NaN
+                         Double.longBitsToDouble(0x7FF0000000000001L),
+                         Double.longBitsToDouble(0xFFF0000000000001L),
+                         Double.longBitsToDouble(0x7FF8555555555555L),
+                         Double.longBitsToDouble(0xFFF8555555555555L),
+                         Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),
+                         Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),
+                         Double.longBitsToDouble(0x7FFDeadBeef00000L),
+                         Double.longBitsToDouble(0xFFFDeadBeef00000L),
+                         Double.longBitsToDouble(0x7FFCafeBabe00000L),
+                         Double.longBitsToDouble(0xFFFCafeBabe00000L)};
+
+        // Tests shared between Math and StrictMath versions
+        for(int i = 0; i < 2; i++) {
+            for(int j = 0; j < 2; j++) {
+                for(int m = 0; m < testCases[i].length; m++) {
+                    for(int n = 0; n < testCases[j].length; n++) {
+                        // copySign(magnitude, sign)
+                        failures+=Tests.test("MathcopySign(double,double)",
+                                             testCases[i][m],testCases[j][n],
+                                             Math.copySign(testCases[i][m], testCases[j][n]),
+                                             (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );
+
+                        failures+=Tests.test("StrictMath.copySign(double,double)",
+                                             testCases[i][m],testCases[j][n],
+                                             StrictMath.copySign(testCases[i][m], testCases[j][n]),
+                                             (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );
+                    }
+                }
+            }
+        }
+
+        // For Math.copySign, NaN may effectively have either sign bit
+        // while for StrictMath.copySign NaNs are treated as if they
+        // always have a zero sign bit (i.e. as positive numbers)
+        for(int i = 0; i < 2; i++) {
+            for(int j = 0; j < NaNs.length; j++) {
+                for(int m = 0; m < testCases[i].length; m++) {
+                    // copySign(magnitude, sign)
+
+                    failures += (Math.abs(Math.copySign(testCases[i][m], NaNs[j])) ==
+                                 Math.abs(testCases[i][m])) ? 0:1;
+
+
+                    failures+=Tests.test("StrictMath.copySign(double,double)",
+                                         testCases[i][m], NaNs[j],
+                                         StrictMath.copySign(testCases[i][m], NaNs[j]),
+                                         Math.abs(testCases[i][m]) );
+                }
+            }
+        }
+
+
+        return failures;
+    }
+
+    /* ************************ scalb tests ******************************* */
+
+    static int testScalbCase(float value, int scale_factor, float expected) {
+        int failures=0;
+
+        failures+=Tests.test("Math.scalb(float,int)",
+                             value, scale_factor,
+                             Math.scalb(value, scale_factor), expected);
+
+        failures+=Tests.test("Math.scalb(float,int)",
+                             -value, scale_factor,
+                             Math.scalb(-value, scale_factor), -expected);
+
+        failures+=Tests.test("StrictMath.scalb(float,int)",
+                             value, scale_factor,
+                             StrictMath.scalb(value, scale_factor), expected);
+
+        failures+=Tests.test("StrictMath.scalb(float,int)",
+                             -value, scale_factor,
+                             StrictMath.scalb(-value, scale_factor), -expected);
+        return failures;
+    }
+
+    public static int testFloatScalb() {
+        int failures=0;
+        int MAX_SCALE = FloatConsts.MAX_EXPONENT + -FloatConsts.MIN_EXPONENT +
+                        FloatConsts.SIGNIFICAND_WIDTH + 1;
+
+
+        // Arguments x, where scalb(x,n) is x for any n.
+        float [] identityTestCases = {NaNf,
+                                      -0.0f,
+                                      +0.0f,
+                                      infinityF,
+                                      -infinityF
+        };
+
+        float [] subnormalTestCases = {
+            Float.MIN_VALUE,
+            3.0f*Float.MIN_VALUE,
+            Float_MAX_SUBNORMALmm,
+            Float_MAX_SUBNORMAL
+        };
+
+        float [] someTestCases = {
+            Float.MIN_VALUE,
+            3.0f*Float.MIN_VALUE,
+            Float_MAX_SUBNORMALmm,
+            Float_MAX_SUBNORMAL,
+            FloatConsts.MIN_NORMAL,
+            1.0f,
+            2.0f,
+            3.0f,
+            (float)Math.PI,
+            Float_MAX_VALUEmm,
+            Float.MAX_VALUE
+        };
+
+        int [] oneMultiplyScalingFactors = {
+            FloatConsts.MIN_EXPONENT,
+            FloatConsts.MIN_EXPONENT+1,
+            -3,
+            -2,
+            -1,
+            0,
+            1,
+            2,
+            3,
+            FloatConsts.MAX_EXPONENT-1,
+            FloatConsts.MAX_EXPONENT
+        };
+
+        int [] manyScalingFactors = {
+            Integer.MIN_VALUE,
+            Integer.MIN_VALUE+1,
+            -MAX_SCALE -1,
+            -MAX_SCALE,
+            -MAX_SCALE+1,
+
+            2*FloatConsts.MIN_EXPONENT-1,       // -253
+            2*FloatConsts.MIN_EXPONENT,         // -252
+            2*FloatConsts.MIN_EXPONENT+1,       // -251
+
+            FpUtils.ilogb(Float.MIN_VALUE)-1,   // -150
+            FpUtils.ilogb(Float.MIN_VALUE),     // -149
+            -FloatConsts.MAX_EXPONENT,          // -127
+            FloatConsts.MIN_EXPONENT,           // -126
+
+            -2,
+            -1,
+            0,
+            1,
+            2,
+
+            FloatConsts.MAX_EXPONENT-1,         // 126
+            FloatConsts.MAX_EXPONENT,           // 127
+            FloatConsts.MAX_EXPONENT+1,         // 128
+
+            2*FloatConsts.MAX_EXPONENT-1,       // 253
+            2*FloatConsts.MAX_EXPONENT,         // 254
+            2*FloatConsts.MAX_EXPONENT+1,       // 255
+
+            MAX_SCALE-1,
+            MAX_SCALE,
+            MAX_SCALE+1,
+            Integer.MAX_VALUE-1,
+            Integer.MAX_VALUE
+        };
+
+        // Test cases where scaling is always a no-op
+        for(int i=0; i < identityTestCases.length; i++) {
+            for(int j=0; j < manyScalingFactors.length; j++) {
+                failures += testScalbCase(identityTestCases[i],
+                                          manyScalingFactors[j],
+                                          identityTestCases[i]);
+            }
+        }
+
+        // Test cases where result is 0.0 or infinity due to magnitude
+        // of the scaling factor
+        for(int i=0; i < someTestCases.length; i++) {
+            for(int j=0; j < manyScalingFactors.length; j++) {
+                int scaleFactor = manyScalingFactors[j];
+                if (Math.abs(scaleFactor) >= MAX_SCALE) {
+                    float value = someTestCases[i];
+                    failures+=testScalbCase(value,
+                                            scaleFactor,
+                                            FpUtils.copySign( (scaleFactor>0?infinityF:0.0f), value) );
+                }
+            }
+        }
+
+        // Test cases that could be done with one floating-point
+        // multiply.
+        for(int i=0; i < someTestCases.length; i++) {
+            for(int j=0; j < oneMultiplyScalingFactors.length; j++) {
+                int scaleFactor = oneMultiplyScalingFactors[j];
+                    float value = someTestCases[i];
+
+                    failures+=testScalbCase(value,
+                                            scaleFactor,
+                                            value*powerOfTwoF(scaleFactor));
+            }
+        }
+
+        // Create 2^MAX_EXPONENT
+        float twoToTheMaxExp = 1.0f; // 2^0
+        for(int i = 0; i < FloatConsts.MAX_EXPONENT; i++)
+            twoToTheMaxExp *=2.0f;
+
+        // Scale-up subnormal values until they all overflow
+        for(int i=0; i < subnormalTestCases.length; i++) {
+            float scale = 1.0f; // 2^j
+            float value = subnormalTestCases[i];
+
+            for(int j=FloatConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow
+                int scaleFactor = j;
+
+                failures+=testScalbCase(value,
+                                        scaleFactor,
+                                        (FpUtils.ilogb(value) +j > FloatConsts.MAX_EXPONENT ) ?
+                                        FpUtils.copySign(infinityF, value) : // overflow
+                                        // calculate right answer
+                                        twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );
+                scale*=2.0f;
+            }
+        }
+
+        // Scale down a large number until it underflows.  By scaling
+        // down MAX_NORMALmm, the first subnormal result will be exact
+        // but the next one will round -- all those results can be
+        // checked by halving a separate value in the loop.  Actually,
+        // we can keep halving and checking until the product is zero
+        // since:
+        //
+        // 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact
+        // it will round *up*
+        //
+        // 2. When rounding first occurs in the expected product, it
+        // too rounds up, to 2^-MAX_EXPONENT.
+        //
+        // Halving expected after rounding happends to give the same
+        // result as the scalb operation.
+        float expected = Float_MAX_VALUEmm *0.5f;
+        for(int i = -1; i > -MAX_SCALE; i--) {
+            failures+=testScalbCase(Float_MAX_VALUEmm, i, expected);
+
+            expected *= 0.5f;
+        }
+
+        // Tricky rounding tests:
+        // Scale down a large number into subnormal range such that if
+        // scalb is being implemented with multiple floating-point
+        // multiplies, the value would round twice if the multiplies
+        // were done in the wrong order.
+
+        float value = 0x8.0000bP-5f;
+        expected = 0x1.00001p-129f;
+
+        for(int i = 0; i < 129; i++) {
+            failures+=testScalbCase(value,
+                                    -127-i,
+                                    expected);
+            value *=2.0f;
+        }
+
+        return failures;
+    }
+
+    static int testScalbCase(double value, int scale_factor, double expected) {
+        int failures=0;
+
+        failures+=Tests.test("Math.scalb(double,int)",
+                             value, scale_factor,
+                             Math.scalb(value, scale_factor), expected);
+
+        failures+=Tests.test("Math.scalb(double,int)",
+                             -value, scale_factor,
+                             Math.scalb(-value, scale_factor), -expected);
+
+        failures+=Tests.test("StrictMath.scalb(double,int)",
+                             value, scale_factor,
+                             StrictMath.scalb(value, scale_factor), expected);
+
+        failures+=Tests.test("StrictMath.scalb(double,int)",
+                             -value, scale_factor,
+                             StrictMath.scalb(-value, scale_factor), -expected);
+
+        return failures;
+    }
+
+    public static int testDoubleScalb() {
+        int failures=0;
+        int MAX_SCALE = DoubleConsts.MAX_EXPONENT + -DoubleConsts.MIN_EXPONENT +
+                        DoubleConsts.SIGNIFICAND_WIDTH + 1;
+
+
+        // Arguments x, where scalb(x,n) is x for any n.
+        double [] identityTestCases = {NaNd,
+                                      -0.0,
+                                      +0.0,
+                                      infinityD,
+        };
+
+        double [] subnormalTestCases = {
+            Double.MIN_VALUE,
+            3.0d*Double.MIN_VALUE,
+            Double_MAX_SUBNORMALmm,
+            Double_MAX_SUBNORMAL
+        };
+
+        double [] someTestCases = {
+            Double.MIN_VALUE,
+            3.0d*Double.MIN_VALUE,
+            Double_MAX_SUBNORMALmm,
+            Double_MAX_SUBNORMAL,
+            DoubleConsts.MIN_NORMAL,
+            1.0d,
+            2.0d,
+            3.0d,
+            Math.PI,
+            Double_MAX_VALUEmm,
+            Double.MAX_VALUE
+        };
+
+        int [] oneMultiplyScalingFactors = {
+            DoubleConsts.MIN_EXPONENT,
+            DoubleConsts.MIN_EXPONENT+1,
+            -3,
+            -2,
+            -1,
+            0,
+            1,
+            2,
+            3,
+            DoubleConsts.MAX_EXPONENT-1,
+            DoubleConsts.MAX_EXPONENT
+        };
+
+        int [] manyScalingFactors = {
+            Integer.MIN_VALUE,
+            Integer.MIN_VALUE+1,
+            -MAX_SCALE -1,
+            -MAX_SCALE,
+            -MAX_SCALE+1,
+
+            2*DoubleConsts.MIN_EXPONENT-1,      // -2045
+            2*DoubleConsts.MIN_EXPONENT,        // -2044
+            2*DoubleConsts.MIN_EXPONENT+1,      // -2043
+
+            FpUtils.ilogb(Double.MIN_VALUE)-1,  // -1076
+            FpUtils.ilogb(Double.MIN_VALUE),    // -1075
+            -DoubleConsts.MAX_EXPONENT,         // -1023
+            DoubleConsts.MIN_EXPONENT,          // -1022
+
+            -2,
+            -1,
+            0,
+            1,
+            2,
+
+            DoubleConsts.MAX_EXPONENT-1,        // 1022
+            DoubleConsts.MAX_EXPONENT,          // 1023
+            DoubleConsts.MAX_EXPONENT+1,        // 1024
+
+            2*DoubleConsts.MAX_EXPONENT-1,      // 2045
+            2*DoubleConsts.MAX_EXPONENT,        // 2046
+            2*DoubleConsts.MAX_EXPONENT+1,      // 2047
+
+            MAX_SCALE-1,
+            MAX_SCALE,
+            MAX_SCALE+1,
+            Integer.MAX_VALUE-1,
+            Integer.MAX_VALUE
+        };
+
+        // Test cases where scaling is always a no-op
+        for(int i=0; i < identityTestCases.length; i++) {
+            for(int j=0; j < manyScalingFactors.length; j++) {
+                failures += testScalbCase(identityTestCases[i],
+                                          manyScalingFactors[j],
+                                          identityTestCases[i]);
+            }
+        }
+
+        // Test cases where result is 0.0 or infinity due to magnitude
+        // of the scaling factor
+        for(int i=0; i < someTestCases.length; i++) {
+            for(int j=0; j < manyScalingFactors.length; j++) {
+                int scaleFactor = manyScalingFactors[j];
+                if (Math.abs(scaleFactor) >= MAX_SCALE) {
+                    double value = someTestCases[i];
+                    failures+=testScalbCase(value,
+                                            scaleFactor,
+                                            FpUtils.copySign( (scaleFactor>0?infinityD:0.0), value) );
+                }
+            }
+        }
+
+        // Test cases that could be done with one floating-point
+        // multiply.
+        for(int i=0; i < someTestCases.length; i++) {
+            for(int j=0; j < oneMultiplyScalingFactors.length; j++) {
+                int scaleFactor = oneMultiplyScalingFactors[j];
+                    double value = someTestCases[i];
+
+                    failures+=testScalbCase(value,
+                                            scaleFactor,
+                                            value*powerOfTwoD(scaleFactor));
+            }
+        }
+
+        // Create 2^MAX_EXPONENT
+        double twoToTheMaxExp = 1.0; // 2^0
+        for(int i = 0; i < DoubleConsts.MAX_EXPONENT; i++)
+            twoToTheMaxExp *=2.0;
+
+        // Scale-up subnormal values until they all overflow
+        for(int i=0; i < subnormalTestCases.length; i++) {
+            double scale = 1.0; // 2^j
+            double value = subnormalTestCases[i];
+
+            for(int j=DoubleConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow
+                int scaleFactor = j;
+
+                failures+=testScalbCase(value,
+                                        scaleFactor,
+                                        (FpUtils.ilogb(value) +j > DoubleConsts.MAX_EXPONENT ) ?
+                                        FpUtils.copySign(infinityD, value) : // overflow
+                                        // calculate right answer
+                                        twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );
+                scale*=2.0;
+            }
+        }
+
+        // Scale down a large number until it underflows.  By scaling
+        // down MAX_NORMALmm, the first subnormal result will be exact
+        // but the next one will round -- all those results can be
+        // checked by halving a separate value in the loop.  Actually,
+        // we can keep halving and checking until the product is zero
+        // since:
+        //
+        // 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact
+        // it will round *up*
+        //
+        // 2. When rounding first occurs in the expected product, it
+        // too rounds up, to 2^-MAX_EXPONENT.
+        //
+        // Halving expected after rounding happends to give the same
+        // result as the scalb operation.
+        double expected = Double_MAX_VALUEmm *0.5f;
+        for(int i = -1; i > -MAX_SCALE; i--) {
+            failures+=testScalbCase(Double_MAX_VALUEmm, i, expected);
+
+            expected *= 0.5;
+        }
+
+        // Tricky rounding tests:
+        // Scale down a large number into subnormal range such that if
+        // scalb is being implemented with multiple floating-point
+        // multiplies, the value would round twice if the multiplies
+        // were done in the wrong order.
+
+        double value = 0x1.000000000000bP-1;
+        expected     = 0x0.2000000000001P-1022;
+        for(int i = 0; i < DoubleConsts.MAX_EXPONENT+2; i++) {
+            failures+=testScalbCase(value,
+                                    -1024-i,
+                                    expected);
+            value *=2.0;
+        }
+
+        return failures;
+    }
+
+    /* ************************* ulp tests ******************************* */
+
+
+    /*
+     * Test Math.ulp and StrictMath.ulp with +d and -d.
+     */
+    static int testUlpCase(float f, float expected) {
+        float minus_f = -f;
+        int failures=0;
+
+        failures+=Tests.test("Math.ulp(float)", f,
+                             Math.ulp(f), expected);
+        failures+=Tests.test("Math.ulp(float)", minus_f,
+                             Math.ulp(minus_f), expected);
+        failures+=Tests.test("StrictMath.ulp(float)", f,
+                             StrictMath.ulp(f), expected);
+        failures+=Tests.test("StrictMath.ulp(float)", minus_f,
+                             StrictMath.ulp(minus_f), expected);
+        return failures;
+    }
+
+    static int testUlpCase(double d, double expected) {
+        double minus_d = -d;
+        int failures=0;
+
+        failures+=Tests.test("Math.ulp(double)", d,
+                             Math.ulp(d), expected);
+        failures+=Tests.test("Math.ulp(double)", minus_d,
+                             Math.ulp(minus_d), expected);
+        failures+=Tests.test("StrictMath.ulp(double)", d,
+                             StrictMath.ulp(d), expected);
+        failures+=Tests.test("StrictMath.ulp(double)", minus_d,
+                             StrictMath.ulp(minus_d), expected);
+        return failures;
+    }
+
+    public static int testFloatUlp() {
+        int failures = 0;
+        float [] specialValues = {NaNf,
+                                  Float.POSITIVE_INFINITY,
+                                  +0.0f,
+                                  +1.0f,
+                                  +2.0f,
+                                  +16.0f,
+                                  +Float.MIN_VALUE,
+                                  +Float_MAX_SUBNORMAL,
+                                  +FloatConsts.MIN_NORMAL,
+                                  +Float.MAX_VALUE
+        };
+
+        float [] specialResults = {NaNf,
+                                   Float.POSITIVE_INFINITY,
+                                   Float.MIN_VALUE,
+                                   powerOfTwoF(-23),
+                                   powerOfTwoF(-22),
+                                   powerOfTwoF(-19),
+                                   Float.MIN_VALUE,
+                                   Float.MIN_VALUE,
+                                   Float.MIN_VALUE,
+                                   powerOfTwoF(104)
+        };
+
+        // Special value tests
+        for(int i = 0; i < specialValues.length; i++) {
+            failures += testUlpCase(specialValues[i], specialResults[i]);
+        }
+
+
+        // Normal exponent tests
+        for(int i = FloatConsts.MIN_EXPONENT; i <= FloatConsts.MAX_EXPONENT; i++) {
+            float expected;
+
+            // Create power of two
+            float po2 = powerOfTwoF(i);
+            expected = FpUtils.scalb(1.0f, i - (FloatConsts.SIGNIFICAND_WIDTH-1));
+
+            failures += testUlpCase(po2, expected);
+
+            // Generate some random bit patterns for the significand
+            for(int j = 0; j < 10; j++) {
+                int randSignif = rand.nextInt();
+                float randFloat;
+
+                randFloat = Float.intBitsToFloat( // Exponent
+                                                 (Float.floatToIntBits(po2)&
+                                                  (~FloatConsts.SIGNIF_BIT_MASK)) |
+                                                 // Significand
+                                                 (randSignif &
+                                                  FloatConsts.SIGNIF_BIT_MASK) );
+
+                failures += testUlpCase(randFloat, expected);
+            }
+
+            if (i > FloatConsts.MIN_EXPONENT) {
+                float po2minus = FpUtils.nextAfter(po2,
+                                                   Float.NEGATIVE_INFINITY);
+                failures += testUlpCase(po2minus, expected/2.0f);
+            }
+        }
+
+        // Subnormal tests
+
+        /*
+         * Start with MIN_VALUE, left shift, test high value, low
+         * values, and random in between.
+         *
+         * Use nextAfter to calculate, high value of previous binade,
+         * loop count i will indicate how many random bits, if any are
+         * needed.
+         */
+
+        float top=Float.MIN_VALUE;
+        for( int i = 1;
+            i < FloatConsts.SIGNIFICAND_WIDTH;
+            i++, top *= 2.0f) {
+
+            failures += testUlpCase(top, Float.MIN_VALUE);
+
+            // Test largest value in next smaller binade
+            if (i >= 3) {// (i == 1) would test 0.0;
+                         // (i == 2) would just retest MIN_VALUE
+                testUlpCase(FpUtils.nextAfter(top, 0.0f),
+                            Float.MIN_VALUE);
+
+                if( i >= 10) {
+                    // create a bit mask with (i-1) 1's in the low order
+                    // bits
+                    int mask = ~((~0)<<(i-1));
+                    float randFloat = Float.intBitsToFloat( // Exponent
+                                                 Float.floatToIntBits(top) |
+                                                 // Significand
+                                                 (rand.nextInt() & mask ) ) ;
+
+                    failures += testUlpCase(randFloat, Float.MIN_VALUE);
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    public static int testDoubleUlp() {
+        int failures = 0;
+        double [] specialValues = {NaNd,
+                                  Double.POSITIVE_INFINITY,
+                                  +0.0d,
+                                  +1.0d,
+                                  +2.0d,
+                                  +16.0d,
+                                  +Double.MIN_VALUE,
+                                  +Double_MAX_SUBNORMAL,
+                                  +DoubleConsts.MIN_NORMAL,
+                                  +Double.MAX_VALUE
+        };
+
+        double [] specialResults = {NaNf,
+                                   Double.POSITIVE_INFINITY,
+                                   Double.MIN_VALUE,
+                                   powerOfTwoD(-52),
+                                   powerOfTwoD(-51),
+                                   powerOfTwoD(-48),
+                                   Double.MIN_VALUE,
+                                   Double.MIN_VALUE,
+                                   Double.MIN_VALUE,
+                                   powerOfTwoD(971)
+        };
+
+        // Special value tests
+        for(int i = 0; i < specialValues.length; i++) {
+            failures += testUlpCase(specialValues[i], specialResults[i]);
+        }
+
+
+        // Normal exponent tests
+        for(int i = DoubleConsts.MIN_EXPONENT; i <= DoubleConsts.MAX_EXPONENT; i++) {
+            double expected;
+
+            // Create power of two
+            double po2 = powerOfTwoD(i);
+            expected = FpUtils.scalb(1.0, i - (DoubleConsts.SIGNIFICAND_WIDTH-1));
+
+            failures += testUlpCase(po2, expected);
+
+            // Generate some random bit patterns for the significand
+            for(int j = 0; j < 10; j++) {
+                long randSignif = rand.nextLong();
+                double randDouble;
+
+                randDouble = Double.longBitsToDouble( // Exponent
+                                                 (Double.doubleToLongBits(po2)&
+                                                  (~DoubleConsts.SIGNIF_BIT_MASK)) |
+                                                 // Significand
+                                                 (randSignif &
+                                                  DoubleConsts.SIGNIF_BIT_MASK) );
+
+                failures += testUlpCase(randDouble, expected);
+            }
+
+            if (i > DoubleConsts.MIN_EXPONENT) {
+                double po2minus = FpUtils.nextAfter(po2,
+                                                    Double.NEGATIVE_INFINITY);
+                failures += testUlpCase(po2minus, expected/2.0f);
+            }
+        }
+
+        // Subnormal tests
+
+        /*
+         * Start with MIN_VALUE, left shift, test high value, low
+         * values, and random in between.
+         *
+         * Use nextAfter to calculate, high value of previous binade,
+         * loop count i will indicate how many random bits, if any are
+         * needed.
+         */
+
+        double top=Double.MIN_VALUE;
+        for( int i = 1;
+            i < DoubleConsts.SIGNIFICAND_WIDTH;
+            i++, top *= 2.0f) {
+
+            failures += testUlpCase(top, Double.MIN_VALUE);
+
+            // Test largest value in next smaller binade
+            if (i >= 3) {// (i == 1) would test 0.0;
+                         // (i == 2) would just retest MIN_VALUE
+                testUlpCase(FpUtils.nextAfter(top, 0.0f),
+                            Double.MIN_VALUE);
+
+                if( i >= 10) {
+                    // create a bit mask with (i-1) 1's in the low order
+                    // bits
+                    int mask = ~((~0)<<(i-1));
+                    double randDouble = Double.longBitsToDouble( // Exponent
+                                                 Double.doubleToLongBits(top) |
+                                                 // Significand
+                                                 (rand.nextLong() & mask ) ) ;
+
+                    failures += testUlpCase(randDouble, Double.MIN_VALUE);
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    public static int testFloatSignum() {
+        int failures = 0;
+        float testCases [][] = {
+            {NaNf,                      NaNf},
+            {-infinityF,                -1.0f},
+            {-Float.MAX_VALUE,          -1.0f},
+            {-FloatConsts.MIN_NORMAL,   -1.0f},
+            {-1.0f,                     -1.0f},
+            {-2.0f,                     -1.0f},
+            {-Float_MAX_SUBNORMAL,      -1.0f},
+            {-Float.MIN_VALUE,          -1.0f},
+            {-0.0f,                     -0.0f},
+            {+0.0f,                     +0.0f},
+            {Float.MIN_VALUE,            1.0f},
+            {Float_MAX_SUBNORMALmm,      1.0f},
+            {Float_MAX_SUBNORMAL,        1.0f},
+            {FloatConsts.MIN_NORMAL,     1.0f},
+            {1.0f,                       1.0f},
+            {2.0f,                       1.0f},
+            {Float_MAX_VALUEmm,          1.0f},
+            {Float.MAX_VALUE,            1.0f},
+            {infinityF,                  1.0f}
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            failures+=Tests.test("Math.signum(float)",
+                                 testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]);
+            failures+=Tests.test("StrictMath.signum(float)",
+                                 testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]);
+        }
+
+        return failures;
+    }
+
+    public static int testDoubleSignum() {
+        int failures = 0;
+        double testCases [][] = {
+            {NaNd,                      NaNd},
+            {-infinityD,                -1.0},
+            {-Double.MAX_VALUE,         -1.0},
+            {-DoubleConsts.MIN_NORMAL,  -1.0},
+            {-1.0,                      -1.0},
+            {-2.0,                      -1.0},
+            {-Double_MAX_SUBNORMAL,     -1.0},
+            {-Double.MIN_VALUE,         -1.0d},
+            {-0.0d,                     -0.0d},
+            {+0.0d,                     +0.0d},
+            {Double.MIN_VALUE,           1.0},
+            {Double_MAX_SUBNORMALmm,     1.0},
+            {Double_MAX_SUBNORMAL,       1.0},
+            {DoubleConsts.MIN_NORMAL,    1.0},
+            {1.0,                        1.0},
+            {2.0,                        1.0},
+            {Double_MAX_VALUEmm,         1.0},
+            {Double.MAX_VALUE,           1.0},
+            {infinityD,                  1.0}
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+            failures+=Tests.test("Math.signum(double)",
+                                 testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]);
+            failures+=Tests.test("StrictMath.signum(double)",
+                                 testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]);
+        }
+
+        return failures;
+    }
+
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += testFloatGetExponent();
+        failures += testDoubleGetExponent();
+
+        failures += testFloatNextAfter();
+        failures += testDoubleNextAfter();
+
+        failures += testFloatNextUp();
+        failures += testDoubleNextUp();
+
+        failures += testFloatNextDown();
+        failures += testDoubleNextDown();
+
+        failures += testFloatBooleanMethods();
+        failures += testDoubleBooleanMethods();
+
+        failures += testFloatCopySign();
+        failures += testDoubleCopySign();
+
+        failures += testFloatScalb();
+        failures += testDoubleScalb();
+
+        failures += testFloatUlp();
+        failures += testDoubleUlp();
+
+        failures += testFloatSignum();
+        failures += testDoubleSignum();
+
+        if (failures > 0) {
+            System.err.println("Testing the recommended functions incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/Log10Tests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4074599 4939441
+ * @summary Tests for {Math, StrictMath}.log10
+ * @author Joseph D. Darcy
+ */
+
+import sun.misc.FpUtils;
+import sun.misc.DoubleConsts;
+
+public class Log10Tests {
+    private Log10Tests(){}
+
+    static final double infinityD = Double.POSITIVE_INFINITY;
+    static final double NaNd = Double.NaN;
+    static final double LN_10 = StrictMath.log(10.0);
+
+    // Initialize shared random number generator
+    static java.util.Random rand = new java.util.Random(0L);
+
+    static int testLog10Case(double input, double expected) {
+        int failures=0;
+
+        failures+=Tests.test("Math.log10(double)", input,
+                             Math.log10(input), expected);
+
+        failures+=Tests.test("StrictMath.log10(double)", input,
+                             StrictMath.log10(input), expected);
+
+        return failures;
+    }
+
+    static int testLog10() {
+        int failures = 0;
+
+        double [][] testCases = {
+            {Double.NaN,                NaNd},
+            {Double.longBitsToDouble(0x7FF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0xFFF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0x7FF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0xFFF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0x7FFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0x7FFCafeBabe00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFCafeBabe00000L),      NaNd},
+            {Double.NEGATIVE_INFINITY,  NaNd},
+            {-8.0,                      NaNd},
+            {-1.0,                      NaNd},
+            {-DoubleConsts.MIN_NORMAL,  NaNd},
+            {-Double.MIN_VALUE,         NaNd},
+            {-0.0,                      -infinityD},
+            {+0.0,                      -infinityD},
+            {+1.0,                      0.0},
+            {Double.POSITIVE_INFINITY,  infinityD},
+        };
+
+        // Test special cases
+        for(int i = 0; i < testCases.length; i++) {
+            failures += testLog10Case(testCases[i][0],
+                                          testCases[i][1]);
+        }
+
+        // Test log10(10^n) == n for integer n; 10^n, n < 0 is not
+        // exactly representable as a floating-point value -- up to
+        // 10^22 can be represented exactly
+        double testCase = 1.0;
+        for(int i = 0; i < 23; i++) {
+            failures += testLog10Case(testCase, i);
+            testCase *= 10.0;
+        }
+
+        // Test for gross inaccuracy by comparing to log; should be
+        // within a few ulps of log(x)/log(10)
+        for(int i = 0; i < 10000; i++) {
+            double input = Double.longBitsToDouble(rand.nextLong());
+            if(! FpUtils.isFinite(input))
+                continue; // avoid testing NaN and infinite values
+            else {
+                input = Math.abs(input);
+
+                double expected = StrictMath.log(input)/LN_10;
+                if( ! FpUtils.isFinite(expected))
+                    continue; // if log(input) overflowed, try again
+                else {
+                    double result;
+
+                    if( Math.abs(((result=Math.log10(input)) - expected)/Math.ulp(expected)) > 3) {
+                        failures++;
+                        System.err.println("For input " + input +
+                                           ", Math.log10 was more than 3 ulps different from " +
+                                           "log(input)/log(10): log10(input) = " + result +
+                                           "\tlog(input)/log(10) = " + expected);
+                    }
+
+                    if( Math.abs(((result=StrictMath.log10(input)) - expected)/Math.ulp(expected)) > 3) {
+                        failures++;
+                        System.err.println("For input " + input +
+                                           ", StrictMath.log10 was more than 3 ulps different from " +
+                                           "log(input)/log(10): log10(input) = " + result +
+                                           "\tlog(input)/log(10) = " + expected);
+                    }
+
+
+                }
+            }
+        }
+
+        // Test for accuracy and monotonicity near log10(1.0).  From
+        // the Taylor expansion of log,
+        // log10(1+z) ~= (z -(z^2)/2)/LN_10;
+        {
+            double neighbors[] =        new double[40];
+            double neighborsStrict[] =  new double[40];
+            double z = Double.NaN;
+
+            // Test inputs greater than 1.0.
+            neighbors[0] =              Math.log10(1.0);
+            neighborsStrict[0] =        StrictMath.log10(1.0);
+
+            double input[] =  new double[40];
+            int half = input.length/2;
+
+
+            // Initialize input to the 40 consecutive double values
+            // "centered" at 1.0.
+            double up = Double.NaN;
+            double down = Double.NaN;
+            for(int i = 0; i < half; i++) {
+                if (i == 0) {
+                    input[half] = 1.0;
+                    up   = FpUtils.nextUp(1.0);
+                    down = FpUtils.nextDown(1.0);
+                } else {
+                    input[half + i] = up;
+                    input[half - i] = down;
+                    up   = FpUtils.nextUp(up);
+                    down = FpUtils.nextDown(down);
+                }
+            }
+            input[0] = FpUtils.nextDown(input[1]);
+
+            for(int i = 0; i < neighbors.length; i++) {
+                neighbors[i] =          Math.log10(input[i]);
+                neighborsStrict[i] =    StrictMath.log10(input[i]);
+
+                // Test accuracy.
+                z = input[i] - 1.0;
+                double expected = (z - (z*z)*0.5)/LN_10;
+                if ( Math.abs(neighbors[i] - expected ) > 3*Math.ulp(expected) ) {
+                    failures++;
+                    System.err.println("For input near 1.0 " + input[i] +
+                                       ", Math.log10(1+z) was more than 3 ulps different from " +
+                                       "(z-(z^2)/2)/ln(10): log10(input) = " + neighbors[i] +
+                                       "\texpected about = " + expected);
+                }
+
+                if ( Math.abs(neighborsStrict[i] - expected ) > 3*Math.ulp(expected) ) {
+                    failures++;
+                    System.err.println("For input near 1.0 " + input[i] +
+                                       ", StrictMath.log10(1+z) was more than 3 ulps different from " +
+                                       "(z-(z^2)/2)/ln(10): log10(input) = " + neighborsStrict[i] +
+                                       "\texpected about = " + expected);
+                }
+
+                // Test monotonicity
+                if( i > 0) {
+                    if( neighbors[i-1] > neighbors[i] ) {
+                        failures++;
+                        System.err.println("Monotonicity failure for Math.log10  at " + input[i] +
+                                           " and prior value.");
+                    }
+
+                    if( neighborsStrict[i-1] > neighborsStrict[i] ) {
+                        failures++;
+                        System.err.println("Monotonicity failure for StrictMath.log10  at " + input[i] +
+                                           " and prior value.");
+                    }
+                }
+            }
+
+        }
+
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += testLog10();
+
+        if (failures > 0) {
+            System.err.println("Testing log10 incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/Log1pTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4851638 4939441
+ * @summary Tests for {Math, StrictMath}.log1p
+ * @author Joseph D. Darcy
+ */
+
+import sun.misc.DoubleConsts;
+import sun.misc.FpUtils;
+
+public class Log1pTests {
+    private Log1pTests(){}
+
+    static final double infinityD = Double.POSITIVE_INFINITY;
+    static final double NaNd = Double.NaN;
+
+    /**
+     * Formulation taken from HP-15C Advanced Functions Handbook, part
+     * number HP 0015-90011, p 181.  This is accurate to a few ulps.
+     */
+    static double hp15cLogp(double x) {
+        double u = 1.0 + x;
+        return (u==1.0? x : StrictMath.log(u)*x/(u-1) );
+    }
+
+    /*
+     * The Taylor expansion of ln(1 + x) for -1 < x <= 1 is:
+     *
+     * x - x^2/2 + x^3/3 - ... -(-x^j)/j
+     *
+     * Therefore, for small values of x, log1p(x) ~= x.  For large
+     * values of x, log1p(x) ~= log(x).
+     *
+     * Also x/(x+1) < ln(1+x) < x
+     */
+
+    static int testLog1p() {
+        int failures = 0;
+
+        double [][] testCases = {
+            {Double.NaN,                NaNd},
+            {Double.longBitsToDouble(0x7FF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0xFFF0000000000001L),      NaNd},
+            {Double.longBitsToDouble(0x7FF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0xFFF8555555555555L),      NaNd},
+            {Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),      NaNd},
+            {Double.longBitsToDouble(0x7FFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFDeadBeef00000L),      NaNd},
+            {Double.longBitsToDouble(0x7FFCafeBabe00000L),      NaNd},
+            {Double.longBitsToDouble(0xFFFCafeBabe00000L),      NaNd},
+            {Double.NEGATIVE_INFINITY,  NaNd},
+            {-8.0,                      NaNd},
+            {-1.0,                      -infinityD},
+            {-0.0,                      -0.0},
+            {+0.0,                      +0.0},
+            {infinityD,                 infinityD},
+        };
+
+        // Test special cases
+        for(int i = 0; i < testCases.length; i++) {
+            failures += testLog1pCaseWithUlpDiff(testCases[i][0],
+                                                 testCases[i][1], 0);
+        }
+
+        // For |x| < 2^-54 log1p(x) ~= x
+        for(int i = DoubleConsts.MIN_SUB_EXPONENT; i <= -54; i++) {
+            double d = FpUtils.scalb(2, i);
+            failures += testLog1pCase(d, d);
+            failures += testLog1pCase(-d, -d);
+        }
+
+        // For x > 2^53 log1p(x) ~= log(x)
+        for(int i = 53; i <= DoubleConsts.MAX_EXPONENT; i++) {
+            double d = FpUtils.scalb(2, i);
+            failures += testLog1pCaseWithUlpDiff(d, StrictMath.log(d), 2.001);
+        }
+
+        // Construct random values with exponents ranging from -53 to
+        // 52 and compare against HP-15C formula.
+        java.util.Random rand = new java.util.Random();
+        for(int i = 0; i < 1000; i++) {
+            double d = rand.nextDouble();
+
+            d = FpUtils.scalb(d, -53 - FpUtils.ilogb(d));
+
+            for(int j = -53; j <= 52; j++) {
+                failures += testLog1pCaseWithUlpDiff(d, hp15cLogp(d), 5);
+
+                d *= 2.0; // increase exponent by 1
+            }
+        }
+
+        // Test for monotonicity failures near values y-1 where y ~=
+        // e^x.  Test two numbers before and two numbers after each
+        // chosen value; i.e.
+        //
+        // pcNeighbors[] =
+        // {nextDown(nextDown(pc)),
+        // nextDown(pc),
+        // pc,
+        // nextUp(pc),
+        // nextUp(nextUp(pc))}
+        //
+        // and we test that log1p(pcNeighbors[i]) <= log1p(pcNeighbors[i+1])
+        {
+            double pcNeighbors[] = new double[5];
+            double pcNeighborsLog1p[] = new double[5];
+            double pcNeighborsStrictLog1p[] = new double[5];
+
+            for(int i = -36; i <= 36; i++) {
+                double pc = StrictMath.pow(Math.E, i) - 1;
+
+                pcNeighbors[2] = pc;
+                pcNeighbors[1] = FpUtils.nextDown(pc);
+                pcNeighbors[0] = FpUtils.nextDown(pcNeighbors[1]);
+                pcNeighbors[3] = FpUtils.nextUp(pc);
+                pcNeighbors[4] = FpUtils.nextUp(pcNeighbors[3]);
+
+                for(int j = 0; j < pcNeighbors.length; j++) {
+                    pcNeighborsLog1p[j]       =       Math.log1p(pcNeighbors[j]);
+                    pcNeighborsStrictLog1p[j] = StrictMath.log1p(pcNeighbors[j]);
+                }
+
+                for(int j = 0; j < pcNeighborsLog1p.length-1; j++) {
+                    if(pcNeighborsLog1p[j] >  pcNeighborsLog1p[j+1] ) {
+                        failures++;
+                        System.err.println("Monotonicity failure for Math.log1p on " +
+                                          pcNeighbors[j] + " and "  +
+                                          pcNeighbors[j+1] + "\n\treturned " +
+                                          pcNeighborsLog1p[j] + " and " +
+                                          pcNeighborsLog1p[j+1] );
+                    }
+
+                    if(pcNeighborsStrictLog1p[j] >  pcNeighborsStrictLog1p[j+1] ) {
+                        failures++;
+                        System.err.println("Monotonicity failure for StrictMath.log1p on " +
+                                          pcNeighbors[j] + " and "  +
+                                          pcNeighbors[j+1] + "\n\treturned " +
+                                          pcNeighborsStrictLog1p[j] + " and " +
+                                          pcNeighborsStrictLog1p[j+1] );
+                    }
+
+
+                }
+
+            }
+        }
+
+        return failures;
+    }
+
+    public static int testLog1pCase(double input,
+                                    double expected) {
+        return testLog1pCaseWithUlpDiff(input, expected, 1);
+    }
+
+    public static int testLog1pCaseWithUlpDiff(double input,
+                                               double expected,
+                                               double ulps) {
+        int failures = 0;
+        failures += Tests.testUlpDiff("Math.lop1p(double",
+                                      input, Math.log1p(input),
+                                      expected, ulps);
+        failures += Tests.testUlpDiff("StrictMath.log1p(double",
+                                      input, StrictMath.log1p(input),
+                                      expected, ulps);
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += testLog1p();
+
+        if (failures > 0) {
+            System.err.println("Testing log1p incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/MinMax.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,124 @@
+/*
+ * Copyright 1997 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @bug 4010528 4010529
+   @summary Math.min and Math.max should treat negative zero as strictly
+            less than positive zero
+ */
+
+
+public class MinMax {
+
+
+    static void go(String what, float result, float correctResult) {
+        String v = what + ": got " + result + ", expected " + correctResult;
+        if (!(Float.toString(result).equals(Float.toString(correctResult))))
+            throw new RuntimeException(v);
+        System.err.println(v);
+    }
+
+    static void go(String what, double result, double correctResult) {
+        String v = what + ": got " + result + ", expected " + correctResult;
+        if (!(Double.toString(result).equals(Double.toString(correctResult))))
+            throw new RuntimeException(v);
+        System.err.println(v);
+    }
+
+
+    public static void main(String[] args) {
+
+        float fnz = -0.0f;
+        float fpz = +0.0f;
+
+        go("Math.min(fnz, fnz)", Math.min(fnz, fnz), fnz);
+        go("Math.min(fnz, fpz)", Math.min(fnz, fpz), fnz);
+        go("Math.min(fpz, fnz)", Math.min(fpz, fnz), fnz);
+        go("Math.min(fpz, fpz)", Math.min(fpz, fpz), fpz);
+
+        go("Math.min(-1.0f, fnz)", Math.min(-1.0f, fnz), -1.0f);
+        go("Math.min(-1.0f, fpz)", Math.min(-1.0f, fpz), -1.0f);
+        go("Math.min(+1.0f, fnz)", Math.min(+1.0f, fnz), fnz);
+        go("Math.min(+1.0f, fpz)", Math.min(+1.0f, fpz), fpz);
+        go("Math.min(-1.0f, +1.0f)", Math.min(-1.0f, +1.0f), -1.0f);
+        go("Math.min(fnz, -1.0f)", Math.min(fnz, -1.0f), -1.0f);
+        go("Math.min(fpz, -1.0f)", Math.min(fpz, -1.0f), -1.0f);
+        go("Math.min(fnz, +1.0f)", Math.min(fnz, +1.0f), fnz);
+        go("Math.min(fpz, +1.0f)", Math.min(fpz, +1.0f), fpz);
+        go("Math.min(+1.0f, -1.0f)", Math.min(+1.0f, -1.0f), -1.0f);
+
+        go("Math.max(fnz, fnz)", Math.max(fnz, fnz), fnz);
+        go("Math.max(fnz, fpz)", Math.max(fnz, fpz), fpz);
+        go("Math.max(fpz, fnz)", Math.max(fpz, fnz), fpz);
+        go("Math.max(fpz, fpz)", Math.max(fpz, fpz), fpz);
+
+        go("Math.max(-1.0f, fnz)", Math.max(-1.0f, fnz), fnz);
+        go("Math.max(-1.0f, fpz)", Math.max(-1.0f, fpz), fpz);
+        go("Math.max(+1.0f, fnz)", Math.max(+1.0f, fnz), +1.0f);
+        go("Math.max(+1.0f, fpz)", Math.max(+1.0f, fpz), +1.0f);
+        go("Math.max(-1.0f, +1.0f)", Math.max(-1.0f, +1.0f), +1.0f);
+        go("Math.max(fnz, -1.0f)", Math.max(fnz, -1.0f), fnz);
+        go("Math.max(fpz, -1.0f)", Math.max(fpz, -1.0f), fpz);
+        go("Math.max(fnz, +1.0f)", Math.max(fnz, +1.0f), +1.0f);
+        go("Math.max(fpz, +1.0f)", Math.max(fpz, +1.0f), +1.0f);
+        go("Math.max(+1.0f, -1.0f)", Math.max(+1.0f, -1.0f), +1.0f);
+
+
+        double dnz = -0.0d;
+        double dpz = +0.0d;
+
+        go("Math.min(dnz, dnz)", Math.min(dnz, dnz), dnz);
+        go("Math.min(dnz, dpz)", Math.min(dnz, dpz), dnz);
+        go("Math.min(dpz, dnz)", Math.min(dpz, dnz), dnz);
+        go("Math.min(dpz, dpz)", Math.min(dpz, dpz), dpz);
+
+        go("Math.min(-1.0d, dnz)", Math.min(-1.0d, dnz), -1.0d);
+        go("Math.min(-1.0d, dpz)", Math.min(-1.0d, dpz), -1.0d);
+        go("Math.min(+1.0d, dnz)", Math.min(+1.0d, dnz), dnz);
+        go("Math.min(+1.0d, dpz)", Math.min(+1.0d, dpz), dpz);
+        go("Math.min(-1.0d, +1.0d)", Math.min(-1.0d, +1.0d), -1.0d);
+        go("Math.min(dnz, -1.0d)", Math.min(dnz, -1.0d), -1.0d);
+        go("Math.min(dpz, -1.0d)", Math.min(dpz, -1.0d), -1.0d);
+        go("Math.min(dnz, +1.0d)", Math.min(dnz, +1.0d), dnz);
+        go("Math.min(dpz, +1.0d)", Math.min(dpz, +1.0d), dpz);
+        go("Math.min(+1.0d, -1.0d)", Math.min(+1.0d, -1.0d), -1.0d);
+
+        go("Math.max(dnz, dnz)", Math.max(dnz, dnz), dnz);
+        go("Math.max(dnz, dpz)", Math.max(dnz, dpz), dpz);
+        go("Math.max(dpz, dnz)", Math.max(dpz, dnz), dpz);
+        go("Math.max(dpz, dpz)", Math.max(dpz, dpz), dpz);
+
+        go("Math.max(-1.0d, dnz)", Math.max(-1.0d, dnz), dnz);
+        go("Math.max(-1.0d, dpz)", Math.max(-1.0d, dpz), dpz);
+        go("Math.max(+1.0d, dnz)", Math.max(+1.0d, dnz), +1.0d);
+        go("Math.max(+1.0d, dpz)", Math.max(+1.0d, dpz), +1.0d);
+        go("Math.max(-1.0d, +1.0d)", Math.max(-1.0d, +1.0d), +1.0d);
+        go("Math.max(dnz, -1.0d)", Math.max(dnz, -1.0d), dnz);
+        go("Math.max(dpz, -1.0d)", Math.max(dpz, -1.0d), dpz);
+        go("Math.max(dnz, +1.0d)", Math.max(dnz, +1.0d), +1.0d);
+        go("Math.max(dpz, +1.0d)", Math.max(dpz, +1.0d), +1.0d);
+        go("Math.max(+1.0d, -1.0d)", Math.max(+1.0d, -1.0d), +1.0d);
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/PowTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4984407 5033578
+ * @summary Tests for {Math, StrictMath}.pow
+ * @compile -source 1.5 PowTests.java
+ * @run main PowTests
+ * @author Joseph D. Darcy
+ */
+
+public class PowTests {
+    private PowTests(){}
+
+    static final double infinityD = Double.POSITIVE_INFINITY;
+
+    static int testPowCase(double input1, double input2, double expected) {
+        int failures = 0;
+        failures += Tests.test("StrictMath.pow(double, double)", input1, input2,
+                               StrictMath.pow(input1, input2), expected);
+        failures += Tests.test("Math.pow(double, double)", input1, input2,
+                               Math.pow(input1, input2), expected);
+        return failures;
+    }
+
+
+    static int testStrictPowCase(double input1, double input2, double expected) {
+        int failures = 0;
+        failures += Tests.test("StrictMath.pow(double, double)", input1, input2,
+                               StrictMath.pow(input1, input2), expected);
+        return failures;
+    }
+
+    static int testNonstrictPowCase(double input1, double input2, double expected) {
+        int failures = 0;
+        failures += Tests.test("Math.pow(double, double)", input1, input2,
+                               Math.pow(input1, input2), expected);
+        return failures;
+    }
+
+    /*
+     * Test for bad negation implementation.
+     */
+    static int testPow() {
+        int failures = 0;
+
+        double [][] testCases = {
+            {-0.0,               3.0,   -0.0},
+            {-0.0,               4.0,    0.0},
+            {-infinityD,        -3.0,   -0.0},
+            {-infinityD,        -4.0,    0.0},
+        };
+
+        for (double[] testCase : testCases) {
+            failures+=testPowCase(testCase[0], testCase[1], testCase[2]);
+        }
+
+        return failures;
+    }
+
+    /*
+     * Test cross-product of different kinds of arguments.
+     */
+    static int testCrossProduct() {
+        int failures = 0;
+
+        double testData[] = {
+                                Double.NEGATIVE_INFINITY,
+/* > -oo */                     -Double.MAX_VALUE,
+/**/                            (double)Long.MIN_VALUE,
+/**/                            (double) -((1L<<53)+2L),
+/**/                            (double) -((1L<<53)),
+/**/                            (double) -((1L<<53)-1L),
+/**/                            -((double)Integer.MAX_VALUE + 4.0),
+/**/                            (double)Integer.MIN_VALUE - 1.0,
+/**/                            (double)Integer.MIN_VALUE,
+/**/                            (double)Integer.MIN_VALUE + 1.0,
+/**/                            -Math.PI,
+/**/                            -3.0,
+/**/                            -Math.E,
+/**/                            -2.0,
+/**/                            -1.0000000000000004,
+/* < -1.0 */                    -1.0000000000000002, // nextAfter(-1.0, -oo)
+                                -1.0,
+/* > -1.0 */                    -0.9999999999999999, // nextAfter(-1.0, +oo)
+/* > -1.0 */                    -0.9999999999999998,
+/**/                            -0.5,
+/**/                            -1.0/3.0,
+/* < 0.0 */                     -Double.MIN_VALUE,
+                                -0.0,
+                                +0.0,
+/* > 0.0 */                     +Double.MIN_VALUE,
+/**/                            +1.0/3.0,
+/**/                            +0.5,
+/**/                            +0.9999999999999998,
+/* < +1.0 */                    +0.9999999999999999, // nextAfter(-1.0, +oo)
+                                +1.0,
+/* > 1.0 */                     +1.0000000000000002, // nextAfter(+1.0, +oo)
+/**/                            +1.0000000000000004,
+/**/                            +2.0,
+/**/                            +Math.E,
+/**/                            +3.0,
+/**/                            +Math.PI,
+/**/                            -(double)Integer.MIN_VALUE - 1.0,
+/**/                            -(double)Integer.MIN_VALUE,
+/**/                            -(double)Integer.MIN_VALUE + 1.0,
+/**/                            (double)Integer.MAX_VALUE + 4.0,
+/**/                            (double) ((1L<<53)-1L),
+/**/                            (double) ((1L<<53)),
+/**/                            (double) ((1L<<53)+2L),
+/**/                            -(double)Long.MIN_VALUE,
+/* < oo */                      Double.MAX_VALUE,
+                                Double.POSITIVE_INFINITY,
+                                Double.NaN
+    };
+
+        double NaN = Double.NaN;
+        for(double x: testData) {
+            for(double y: testData) {
+                boolean testPass = false;
+                double expected=NaN;
+                double actual;
+
+                // First, switch on y
+                if( Double.isNaN(y)) {
+                    expected = NaN;
+                } else if (y == 0.0) {
+                    expected = 1.0;
+                } else if (Double.isInfinite(y) ) {
+                    if(y > 0) { // x ^ (+oo)
+                        if (Math.abs(x) > 1.0) {
+                            expected = Double.POSITIVE_INFINITY;
+                        } else if (Math.abs(x) == 1.0) {
+                            expected = NaN;
+                        } else if (Math.abs(x) < 1.0) {
+                            expected = +0.0;
+                        } else { // x is NaN
+                            assert Double.isNaN(x);
+                            expected = NaN;
+                        }
+                    } else { // x ^ (-oo)
+                        if (Math.abs(x) > 1.0) {
+                            expected = +0.0;
+                        } else if (Math.abs(x) == 1.0) {
+                            expected = NaN;
+                        } else if (Math.abs(x) < 1.0) {
+                            expected = Double.POSITIVE_INFINITY;
+                        } else { // x is NaN
+                            assert Double.isNaN(x);
+                            expected = NaN;
+                        }
+                    } /* end Double.isInfinite(y) */
+                } else if (y == 1.0) {
+                    expected = x;
+                } else if (Double.isNaN(x)) { // Now start switching on x
+                    assert y != 0.0;
+                    expected = NaN;
+                } else if (x == Double.NEGATIVE_INFINITY) {
+                    expected = (y < 0.0) ? f2(y) :f1(y);
+                } else if (x == Double.POSITIVE_INFINITY) {
+                    expected = (y < 0.0) ? +0.0 : Double.POSITIVE_INFINITY;
+                } else if (equivalent(x, +0.0)) {
+                    assert y != 0.0;
+                    expected = (y < 0.0) ? Double.POSITIVE_INFINITY: +0.0;
+                } else if (equivalent(x, -0.0)) {
+                    assert y != 0.0;
+                    expected = (y < 0.0) ? f1(y): f2(y);
+                } else if( x < 0.0) {
+                    assert y != 0.0;
+                    failures += testStrictPowCase(x, y, f3(x, y));
+                    failures += testNonstrictPowCase(x, y, f3ns(x, y));
+                    continue;
+                } else {
+                    // go to next iteration
+                    expected = NaN;
+                    continue;
+                }
+
+                failures += testPowCase(x, y, expected);
+            } // y
+        } // x
+        return failures;
+    }
+
+    static boolean equivalent(double a, double b) {
+        return Double.compare(a, b) == 0;
+    }
+
+    static double f1(double y) {
+        return (intClassify(y) == 1)?
+            Double.NEGATIVE_INFINITY:
+            Double.POSITIVE_INFINITY;
+    }
+
+
+    static double f2(double y) {
+        return (intClassify(y) == 1)?-0.0:0.0;
+    }
+
+    static double f3(double x, double y) {
+        switch( intClassify(y) ) {
+        case 0:
+            return StrictMath.pow(Math.abs(x), y);
+            // break;
+
+        case 1:
+            return -StrictMath.pow(Math.abs(x), y);
+            // break;
+
+        case -1:
+            return Double.NaN;
+            // break;
+
+        default:
+            throw new AssertionError("Bad classification.");
+            // break;
+        }
+    }
+
+    static double f3ns(double x, double y) {
+        switch( intClassify(y) ) {
+        case 0:
+            return Math.pow(Math.abs(x), y);
+            // break;
+
+        case 1:
+            return -Math.pow(Math.abs(x), y);
+            // break;
+
+        case -1:
+            return Double.NaN;
+            // break;
+
+        default:
+            throw new AssertionError("Bad classification.");
+            // break;
+        }
+    }
+
+    static boolean isFinite(double a) {
+        return (0.0*a  == 0);
+    }
+
+    /**
+     * Return classification of argument: -1 for non-integers, 0 for
+     * even integers, 1 for odd integers.
+     */
+    static int intClassify(double a) {
+        if(!isFinite(a) || // NaNs and infinities
+           (a != Math.floor(a) )) { // only integers are fixed-points of floor
+                return -1;
+        }
+        else {
+            // Determine if argument is an odd or even integer.
+
+            a = StrictMath.abs(a); // absolute value doesn't affect odd/even
+
+            if(a+1.0 == a) { // a > maximum odd floating-point integer
+                return 0; // Large integers are all even
+            }
+            else { // Convert double -> long and look at low-order bit
+                long ell = (long)  a;
+                return ((ell & 0x1L) == (long)1)?1:0;
+            }
+        }
+    }
+
+    public static void main(String [] argv) {
+        int failures = 0;
+
+        failures += testPow();
+        failures += testCrossProduct();
+
+        if (failures > 0) {
+            System.err.println("Testing pow incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/Rint.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,122 @@
+/*
+ * Copyright 1998-2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4101566 4831589
+ * @summary Check for correct implementation of Math.rint(double)
+ *
+ */
+
+import sun.misc.FpUtils;
+import sun.misc.DoubleConsts;
+
+public class Rint {
+
+    static int testRintCase(double input, double expected) {
+        int failures = 0;
+        double result;
+        failures += Tests.test("Math.rint",  input, Math.rint(input),   expected);
+        failures += Tests.test("Math.rint", -input, Math.rint(-input), -expected);
+        failures += Tests.test("StrictMath.rint",
+                               input, StrictMath.rint(input),   expected);
+        failures += Tests.test("StrictMath.rint", -input,
+                               StrictMath.rint(-input), -expected);
+        return failures;
+    }
+
+
+    public static void main(String args[]) {
+        int failures = 0;
+        double twoToThe52 = FpUtils.scalb(1.0, 52); // 2^52
+
+        double [][] testCases = {
+            {0.0,                               0.0},
+            {Double.MIN_VALUE,                  0.0},
+            {FpUtils.nextDown(DoubleConsts.MIN_NORMAL), 0.0},
+            {DoubleConsts.MIN_NORMAL,           0.0},
+
+            {0.2,                               0.0},
+
+            {FpUtils.nextDown(0.5),             0.0},
+            {                 0.5,              0.0},
+            {  FpUtils.nextUp(0.5),             1.0},
+
+            {0.7,                               1.0},
+            {FpUtils.nextDown(1.0),             1.0},
+            {                 1.0,              1.0},
+            {  FpUtils.nextUp(1.0),             1.0},
+
+            {FpUtils.nextDown(1.5),             1.0},
+            {                 1.5,              2.0},
+            {  FpUtils.nextUp(1.5),             2.0},
+
+            {4.2,                               4.0},
+            {4.5,                               4.0},
+            {4.7,                               5.0},
+
+            {7.5,                               8.0},
+            {7.2,                               7.0},
+            {7.7,                               8.0},
+
+            {150000.75,                         150001.0},
+            {300000.5,                          300000.0},
+            {FpUtils.nextUp(300000.5),          300001.0},
+            {FpUtils.nextDown(300000.75),       300001.0},
+            {300000.75,                         300001.0},
+            {FpUtils.nextUp(300000.75),         300001.0},
+            {300000.99,                         300001.0},
+            {262144.75,                         262145.0}, //(2^18 ) + 0.75
+            {499998.75,                         499999.0},
+            {524287.75,                         524288.0}, //(2^19 -1) + 0.75
+            {524288.75,                         524289.0},
+
+            {FpUtils.nextDown(twoToThe52),      twoToThe52},
+            {twoToThe52,                        twoToThe52},
+            {FpUtils.nextUp(twoToThe52),        FpUtils.nextUp(twoToThe52)},
+
+            {Double.MAX_VALUE,          Double.MAX_VALUE},
+            {Double.POSITIVE_INFINITY,  Double.POSITIVE_INFINITY},
+            {Double.NaN,                        Double.NaN}
+
+        };
+
+
+        for(int i = 0; i < testCases.length; i++) {
+            failures += testRintCase(testCases[i][0], testCases[i][1]);
+        }
+
+        // Test values throughout exponent range
+        for(double d = Double.MIN_VALUE;
+            d < Double.POSITIVE_INFINITY; d *= 2) {
+            failures += testRintCase(d, ((d<=0.5)?0.0:d));
+        }
+
+        if (failures > 0) {
+            System.err.println("Testing {Math, StrictMath}.rint incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/TanTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 5033578
+ * @summary Tests for {Math, StrictMath}.tan
+ * @compile -source 1.5 TanTests.java
+ * @run main TanTests
+ * @author Joseph D. Darcy
+ */
+
+public class TanTests {
+    private TanTests(){}
+
+    static int testTanCase(double input, double expected, double ulps) {
+        int failures = 0;
+        failures += Tests.testUlpDiff("StrictMath.tan(double, double)", input,
+                               StrictMath.tan(input), expected, ulps);
+        failures += Tests.testUlpDiff("Math.tan(double, double)", input,
+                               Math.tan(input), expected, ulps);
+        return failures;
+    }
+
+    static int testTan() {
+        int failures = 0;
+
+        double [][] testCases = {
+            // 1.1 ulp case from Gonnet
+            {0x1.31b97c4000001p24,      -0x1.d08538b656222p34,  1.9},
+            // Remaining test cases adapted from work by Alex Liu
+            {0x1.be1b2d17ba207p6, -0x1.cf489c89f8066p49, 1.100000},
+            {0x1.e0a9e6ab97de7p7, 0x1.d31ce95f57459p50, 1.100000},
+            {0x1.23f8c5bcf003ep11, 0x1.f022585dbb50ap50, 1.100000},
+            {0x1.44bdb557e1dc1p20, 0x1.b67eaf362701fp49, 1.100000},
+            {0x1.604759040fb6fp68, 0x1.d574bc1f9e903p50, 1.100000},
+            {0x1.3d33fa4e5ba47p70, 0x1.ce1dd6e33fef8p49, 1.100000},
+            {0x1.f19e5d71b26bap85, 0x1.c2536a9119dd2p55, 1.100000},
+            {0x1.43ed062d2d62cp88, -0x1.c94b0c5b7b05p49, 1.100000},
+            {0x1.b7b895b030bep88, -0x1.cba9ebb0f20b9p51, 1.100000},
+            {0x1.a86090fe7c144p95, 0x1.d5ad72ca48bbfp48, 1.100000},
+            {0x1.d199df0700a61p95, -0x1.b8dd636f8dba7p49, 1.100000},
+            {0x1.d713037d1d222p106, -0x1.d57f035fd0146p48, 1.100000},
+            {0x1.ed1f6b066569bp115, 0x1.840af46cc9bep48, 1.100000},
+            {0x1.16800a51eff75p118, 0x1.c9f91caf08a6ap49, 1.100000},
+            {0x1.c1169c1040ecdp134, 0x1.e44a7eb56cb7p48, 1.100000},
+            {0x1.19b0fb40dddd5p145, -0x1.f1b1c235774b2p48, 1.100000},
+            {0x1.4d6b47f2480f8p162, 0x1.da1c2010795a5p51, 1.100000},
+            {0x1.682ff8e5429ddp163, -0x1.95a7aee1e93bep55, 1.100000},
+            {0x1.d0569fad9657dp204, -0x1.8f2ca17123aa5p49, 1.100000},
+            {0x1.55505de5bbc14p206, -0x1.e8d28e39ddf9p50, 1.100000},
+            {0x1.cf497083e6c77p206, -0x1.fd3fbaa40de18p49, 1.100000},
+            {0x1.c5b30c8686203p214, 0x1.f4d14469638a9p48, 1.100000},
+            {0x1.60d15b12ff0b7p217, 0x1.bc150932bd3d7p48, 1.100000},
+            {0x1.07cc6858d980bp218, -0x1.f3f7355c983a5p51, 1.100000},
+            {0x1.e06a67cd86969p218, 0x1.b0873124d98afp51, 1.100000},
+            {0x1.49704174c38e3p229, 0x1.e0301142ccbc2p49, 1.100000},
+            {0x1.ea19ceab3b06ap230, -0x1.fc22e687f0482p48, 1.100000},
+            {0x1.0c905503fea72p236, -0x1.7d4e9a45014d5p49, 1.100000},
+            {0x1.28eb1f8ddd7c3p257, -0x1.a951893680c71p49, 1.100000},
+            {0x1.310b11af2bfbep260, 0x1.84d458039c2e6p48, 1.100000},
+            {0x1.f3c172bb7afc2p265, -0x1.fb3139d3ba04fp49, 1.100000},
+            {0x1.54a28326cfedep267, 0x1.f416de8fb60bap53, 1.100000},
+            {0x1.5a5154d9d609dp269, -0x1.83d74cea8141p51, 1.100000},
+            {0x1.3ee75fd803b21p275, 0x1.b9ab67b61bf65p50, 1.100000},
+            {0x1.f4a4c781834d9p277, -0x1.d639ec63bf3b6p49, 1.100000},
+            {0x1.2053d5c14cf78p279, 0x1.fc31413372cdcp50, 1.100000},
+            {0x1.896d0a9acee4cp298, 0x1.f9136d6e27a5cp48, 1.100000},
+            {0x1.f010da08a862p302, -0x1.fd812c5e13483p49, 1.100000},
+            {0x1.65f2e272f729fp308, -0x1.f9f642ddaa32dp49, 1.100000},
+            {0x1.a8afbc4edb07dp309, 0x1.fa0d458320902p52, 1.100000},
+            {0x1.4d311a5447cdep329, -0x1.f7e98fe193e81p49, 1.100000},
+            {0x1.808f66338b21bp345, -0x1.bceaf45f61155p49, 1.100000},
+            {0x1.5a34aacf5ded1p350, 0x1.d41f0f13fadd4p49, 1.100000},
+            {0x1.3e8b85532bad1p354, -0x1.f0b21179d663ep49, 1.100000},
+            {0x1.1c2ecf01570acp394, -0x1.c215c9e2b7b24p49, 1.100000},
+            {0x1.666eba99d2837p402, 0x1.fbd5c4b527506p48, 1.100000},
+            {0x1.6cc39f07fafbbp460, -0x1.f087548a00e7cp49, 1.100000},
+            {0x1.9481228fea3ffp463, -0x1.c585e64ff44c8p48, 1.100000},
+            {0x1.79c3af0b4d0d4p466, 0x1.c9ed3716691f2p51, 1.100000},
+            {0x1.993ea84c3e23bp468, 0x1.a6b3954fc37f3p49, 1.100000},
+            {0x1.cfd6b13f64408p470, -0x1.f4db7cc2c09bp47, 1.100000},
+            {0x1.b820ccdd52299p473, 0x1.77a1ff863b0f3p52, 1.100000},
+            {0x1.157ef3a1528a5p475, -0x1.f4e14ddc45e49p51, 1.100000},
+            {0x1.b492a8997bc36p478, -0x1.e0db26b7f03e8p48, 1.100000},
+            {0x1.e0ea5674b831bp480, 0x1.e0ad6b3cdccdfp48, 1.100000},
+            {0x1.c62ac8b32cb9ep497, 0x1.c95d00a36f677p48, 1.100000},
+            {0x1.467f1daf12b43p498, 0x1.c6d3fdc096f0bp50, 1.100000},
+            {0x1.336e5a83e390cp502, 0x1.fc873dae28572p48, 1.100000},
+            {0x1.aaab1de0d6727p506, -0x1.e0482967d0354p49, 1.100000},
+            {0x1.e5ce06a12139cp507, 0x1.cea42e29735bdp49, 1.100000},
+            {0x1.87dad74d0dda8p516, -0x1.b2cde6c0a8b9fp48, 1.100000},
+            {0x1.e4feb94ee0989p524, -0x1.b227d0d0ffaa8p49, 1.100000},
+            {0x1.31c082b1361ebp525, 0x1.a7ed49158d736p49, 1.100000},
+            {0x1.56913865b3e16p531, 0x1.eeb7a32591c3bp52, 1.100000},
+            {0x1.36ade1fa883cap544, -0x1.fa087aadc0cbp48, 1.100000},
+            {0x1.de57314df4af8p559, 0x1.c686aa5a41075p49, 1.100000},
+            {0x1.0bb29bf7960ddp586, -0x1.d29ae1a3023cep50, 1.100000},
+            {0x1.049a584685941p588, -0x1.eebfb159dba67p51, 1.100000},
+            {0x1.33c1d4257b294p589, 0x1.ea1eedabea109p48, 1.100000},
+            {0x1.3587e511bf47bp590, 0x1.c897858ce0ca9p48, 1.100000},
+            {0x1.d12ee010c0facp590, 0x1.ab5b4b5065aa3p48, 1.100000},
+            {0x1.87bbed5af48d9p605, 0x1.f512c3b2be7cap50, 1.100000},
+            {0x1.a0b1131240cebp605, -0x1.fa373983fd571p48, 1.100000},
+            {0x1.116fdda1a04c9p616, -0x1.d76fdbc8552f3p51, 1.100000},
+            {0x1.67ebae833a034p620, 0x1.e1313af0a4075p50, 1.100000},
+            {0x1.9a50fbc5b0fecp627, 0x1.d89150884fbf7p50, 1.100000},
+            {0x1.6d625e0757e9cp631, -0x1.d0a5ecf002555p49, 1.100000},
+            {0x1.e880344cc9913p636, -0x1.fafd04caaf58bp48, 1.100000},
+            {0x1.e0a180b843cc5p650, 0x1.ea2aea3b8c953p49, 1.100000},
+            {0x1.fa91ce15157b2p652, 0x1.e6f5f4d47d83fp48, 1.100000},
+            {0x1.7696347caf8dfp654, 0x1.e0d36f2aef7dap51, 1.100000},
+            {0x1.886484b536161p666, -0x1.e3c96481e335bp51, 1.100000},
+            {0x1.0aa3ff2b41abdp675, -0x1.b3300ee04b4c8p50, 1.100000},
+            {0x1.d695ac08fe897p675, -0x1.c27fd21ecb13p51, 1.100000},
+            {0x1.4c1e532d7a99ap680, 0x1.e2ec695260c39p49, 1.100000},
+            {0x1.44a9f3e395802p685, -0x1.e7273ab9ce8e2p52, 1.100000},
+            {0x1.3a25ec2b43d45p697, -0x1.d23187ba6321ep49, 1.100000},
+            {0x1.96f5c2420c3fdp716, -0x1.ea06ab71ad719p49, 1.100000},
+            {0x1.926c063a9406bp741, 0x1.e3d3d9262fd66p48, 1.100000},
+            {0x1.1a57713d6fd93p754, -0x1.c10074d49490dp48, 1.100000},
+            {0x1.739387922e672p772, 0x1.bda527e215a3cp49, 1.100000},
+            {0x1.d286eff17f4d4p793, 0x1.d01c678ebfa1p49, 1.100000},
+            {0x1.f3d777206a062p794, -0x1.d8604b6d18385p49, 1.100000},
+            {0x1.ae91e6574da91p826, -0x1.fd1b26ab656c2p49, 1.100000},
+            {0x1.4422b3c871c9p836, 0x1.9d2cab1f3aebcp48, 1.100000},
+            {0x1.7ff8537071e1p840, 0x1.badde451c6ed7p48, 1.100000},
+            {0x1.c6fe9202e219dp845, -0x1.b2aa20745de3p51, 1.100000},
+            {0x1.a95a0b4015d88p846, 0x1.cdf5dfd045657p50, 1.100000},
+            {0x1.f823b9cff0daep867, 0x1.fd72fce3d5505p48, 1.100000},
+            {0x1.a6bee2afcd2fp886, 0x1.fe06265cd3aebp49, 1.100000},
+            {0x1.7b034b3412d17p892, 0x1.e48055812d391p50, 1.100000},
+            {0x1.58588f8cda276p894, 0x1.f806fddf0dd05p53, 1.100000},
+            {0x1.ce750a7963463p896, 0x1.e94f1f4018402p48, 1.100000},
+            {0x1.3d50a91fe82cfp897, 0x1.cd518fda10e95p48, 1.100000},
+            {0x1.f82dea1c0b809p897, -0x1.d6a0ef08179c5p48, 1.100000},
+            {0x1.38673e8c6a4afp903, 0x1.f4113a036478p48, 1.100000},
+            {0x1.dfb75e4a7432p911, 0x1.eb7bc6cb4d7f3p48, 1.100000},
+            {0x1.1230b975a72b3p916, -0x1.e1042be0759f9p48, 1.100000},
+            {0x1.302c2f5a4e6e5p916, 0x1.f66a9874cd60ap48, 1.100000},
+            {0x1.04e07a1d67b93p921, 0x1.87735139f6a0bp53, 1.100000},
+            {0x1.5a3eb79cd06fap931, -0x1.e00930c219ef3p51, 1.100000},
+            {0x1.8fb45679936fp937, 0x1.9a427588645c4p50, 1.100000},
+            {0x1.c4abb225260c6p964, -0x1.d1e64e91ac6ap50, 1.100000},
+            {0x1.b43e449b25382p982, -0x1.f1848cc5ac4fep50, 1.100000},
+            {0x1.504d9d7179b1ap983, 0x1.a4e51ea807786p48, 1.100000},
+            {0x1.83a5af80fb39bp987, 0x1.a6dde6c2220ebp48, 1.100000},
+            {0x1.5d978d9ad84c8p1011, 0x1.ec96900bfd1ddp51, 1.100000},
+        };
+
+        for(double[] testCase: testCases) {
+            failures += testTanCase(testCase[0], testCase[1], testCase[2]);
+        }
+
+        return failures;
+    }
+
+    public static void main(String [] argv) {
+        int failures = 0;
+
+        failures += testTan();
+
+        if (failures > 0) {
+            System.err.println("Testing tan incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Math/Tests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * Shared static test methods for numerical tests.  Sharing these
+ * helper test methods avoids repeated functions in the various test
+ * programs.  The test methods return 1 for a test failure and 0 for
+ * success.  The order of arguments to the test methods is generally
+ * the test name, followed by the test arguments, the computed result,
+ * and finally the expected result.
+ */
+
+import sun.misc.FpUtils;
+
+public class Tests {
+    private Tests(){}; // do not instantiate
+
+    private static String toHexString(float f) {
+        if (!Float.isNaN(f))
+            return Float.toHexString(f);
+        else
+            return "NaN(0x" + Integer.toHexString(Float.floatToRawIntBits(f)) + ")";
+    }
+
+    private static String toHexString(double d) {
+        if (!Double.isNaN(d))
+            return Double.toHexString(d);
+        else
+            return "NaN(0x" + Long.toHexString(Double.doubleToRawLongBits(d)) + ")";
+    }
+
+    public static int test(String testName, float input,
+                           boolean result, boolean expected) {
+        if (expected != result) {
+            System.err.println("Failure for " + testName + ":\n" +
+                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
+                               "\texpected  " + expected + "\n"  +
+                               "\tgot       " + result   + ").");
+            return 1;
+        }
+        else
+            return 0;
+    }
+
+    public static int test(String testName, double input,
+                           boolean result, boolean expected) {
+        if (expected != result) {
+            System.err.println("Failure for " + testName + ":\n" +
+                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
+                               "\texpected  " + expected + "\n"  +
+                               "\tgot       " + result   + ").");
+            return 1;
+        }
+        else
+            return 0;
+    }
+
+    public static int test(String testName, float input1, float input2,
+                           boolean result, boolean expected) {
+        if (expected != result) {
+            System.err.println("Failure for "  + testName + ":\n" +
+                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
+                                               + input2   + "\t(" + toHexString(input2) + ")\n" +
+                               "\texpected  "  + expected + "\n"  +
+                               "\tgot       "  + result   + ").");
+            return 1;
+        }
+        return 0;
+    }
+
+    public static int test(String testName, double input1, double input2,
+                           boolean result, boolean expected) {
+        if (expected != result) {
+            System.err.println("Failure for "  + testName + ":\n" +
+                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
+                                               + input2   + "\t(" + toHexString(input2) + ")\n" +
+                               "\texpected  "  + expected + "\n"  +
+                               "\tgot       "  + result   + ").");
+            return 1;
+        }
+        return 0;
+    }
+
+    public static int test(String testName, float input,
+                           int result, int expected) {
+        if (expected != result) {
+            System.err.println("Failure for " + testName + ":\n" +
+                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
+                               "\texpected  " + expected + "\n" +
+                               "\tgot       " + result    + ").");
+            return 1;
+        }
+        return 0;
+    }
+
+    public  static int test(String testName, double input,
+                            int result, int expected) {
+        if (expected != result) {
+            System.err.println("Failure for " + testName + ":\n" +
+                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
+                               "\texpected  " + expected + "\n"  +
+                               "\tgot       " + result   + ").");
+            return 1;
+        }
+        else
+            return 0;
+    }
+
+    public static int test(String testName, float input,
+                           float result, float expected) {
+        if (Float.compare(expected, result) != 0 ) {
+            System.err.println("Failure for " + testName + ":\n" +
+                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
+                               "\texpected  " + expected + "\t(" + toHexString(expected) + ")\n" +
+                               "\tgot       " + result   + "\t(" + toHexString(result) + ").");
+            return 1;
+        }
+        else
+            return 0;
+    }
+
+
+    public static int test(String testName, double input,
+                           double result, double expected) {
+        if (Double.compare(expected, result ) != 0) {
+            System.err.println("Failure for " + testName + ":\n" +
+                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
+                               "\texpected  " + expected + "\t(" + toHexString(expected) + ")\n" +
+                               "\tgot       " + result   + "\t(" + toHexString(result) + ").");
+            return 1;
+        }
+        else
+            return 0;
+    }
+
+    public static int test(String testName,
+                           float input1, double input2,
+                           float result, float expected) {
+        if (Float.compare(expected, result ) != 0) {
+            System.err.println("Failure for "  + testName + ":\n" +
+                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
+                                               + input2   + "\t(" + toHexString(input2) + ")\n" +
+                               "\texpected  "  + expected + "\t(" + toHexString(expected) + ")\n" +
+                               "\tgot       "  + result   + "\t(" + toHexString(result) + ").");
+            return 1;
+        }
+        else
+            return 0;
+    }
+
+    public static int test(String testName,
+                           double input1, double input2,
+                           double result, double expected) {
+        if (Double.compare(expected, result ) != 0) {
+            System.err.println("Failure for "  + testName + ":\n" +
+                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
+                                               + input2   + "\t(" + toHexString(input2) + ")\n" +
+                               "\texpected  "  + expected + "\t(" + toHexString(expected) + ")\n" +
+                               "\tgot       "  + result   + "\t(" + toHexString(result) + ").");
+            return 1;
+        }
+        else
+            return 0;
+    }
+
+    public static int test(String testName,
+                           float input1, int input2,
+                           float result, float expected) {
+        if (Float.compare(expected, result ) != 0) {
+            System.err.println("Failure for "  + testName + ":\n" +
+                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
+                                               + input2   + "\n"  +
+                               "\texpected  "  + expected + "\t(" + toHexString(expected) + ")\n" +
+                               "\tgot       "  + result   + "\t(" + toHexString(result) + ").");
+            return 1;
+        }
+        else
+            return 0;
+    }
+
+    public static int test(String testName,
+                           double input1, int input2,
+                           double result, double expected) {
+        if (Double.compare(expected, result ) != 0) {
+            System.err.println("Failure for "  + testName + ":\n" +
+                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
+                                               + input2   + "\n"  +
+                               "\texpected  "  + expected + "\t(" + toHexString(expected) + ")\n" +
+                               "\tgot       "  + result   + "\t(" + toHexString(result) + ").");
+            return 1;
+        }
+        else
+            return 0;
+    }
+
+    static int testUlpCore(double result, double expected, double ulps) {
+        // We assume we won't be unlucky and have an inexact expected
+        // be nextDown(2^i) when 2^i would be the correctly rounded
+        // answer.  This would cause the ulp size to be half as large
+        // as it should be, doubling the measured error).
+
+        if (Double.compare(expected, result) == 0) {
+            return 0;   // result and expected are equivalent
+        } else {
+            if( ulps == 0.0) {
+                // Equivalent results required but not found
+                return 1;
+            } else {
+                double difference = expected - result;
+                if (FpUtils.isUnordered(expected, result) ||
+                    Double.isNaN(difference) ||
+                    // fail if greater than or unordered
+                    !(Math.abs( difference/Math.ulp(expected) ) <= Math.abs(ulps)) ) {
+                    return 1;
+                }
+                else
+                    return 0;
+            }
+        }
+    }
+
+    // One input argument.
+    public static int testUlpDiff(String testName, double input,
+                                  double result, double expected, double ulps) {
+        int code = testUlpCore(result, expected, ulps);
+        if (code == 1) {
+            System.err.println("Failure for " + testName + ":\n" +
+                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
+                               "\texpected  " + expected + "\t(" + toHexString(expected) + ")\n" +
+                               "\tgot       " + result   + "\t(" + toHexString(result) + ");\n" +
+                               "\tdifference greater than ulp tolerance " + ulps);
+        }
+        return code;
+    }
+
+    // Two input arguments.
+    public static int testUlpDiff(String testName, double input1, double input2,
+                                  double result, double expected, double ulps) {
+        int code = testUlpCore(result, expected, ulps);
+        if (code == 1) {
+            System.err.println("Failure for "  + testName + ":\n" +
+                               "\tFor inputs " + input1   + "\t(" + toHexString(input1) + ") and "
+                                               + input2   + "\t(" + toHexString(input2) + ")\n" +
+                               "\texpected  "  + expected + "\t(" + toHexString(expected) + ")\n" +
+                               "\tgot       "  + result   + "\t(" + toHexString(result) + ");\n" +
+                               "\tdifference greater than ulp tolerance " + ulps);
+        }
+        return code;
+    }
+
+    // For a successful test, the result must be within the ulp bound of
+    // expected AND the result must have absolute value less than or
+    // equal to absBound.
+    public static int testUlpDiffWithAbsBound(String testName, double input,
+                                              double result, double expected,
+                                              double ulps, double absBound) {
+        int code = 0;   // return code value
+
+        if (!(StrictMath.abs(result) <= StrictMath.abs(absBound)) &&
+            !Double.isNaN(expected)) {
+            code = 1;
+        } else
+            code = testUlpCore(result, expected, ulps);
+
+        if (code == 1) {
+            System.err.println("Failure for " + testName + ":\n" +
+                               "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
+                               "\texpected  " + expected + "\t(" + toHexString(expected) + ")\n" +
+                               "\tgot       " + result   + "\t(" + toHexString(result) + ");\n" +
+                               "\tdifference greater than ulp tolerance " + ulps +
+                               " or the result has larger magnitude than " + absBound);
+        }
+        return code;
+    }
+
+    // For a successful test, the result must be within the ulp bound of
+    // expected AND the result must have absolute value greater than
+    // or equal to the lowerBound.
+    public static int testUlpDiffWithLowerBound(String testName, double input,
+                                                double result, double expected,
+                                                double ulps, double lowerBound) {
+        int code = 0;   // return code value
+
+        if (!(result >= lowerBound) && !Double.isNaN(expected)) {
+            code = 1;
+        } else
+            code = testUlpCore(result, expected, ulps);
+
+        if (code == 1) {
+            System.err.println("Failure for " + testName +
+                               ":\n" +
+                               "\tFor input "   + input    + "\t(" + toHexString(input) + ")" +
+                               "\n\texpected  " + expected + "\t(" + toHexString(expected) + ")" +
+                               "\n\tgot       " + result   + "\t(" + toHexString(result) + ");" +
+                               "\ndifference greater than ulp tolerance " + ulps +
+                               " or result not greater than or equal to the bound " + lowerBound);
+        }
+        return code;
+    }
+
+    public static int testTolerance(String testName, double input,
+                                    double result, double expected, double tolerance) {
+        if (Double.compare(expected, result ) != 0) {
+            double difference = expected - result;
+            if (FpUtils.isUnordered(expected, result) ||
+                Double.isNaN(difference) ||
+                // fail if greater than or unordered
+                !(Math.abs((difference)/expected) <= StrictMath.pow(10, -tolerance)) ) {
+                System.err.println("Failure for " + testName + ":\n" +
+                                   "\tFor input " + input    + "\t(" + toHexString(input) + ")\n" +
+                                   "\texpected  " + expected + "\t(" + toHexString(expected) + ")\n" +
+                                   "\tgot       " + result   + "\t(" + toHexString(result) + ");\n" +
+                                   "\tdifference greater than tolerance 10^-" + tolerance);
+                return 1;
+            }
+            return 0;
+        }
+        else
+            return 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Short/ByteSwap.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     4495754
+ * @summary Basic test for int byte swap code on short and char
+ * @author  Josh Bloch
+ */
+
+public class ByteSwap {
+    public static void main(String args[]) {
+        if (Short.reverseBytes((short)0xaabb) != (short)0xbbaa)
+            throw new RuntimeException("short");
+
+        if (Character.reverseBytes((char)0xaabb) != (char)0xbbaa)
+            throw new RuntimeException("char");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Short/Decode.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4136371 5017980 6576055
+ * @summary Test Short.decode method
+ * @author madbot
+ * @author Joseph D. Darcy
+ */
+
+/**
+ * There are six methods in java.lang.Short which transform strings
+ * into a short or Short value:
+ *
+ * public Short(String s)
+ * public static Short decode(String nm)
+ * public static short parseShort(String s, int radix)
+ * public static short parseShort(String s)
+ * public static Short valueOf(String s, int radix)
+ * public static Short valueOf(String s)
+ *
+ * However, of these only decode has a nontrivial implementation
+ * in that class.
+ */
+public class Decode {
+
+    private static void check(String ashort, short expected) {
+        short sh = (Short.decode(ashort)).shortValue();
+        if (sh != expected)
+            throw new RuntimeException("Short.decode failed. String:" +
+                                                ashort + " Result:" + sh);
+    }
+
+    private static void checkFailure(String val, String message) {
+        try {
+            short n = (Short.decode(val)).shortValue();
+            throw new RuntimeException(message);
+        } catch (NumberFormatException e) { /* Okay */}
+    }
+
+    public static void main(String[] args) throws Exception {
+        check(new String(""+Short.MIN_VALUE), Short.MIN_VALUE);
+        check(new String(""+Short.MAX_VALUE), Short.MAX_VALUE);
+
+        check("10",   (short)10);
+        check("0x10", (short)16);
+        check("0X10", (short)16);
+        check("010",  (short)8);
+        check("#10",  (short)16);
+
+        check("+10",   (short)10);
+        check("+0x10", (short)16);
+        check("+0X10", (short)16);
+        check("+010",  (short)8);
+        check("+#10",  (short)16);
+
+        check("-10",   (short)-10);
+        check("-0x10", (short)-16);
+        check("-0X10", (short)-16);
+        check("-010",  (short)-8);
+        check("-#10",  (short)-16);
+
+        check(Integer.toString((int)Short.MIN_VALUE), Short.MIN_VALUE);
+        check(Integer.toString((int)Short.MAX_VALUE), Short.MAX_VALUE);
+
+        checkFailure("0x-10",   "Short.decode allows negative sign in wrong position.");
+        checkFailure("0x+10",   "Short.decode allows positive sign in wrong position.");
+
+        checkFailure("+",       "Raw plus sign allowed.");
+        checkFailure("-",       "Raw minus sign allowed.");
+
+        checkFailure(Integer.toString((int)Short.MIN_VALUE - 1), "Out of range");
+        checkFailure(Integer.toString((int)Short.MAX_VALUE + 1), "Out of range");
+
+        checkFailure("", "Empty String");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StrictMath/CubeRootTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,473 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4347132
+ * @summary Tests specifically for StrictMath.cbrt
+ * @author Joseph D. Darcy
+ */
+
+/**
+ * The tests in ../Math/CubeRootTests.java test properties that should
+ * hold for any cube root implementation, including the FDLIBM-based
+ * one required for StrictMath.cbrt.  Therefore, the test cases in
+ * ../Math/CubeRootTests.java are run against both the Math and
+ * StrictMath versions of cube root.  The role of this test is to
+ * verify that the FDLIBM cbrt algorithm is being used by running
+ * golden file tests on values that may vary from one conforming cube
+ * root implementation to another.
+ */
+
+public class CubeRootTests {
+    private CubeRootTests(){}
+
+    static int testCubeRootCase(double input, double expected) {
+        int failures=0;
+
+        double minus_input = -input;
+        double minus_expected = -expected;
+
+        failures+=Tests.test("StrictMath.cbrt(double)", input,
+                             StrictMath.cbrt(input), expected);
+        failures+=Tests.test("StrictMath.cbrt(double)", minus_input,
+                             StrictMath.cbrt(minus_input), minus_expected);
+        return failures;
+    }
+
+    static int testCubeRoot() {
+        int failures = 0;
+        double [][] testCases = {
+            {0x1.ffffffffffffep-766,    0x1.fffffffffffffp-256},
+            {0x1.ffffffffffffep-763,    0x1.fffffffffffffp-255},
+            {0x1.ffffffffffffep-760,    0x1.fffffffffffffp-254},
+            {0x1.ffffffffffffep-757,    0x1.fffffffffffffp-253},
+            {0x1.ffffffffffffep-754,    0x1.fffffffffffffp-252},
+            {0x1.ffffffffffffep-751,    0x1.fffffffffffffp-251},
+            {0x1.ffffffffffffep-748,    0x1.fffffffffffffp-250},
+            {0x1.ffffffffffffep-745,    0x1.fffffffffffffp-249},
+            {0x1.ffffffffffffep-742,    0x1.fffffffffffffp-248},
+            {0x1.ffffffffffffep-739,    0x1.fffffffffffffp-247},
+            {0x1.ffffffffffffep-1006,   0x1.fffffffffffffp-336},
+            {0x1.ffffffffffffep-736,    0x1.fffffffffffffp-246},
+            {0x1.ffffffffffffep-733,    0x1.fffffffffffffp-245},
+            {0x1.ffffffffffffep-730,    0x1.fffffffffffffp-244},
+            {0x1.ffffffffffffep-727,    0x1.fffffffffffffp-243},
+            {0x1.ffffffffffffep-724,    0x1.fffffffffffffp-242},
+            {0x1.ffffffffffffep-721,    0x1.fffffffffffffp-241},
+            {0x1.ffffffffffffep-718,    0x1.fffffffffffffp-240},
+            {0x1.ffffffffffffep-715,    0x1.fffffffffffffp-239},
+            {0x1.ffffffffffffep-712,    0x1.fffffffffffffp-238},
+            {0x1.ffffffffffffep-709,    0x1.fffffffffffffp-237},
+            {0x1.ffffffffffffep-706,    0x1.fffffffffffffp-236},
+            {0x1.ffffffffffffep-703,    0x1.fffffffffffffp-235},
+            {0x1.ffffffffffffep-700,    0x1.fffffffffffffp-234},
+            {0x1.ffffffffffffep-697,    0x1.fffffffffffffp-233},
+            {0x1.ffffffffffffep-694,    0x1.fffffffffffffp-232},
+            {0x1.ffffffffffffep-691,    0x1.fffffffffffffp-231},
+            {0x1.ffffffffffffep-1003,   0x1.fffffffffffffp-335},
+            {0x1.ffffffffffffep-688,    0x1.fffffffffffffp-230},
+            {0x1.ffffffffffffep-685,    0x1.fffffffffffffp-229},
+            {0x1.ffffffffffffep-682,    0x1.fffffffffffffp-228},
+            {0x1.ffffffffffffep-679,    0x1.fffffffffffffp-227},
+            {0x1.ffffffffffffep-676,    0x1.fffffffffffffp-226},
+            {0x1.ffffffffffffep-673,    0x1.fffffffffffffp-225},
+            {0x1.ffffffffffffep-670,    0x1.fffffffffffffp-224},
+            {0x1.ffffffffffffep-667,    0x1.fffffffffffffp-223},
+            {0x1.ffffffffffffep-664,    0x1.fffffffffffffp-222},
+            {0x1.ffffffffffffep-661,    0x1.fffffffffffffp-221},
+            {0x1.ffffffffffffep-658,    0x1.fffffffffffffp-220},
+            {0x1.ffffffffffffep-655,    0x1.fffffffffffffp-219},
+            {0x1.ffffffffffffep-652,    0x1.fffffffffffffp-218},
+            {0x1.ffffffffffffep-649,    0x1.fffffffffffffp-217},
+            {0x1.ffffffffffffep-646,    0x1.fffffffffffffp-216},
+            {0x1.ffffffffffffep-643,    0x1.fffffffffffffp-215},
+            {0x1.ffffffffffffep-1000,   0x1.fffffffffffffp-334},
+            {0x1.ffffffffffffep-640,    0x1.fffffffffffffp-214},
+            {0x1.ffffffffffffep-637,    0x1.fffffffffffffp-213},
+            {0x1.ffffffffffffep-634,    0x1.fffffffffffffp-212},
+            {0x1.ffffffffffffep-631,    0x1.fffffffffffffp-211},
+            {0x1.ffffffffffffep-628,    0x1.fffffffffffffp-210},
+            {0x1.ffffffffffffep-625,    0x1.fffffffffffffp-209},
+            {0x1.ffffffffffffep-622,    0x1.fffffffffffffp-208},
+            {0x1.ffffffffffffep-619,    0x1.fffffffffffffp-207},
+            {0x1.ffffffffffffep-616,    0x1.fffffffffffffp-206},
+            {0x1.ffffffffffffep-613,    0x1.fffffffffffffp-205},
+            {0x1.ffffffffffffep-610,    0x1.fffffffffffffp-204},
+            {0x1.ffffffffffffep-607,    0x1.fffffffffffffp-203},
+            {0x1.ffffffffffffep-604,    0x1.fffffffffffffp-202},
+            {0x1.ffffffffffffep-601,    0x1.fffffffffffffp-201},
+            {0x1.ffffffffffffep-598,    0x1.fffffffffffffp-200},
+            {0x1.ffffffffffffep-595,    0x1.fffffffffffffp-199},
+            {0x1.ffffffffffffep-997,    0x1.fffffffffffffp-333},
+            {0x1.ffffffffffffep-592,    0x1.fffffffffffffp-198},
+            {0x1.ffffffffffffep-589,    0x1.fffffffffffffp-197},
+            {0x1.ffffffffffffep-586,    0x1.fffffffffffffp-196},
+            {0x1.ffffffffffffep-583,    0x1.fffffffffffffp-195},
+            {0x1.ffffffffffffep-580,    0x1.fffffffffffffp-194},
+            {0x1.ffffffffffffep-577,    0x1.fffffffffffffp-193},
+            {0x1.ffffffffffffep-574,    0x1.fffffffffffffp-192},
+            {0x1.ffffffffffffep-571,    0x1.fffffffffffffp-191},
+            {0x1.ffffffffffffep-568,    0x1.fffffffffffffp-190},
+            {0x1.ffffffffffffep-565,    0x1.fffffffffffffp-189},
+            {0x1.ffffffffffffep-562,    0x1.fffffffffffffp-188},
+            {0x1.ffffffffffffep-559,    0x1.fffffffffffffp-187},
+            {0x1.ffffffffffffep-556,    0x1.fffffffffffffp-186},
+            {0x1.ffffffffffffep-553,    0x1.fffffffffffffp-185},
+            {0x1.ffffffffffffep-550,    0x1.fffffffffffffp-184},
+            {0x1.ffffffffffffep-547,    0x1.fffffffffffffp-183},
+            {0x1.ffffffffffffep-994,    0x1.fffffffffffffp-332},
+            {0x1.ffffffffffffep-544,    0x1.fffffffffffffp-182},
+            {0x1.ffffffffffffep-541,    0x1.fffffffffffffp-181},
+            {0x1.ffffffffffffep-538,    0x1.fffffffffffffp-180},
+            {0x1.ffffffffffffep-535,    0x1.fffffffffffffp-179},
+            {0x1.ffffffffffffep-532,    0x1.fffffffffffffp-178},
+            {0x1.ffffffffffffep-529,    0x1.fffffffffffffp-177},
+            {0x0.00000000001fp-1022,    0x1.fa9c313858568p-356},
+            {0x1.ffffffffffffep-526,    0x1.fffffffffffffp-176},
+            {0x1.ffffffffffffep-523,    0x1.fffffffffffffp-175},
+            {0x1.ffffffffffffep-520,    0x1.fffffffffffffp-174},
+            {0x1.ffffffffffffep-517,    0x1.fffffffffffffp-173},
+            {0x0.00000000001fdp-1022,   0x1.feff7f94ea34dp-356},
+            {0x1.ffffffffffffep-514,    0x1.fffffffffffffp-172},
+            {0x0.00000001fffe7p-1022,   0x1.ffff7aaa87f1bp-352},
+            {0x0.00000001fffffp-1022,   0x1.fffffaaaaa9c7p-352},
+            {0x0.00001ffffff4p-1022,    0x1.ffffffcp-348},
+            {0x0.00001ffffffffp-1022,   0x1.ffffffffaaaabp-348},
+            {0x0.01ffffffffffcp-1022,   0x1.ffffffffffeabp-344},
+            {0x1.ffffffffffffep-511,    0x1.fffffffffffffp-171},
+            {0x1.ffffffffffffep-508,    0x1.fffffffffffffp-170},
+            {0x1.ffffffffffffep-505,    0x1.fffffffffffffp-169},
+            {0x1.ffffffffffffep-502,    0x1.fffffffffffffp-168},
+            {0x1.ffffffffffffep-499,    0x1.fffffffffffffp-167},
+            {0x1.ffffffffffffep-991,    0x1.fffffffffffffp-331},
+            {0x1.ffffffffffffep-496,    0x1.fffffffffffffp-166},
+            {0x1.ffffffffffffep-493,    0x1.fffffffffffffp-165},
+            {0x1.ffffffffffffep-490,    0x1.fffffffffffffp-164},
+            {0x1.ffffffffffffep-487,    0x1.fffffffffffffp-163},
+            {0x1.ffffffffffffep-484,    0x1.fffffffffffffp-162},
+            {0x1.ffffffffffffep-481,    0x1.fffffffffffffp-161},
+            {0x1.ffffffffffffep-478,    0x1.fffffffffffffp-160},
+            {0x1.ffffffffffffep-475,    0x1.fffffffffffffp-159},
+            {0x1.ffffffffffffep-472,    0x1.fffffffffffffp-158},
+            {0x1.ffffffffffffep-469,    0x1.fffffffffffffp-157},
+            {0x1.ffffffffffffep-466,    0x1.fffffffffffffp-156},
+            {0x1.ffffffffffffep-463,    0x1.fffffffffffffp-155},
+            {0x1.ffffffffffffep-460,    0x1.fffffffffffffp-154},
+            {0x1.ffffffffffffep-457,    0x1.fffffffffffffp-153},
+            {0x1.ffffffffffffep-454,    0x1.fffffffffffffp-152},
+            {0x1.ffffffffffffep-451,    0x1.fffffffffffffp-151},
+            {0x1.ffffffffffffep-988,    0x1.fffffffffffffp-330},
+            {0x1.ffffffffffffep-448,    0x1.fffffffffffffp-150},
+            {0x1.ffffffffffffep-445,    0x1.fffffffffffffp-149},
+            {0x1.ffffffffffffep-442,    0x1.fffffffffffffp-148},
+            {0x1.ffffffffffffep-439,    0x1.fffffffffffffp-147},
+            {0x1.ffffffffffffep-436,    0x1.fffffffffffffp-146},
+            {0x1.ffffffffffffep-433,    0x1.fffffffffffffp-145},
+            {0x1.ffffffffffffep-430,    0x1.fffffffffffffp-144},
+            {0x1.ffffffffffffep-427,    0x1.fffffffffffffp-143},
+            {0x1.ffffffffffffep-424,    0x1.fffffffffffffp-142},
+            {0x1.ffffffffffffep-421,    0x1.fffffffffffffp-141},
+            {0x1.ffffffffffffep-418,    0x1.fffffffffffffp-140},
+            {0x1.ffffffffffffep-415,    0x1.fffffffffffffp-139},
+            {0x1.ffffffffffffep-412,    0x1.fffffffffffffp-138},
+            {0x1.ffffffffffffep-409,    0x1.fffffffffffffp-137},
+            {0x1.ffffffffffffep-406,    0x1.fffffffffffffp-136},
+            {0x1.ffffffffffffep-403,    0x1.fffffffffffffp-135},
+            {0x1.ffffffffffffep-985,    0x1.fffffffffffffp-329},
+            {0x1.ffffffffffffep-400,    0x1.fffffffffffffp-134},
+            {0x1.ffffffffffffep-397,    0x1.fffffffffffffp-133},
+            {0x1.ffffffffffffep-394,    0x1.fffffffffffffp-132},
+            {0x1.ffffffffffffep-391,    0x1.fffffffffffffp-131},
+            {0x1.ffffffffffffep-388,    0x1.fffffffffffffp-130},
+            {0x1.ffffffffffffep-385,    0x1.fffffffffffffp-129},
+            {0x1.ffffffffffffep-382,    0x1.fffffffffffffp-128},
+            {0x1.ffffffffffffep-379,    0x1.fffffffffffffp-127},
+            {0x1.ffffffffffffep-376,    0x1.fffffffffffffp-126},
+            {0x1.ffffffffffffep-373,    0x1.fffffffffffffp-125},
+            {0x1.ffffffffffffep-370,    0x1.fffffffffffffp-124},
+            {0x1.ffffffffffffep-367,    0x1.fffffffffffffp-123},
+            {0x1.ffffffffffffep-364,    0x1.fffffffffffffp-122},
+            {0x1.ffffffffffffep-361,    0x1.fffffffffffffp-121},
+            {0x1.ffffffffffffep-358,    0x1.fffffffffffffp-120},
+            {0x1.ffffffffffffep-355,    0x1.fffffffffffffp-119},
+            {0x1.ffffffffffffep-982,    0x1.fffffffffffffp-328},
+            {0x1.ffffffffffffep-352,    0x1.fffffffffffffp-118},
+            {0x1.ffffffffffffep-349,    0x1.fffffffffffffp-117},
+            {0x1.ffffffffffffep-346,    0x1.fffffffffffffp-116},
+            {0x1.ffffffffffffep-343,    0x1.fffffffffffffp-115},
+            {0x1.ffffffffffffep-340,    0x1.fffffffffffffp-114},
+            {0x1.ffffffffffffep-337,    0x1.fffffffffffffp-113},
+            {0x1.ffffffffffffep-334,    0x1.fffffffffffffp-112},
+            {0x1.ffffffffffffep-331,    0x1.fffffffffffffp-111},
+            {0x1.ffffffffffffep-328,    0x1.fffffffffffffp-110},
+            {0x1.ffffffffffffep-325,    0x1.fffffffffffffp-109},
+            {0x1.ffffffffffffep-322,    0x1.fffffffffffffp-108},
+            {0x1.ffffffffffffep-319,    0x1.fffffffffffffp-107},
+            {0x1.ffffffffffffep-316,    0x1.fffffffffffffp-106},
+            {0x1.ffffffffffffep-313,    0x1.fffffffffffffp-105},
+            {0x1.ffffffffffffep-310,    0x1.fffffffffffffp-104},
+            {0x1.ffffffffffffep-307,    0x1.fffffffffffffp-103},
+            {0x1.ffffffffffffep-979,    0x1.fffffffffffffp-327},
+            {0x1.ffffffffffffep-304,    0x1.fffffffffffffp-102},
+            {0x1.ffffffffffffep-301,    0x1.fffffffffffffp-101},
+            {0x1.ffffffffffffep-298,    0x1.fffffffffffffp-100},
+            {0x1.ffffffffffffep-295,    0x1.fffffffffffffp-99},
+            {0x1.ffffffffffffep-292,    0x1.fffffffffffffp-98},
+            {0x1.ffffffffffffep-289,    0x1.fffffffffffffp-97},
+            {0x1.ffffffffffffep-286,    0x1.fffffffffffffp-96},
+            {0x1.ffffffffffffep-283,    0x1.fffffffffffffp-95},
+            {0x1.ffffffffffffep-280,    0x1.fffffffffffffp-94},
+            {0x1.ffffffffffffep-277,    0x1.fffffffffffffp-93},
+            {0x1.ffffffffffffep-274,    0x1.fffffffffffffp-92},
+            {0x1.ffffffffffffep-271,    0x1.fffffffffffffp-91},
+            {0x1.ffffffffffffep-268,    0x1.fffffffffffffp-90},
+            {0x1.ffffffffffffep-265,    0x1.fffffffffffffp-89},
+            {0x1.ffffffffffffep-262,    0x1.fffffffffffffp-88},
+            {0x1.ffffffffffffep-259,    0x1.fffffffffffffp-87},
+            {0x1.ffffffffffffep-1021,   0x1.fffffffffffffp-341},
+            {0x1.ffffffffffffep-976,    0x1.fffffffffffffp-326},
+            {0x1.ffffffffffffep-256,    0x1.fffffffffffffp-86},
+            {0x1.ffffffffffffep-253,    0x1.fffffffffffffp-85},
+            {0x1.ffffffffffffep-250,    0x1.fffffffffffffp-84},
+            {0x1.ffffffffffffep-247,    0x1.fffffffffffffp-83},
+            {0x1.ffffffffffffep-244,    0x1.fffffffffffffp-82},
+            {0x1.ffffffffffffep-241,    0x1.fffffffffffffp-81},
+            {0x1.ffffffffffffep-238,    0x1.fffffffffffffp-80},
+            {0x1.ffffffffffffep-235,    0x1.fffffffffffffp-79},
+            {0x1.ffffffffffffep-232,    0x1.fffffffffffffp-78},
+            {0x1.ffffffffffffep-229,    0x1.fffffffffffffp-77},
+            {0x1.ffffffffffffep-226,    0x1.fffffffffffffp-76},
+            {0x1.ffffffffffffep-223,    0x1.fffffffffffffp-75},
+            {0x1.ffffffffffffep-220,    0x1.fffffffffffffp-74},
+            {0x1.ffffffffffffep-217,    0x1.fffffffffffffp-73},
+            {0x1.ffffffffffffep-214,    0x1.fffffffffffffp-72},
+            {0x1.ffffffffffffep-211,    0x1.fffffffffffffp-71},
+            {0x1.ffffffffffffep-973,    0x1.fffffffffffffp-325},
+            {0x1.ffffffffffffep-208,    0x1.fffffffffffffp-70},
+            {0x1.ffffffffffffep-205,    0x1.fffffffffffffp-69},
+            {0x1.ffffffffffffep-202,    0x1.fffffffffffffp-68},
+            {0x1.ffffffffffffep-199,    0x1.fffffffffffffp-67},
+            {0x1.ffffffffffffep-196,    0x1.fffffffffffffp-66},
+            {0x1.ffffffffffffep-193,    0x1.fffffffffffffp-65},
+            {0x1.ffffffffffffep-190,    0x1.fffffffffffffp-64},
+            {0x1.ffffffffffffep-187,    0x1.fffffffffffffp-63},
+            {0x1.ffffffffffffep-184,    0x1.fffffffffffffp-62},
+            {0x1.ffffffffffffep-181,    0x1.fffffffffffffp-61},
+            {0x1.ffffffffffffep-178,    0x1.fffffffffffffp-60},
+            {0x1.ffffffffffffep-175,    0x1.fffffffffffffp-59},
+            {0x1.ffffffffffffep-172,    0x1.fffffffffffffp-58},
+            {0x1.ffffffffffffep-169,    0x1.fffffffffffffp-57},
+            {0x1.ffffffffffffep-166,    0x1.fffffffffffffp-56},
+            {0x1.ffffffffffffep-163,    0x1.fffffffffffffp-55},
+            {0x1.ffffffffffffep-970,    0x1.fffffffffffffp-324},
+            {0x1.ffffffffffffep-160,    0x1.fffffffffffffp-54},
+            {0x1.ffffffffffffep-157,    0x1.fffffffffffffp-53},
+            {0x1.ffffffffffffep-154,    0x1.fffffffffffffp-52},
+            {0x1.ffffffffffffep-151,    0x1.fffffffffffffp-51},
+            {0x1.ffffffffffffep-148,    0x1.fffffffffffffp-50},
+            {0x1.ffffffffffffep-145,    0x1.fffffffffffffp-49},
+            {0x1.ffffffffffffep-142,    0x1.fffffffffffffp-48},
+            {0x1.ffffffffffffep-139,    0x1.fffffffffffffp-47},
+            {0x1.ffffffffffffep-136,    0x1.fffffffffffffp-46},
+            {0x1.ffffffffffffep-133,    0x1.fffffffffffffp-45},
+            {0x1.ffffffffffffep-130,    0x1.fffffffffffffp-44},
+            {0x1.ffffffffffffep-127,    0x1.fffffffffffffp-43},
+            {0x1.ffffffffffffep-124,    0x1.fffffffffffffp-42},
+            {0x1.ffffffffffffep-121,    0x1.fffffffffffffp-41},
+            {0x1.ffffffffffffep-118,    0x1.fffffffffffffp-40},
+            {0x1.ffffffffffffep-115,    0x1.fffffffffffffp-39},
+            {0x1.ffffffffffffep-967,    0x1.fffffffffffffp-323},
+            {0x1.ffffffffffffep-112,    0x1.fffffffffffffp-38},
+            {0x1.ffffffffffffep-109,    0x1.fffffffffffffp-37},
+            {0x1.ffffffffffffep-106,    0x1.fffffffffffffp-36},
+            {0x1.ffffffffffffep-103,    0x1.fffffffffffffp-35},
+            {0x1.ffffffffffffep-100,    0x1.fffffffffffffp-34},
+            {0x1.ffffffffffffep-97,     0x1.fffffffffffffp-33},
+            {0x1.ffffffffffffep-94,     0x1.fffffffffffffp-32},
+            {0x1.ffffffffffffep-91,     0x1.fffffffffffffp-31},
+            {0x1.ffffffffffffep-88,     0x1.fffffffffffffp-30},
+            {0x1.ffffffffffffep-85,     0x1.fffffffffffffp-29},
+            {0x1.ffffffffffffep-82,     0x1.fffffffffffffp-28},
+            {0x1.ffffffffffffep-79,     0x1.fffffffffffffp-27},
+            {0x1.ffffffffffffep-76,     0x1.fffffffffffffp-26},
+            {0x1.ffffffffffffep-73,     0x1.fffffffffffffp-25},
+            {0x1.ffffffffffffep-70,     0x1.fffffffffffffp-24},
+            {0x1.ffffffffffffep-67,     0x1.fffffffffffffp-23},
+            {0x1.ffffffffffffep-964,    0x1.fffffffffffffp-322},
+            {0x1.ffffffffffffep-64,     0x1.fffffffffffffp-22},
+            {0x1.ffffffffffffep-61,     0x1.fffffffffffffp-21},
+            {0x1.ffffffffffffep-58,     0x1.fffffffffffffp-20},
+            {0x1.ffffffffffffep-55,     0x1.fffffffffffffp-19},
+            {0x1.ffffffffffffep-52,     0x1.fffffffffffffp-18},
+            {0x1.ffffffffffffep-49,     0x1.fffffffffffffp-17},
+            {0x1.ffffffffffffep-46,     0x1.fffffffffffffp-16},
+            {0x1.ffffffffffffep-43,     0x1.fffffffffffffp-15},
+            {0x1.ffffffffffffep-40,     0x1.fffffffffffffp-14},
+            {0x1.ffffffffffffep-37,     0x1.fffffffffffffp-13},
+            {0x1.ffffffffffffep-34,     0x1.fffffffffffffp-12},
+            {0x1.ffffffffffffep-31,     0x1.fffffffffffffp-11},
+            {0x1.ffffffffffffep-28,     0x1.fffffffffffffp-10},
+            {0x1.ffffffffffffep-25,     0x1.fffffffffffffp-9},
+            {0x1.ffffffffffffep-22,     0x1.fffffffffffffp-8},
+            {0x0.000000000003ep-1022,   0x1.fa9c313858568p-357},
+            {0x1.ffffffffffffep-19,     0x1.fffffffffffffp-7},
+            {0x1.ffffffffffffep-961,    0x1.fffffffffffffp-321},
+            {0x1.ffffffffffffep-16,     0x1.fffffffffffffp-6},
+            {0x1.ffffffffffffep-13,     0x1.fffffffffffffp-5},
+            {0x1.ffffffffffffep-10,     0x1.fffffffffffffp-4},
+            {0x1.ffffffffffffep-7,      0x1.fffffffffffffp-3},
+            {0x0.000000000003fp-1022,   0x1.fd51bf2069fe6p-357},
+            {0x1.ffffffffffffep-4,      0x1.fffffffffffffp-2},
+            {0x1.ffffffffffffep-1,      0x1.fffffffffffffp-1},
+            {0x0.000000003fffcp-1022,   0x1.ffff55551c71bp-353},
+            {0x0.000003fffffe8p-1022,   0x1.ffffffcp-349},
+            {0x0.000003ffffffcp-1022,   0x1.fffffff555555p-349},
+            {0x0.003fffffffff9p-1022,   0x1.fffffffffed55p-345},
+            {0x1.ffffffffffffep2,       0x1.fffffffffffffp0},
+            {0x1.bp4,                   0x1.8p1},
+            {0x1.ffffffffffffep5,       0x1.fffffffffffffp1},
+            {0x1.f3ffffffffff4p6,       0x1.3fffffffffffep2},
+            {0x1.f3ffffffffffcp6,       0x1.3ffffffffffffp2},
+            {0x1.bp7,                   0x1.8p2},
+            {0x1.56ffffffffffep8,       0x1.bffffffffffffp2},
+            {0x1.ffffffffffffep8,       0x1.fffffffffffffp2},
+            {0x1.6c8p9,                 0x1.2p3},
+            {0x1.f3ffffffffff4p9,       0x1.3fffffffffffep3},
+            {0x1.f3ffffffffffcp9,       0x1.3ffffffffffffp3},
+            {0x1.4cbfffffffffcp10,      0x1.5fffffffffffep3},
+            {0x1.4cbfffffffffep10,      0x1.5ffffffffffffp3},
+            {0x1.bp10,                  0x1.8p3},
+            {0x1.129ffffffffa4p11,      0x1.9ffffffffffd1p3},
+            {0x1.129fffffffffep11,      0x1.9ffffffffffffp3},
+            {0x1.56ffffffffffep11,      0x1.bffffffffffffp3},
+            {0x1.a5ep11,                0x1.ep3},
+            {0x1.ffffffffffffep11,      0x1.fffffffffffffp3},
+            {0x1.330fffffffc1ep12,      0x1.0fffffffffedbp4},
+            {0x1.331p12,                0x1.1p4},
+            {0x1.6c8p12,                0x1.2p4},
+            {0x1.acafffffffffap12,      0x1.2ffffffffffffp4},
+            {0x1.acafffffffffep12,      0x1.2ffffffffffffp4},
+            {0x1.ffffffffffffep-958,    0x1.fffffffffffffp-320},
+            {0x1.ffffffffffffep-955,    0x1.fffffffffffffp-319},
+            {0x1.ffffffffffffep-952,    0x1.fffffffffffffp-318},
+            {0x1.ffffffffffffep-949,    0x1.fffffffffffffp-317},
+            {0x1.ffffffffffffep-946,    0x1.fffffffffffffp-316},
+            {0x1.ffffffffffffep-943,    0x1.fffffffffffffp-315},
+            {0x1.ffffffffffffep-940,    0x1.fffffffffffffp-314},
+            {0x1.ffffffffffffep-937,    0x1.fffffffffffffp-313},
+            {0x1.ffffffffffffep-934,    0x1.fffffffffffffp-312},
+            {0x1.ffffffffffffep-931,    0x1.fffffffffffffp-311},
+            {0x1.ffffffffffffep-1018,   0x1.fffffffffffffp-340},
+            {0x1.ffffffffffffep-928,    0x1.fffffffffffffp-310},
+            {0x1.ffffffffffffep-925,    0x1.fffffffffffffp-309},
+            {0x1.ffffffffffffep-922,    0x1.fffffffffffffp-308},
+            {0x1.ffffffffffffep-919,    0x1.fffffffffffffp-307},
+            {0x1.ffffffffffffep-916,    0x1.fffffffffffffp-306},
+            {0x1.ffffffffffffep-913,    0x1.fffffffffffffp-305},
+            {0x1.ffffffffffffep-910,    0x1.fffffffffffffp-304},
+            {0x1.ffffffffffffep-907,    0x1.fffffffffffffp-303},
+            {0x1.ffffffffffffep-904,    0x1.fffffffffffffp-302},
+            {0x0.0000000000007p-1022,   0x1.e9b5dba58189ep-358},
+            {0x1.ffffffffffffep-901,    0x1.fffffffffffffp-301},
+            {0x1.ffffffffffffep-898,    0x1.fffffffffffffp-300},
+            {0x0.0000000007ffp-1022,    0x1.ffeaa9c70ca31p-354},
+            {0x0.0000000007ffep-1022,   0x1.fffd5551c7149p-354},
+            {0x0.0000007fffffdp-1022,   0x1.ffffffcp-350},
+            {0x0.0000007fffffep-1022,   0x1.ffffffd555555p-350},
+            {0x0.0007ffffffffap-1022,   0x1.fffffffff8p-346},
+            {0x0.7ffffffffffffp-1022,   0x1.fffffffffffffp-342},
+            {0x1.ffffffffffffep-895,    0x1.fffffffffffffp-299},
+            {0x1.ffffffffffffep-892,    0x1.fffffffffffffp-298},
+            {0x1.ffffffffffffep-889,    0x1.fffffffffffffp-297},
+            {0x1.ffffffffffffep-886,    0x1.fffffffffffffp-296},
+            {0x1.ffffffffffffep-883,    0x1.fffffffffffffp-295},
+            {0x1.ffffffffffffep-1015,   0x1.fffffffffffffp-339},
+            {0x1.ffffffffffffep-880,    0x1.fffffffffffffp-294},
+            {0x1.ffffffffffffep-877,    0x1.fffffffffffffp-293},
+            {0x1.ffffffffffffep-874,    0x1.fffffffffffffp-292},
+            {0x1.ffffffffffffep-871,    0x1.fffffffffffffp-291},
+            {0x1.ffffffffffffep-868,    0x1.fffffffffffffp-290},
+            {0x1.ffffffffffffep-865,    0x1.fffffffffffffp-289},
+            {0x1.ffffffffffffep-862,    0x1.fffffffffffffp-288},
+            {0x1.ffffffffffffep-859,    0x1.fffffffffffffp-287},
+            {0x1.ffffffffffffep-856,    0x1.fffffffffffffp-286},
+            {0x1.ffffffffffffep-853,    0x1.fffffffffffffp-285},
+            {0x1.ffffffffffffep-850,    0x1.fffffffffffffp-284},
+            {0x1.ffffffffffffep-847,    0x1.fffffffffffffp-283},
+            {0x1.ffffffffffffep-844,    0x1.fffffffffffffp-282},
+            {0x1.ffffffffffffep-841,    0x1.fffffffffffffp-281},
+            {0x1.ffffffffffffep-838,    0x1.fffffffffffffp-280},
+            {0x1.ffffffffffffep-835,    0x1.fffffffffffffp-279},
+            {0x1.ffffffffffffep-1012,   0x1.fffffffffffffp-338},
+            {0x1.ffffffffffffep-832,    0x1.fffffffffffffp-278},
+            {0x1.ffffffffffffep-829,    0x1.fffffffffffffp-277},
+            {0x1.ffffffffffffep-826,    0x1.fffffffffffffp-276},
+            {0x1.ffffffffffffep-823,    0x1.fffffffffffffp-275},
+            {0x1.ffffffffffffep-820,    0x1.fffffffffffffp-274},
+            {0x1.ffffffffffffep-817,    0x1.fffffffffffffp-273},
+            {0x1.ffffffffffffep-814,    0x1.fffffffffffffp-272},
+            {0x1.ffffffffffffep-811,    0x1.fffffffffffffp-271},
+            {0x1.ffffffffffffep-808,    0x1.fffffffffffffp-270},
+            {0x1.ffffffffffffep-805,    0x1.fffffffffffffp-269},
+            {0x1.ffffffffffffep-802,    0x1.fffffffffffffp-268},
+            {0x1.ffffffffffffep-799,    0x1.fffffffffffffp-267},
+            {0x1.ffffffffffffep-796,    0x1.fffffffffffffp-266},
+            {0x1.ffffffffffffep-793,    0x1.fffffffffffffp-265},
+            {0x1.ffffffffffffep-790,    0x1.fffffffffffffp-264},
+            {0x1.ffffffffffffep-787,    0x1.fffffffffffffp-263},
+            {0x1.ffffffffffffep-1009,   0x1.fffffffffffffp-337},
+            {0x1.ffffffffffffep-784,    0x1.fffffffffffffp-262},
+            {0x1.ffffffffffffep-781,    0x1.fffffffffffffp-261},
+            {0x1.ffffffffffffep-778,    0x1.fffffffffffffp-260},
+            {0x1.ffffffffffffep-775,    0x1.fffffffffffffp-259},
+            {0x1.ffffffffffffep-772,    0x1.fffffffffffffp-258},
+            {0x1.ffffffffffffep-769,    0x1.fffffffffffffp-257},
+            {0x0.0000000000ffep-1022,   0x1.ffeaa9c70ca31p-355},
+            {0x0.0000000000fffp-1022,   0x1.fff5551c6fcd6p-355},
+            {0x0.0000000ffff86p-1022,   0x1.ffffaeaa9dbf1p-351},
+            {0x0.0000000ffffffp-1022,   0x1.ffffff5555552p-351},
+            {0x0.0000ffffffap-1022,     0x1.ffffffcp-347},
+            {0x0.0000ffffffff8p-1022,   0x1.ffffffffaaaabp-347},
+            {0x0.0fffffffffffbp-1022,   0x1.fffffffffffcbp-343}
+        };
+
+        for(double[] testCase: testCases)
+            failures+=testCubeRootCase(testCase[0], testCase[1]);
+
+        return failures;
+    }
+
+
+    public static void main(String [] argv) {
+        int failures = 0;
+
+        failures += testCubeRoot();
+
+        if (failures > 0) {
+            System.err.println("Testing the cube root incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StrictMath/Expm1Tests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,795 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4851638
+ * @summary Tests for StrictMath.expm1
+ * @author Joseph D. Darcy
+ */
+
+/**
+ * The tests in ../Math/Expm1Tests.java test properties that should
+ * hold for any expm1 implementation, including the FDLIBM-based one
+ * required for StrictMath.expm1.  Therefore, the test cases in
+ * ../Math/Expm1Tests.java are run against both the Math and
+ * StrictMath versions of expm1.  The role of this test is to verify
+ * that the FDLIBM expm1 algorithm is being used by running golden
+ * file tests on values that may vary from one conforming expm1
+ * implementation to another.
+ */
+
+public class Expm1Tests {
+    private Expm1Tests(){}
+
+    static int testExpm1Case(double input, double expected) {
+        return Tests.test("StrictMath.expm1(double)", input,
+                          StrictMath.expm1(input), expected);
+    }
+
+    static int testExpm1() {
+        int failures = 0;
+
+        // Test cases in the range [-36.75, 710]
+        double [][] testCases = {
+            {-0x1.580000008c619p3,      -0x1.fffd3069586f6p-1},
+            {-0x1.380000008c721p3,      -0x1.fff85bf4a6e98p-1},
+            {-0x1.180000008c9fap3,      -0x1.ffeb3aeb95524p-1},
+            {-0x1.f0000001197ccp2,      -0x1.ffc78aadc116ap-1},
+            {-0x1.b0000001197e7p2,      -0x1.ff6687cca710bp-1},
+            {-0x1.70000001197f6p2,      -0x1.fe5ed3992a519p-1},
+            {-0x1.30000001198p2,        -0x1.fb9201482bdfap-1},
+            {-0x1.e000000233006p1,      -0x1.f3f57b658d6fbp-1},
+            {-0x1.6000000233012p1,      -0x1.df44d8ee30b76p-1},
+            {-0x1.c000000466028p0,      -0x1.a7071a097ed5ep-1},
+            {-0x1.80000008cc052p-1,     -0x1.0e25f8a4a95b7p-1},
+            {0x1.ffffffdccfeb7p-3,      0x1.22d78ef909144p-2},
+            {0x1.3ffffffb99fd7p0,       0x1.3ec38ed3629a6p1},
+            {0x1.1ffffffdccfebp1,       0x1.0f9b882a107edp3},
+            {0x1.9ffffffdccfebp1,       0x1.8ca53b70fa11bp4},
+            {0x1.0ffffffee67f6p2,       0x1.146bf132050c5p6},
+            {0x1.4ffffffee67f5p2,       0x1.7b21ede9f0bdap7},
+            {0x1.8ffffffee67f5p2,       0x1.0281a438aa523p9},
+            {0x1.cffffffee67f5p2,       0x1.5fc6b5cf322c4p10},
+            {0x1.07ffffff733fap3,       0x1.de5406b276b92p11},
+            {0x1.27ffffff733fap3,       0x1.451c8690d1567p13},
+            {0x1.47ffffff733fap3,       0x1.b9e62ae5924dfp14},
+            {0x1.67ffffff733fap3,       0x1.2c4eeb7089cp16},
+            {0x1.87ffffff733fap3,       0x1.982a24f2ab78ap17},
+            {0x1.a7ffffff733fap3,       0x1.1560a14319349p19},
+            {0x1.c7ffffff733fap3,       0x1.78fed772b40f2p20},
+            {0x1.e7ffffff733fap3,       0x1.0031f18ee602fp22},
+            {0x1.03ffffffb99fdp4,       0x1.5c348d8118f26p23},
+            {0x1.13ffffffb99fdp4,       0x1.d942943e22d74p24},
+            {0x1.23ffffffb99fcp4,       0x1.419d1309466ep26},
+            {0x1.33ffffffb99fcp4,       0x1.b51e403430afep27},
+            {0x1.43ffffffb99fcp4,       0x1.290d76c47bd4cp29},
+            {0x1.53ffffffb99fcp4,       0x1.93bc8061146dp30},
+            {0x1.63ffffffb99fbp4,       0x1.125e0665544a5p32},
+            {0x1.73ffffffb99fbp4,       0x1.74e75f9de5d7cp33},
+            {0x1.83ffffffb99fbp4,       0x1.fad42d3f28732p34},
+            {0x1.93ffffffb99fbp4,       0x1.586d071cb8f87p36},
+            {0x1.a3ffffffb99fbp4,       0x1.d41f91d0b4e6ep37},
+            {0x1.b3ffffffb99fbp4,       0x1.3e1f6e5bc0242p39},
+            {0x1.c3ffffffb99fbp4,       0x1.b05fa9aebfa64p40},
+            {0x1.d3ffffffb99fbp4,       0x1.25d410cc90a38p42},
+            {0x1.e3ffffffb99fbp4,       0x1.8f5aab33aa6c6p43},
+            {0x1.f3ffffffb99fbp4,       0x1.0f63a91bc9797p45},
+            {0x1.01ffffffdccfep5,       0x1.70db367c88b28p46},
+            {0x1.09ffffffdccfep5,       0x1.f553e36d2975fp47},
+            {0x1.11ffffffdccfep5,       0x1.54afff2230e99p49},
+            {0x1.19ffffffdccfep5,       0x1.cf0ad451f1e9fp50},
+            {0x1.21ffffffdccfep5,       0x1.3aab7c88ef991p52},
+            {0x1.29ffffffdccfep5,       0x1.abae41ecccd22p53},
+            {0x1.31ffffffdccfep5,       0x1.22a3a0462535fp55},
+            {0x1.39ffffffdccfdp5,       0x1.8b050329f95c8p56},
+            {0x1.41ffffffdccfdp5,       0x1.0c719224d80a2p58},
+            {0x1.49ffffffdccfdp5,       0x1.6cda4c755ea56p59},
+            {0x1.51ffffffdccfdp5,       0x1.efe2e2b6ad6ebp60},
+            {0x1.59ffffffdccfdp5,       0x1.50fd5a6337c61p62},
+            {0x1.61ffffffdccfdp5,       0x1.ca043518d78acp63},
+            {0x1.69ffffffdccfdp5,       0x1.374122dd2fbdbp65},
+            {0x1.71ffffffdccfdp5,       0x1.a709e46cc671ep66},
+            {0x1.79ffffffdccfdp5,       0x1.1f7c0c5482bf3p68},
+            {0x1.81ffffffdccfdp5,       0x1.86bb667297515p69},
+            {0x1.89ffffffdccfcp5,       0x1.0987aa8375abcp71},
+            {0x1.91ffffffdccfcp5,       0x1.68e48248f27ddp72},
+            {0x1.99ffffffdccfcp5,       0x1.ea8100a2e27e9p73},
+            {0x1.a1ffffffdccfcp5,       0x1.4d54fc02d9352p75},
+            {0x1.a9ffffffdccfcp5,       0x1.c50b8ceab6ad1p76},
+            {0x1.b1ffffffdccfcp5,       0x1.33e046afc7062p78},
+            {0x1.b9ffffffdccfcp5,       0x1.a2726cf2e78e3p79},
+            {0x1.c1ffffffdccfcp5,       0x1.1c5d3c581edf2p81},
+            {0x1.c9ffffffdccfcp5,       0x1.827db3961daecp82},
+            {0x1.d1ffffffdccfbp5,       0x1.06a5db797b4b2p84},
+            {0x1.d9ffffffdccfbp5,       0x1.64f9b90e23fb4p85},
+            {0x1.e1ffffffdccfbp5,       0x1.e52e132ebafe2p86},
+            {0x1.e9ffffffdccfbp5,       0x1.49b6c774442efp88},
+            {0x1.f1ffffffdccfbp5,       0x1.c020b4f9d926cp89},
+            {0x1.f9ffffffdccfbp5,       0x1.3088cda20d465p91},
+            {0x1.00ffffffee67ep6,       0x1.9de7b7a818186p92},
+            {0x1.04ffffffee67ep6,       0x1.194717f5da259p94},
+            {0x1.08ffffffee67ep6,       0x1.7e4bc97a2360dp95},
+            {0x1.0cffffffee67ep6,       0x1.03cc0e87f367bp97},
+            {0x1.10ffffffee67ep6,       0x1.6119d231b67f5p98},
+            {0x1.14ffffffee67ep6,       0x1.dfe9f0cbe5942p99},
+            {0x1.18ffffffee67ep6,       0x1.4622a079fc2a6p101},
+            {0x1.1cffffffee67ep6,       0x1.bb4386e45ae94p102},
+            {0x1.20ffffffee67ep6,       0x1.2d3a9d9e9fe6p104},
+            {0x1.24ffffffee67ep6,       0x1.9969a118d6261p105},
+            {0x1.28ffffffee67ep6,       0x1.1639871642331p107},
+            {0x1.2cffffffee67ep6,       0x1.7a2587603a84bp108},
+            {0x1.30ffffffee67ep6,       0x1.00fa2d6e6a76ep110},
+            {0x1.34ffffffee67ep6,       0x1.5d44af7562574p111},
+            {0x1.38ffffffee67ep6,       0x1.dab4705f88c02p112},
+            {0x1.3cffffffee67ep6,       0x1.42986b24fc9dcp114},
+            {0x1.40ffffffee67ep6,       0x1.b673dcb2fe519p115},
+            {0x1.44ffffffee67ep6,       0x1.29f59cd896383p117},
+            {0x1.48ffffffee67ep6,       0x1.94f806342143cp118},
+            {0x1.4cffffffee67ep6,       0x1.133471e4d5b38p120},
+            {0x1.50ffffffee67ep6,       0x1.760acce4f0e03p121},
+            {0x1.54ffffffee67ep6,       0x1.fc604454828ddp122},
+            {0x1.58ffffffee67ep6,       0x1.597a32eee8c46p124},
+            {0x1.5cffffffee67ep6,       0x1.d58d694102246p125},
+            {0x1.60ffffffee67ep6,       0x1.3f180bd3df0d2p127},
+            {0x1.64ffffffee67ep6,       0x1.b1b190d803f07p128},
+            {0x1.68ffffffee67ep6,       0x1.26b9b1cab82dap130},
+            {0x1.6cffffffee67ep6,       0x1.9092c44a68bc1p131},
+            {0x1.70ffffffee67ep6,       0x1.1037c0cf4a5a6p133},
+            {0x1.74ffffffee67ep6,       0x1.71fb79fed30fbp134},
+            {0x1.78ffffffee67ep6,       0x1.f6dbadec024eep135},
+            {0x1.7cffffffee67ep6,       0x1.55ba3f072a6dbp137},
+            {0x1.80ffffffee67ep6,       0x1.d074b338a9163p138},
+            {0x1.84ffffffee67ep6,       0x1.3ba167320351ap140},
+            {0x1.88ffffffee67ep6,       0x1.acfc7e2e0558bp141},
+            {0x1.8cffffffee67ep6,       0x1.2386c336b7163p143},
+            {0x1.90ffffffee67ep6,       0x1.8c39b90c7cdap144},
+            {0x1.94ffffffee67ep6,       0x1.0d435c84d4e66p146},
+            {0x1.98ffffffee67ep6,       0x1.6df76efd7275ep147},
+            {0x1.9cffffffee67ep6,       0x1.f1666c9163f86p148},
+            {0x1.a0ffffffee67ep6,       0x1.5204b679406b7p150},
+            {0x1.a4ffffffee67ep6,       0x1.cb6a267e94b7ap151},
+            {0x1.a8ffffffee67ep6,       0x1.38346236ba483p153},
+            {0x1.acffffffee67ep6,       0x1.a8547ff6d3311p154},
+            {0x1.b0ffffffee67ep6,       0x1.205cb8246899ap156},
+            {0x1.b4ffffffee67ep6,       0x1.87ecc28a831c1p157},
+            {0x1.b8ffffffee67ep6,       0x1.0a572df57323ep159},
+            {0x1.bcffffffee67ep6,       0x1.69fe8c886de24p160},
+            {0x1.c0ffffffee67ep6,       0x1.ec0055aa644acp161},
+            {0x1.c4ffffffee67ep6,       0x1.4e597c5197d13p163},
+            {0x1.c8ffffffee67ep6,       0x1.c66d9bb965746p164},
+            {0x1.ccffffffee67ep6,       0x1.34d0e22472ce2p166},
+            {0x1.d0ffffffee67ep6,       0x1.a3b971da5668ap167},
+            {0x1.d4ffffffee67ep6,       0x1.1d3b77e103d1ap169},
+            {0x1.d8ffffffee67ep6,       0x1.83abbf32ed4f6p170},
+            {0x1.dcffffffee67ep6,       0x1.07731e5137e95p172},
+            {0x1.e0ffffffee67ep6,       0x1.6610b39e7ce7p173},
+            {0x1.e4ffffffee67ep6,       0x1.e6a93f132076cp174},
+            {0x1.e8ffffffee67ep6,       0x1.4ab873ed0fb2cp176},
+            {0x1.ecffffffee67ep6,       0x1.c17eebfd11debp177},
+            {0x1.f0ffffffee67ep6,       0x1.3176cc87e9082p179},
+            {0x1.f4ffffffee67ep6,       0x1.9f2b2fe57487ap180},
+            {0x1.f8ffffffee67ep6,       0x1.1a22e9fe60816p182},
+            {0x1.fcffffffee67ep6,       0x1.7f768dd1738aap183},
+            {0x1.007ffffff733fp7,       0x1.049717079907bp185},
+            {0x1.027ffffff733fp7,       0x1.622dc5947dd63p186},
+            {0x1.047ffffff733fp7,       0x1.e160ff1ccd30cp187},
+            {0x1.067ffffff733fp7,       0x1.472180f8199d7p189},
+            {0x1.087ffffff733fp7,       0x1.bc9df0c9b6e0fp190},
+            {0x1.0a7ffffff733fp7,       0x1.2e26073757ed6p192},
+            {0x1.0c7ffffff733fp7,       0x1.9aa99688f714bp193},
+            {0x1.0e7ffffff733fp7,       0x1.1712f6523864dp195},
+            {0x1.107ffffff733fp7,       0x1.7b4d0d8e11012p196},
+            {0x1.127ffffff733fp7,       0x1.01c301c6bf29cp198},
+            {0x1.147ffffff733fp7,       0x1.5e55a41486608p199},
+            {0x1.167ffffff733fp7,       0x1.dc276c8c7156p200},
+            {0x1.187ffffff733fp7,       0x1.4394876ddc7dap202},
+            {0x1.1a7ffffff733fp7,       0x1.b7ca840a6b3bap203},
+            {0x1.1c7ffffff733fp7,       0x1.2ade7851ad0fep205},
+            {0x1.1e7ffffff733fp7,       0x1.963482987606p206},
+            {0x1.207ffffff733fp7,       0x1.140b84f56a91bp208},
+            {0x1.227ffffff733fp7,       0x1.772f1dec03a66p209},
+            {0x1.247ffffff733fp7,       0x1.fded90f5af3ap210},
+            {0x1.267ffffff733fp7,       0x1.5a88311cf6cbdp212},
+            {0x1.287ffffff733fp7,       0x1.d6fc5e99a419dp213},
+            {0x1.2a7ffffff733fp7,       0x1.40116b9759ebap215},
+            {0x1.2c7ffffff733fp7,       0x1.b304801416466p216},
+            {0x1.2e7ffffff733fp7,       0x1.27a0063dbe9cep218},
+            {0x1.307ffffff733fp7,       0x1.91cbd14945353p219},
+            {0x1.327ffffff733fp7,       0x1.110c7e4340e4fp221},
+            {0x1.347ffffff733fp7,       0x1.731c9ec8ce996p222},
+            {0x1.367ffffff733fp7,       0x1.f864aa9acffbdp223},
+            {0x1.387ffffff733fp7,       0x1.56c54eff8fbcdp225},
+            {0x1.3a7ffffff733fp7,       0x1.d1dfaced4eb1p226},
+            {0x1.3c7ffffff733fp7,       0x1.3c98120a95d78p228},
+            {0x1.3e7ffffff733fp7,       0x1.ae4bbfa449eaap229},
+            {0x1.407ffffff733fp7,       0x1.246a97a9838dcp231},
+            {0x1.427ffffff733fp7,       0x1.8d6f603164cebp232},
+            {0x1.447ffffff733fp7,       0x1.0e15cad8b775ep234},
+            {0x1.467ffffff733fp7,       0x1.6f15705b3f514p235},
+            {0x1.487ffffff733fp7,       0x1.f2eb25494787dp236},
+            {0x1.4a7ffffff733fp7,       0x1.530ce0608a8acp238},
+            {0x1.4c7ffffff733fp7,       0x1.ccd12fa07172p239},
+            {0x1.4e7ffffff733fp7,       0x1.39285fa9c08e7p241},
+            {0x1.507ffffff733fp7,       0x1.a9a01de01fd02p242},
+            {0x1.527ffffff733fp7,       0x1.213e13894e05p244},
+            {0x1.547ffffff733fp7,       0x1.891f0d4674b33p245},
+            {0x1.567ffffff733fp7,       0x1.0b275393c60b2p247},
+            {0x1.587ffffff733fp7,       0x1.6b1973327581dp248},
+            {0x1.5a7ffffff733fp7,       0x1.ed80d645874cfp249},
+            {0x1.5c7ffffff733fp7,       0x1.4f5ec835b4172p251},
+            {0x1.5e7ffffff733fp7,       0x1.c7d0bf3aec5fcp252},
+            {0x1.607ffffff733fp7,       0x1.35c239a263125p254},
+            {0x1.627ffffff733fp7,       0x1.a501765319bp255},
+            {0x1.647ffffff733fp7,       0x1.1e1a611707cfbp257},
+            {0x1.667ffffff733fp7,       0x1.84dab6dcaac3cp258},
+            {0x1.687ffffff733fp7,       0x1.08410192ab89ep260},
+            {0x1.6a7ffffff733fp7,       0x1.67288834edb2fp261},
+            {0x1.6c7ffffff733fp7,       0x1.e825934abdad9p262},
+            {0x1.6e7ffffff733fp7,       0x1.4bbae9c58a222p264},
+            {0x1.707ffffff733fp7,       0x1.c2de34b24b161p265},
+            {0x1.727ffffff733fp7,       0x1.3265856c8dbdcp267},
+            {0x1.747ffffff733fp7,       0x1.a06fa4ee04c8ep268},
+            {0x1.767ffffff733fp7,       0x1.1aff67d171068p270},
+            {0x1.787ffffff733fp7,       0x1.80a23ba5cc0fep271},
+            {0x1.7a7ffffff733fp7,       0x1.0562be333b5b6p273},
+            {0x1.7c7ffffff733fp7,       0x1.6342909f8e806p274},
+            {0x1.7e7ffffff733fp7,       0x1.e2d932898c11cp275},
+            {0x1.807ffffff733ep7,       0x1.482128a65b0aap277},
+            {0x1.827ffffff733ep7,       0x1.bdf9696894p278},
+            {0x1.847ffffff733ep7,       0x1.2f1228ca0924p280},
+            {0x1.867ffffff733ep7,       0x1.9bea8605e05b8p281},
+            {0x1.887ffffff733ep7,       0x1.17ed0f7b60befp283},
+            {0x1.8a7ffffff733ep7,       0x1.7c757ab028d2cp284},
+            {0x1.8c7ffffff733ep7,       0x1.028c73122cbaap286},
+            {0x1.8e7ffffff733ep7,       0x1.5f676e04b872p287},
+            {0x1.907ffffff733ep7,       0x1.dd9b8aa6c07f4p288},
+            {0x1.927ffffff733ep7,       0x1.449168bd6830bp290},
+            {0x1.947ffffff733ep7,       0x1.b922372b1b22fp291},
+            {0x1.967ffffff733ep7,       0x1.2bc809c589606p293},
+            {0x1.987ffffff733ep7,       0x1.9771f652c776ap294},
+            {0x1.9a7ffffff733ep7,       0x1.14e3401b07fc7p296},
+            {0x1.9c7ffffff733ep7,       0x1.785453659b7d4p297},
+            {0x1.9e7ffffff733ep7,       0x1.ff7c1414d829fp298},
+            {0x1.a07ffffff733ep7,       0x1.5b97024b58a63p300},
+            {0x1.a27ffffff733ep7,       0x1.d86c72ba13072p301},
+            {0x1.a47ffffff733ep7,       0x1.410b8e3e0a59p303},
+            {0x1.a67ffffff733ep7,       0x1.b458783157a34p304},
+            {0x1.a87ffffff733ep7,       0x1.28870eb1e33efp306},
+            {0x1.aa7ffffff733ep7,       0x1.9305d2eedd47p307},
+            {0x1.ac7ffffff733ep7,       0x1.11e1e1f93656cp309},
+            {0x1.ae7ffffff733ep7,       0x1.743ea58a8a142p310},
+            {0x1.b07ffffff733ep7,       0x1.f9eeda68dbff6p311},
+            {0x1.b27ffffff733ep7,       0x1.57d12fadfda18p313},
+            {0x1.b47ffffff733ep7,       0x1.d34bc24ce61e7p314},
+            {0x1.b67ffffff733ep7,       0x1.3d8f7da8d8d95p316},
+            {0x1.b87ffffff733ep7,       0x1.af9c071bbd116p317},
+            {0x1.ba7ffffff733ep7,       0x1.254f1e2943f7fp319},
+            {0x1.bc7ffffff733ep7,       0x1.8ea5f9553ce5ep320},
+            {0x1.be7ffffff733ep7,       0x1.0ee8dda0a100cp322},
+            {0x1.c07ffffff733ep7,       0x1.7034513ceac7dp323},
+            {0x1.c27ffffff733ep7,       0x1.f4710dcb08bdcp324},
+            {0x1.c47ffffff733ep7,       0x1.5415d8b9ef19cp326},
+            {0x1.c67ffffff733ep7,       0x1.ce3951590b045p327},
+            {0x1.c87ffffff733ep7,       0x1.3a1d1bcad2ec4p329},
+            {0x1.ca7ffffff733ep7,       0x1.aaecbef297a4ap330},
+            {0x1.cc7ffffff733ep7,       0x1.22201f0c6ae88p332},
+            {0x1.ce7ffffff733ep7,       0x1.8a524760ebdc1p333},
+            {0x1.d07ffffff733ep7,       0x1.0bf81bdd2ba52p335},
+            {0x1.d27ffffff733ep7,       0x1.6c3536f34b0c2p336},
+            {0x1.d47ffffff733ep7,       0x1.ef02835e6a7d8p337},
+            {0x1.d67ffffff733ep7,       0x1.5064e04e480fep339},
+            {0x1.d87ffffff733ep7,       0x1.c934f847894a8p340},
+            {0x1.da7ffffff733ep7,       0x1.36b44dbc8b633p342},
+            {0x1.dc7ffffff733ep7,       0x1.a64a7b24ebae2p343},
+            {0x1.de7ffffff733ep7,       0x1.1ef9f881e57b8p345},
+            {0x1.e07ffffff733ep7,       0x1.860a9b4bcf9dfp346},
+            {0x1.e27ffffff733ep7,       0x1.090f85bb33493p348},
+            {0x1.e47ffffff733ep7,       0x1.6841377bd96e9p349},
+            {0x1.e67ffffff733ep7,       0x1.e9a310bd2715dp350},
+            {0x1.e87ffffff733ep7,       0x1.4cbe299b1372dp352},
+            {0x1.ea7ffffff733ep7,       0x1.c43e8fef69d0dp353},
+            {0x1.ec7ffffff733ep7,       0x1.3354f8e156a72p355},
+            {0x1.ee7ffffff733ep7,       0x1.a1b51787582dfp356},
+            {0x1.f07ffffff733ep7,       0x1.1bdc91f54d333p358},
+            {0x1.f27ffffff733ep7,       0x1.81ced3ada5ec9p359},
+            {0x1.f47ffffff733ep7,       0x1.062f0486db268p361},
+            {0x1.f67ffffff733ep7,       0x1.645833fb72196p362},
+            {0x1.f87ffffff733ep7,       0x1.e4528bf7332d2p363},
+            {0x1.fa7ffffff733ep7,       0x1.492198206b3aep365},
+            {0x1.fc7ffffff733ep7,       0x1.bf55f194851b5p366},
+            {0x1.fe7ffffff733ep7,       0x1.2fff02e67affep368},
+            {0x1.003ffffffb99fp8,       0x1.9d2c7052fc80ep369},
+            {0x1.013ffffffb99fp8,       0x1.18c7d31687cep371},
+            {0x1.023ffffffb99fp8,       0x1.7d9ecf7b00132p372},
+            {0x1.033ffffffb99fp8,       0x1.035681cb5b766p374},
+            {0x1.043ffffffb99fp8,       0x1.607a0decadfaep375},
+            {0x1.053ffffffb99fp8,       0x1.df10cb910ae14p376},
+            {0x1.063ffffffb99fp8,       0x1.458f0fad99f57p378},
+            {0x1.073ffffffb99fp8,       0x1.ba7af6e654fa2p379},
+            {0x1.083ffffffb99fp8,       0x1.2cb251c2631d6p381},
+            {0x1.093ffffffb99fp8,       0x1.98b06224611f2p382},
+            {0x1.0a3ffffffb99fp8,       0x1.15bba3d909807p384},
+            {0x1.0b3ffffffb99fp8,       0x1.797a6e0440f8fp385},
+            {0x1.0c3ffffffb99fp8,       0x1.0085e752522ap387},
+            {0x1.0d3ffffffb99fp8,       0x1.5ca6a71ef489ep388},
+            {0x1.0e3ffffffb99fp8,       0x1.d9dda6826dfc7p389},
+            {0x1.0f3ffffffb99fp8,       0x1.420674603ebb2p391},
+            {0x1.103ffffffb99fp8,       0x1.b5ad79fec979p392},
+            {0x1.113ffffffb99fp8,       0x1.296ecbb3d2db7p394},
+            {0x1.123ffffffb99fp8,       0x1.9440c9fa6362ap395},
+            {0x1.133ffffffb99fp8,       0x1.12b7ec73193e4p397},
+            {0x1.143ffffffb99fp8,       0x1.75618ef49dffep398},
+            {0x1.153ffffffb99fp8,       0x1.fb7a3e462b12ap399},
+            {0x1.163ffffffb99fp8,       0x1.58dde1b590206p401},
+            {0x1.173ffffffb99fp8,       0x1.d4b8f4351faecp402},
+            {0x1.183ffffffb99fp8,       0x1.3e87aaa373892p404},
+            {0x1.193ffffffb99fp8,       0x1.b0ed5561210d9p405},
+            {0x1.1a3ffffffb99fp8,       0x1.263457411e3a5p407},
+            {0x1.1b3ffffffb99fp8,       0x1.8fdd8535244cdp408},
+            {0x1.1c3ffffffb99fp8,       0x1.0fbc955d170d1p410},
+            {0x1.1d3ffffffb99fp8,       0x1.7154125122a86p411},
+            {0x1.1e3ffffffb99fp8,       0x1.f5f8270411675p412},
+            {0x1.1f3ffffffb99fp8,       0x1.551fa026c4e4cp414},
+            {0x1.203ffffffb99fp8,       0x1.cfa28c83a9c15p415},
+            {0x1.213ffffffb99fp8,       0x1.3b12972ef5f7ap417},
+            {0x1.223ffffffb99fp8,       0x1.ac3a63f8c3fc9p418},
+            {0x1.233ffffffb99fp8,       0x1.2302db376285dp420},
+            {0x1.243ffffffb99fp8,       0x1.8b867194fa443p421},
+            {0x1.253ffffffb99fp8,       0x1.0cc98750c45aep423},
+            {0x1.263ffffffb99fp8,       0x1.6d51d877b6f1bp424},
+            {0x1.273ffffffb99fp8,       0x1.f0855ddfe3faap425},
+            {0x1.283ffffffb99fp8,       0x1.516bc53aea3aap427},
+            {0x1.293ffffffb99fp8,       0x1.ca9a47b823396p428},
+            {0x1.2a3ffffffb99fp8,       0x1.37a71f0652462p430},
+            {0x1.2b3ffffffb99fp8,       0x1.a794811822eb3p431},
+            {0x1.2c3ffffffb99fp8,       0x1.1fda3ea9c1a4fp433},
+            {0x1.2d3ffffffb99fp8,       0x1.873b6d3965cp434},
+            {0x1.2e3ffffffb99fp8,       0x1.09deab488e539p436},
+            {0x1.2f3ffffffb99fp8,       0x1.695ac21e2870ep437},
+            {0x1.303ffffffb99fp8,       0x1.eb21b852a647cp438},
+            {0x1.313ffffffb99fp8,       0x1.4dc2340b86b4cp440},
+            {0x1.323ffffffb99fp8,       0x1.c59ffe8afa62cp441},
+            {0x1.333ffffffb99fp8,       0x1.3445277810b78p443},
+            {0x1.343ffffffb99fp8,       0x1.a2fb88779894fp444},
+            {0x1.353ffffffb99fp8,       0x1.1cba68f09f8c5p446},
+            {0x1.363ffffffb99fp8,       0x1.82fc56a008db6p447},
+            {0x1.373ffffffb99fp8,       0x1.06fbea7eda2dfp449},
+            {0x1.383ffffffb99fp8,       0x1.656eb0513614ep450},
+            {0x1.393ffffffb99fp8,       0x1.e5cd0c4b86aaap451},
+            {0x1.3a3ffffffb99fp8,       0x1.4a22d0026e7ffp453},
+            {0x1.3b3ffffffb99fp8,       0x1.c0b38a21c236cp454},
+            {0x1.3c3ffffffb99fp8,       0x1.30ec961ce5379p456},
+            {0x1.3d3ffffffb99fp8,       0x1.9e6f56344e9dp457},
+            {0x1.3e3ffffffb99fp8,       0x1.19a341a8e1ccbp459},
+            {0x1.3f3ffffffb99fp8,       0x1.7ec90ca3a1c6dp460},
+            {0x1.403ffffffb99fp8,       0x1.04212e6d536d6p462},
+            {0x1.413ffffffb99fp8,       0x1.618d84739e91cp463},
+            {0x1.423ffffffb99fp8,       0x1.e087302e9607ap464},
+            {0x1.433ffffffb99fp8,       0x1.468d7cd8e4417p466},
+            {0x1.443ffffffb99fp8,       0x1.bbd4c40e0317cp467},
+            {0x1.453ffffffb99fp8,       0x1.2d9d50d6e1436p469},
+            {0x1.463ffffffb99fp8,       0x1.99efc6cf25729p470},
+            {0x1.473ffffffb99fp8,       0x1.1694b0b33138ap472},
+            {0x1.483ffffffb99fp8,       0x1.7aa16e7b0810dp473},
+            {0x1.493ffffffb99fp8,       0x1.014e60cc3c10bp475},
+            {0x1.4a3ffffffb99fp8,       0x1.5db7203d316b3p476},
+            {0x1.4b3ffffffb99fp8,       0x1.db4ffad383047p477},
+            {0x1.4c3ffffffb99fp8,       0x1.43021e96bc60ep479},
+            {0x1.4d3ffffffb99fp8,       0x1.b703864c0ed74p480},
+            {0x1.4e3ffffffb99fp8,       0x1.2a573dd0a80e6p482},
+            {0x1.4f3ffffffb99fp8,       0x1.957cb72b9f3f6p483},
+            {0x1.503ffffffb99fp8,       0x1.138e9e333d9afp485},
+            {0x1.513ffffffb99fp8,       0x1.76855bb82cbcep486},
+            {0x1.523ffffffb99fp8,       0x1.fd06d7237d52bp487},
+            {0x1.533ffffffb99fp8,       0x1.59eb65b9e296ap489},
+            {0x1.543ffffffb99fp8,       0x1.d627438458c6ap490},
+            {0x1.553ffffffb99fp8,       0x1.3f80999182b7ap492},
+            {0x1.563ffffffb99fp8,       0x1.b23fab41d7fcdp493},
+            {0x1.573ffffffb99fp8,       0x1.271a437ca4dd9p495},
+            {0x1.583ffffffb99fp8,       0x1.9116048ecdd82p496},
+            {0x1.593ffffffb99fp8,       0x1.1090f28f03784p498},
+            {0x1.5a3ffffffb99fp8,       0x1.7274b4471d222p499},
+            {0x1.5b3ffffffb99fp8,       0x1.f78071e284acfp500},
+            {0x1.5c3ffffffb99fp8,       0x1.562a3748e0ae8p502},
+            {0x1.5d3ffffffb99fp8,       0x1.d10ce1fc412f2p503},
+            {0x1.5e3ffffffb99fp8,       0x1.3c08d26ba29edp505},
+            {0x1.5f3ffffffb99fp8,       0x1.ad890dbdcc46ap506},
+            {0x1.603ffffffb99fp8,       0x1.23e648944393ap508},
+            {0x1.613ffffffb99fp8,       0x1.8cbb8c9e43a63p509},
+            {0x1.623ffffffb99fp8,       0x1.0d9b966e13d61p511},
+            {0x1.633ffffffb99fp8,       0x1.6e6f586d0888dp512},
+            {0x1.643ffffffb99fp8,       0x1.f20966b5813aep513},
+            {0x1.653ffffffb99fp8,       0x1.5273779badaf2p515},
+            {0x1.663ffffffb99fp8,       0x1.cc00ae664a89p516},
+            {0x1.673ffffffb99fp8,       0x1.389aae1391554p518},
+            {0x1.683ffffffb99fp8,       0x1.a8df88f5b2588p519},
+            {0x1.693ffffffb99fp8,       0x1.20bb34172b66ap521},
+            {0x1.6a3ffffffb99fp8,       0x1.886d2d5f07833p522},
+            {0x1.6b3ffffffb99fp8,       0x1.0aae72b8de01ep524},
+            {0x1.6c3ffffffb99fp8,       0x1.6a7528c7487fep525},
+            {0x1.6d3ffffffb99fp8,       0x1.eca18af43a36cp526},
+            {0x1.6e3ffffffb99fp8,       0x1.4ec709b53a35fp528},
+            {0x1.6f3ffffffb99fp8,       0x1.c702815c30a11p529},
+            {0x1.703ffffffb99fp8,       0x1.353611c2fab72p531},
+            {0x1.713ffffffb99fp8,       0x1.a442f8858a925p532},
+            {0x1.723ffffffb99fp8,       0x1.1d98ed4a7bba3p534},
+            {0x1.733ffffffb99fp8,       0x1.842ac5348b7cep535},
+            {0x1.743ffffffb99fp8,       0x1.07c97097fb529p537},
+            {0x1.753ffffffb99fp8,       0x1.6686064a6be2ap538},
+            {0x1.763ffffffb99fp8,       0x1.e748b46cfe14cp539},
+            {0x1.773ffffffb99fp8,       0x1.4b24d0e9033c7p541},
+            {0x1.783ffffffb99fp8,       0x1.c21233e5293dap542},
+            {0x1.793ffffffb99fp8,       0x1.31dae2fdf0407p544},
+            {0x1.7a3ffffffb99fp8,       0x1.9fb3386e7303dp545},
+            {0x1.7b3ffffffb99fp8,       0x1.1a7f5bb80b183p547},
+            {0x1.7c3ffffffb99fp8,       0x1.7ff432dfa67a9p548},
+            {0x1.7d3ffffffb99fp8,       0x1.04ec79737cde7p550},
+            {0x1.7e3ffffffb99fp8,       0x1.62a1d2414486ep551},
+            {0x1.7f3ffffffb99fp8,       0x1.e1feb963592a3p552},
+            {0x1.803ffffffb99fp8,       0x1.478cb0da3248p554},
+            {0x1.813ffffffb99fp8,       0x1.bd2f9f74b3ecep555},
+            {0x1.823ffffffb99fp8,       0x1.2e8907921a545p557},
+            {0x1.833ffffffb99fp8,       0x1.9b3025158e763p558},
+            {0x1.843ffffffb99fp8,       0x1.176e672da841p560},
+            {0x1.853ffffffb99fp8,       0x1.7bc9557d90bb5p561},
+            {0x1.863ffffffb99fp8,       0x1.021776f23b20ap563},
+            {0x1.873ffffffb99fp8,       0x1.5ec86e4bf78ccp564},
+            {0x1.883ffffffb99fp8,       0x1.dcc3708ecfe88p565},
+            {0x1.893ffffffb99fp8,       0x1.43fe8d7ac0079p567},
+            {0x1.8a3ffffffb99fp8,       0x1.b85a9de96d206p568},
+            {0x1.8b3ffffffb99fp8,       0x1.2b406595ebc2fp570},
+            {0x1.8c3ffffffb99fp8,       0x1.96b99b42ee81ep571},
+            {0x1.8d3ffffffb99fp8,       0x1.1465f7bc5d4f3p573},
+            {0x1.8e3ffffffb99fp8,       0x1.77aa0c86e3254p574},
+            {0x1.8f3ffffffb99fp8,       0x1.fe94a5f24f127p575},
+            {0x1.903ffffffb99fp8,       0x1.5af9bc5f10484p577},
+            {0x1.913ffffffb99fp8,       0x1.d796b1199ca0dp578},
+            {0x1.923ffffffb99fp8,       0x1.407a4b0a99581p580},
+            {0x1.933ffffffb99fp8,       0x1.b393098be48c6p581},
+            {0x1.943ffffffb99fp8,       0x1.2800e367d7873p583},
+            {0x1.953ffffffb99fp8,       0x1.924f782080a9p584},
+            {0x1.963ffffffb99fp8,       0x1.1165f5b7b4e77p586},
+            {0x1.973ffffffb99fp8,       0x1.739637ce995dep587},
+            {0x1.983ffffffb99fp8,       0x1.f909ef553fe1dp588},
+            {0x1.993ffffffb99fp8,       0x1.57359ec295bd8p590},
+            {0x1.9a3ffffffb99fp8,       0x1.d278529f70c72p591},
+            {0x1.9b3ffffffb99fp8,       0x1.3cffce16c6a9fp593},
+            {0x1.9c3ffffffb99fp8,       0x1.aed8bd0d76c2ep594},
+            {0x1.9d3ffffffb99fp8,       0x1.24ca67ad88b68p596},
+            {0x1.9e3ffffffb99fp8,       0x1.8df19938fe6d4p597},
+            {0x1.9f3ffffffb99fp8,       0x1.0e6e49b5016fbp599},
+            {0x1.a03ffffffb99fp8,       0x1.6f8db78116a48p600},
+            {0x1.a13ffffffb99fp8,       0x1.f38e9ecb87da4p601},
+            {0x1.a23ffffffb99fp8,       0x1.537bf81122a93p603},
+            {0x1.a33ffffffb99fp8,       0x1.cd682d2c39ab4p604},
+            {0x1.a43ffffffb99fp8,       0x1.398efb7895c02p606},
+            {0x1.a53ffffffb99fp8,       0x1.aa2b938729ffap607},
+            {0x1.a63ffffffb99fp8,       0x1.219cd9531c9cep609},
+            {0x1.a73ffffffb99fp8,       0x1.899fdc76e059bp610},
+            {0x1.a83ffffffb99fp8,       0x1.0b7edc8aa647ep612},
+            {0x1.a93ffffffb99fp8,       0x1.6b906c232d65ep613},
+            {0x1.aa3ffffffb99fp8,       0x1.ee22898b97fbep614},
+            {0x1.ab3ffffffb99fp8,       0x1.4fccab37000cep616},
+            {0x1.ac3ffffffb99fp8,       0x1.c866193ae89dbp617},
+            {0x1.ad3ffffffb99fp8,       0x1.3627b854c5c27p619},
+            {0x1.ae3ffffffb99fp8,       0x1.a58b68788e1e6p620},
+            {0x1.af3ffffffb99fp8,       0x1.1e781f8a5efe5p622},
+            {0x1.b03ffffffb99fp8,       0x1.855a202353f77p623},
+            {0x1.b13ffffffb99fp8,       0x1.0897974f62fe1p625},
+            {0x1.b23ffffffb99fp8,       0x1.679e369129826p626},
+            {0x1.b33ffffffb99fp8,       0x1.e8c58542c521dp627},
+            {0x1.b43ffffffb99fp8,       0x1.4c279b7142392p629},
+            {0x1.b53ffffffb99fp8,       0x1.c371efb43e76ep630},
+            {0x1.b63ffffffb99fp8,       0x1.32c9ea1ab59ccp632},
+            {0x1.b73ffffffb99fp8,       0x1.a0f817c69fb0ap633},
+            {0x1.b83ffffffb99fp8,       0x1.1b5c21ca08788p635},
+            {0x1.b93ffffffb99fp8,       0x1.812042e534a64p636},
+            {0x1.ba3ffffffb99fp8,       0x1.05b86359a079cp638},
+            {0x1.bb3ffffffb99fp8,       0x1.63b6f7fddd3efp639},
+            {0x1.bc3ffffffb99fp8,       0x1.e3776813fda8ep640},
+            {0x1.bd3ffffffb99fp8,       0x1.488cac4ce84e7p642},
+            {0x1.be3ffffffb99fp8,       0x1.be8b89ed9a77dp643},
+            {0x1.bf3ffffffb99fp8,       0x1.2f75768394a5p645},
+            {0x1.c03ffffffb99fp8,       0x1.9c717dbaae2b8p646},
+            {0x1.c13ffffffb99fp8,       0x1.1848c7ccfefe3p648},
+            {0x1.c23ffffffb99fp8,       0x1.7cf223c0074fbp649},
+            {0x1.c33ffffffb99fp8,       0x1.02e12a3ec0173p651},
+            {0x1.c43ffffffb99fp8,       0x1.5fda91f1b0d98p652},
+            {0x1.c53ffffffb99fp8,       0x1.de38089682abp653},
+            {0x1.c63ffffffb99fp8,       0x1.44fbc1a5fe2ddp655},
+            {0x1.c73ffffffb99fp8,       0x1.b9b2c1a7cc7aap656},
+            {0x1.c83ffffffb99fp8,       0x1.2c2a43919580dp658},
+            {0x1.c93ffffffb99fp8,       0x1.97f7770145248p659},
+            {0x1.ca3ffffffb99fp8,       0x1.153df9919867p661},
+            {0x1.cb3ffffffb99fp8,       0x1.78cfa212f8edcp662},
+            {0x1.cc3ffffffb99fp8,       0x1.0011d5d26caedp664},
+            {0x1.cd3ffffffb99fp8,       0x1.5c08e649b4b94p665},
+            {0x1.ce3ffffffb99fp8,       0x1.d9073dd4a4c7bp666},
+            {0x1.cf3ffffffb99fp8,       0x1.4174bfa6c0d24p668},
+            {0x1.d03ffffffb99fp8,       0x1.b4e7710dea691p669},
+            {0x1.d13ffffffb99fp8,       0x1.28e8378f2345ap671},
+            {0x1.d23ffffffb99fp8,       0x1.9389e0a91894fp672},
+            {0x1.d33ffffffb99fp8,       0x1.123b9f58df0dap674},
+            {0x1.d43ffffffb99fp8,       0x1.74b89d97dfdd3p675},
+            {0x1.d53ffffffb99fp8,       0x1.fa94a04bdb05cp676},
+            {0x1.d63ffffffb99fp8,       0x1.5841d736b633cp678},
+            {0x1.d73ffffffb99fp8,       0x1.d3e4df4a846ddp679},
+            {0x1.d83ffffffb99fp8,       0x1.3df78ac6c50cep681},
+            {0x1.d93ffffffb99fp8,       0x1.b02972b428f19p682},
+            {0x1.da3ffffffb99fp8,       0x1.25af390e18cbep684},
+            {0x1.db3ffffffb99fp8,       0x1.8f289821f41b9p685},
+            {0x1.dc3ffffffb99fp8,       0x1.0f41a1a5d8764p687},
+            {0x1.dd3ffffffb99fp8,       0x1.70acf6623ff32p688},
+            {0x1.de3ffffffb99fp8,       0x1.f515070ef61acp689},
+            {0x1.df3ffffffb99fp8,       0x1.5485473c56dfcp691},
+            {0x1.e03ffffffb99fp8,       0x1.ced0c4e4d59e4p692},
+            {0x1.e13ffffffb99fp8,       0x1.3a8407ca209c6p694},
+            {0x1.e23ffffffb99fp8,       0x1.ab78a196b76fdp695},
+            {0x1.e33ffffffb99fp8,       0x1.227f2ee6fa305p697},
+            {0x1.e43ffffffb99fp8,       0x1.8ad37b3bad33ep698},
+            {0x1.e53ffffffb99fp8,       0x1.0c4fe93ccdf88p700},
+            {0x1.e63ffffffb99fp8,       0x1.6cac8cde514efp701},
+            {0x1.e73ffffffb99fp8,       0x1.efa4b5032b54fp702},
+            {0x1.e83ffffffb99fp8,       0x1.50d31930266e8p704},
+            {0x1.e93ffffffb99fp8,       0x1.c9cac6ffa71cbp705},
+            {0x1.ea3ffffffb99fp8,       0x1.371a1bc09599dp707},
+            {0x1.eb3ffffffb99fp8,       0x1.a6d4d9189f018p708},
+            {0x1.ec3ffffffb99fp8,       0x1.1f580038307ccp710},
+            {0x1.ed3ffffffb99fp8,       0x1.868a6825185b7p711},
+            {0x1.ee3ffffffb99fp8,       0x1.09665f229766bp713},
+            {0x1.ef3ffffffb99fp8,       0x1.68b741d009e02p714},
+            {0x1.f03ffffffb99fp8,       0x1.ea437fb4bc319p715},
+            {0x1.f13ffffffb99fp8,       0x1.4d2b3038bf046p717},
+            {0x1.f23ffffffb99ep8,       0x1.c4d2be652cea4p718},
+            {0x1.f33ffffffb99ep8,       0x1.33b9ac04c0212p720},
+            {0x1.f43ffffffb99ep8,       0x1.a23df502a4a3ap721},
+            {0x1.f53ffffffb99ep8,       0x1.1c39946547606p723},
+            {0x1.f63ffffffb99ep8,       0x1.824d3d6b0103dp724},
+            {0x1.f73ffffffb99ep8,       0x1.0684ec9be79c4p726},
+            {0x1.f83ffffffb99ep8,       0x1.64ccf65229834p727},
+            {0x1.f93ffffffb99ep8,       0x1.e4f13d25df78ap728},
+            {0x1.fa3ffffffb99ep8,       0x1.498d6fcce3f5ep730},
+            {0x1.fb3ffffffb99ep8,       0x1.bfe8844c8ea89p731},
+            {0x1.fc3ffffffb99ep8,       0x1.30629e3b46a18p733},
+            {0x1.fd3ffffffb99ep8,       0x1.9db3d1822eed1p734},
+            {0x1.fe3ffffffb99ep8,       0x1.1923d3162d5cep736},
+            {0x1.ff3ffffffb99ep8,       0x1.7e1bd9f724dbcp737},
+            {0x1.001ffffffdccfp9,       0x1.03ab7b2c9b517p739},
+            {0x1.009ffffffdccfp9,       0x1.60ed8bd54933ep740},
+            {0x1.011ffffffdccfp9,       0x1.dfadc3cd79f32p741},
+            {0x1.019ffffffdccfp9,       0x1.45f9bbb2a35d1p743},
+            {0x1.021ffffffdccfp9,       0x1.bb0bf258b833ap744},
+            {0x1.029ffffffdccfp9,       0x1.2d14d8520baf7p746},
+            {0x1.031ffffffdccfp9,       0x1.99364b282dd34p747},
+            {0x1.039ffffffdccfp9,       0x1.1616a4367556fp749},
+            {0x1.041ffffffdccfp9,       0x1.79f61d0f30fbp750},
+            {0x1.049ffffffdccfp9,       0x1.00d9f49709365p752},
+            {0x1.051ffffffdccfp9,       0x1.5d18e41eebfc4p753},
+            {0x1.059ffffffdccfp9,       0x1.da78ea95d97f9p754},
+            {0x1.061ffffffdccfp9,       0x1.426ff7fe794b6p756},
+            {0x1.069ffffffdccfp9,       0x1.b63ce2972ea1ep757},
+            {0x1.071ffffffdccfp9,       0x1.29d0407f62d33p759},
+            {0x1.079ffffffdccfp9,       0x1.94c53ee806803p760},
+            {0x1.081ffffffdccfp9,       0x1.1311eff49ae9ap762},
+            {0x1.089ffffffdccfp9,       0x1.75dbe653c2ceap763},
+            {0x1.091ffffffdccfp9,       0x1.fc2085b6a9375p764},
+            {0x1.099ffffffdccfp9,       0x1.594ee148935c8p766},
+            {0x1.0a1ffffffdccfp9,       0x1.d55288db74dc3p767},
+            {0x1.0a9ffffffdccfp9,       0x1.3ef00912762eap769},
+            {0x1.0b1ffffffdccfp9,       0x1.b17b2f7ee7f4ep770},
+            {0x1.0b9ffffffdccfp9,       0x1.2694bd41472c4p772},
+            {0x1.0c1ffffffdccfp9,       0x1.90608a1681a3ep773},
+            {0x1.0c9ffffffdccfp9,       0x1.10159ec1486a4p775},
+            {0x1.0d1ffffffdccfp9,       0x1.71cd15bf6b516p776},
+            {0x1.0d9ffffffdccfp9,       0x1.f69ca06d83551p777},
+            {0x1.0e1ffffffdccfp9,       0x1.558f65bed5d1ap779},
+            {0x1.0e9ffffffdccfp9,       0x1.d03a766bae541p780},
+            {0x1.0f1ffffffdccfp9,       0x1.3b79d39d672c6p782},
+            {0x1.0f9ffffffdccfp9,       0x1.acc6b3ef261e7p783},
+            {0x1.101ffffffdccfp9,       0x1.2362355c94574p785},
+            {0x1.109ffffffdccfp9,       0x1.8c080a68bcd97p786},
+            {0x1.111ffffffdccfp9,       0x1.0d21994e9f02ap788},
+            {0x1.119ffffffdccfp9,       0x1.6dc98ba5b51bp789},
+            {0x1.121ffffffdccfp9,       0x1.f1280e4617147p790},
+            {0x1.129ffffffdccfp9,       0x1.51da544077fa2p792},
+            {0x1.131ffffffdccfp9,       0x1.cb308b8399fb7p793},
+            {0x1.139ffffffdccfp9,       0x1.380d3c9a00e7ep795},
+            {0x1.141ffffffdccfp9,       0x1.a81f4b2e55334p796},
+            {0x1.149ffffffdccfp9,       0x1.20388fdc417d5p798},
+            {0x1.151ffffffdccfp9,       0x1.87bb9df31efbp799},
+            {0x1.159ffffffdccfp9,       0x1.0a35c88f80cbp801},
+            {0x1.161ffffffdccfp9,       0x1.69d128b22d25ap802},
+            {0x1.169ffffffdccfp9,       0x1.ebc2a4ab78bb5p803},
+            {0x1.171ffffffdccfp9,       0x1.4e2f8fdd883d6p805},
+            {0x1.179ffffffdccfp9,       0x1.c634a0cec7546p806},
+            {0x1.181ffffffdccfp9,       0x1.34aa294e0c99ep808},
+            {0x1.189ffffffdccfp9,       0x1.a384d0e8ecc3p809},
+            {0x1.191ffffffdccfp9,       0x1.1d17b4109e865p811},
+            {0x1.199ffffffdccfp9,       0x1.837b23284f5e9p812},
+            {0x1.1a1ffffffdccfp9,       0x1.075215b6dcdc8p814},
+            {0x1.1a9ffffffdccfp9,       0x1.65e3cde76e421p815},
+            {0x1.1b1ffffffdccfp9,       0x1.e66c397f0e285p816},
+            {0x1.1b9ffffffdccfp9,       0x1.4a8efbf67ceccp818},
+            {0x1.1c1ffffffdccfp9,       0x1.c1468f660e51bp819},
+            {0x1.1c9ffffffdccfp9,       0x1.31507f4997713p821},
+            {0x1.1d1ffffffdccfp9,       0x1.9ef72130544cep822},
+            {0x1.1d9ffffffdccfp9,       0x1.19ff898e9368dp824},
+            {0x1.1e1ffffffdccfp9,       0x1.7f4678d82ff18p825},
+            {0x1.1e9ffffffdccfp9,       0x1.04766a36fd582p827},
+            {0x1.1f1ffffffdccfp9,       0x1.62015c9e2f34p828},
+            {0x1.1f9ffffffdccfp9,       0x1.e124a317460fp829},
+            {0x1.201ffffffdccfp9,       0x1.46f87c3b54d8ep831},
+            {0x1.209ffffffdccfp9,       0x1.bc6630ce5faecp832},
+            {0x1.211ffffffdccfp9,       0x1.2e00246624382p834},
+            {0x1.219ffffffdccfp9,       0x1.9a761879cac82p835},
+            {0x1.221ffffffdccfp9,       0x1.16eff82ee1911p837},
+            {0x1.229ffffffdccfp9,       0x1.7b1d7e2eda2c6p838},
+            {0x1.231ffffffdccfp9,       0x1.01a2afc0d75c2p840},
+            {0x1.239ffffffdccfp9,       0x1.5e29b684536ep841},
+            {0x1.241ffffffdccfp9,       0x1.dbebb83e52c5dp842},
+            {0x1.249ffffffdccfp9,       0x1.436bf4aaba53p844},
+            {0x1.251ffffffdccfp9,       0x1.b7935ef798935p845},
+            {0x1.259ffffffdccfp9,       0x1.2ab8fec5df362p847},
+            {0x1.261ffffffdccfp9,       0x1.9601939d5137dp848},
+            {0x1.269ffffffdccfp9,       0x1.13e8e80d6759dp850},
+            {0x1.271ffffffdccfp9,       0x1.770012b39ed67p851},
+            {0x1.279ffffffdccfp9,       0x1.fdada086b9c52p852},
+            {0x1.281ffffffdccfp9,       0x1.5a5cbd9bfe665p854},
+            {0x1.289ffffffdccfp9,       0x1.d6c15030e89c1p855},
+            {0x1.291ffffffdccfp9,       0x1.3fe9499128953p857},
+            {0x1.299ffffffdccfp9,       0x1.b2cdf43b59797p858},
+            {0x1.2a1ffffffdccfp9,       0x1.277af4d2d449ap860},
+            {0x1.2a9ffffffdccfp9,       0x1.91996fd498417p861},
+            {0x1.2b1ffffffdccfp9,       0x1.10ea41886590dp863},
+            {0x1.2b9ffffffdccfp9,       0x1.72ee16480890ep864},
+            {0x1.2c1ffffffdccfp9,       0x1.f8256bd5a1072p865},
+            {0x1.2c9ffffffdccfp9,       0x1.569a543aa97d8p867},
+            {0x1.2d1ffffffdccfp9,       0x1.d1a5429cffadp868},
+            {0x1.2d9ffffffdccfp9,       0x1.3c705f8813894p870},
+            {0x1.2e1ffffffdccfp9,       0x1.ae15cb5be04dap871},
+            {0x1.2e9ffffffdccfp9,       0x1.2445ed3e27324p873},
+            {0x1.2f1ffffffdccfp9,       0x1.8d3d8ab9f0bdep874},
+            {0x1.2f9ffffffdccfp9,       0x1.0df3ed3fc701dp876},
+            {0x1.301ffffffdccfp9,       0x1.6ee76926e122bp877},
+            {0x1.309ffffffdccfp9,       0x1.f2ac9640362cap878},
+            {0x1.311ffffffdccfp9,       0x1.52e25d083c6f6p880},
+            {0x1.319ffffffdccfp9,       0x1.cc9767a099276p881},
+            {0x1.321ffffffdccfp9,       0x1.39011b7511e91p883},
+            {0x1.329ffffffdccfp9,       0x1.a96abf82e5bedp884},
+            {0x1.331ffffffdccfp9,       0x1.2119ceff4e062p886},
+            {0x1.339ffffffdccfp9,       0x1.88edc2473f3cfp887},
+            {0x1.341ffffffdccfp9,       0x1.0b05d4146a019p889},
+            {0x1.349ffffffdccfp9,       0x1.6aebebe3397ccp890},
+            {0x1.351ffffffdccfp9,       0x1.ed42f5104656ep891},
+            {0x1.359ffffffdccfp9,       0x1.4f34bafe2847bp893},
+            {0x1.361ffffffdccfp9,       0x1.c79797c887ff8p894},
+            {0x1.369ffffffdccfp9,       0x1.359b628909b0ap896},
+            {0x1.371ffffffdccfp9,       0x1.a4ccac407db6ep897},
+            {0x1.379ffffffdccfp9,       0x1.1df681534dcc2p899},
+            {0x1.381ffffffdccfp9,       0x1.84a9f4d4f272ap900},
+            {0x1.389ffffffdccfp9,       0x1.081fdf276bf44p902},
+            {0x1.391ffffffdccfp9,       0x1.66fb7f67746f6p903},
+            {0x1.399ffffffdccfp9,       0x1.e7e85e064cb73p904},
+            {0x1.3a1ffffffdccfp9,       0x1.4b91516684d28p906},
+            {0x1.3a9ffffffdccfp9,       0x1.c2a5ac0f3d022p907},
+            {0x1.3b1ffffffdccfp9,       0x1.323f1a3f5edc4p909},
+            {0x1.3b9ffffffdccfp9,       0x1.a03b6d89faf11p910},
+            {0x1.3c1ffffffdccfp9,       0x1.1adbebbbf9351p912},
+            {0x1.3c9ffffffdccfp9,       0x1.80720118fc863p913},
+            {0x1.3d1ffffffdccfp9,       0x1.0541f7d976c95p915},
+            {0x1.3d9ffffffdccfp9,       0x1.631604f454091p916},
+            {0x1.3e1ffffffdccfp9,       0x1.e29ca75828ca4p917},
+            {0x1.3e9ffffffdccfp9,       0x1.47f803db3082ep919},
+            {0x1.3f1ffffffdccfp9,       0x1.bdc17ddb963f2p920},
+            {0x1.3f9ffffffdccfp9,       0x1.2eec285d246c2p922},
+            {0x1.401ffffffdccfp9,       0x1.9bb6dfb8d5a7bp923},
+            {0x1.409ffffffdccfp9,       0x1.17c9f5ff316ddp925},
+            {0x1.411ffffffdccfp9,       0x1.7c45c625cf3bcp926},
+            {0x1.419ffffffdccfp9,       0x1.026c07ca1067p928},
+            {0x1.421ffffffdccfp9,       0x1.5f3b5e200997dp929},
+            {0x1.429ffffffdccfp9,       0x1.dd5fa7afd8289p930},
+            {0x1.431ffffffdccfp9,       0x1.4468b644f2c7fp932},
+            {0x1.439ffffffdccfp9,       0x1.b8eae6ffb1c26p933},
+            {0x1.441ffffffdccfp9,       0x1.2ba272f04fa72p935},
+            {0x1.449ffffffdccfp9,       0x1.973edf89954efp936},
+            {0x1.451ffffffdccfp9,       0x1.14c088262904bp938},
+            {0x1.459ffffffdccfp9,       0x1.782523695aef2p939},
+            {0x1.461ffffffdccfp9,       0x1.ff3bf1add8023p940},
+            {0x1.469ffffffdccfp9,       0x1.5b6b6cd54844dp942},
+            {0x1.471ffffffdccfp9,       0x1.d831362a33e02p943},
+            {0x1.479ffffffdccfp9,       0x1.40e34cdaa0c9dp945},
+            {0x1.481ffffffdccfp9,       0x1.b421c1b7c391cp946},
+            {0x1.489ffffffdccfp9,       0x1.2861e04eed965p948},
+            {0x1.491ffffffdccfp9,       0x1.92d34a1abd55p949},
+            {0x1.499ffffffdccfp9,       0x1.11bf8a7ca8dc9p951},
+            {0x1.4a1ffffffdccfp9,       0x1.740ff8ac10594p952},
+            {0x1.4a9ffffffdccfp9,       0x1.f9af6a367aa8cp953},
+            {0x1.4b1ffffffdccfp9,       0x1.57a613525a444p955},
+            {0x1.4b9ffffffdccfp9,       0x1.d3112a55b14f7p956},
+            {0x1.4c1ffffffdccfp9,       0x1.3d67ac204487bp958},
+            {0x1.4c9ffffffdccfp9,       0x1.af65e8a8eee76p959},
+            {0x1.4d1ffffffdccfp9,       0x1.252a57165ab35p961},
+            {0x1.4d9ffffffdccfp9,       0x1.8e73fcebbcdf2p962},
+            {0x1.4e1ffffffdccfp9,       0x1.0ec6e5905727p964},
+            {0x1.4e9ffffffdccfp9,       0x1.7006260fe518p965},
+            {0x1.4f1ffffffdccfp9,       0x1.f4324dde1b853p966},
+            {0x1.4f9ffffffdccfp9,       0x1.53eb342838912p968},
+            {0x1.501ffffffdccfp9,       0x1.cdff5c312677p969},
+            {0x1.509ffffffdccfp9,       0x1.39f5b8e646512p971},
+            {0x1.511ffffffdccfp9,       0x1.aab736e0229e8p972},
+            {0x1.519ffffffdccfp9,       0x1.21fbbe2a7cc33p974},
+            {0x1.521ffffffdccfp9,       0x1.8a20d5dbe17b1p975},
+            {0x1.529ffffffdccfp9,       0x1.0bd6823000616p977},
+            {0x1.531ffffffdccfp9,       0x1.6c078c0f5af0cp978},
+            {0x1.539ffffffdccfp9,       0x1.eec471cd26923p979},
+            {0x1.541ffffffdccfp9,       0x1.503ab239a52eep981},
+            {0x1.549ffffffdccfp9,       0x1.c8fba42a91b8p982},
+            {0x1.551ffffffdccfp9,       0x1.368d584898928p984},
+            {0x1.559ffffffdccfp9,       0x1.a61587d0f8cb4p985},
+            {0x1.561ffffffdccfp9,       0x1.1ed5fcb4fed8p987},
+            {0x1.569ffffffdccfp9,       0x1.85d9b3294cbccp988},
+            {0x1.571ffffffdccfp9,       0x1.08ee496ae24e1p990},
+            {0x1.579ffffffdccfp9,       0x1.68140b7c89c5cp991},
+            {0x1.581ffffffdccfp9,       0x1.e965aba3129a2p992},
+            {0x1.589ffffffdccfp9,       0x1.4c9470ba47e91p994},
+            {0x1.591ffffffdccfp9,       0x1.c405db1de4f69p995},
+            {0x1.599ffffffdccfp9,       0x1.332e6fade5fp997},
+            {0x1.5a1ffffffdccfp9,       0x1.a180b7549973p998},
+            {0x1.5a9ffffffdccfp9,       0x1.1bb8fa248f731p1000},
+            {0x1.5b1ffffffdccfp9,       0x1.819e736fecc0ap1001},
+            {0x1.5b9ffffffdccfp9,       0x1.060e248ff8e45p1003},
+            {0x1.5c1ffffffdccfp9,       0x1.642b85802c37dp1004},
+            {0x1.5c9ffffffdccfp9,       0x1.e415d17516714p1005},
+            {0x1.5d1ffffffdccfp9,       0x1.48f8532dcd8aap1007},
+            {0x1.5d9ffffffdccfp9,       0x1.bf1dda53d4168p1008},
+            {0x1.5e1ffffffdccfp9,       0x1.2fd8e4c6c1a74p1010},
+            {0x1.5e9ffffffdccfp9,       0x1.9cf8a1a8a05e1p1011},
+            {0x1.5f1ffffffdccfp9,       0x1.18a49e2c20c14p1013},
+            {0x1.5f9ffffffdccfp9,       0x1.7d6ef5a877896p1014},
+            {0x1.601ffffffdccfp9,       0x1.0335fd2d4d32ap1016},
+            {0x1.609ffffffdccfp9,       0x1.604ddb98aeeb6p1017},
+            {0x1.611ffffffdccfp9,       0x1.ded4b9cce1c65p1018},
+            {0x1.619ffffffdccep9,       0x1.45663d67095d1p1020},
+            {0x1.621ffffffdccep9,       0x1.ba437b80a6915p1021},
+            {0x1.629ffffffdccep9,       0x1.2c8c9d8cda0c8p1023},
+        };
+
+        for (double[] testCase: testCases)
+            failures+=testExpm1Case(testCase[0], testCase[1]);
+
+        return failures;
+    }
+
+    public static void main(String [] argv) {
+        int failures = 0;
+
+        failures += testExpm1();
+
+        if (failures > 0) {
+            System.err.println("Testing expm1 incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StrictMath/HyperbolicTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4851625
+ * @summary Tests for StrictMath.{sinh, cosh, tanh}
+ * @author Joseph D. Darcy
+ */
+
+/**
+ * The tests in ../Math/HyperbolicTests.java test properties that
+ * should hold for any implementation of the hyperbolic functions
+ * sinh, cos, and tanh, including the FDLIBM-based ones required by
+ * the StrictMath class.  Therefore, the test cases in
+ * ../Math/HyperbolicTests.java are run against both the Math and
+ * StrictMath versions of the hyperbolic methods.  The role of this
+ * test is to verify that the FDLIBM algorithms are being used by
+ * running golden file tests on values that may vary from one
+ * conforming implementation of the hyperbolics to another.
+ */
+
+public class HyperbolicTests {
+    private HyperbolicTests(){}
+
+    static int testSinhCase(double input, double expected) {
+        return Tests.test("StrictMath.sinh(double)", input,
+                          StrictMath.sinh(input), expected);
+    }
+
+    static int testCoshCase(double input, double expected) {
+        return Tests.test("StrictMath.cosh(double)", input,
+                          StrictMath.cosh(input), expected);
+    }
+
+    static int testTanhCase(double input, double expected) {
+        return Tests.test("StrictMath.tanh(double)", input,
+                          StrictMath.tanh(input), expected);
+    }
+
+    static int testSinh() {
+        int failures = 0;
+        double [][] testCases = {
+            {0x1.5798ee2308c3ap-27,     0x1.5798ee2308c3bp-27},
+            {0x1.ffffffffffff8p-26,     0x1.ffffffffffffap-26},
+            {0x1.ffffffffffffep-26,     0x1.0p-25},
+            {0x1.ffffffffffff8p-25,     0x1.ffffffffffffep-25},
+            {0x1.ffffffffffffap-25,     0x1.0p-24},
+            {0x1.ad7f29abcaf47p-24,     0x1.ad7f29abcaf53p-24},
+            {0x1.ad7f29abcaf48p-24,     0x1.ad7f29abcaf54p-24},
+            {0x1.fffffffffffeap-24,     0x1.0p-23},
+            {0x1.ffffffffffff8p-24,     0x1.0000000000007p-23},
+            {0x1.fffffffffffaap-23,     0x1.0p-22},
+            {0x1.ffffffffffff8p-23,     0x1.0000000000027p-22},
+            {0x1.ffffffffffeaap-22,     0x1.0p-21},
+            {0x1.ffffffffffff8p-22,     0x1.00000000000a7p-21},
+            {0x1.ffffffffffaaap-21,     0x1.0p-20},
+            {0x1.ffffffffffff8p-21,     0x1.00000000002a7p-20},
+            {0x1.0c6f7a0b5ed8cp-20,     0x1.0c6f7a0b5f09fp-20},
+            {0x1.0c6f7a0b5ed8dp-20,     0x1.0c6f7a0b5f0ap-20},
+            {0x1.fffffffffeaaap-20,     0x1.0p-19},
+            {0x1.ffffffffffff8p-20,     0x1.0000000000aa7p-19},
+            {0x1.ffffffffffff8p-19,     0x1.0000000002aa7p-18},
+            {0x1.ffffffffffff7p-18,     0x1.000000000aaa6p-17},
+            {0x1.4f8b588e368d9p-17,     0x1.4f8b588e4e928p-17},
+            {0x1.ffffffffffffep-17,     0x1.000000002aaa9p-16},
+            {0x1.0p-16,                 0x1.000000002aaaap-16},
+            {0x1.fffffffffffffp-16,     0x1.00000000aaaabp-15},
+            {0x1.fffffffffeaaap-15,     0x1.00000002aap-14},
+            {0x1.ffffffffffffep-15,     0x1.00000002aaaa9p-14},
+            {0x1.0p-14,                 0x1.00000002aaaaap-14},
+            {0x1.a36e2eb1c3dd4p-14,     0x1.a36e2ebd7e43ap-14},
+            {0x1.a36e2eb1c3f8cp-14,     0x1.a36e2ebd7e5f1p-14},
+            {0x1.a36e2eb1c432cp-14,     0x1.a36e2ebd7e991p-14},
+            {0x1.fffffffffffffp-14,     0x1.0000000aaaaabp-13},
+            {0x1.ffffffffffffep-13,     0x1.0000002aaaaa9p-12},
+            {0x1.0p-12,                 0x1.0000002aaaaaap-12},
+            {0x1.ffffffffff7f9p-12,     0x1.000000aaaa6a9p-11},
+            {0x1.fffffffffffffp-12,     0x1.000000aaaaaadp-11},
+            {0x1.ffffffffffffep-11,     0x1.000002aaaaacbp-10},
+            {0x1.0p-10,                 0x1.000002aaaaaccp-10},
+            {0x1.0624dd2f1a79p-10,      0x1.0624e00c1c776p-10},
+            {0x1.0624dd2f1a8c9p-10,     0x1.0624e00c1c8bp-10},
+            {0x1.0624dd2f1a9fcp-10,     0x1.0624e00c1c9e3p-10},
+            {0x1.ffffffffffffep-10,     0x1.00000aaaaaccbp-9},
+            {0x1.0p-9,                  0x1.00000aaaaacccp-9},
+            {0x1.ffffffffffe4ap-9,      0x1.00002aaaacbf2p-8},
+            {0x1.fffffffffffffp-9,      0x1.00002aaaacccdp-8},
+            {0x1.fffffffffff9dp-8,      0x1.0000aaaaccc9bp-7},
+            {0x1.ffffffffffffep-8,      0x1.0000aaaacccccp-7},
+            {0x1.0p-7,                  0x1.0000aaaaccccdp-7},
+            {0x1.47ae147ae146fp-7,      0x1.47af7a654e9e2p-7},
+            {0x1.47ae147ae147ap-7,      0x1.47af7a654e9eep-7},
+            {0x1.47ae147ae147bp-7,      0x1.47af7a654e9efp-7},
+            {0x1.fffffffffffb6p-7,      0x1.0002aaaccccb4p-6},
+            {0x1.fffffffffffcap-7,      0x1.0002aaaccccbep-6},
+            {0x1.ffffffffffff7p-7,      0x1.0002aaaccccd5p-6},
+            {0x1.fffffffffffe9p-6,      0x1.000aaacccd001p-5},
+            {0x1.ffffffffffff7p-6,      0x1.000aaacccd008p-5},
+            {0x1.fffffffffffffp-6,      0x1.000aaacccd00dp-5},
+            {0x1.ffffffffffff6p-5,      0x1.002aacccd9cd7p-4},
+            {0x1.ffffffffffff8p-5,      0x1.002aacccd9cd9p-4},
+            {0x1.0p-4,                  0x1.002aacccd9cddp-4},
+            {0x1.9999999999995p-4,      0x1.9a487337b59afp-4},
+            {0x1.9999999999996p-4,      0x1.9a487337b59afp-4},
+            {0x1.9999999999998p-4,      0x1.9a487337b59b1p-4},
+            {0x1.ffffffffffffap-4,      0x1.00aaccd00d2edp-3},
+            {0x1.ffffffffffffcp-4,      0x1.00aaccd00d2efp-3},
+            {0x1.ffffffffffff3p-3,      0x1.02accd9d080fbp-2},
+            {0x1.ffffffffffffdp-3,      0x1.02accd9d08101p-2},
+            {0x1.fffffffffffffp-3,      0x1.02accd9d08101p-2},
+            {0x1.fffffffffffecp-2,      0x1.0acd00fe63b8cp-1},
+            {0x1.ffffffffffffcp-2,      0x1.0acd00fe63b94p-1},
+            {0x1.0p-1,                  0x1.0acd00fe63b97p-1},
+            {0x1.ffffffffffff6p-1,      0x1.2cd9fc44eb97ap0},
+            {0x1.ffffffffffffep-1,      0x1.2cd9fc44eb981p0},
+            {0x1.fffffffffffffp0,       0x1.d03cf63b6e19ep1},
+            {0x1.0p1,                   0x1.d03cf63b6e1ap1},
+            {0x1.fffffffffffffp1,       0x1.b4a380370362dp4},
+            {0x1.0p2,                   0x1.b4a380370363p4},
+            {0x1.ffffffffffffcp2,       0x1.749ea514eca4ep10},
+            {0x1.0p3,                   0x1.749ea514eca66p10},
+            {0x1.fffffffffffffp3,       0x1.0f2ebd0a7ffdcp22},
+            {0x1.0p4,                   0x1.0f2ebd0a7ffe4p22},
+            {0x1.fffffffffff68p4,       0x1.1f43fcc4b5b83p45},
+            {0x1.fffffffffffd4p4,       0x1.1f43fcc4b6316p45},
+            {0x1.0p5,                   0x1.1f43fcc4b662cp45},
+        };
+
+        for (double[] testCase: testCases)
+            failures+=testSinhCase(testCase[0], testCase[1]);
+
+        return failures;
+    }
+
+    static int testCosh() {
+        int failures = 0;
+        double [][] testCases = {
+            {0x1.fffffffffb49fp-8,      0x1.00020000aaaabp0},
+            {0x1.47ae147ae0e45p-7,      0x1.000346de27853p0},
+            {0x1.fffffffffd9f3p-7,      0x1.0008000aaab05p0},
+            {0x1.ffffffffff9f1p-7,      0x1.0008000aaab05p0},
+            {0x1.fffffffffe27dp-6,      0x1.002000aaac169p0},
+            {0x1.ffffffffff27bp-6,      0x1.002000aaac16bp0},
+            {0x1.ffffffffffb9cp-5,      0x1.00800aab05b1ep0},
+            {0x1.ffffffffffd9dp-5,      0x1.00800aab05b1fp0},
+            {0x1.9999999999368p-4,      0x1.0147f40224b2ep0},
+            {0x1.9999999999727p-4,      0x1.0147f40224b35p0},
+            {0x1.ffffffffffed1p-4,      0x1.0200aac16db6cp0},
+            {0x1.fffffffffffd1p-4,      0x1.0200aac16db6ep0},
+            {0x1.ffffffffffeb4p-3,      0x1.080ab05ca613bp0},
+            {0x1.ffffffffffff2p-3,      0x1.080ab05ca6146p0},
+            {0x1.ffffffffffff3p-2,      0x1.20ac1862ae8cep0},
+            {0x1.ffffffffffff9p-2,      0x1.20ac1862ae8dp0},
+            {0x1.0p0,                   0x1.8b07551d9f551p0},
+            {0x1.ffffffffffffbp0,       0x1.e18fa0df2d9b3p1},
+            {0x1.ffffffffffffep0,       0x1.e18fa0df2d9b8p1},
+            {0x1.fffffffffffffp0,       0x1.e18fa0df2d9bap1},
+            {0x1.ffffffffffff9p1,       0x1.b4ee858de3e68p4},
+            {0x1.ffffffffffffep1,       0x1.b4ee858de3e7ap4},
+            {0x1.fffffffffffffp1,       0x1.b4ee858de3e7dp4},
+            {0x1.ffffffffffffcp2,       0x1.749eaa93f4e5ep10},
+            {0x1.ffffffffffffdp2,       0x1.749eaa93f4e64p10},
+            {0x1.0p3,                   0x1.749eaa93f4e76p10},
+            {0x1.fffffffffff6fp3,       0x1.0f2ebd0a7fb9p22},
+            {0x1.0p4,                   0x1.0f2ebd0a8005cp22},
+            {0x1.fffffffffffd4p4,       0x1.1f43fcc4b6316p45},
+            {0x1.0p5,                   0x1.1f43fcc4b662cp45},
+        };
+
+        for (double[] testCase: testCases)
+            failures+=testCoshCase(testCase[0], testCase[1]);
+
+        return failures;
+    }
+
+    static int testTanh() {
+        int failures = 0;
+        double [][] testCases = {
+            {0x1.5798ee2308c36p-27,     0x1.5798ee2308c36p-27},
+            {0x1.ffffffffffffep-26,     0x1.ffffffffffffbp-26},
+            {0x1.ffffffffffffep-25,     0x1.ffffffffffff3p-25},
+            {0x1.ad7f29abcaf47p-24,     0x1.ad7f29abcaf2dp-24},
+            {0x1.ad7f29abcaf48p-24,     0x1.ad7f29abcaf2ep-24},
+            {0x1.ffffffffffffep-24,     0x1.fffffffffffd3p-24},
+            {0x1.ffffffffffffep-23,     0x1.fffffffffff53p-23},
+            {0x1.ffffffffffffep-22,     0x1.ffffffffffd53p-22},
+            {0x1.ffffffffffffep-21,     0x1.ffffffffff553p-21},
+            {0x1.0c6f7a0b5ed8dp-20,     0x1.0c6f7a0b5e767p-20},
+            {0x1.ffffffffffffep-20,     0x1.fffffffffd553p-20},
+            {0x1.ffffffffffffep-19,     0x1.fffffffff5553p-19},
+            {0x1.fffffffffffffp-18,     0x1.ffffffffd5555p-18},
+            {0x1.0p-17,                 0x1.ffffffffd5556p-18},
+            {0x1.4f8b588e368edp-17,     0x1.4f8b588e0685p-17},
+            {0x1.fffffffffffffp-17,     0x1.ffffffff55554p-17},
+            {0x1.fffffffffffffp-16,     0x1.fffffffd55555p-16},
+            {0x1.0p-15,                 0x1.fffffffd55556p-16},
+            {0x1.fffffffffe5ddp-15,     0x1.fffffff553b33p-15},
+            {0x1.fffffffffffffp-15,     0x1.fffffff555554p-15},
+            {0x1.a36e2eb1c432dp-14,     0x1.a36e2e9a4f663p-14},
+            {0x1.ffffffffffffep-14,     0x1.ffffffd555553p-14},
+            {0x1.0p-13,                 0x1.ffffffd555555p-14},
+            {0x1.ffffffffffd51p-13,     0x1.ffffff55552aap-13},
+            {0x1.fffffffffffffp-13,     0x1.ffffff5555559p-13},
+            {0x1.ffffffffffffep-12,     0x1.fffffd5555597p-12},
+            {0x1.0p-11,                 0x1.fffffd5555599p-12},
+            {0x1.fffffffffff1p-11,      0x1.fffff555558a9p-11},
+            {0x1.0p-10,                 0x1.fffff5555599ap-11},
+            {0x1.0624dd2f1a9c6p-10,     0x1.0624d77516cabp-10},
+            {0x1.0624dd2f1a9f8p-10,     0x1.0624d77516cdep-10},
+            {0x1.fffffffffffddp-10,     0x1.ffffd55559976p-10},
+            {0x1.fffffffffffffp-10,     0x1.ffffd55559999p-10},
+            {0x1.ffffffffffffcp-9,      0x1.ffff555599993p-9},
+            {0x1.ffffffffffffep-9,      0x1.ffff555599996p-9},
+            {0x1.ffffffffffff8p-8,      0x1.fffd555999924p-8},
+            {0x1.ffffffffffffep-8,      0x1.fffd555999929p-8},
+            {0x1.47ae147ae1458p-7,      0x1.47ab48ae4593cp-7},
+            {0x1.47ae147ae1464p-7,      0x1.47ab48ae45947p-7},
+            {0x1.ffffffffffffep-7,      0x1.fff5559997df6p-7},
+            {0x1.fffffffffffffp-7,      0x1.fff5559997df8p-7},
+            {0x1.ffffffffffff9p-6,      0x1.ffd559992b1d8p-6},
+            {0x1.ffffffffffffep-6,      0x1.ffd559992b1dcp-6},
+            {0x1.ffffffffffff9p-5,      0x1.ff55997e030d1p-5},
+            {0x1.fffffffffffffp-5,      0x1.ff55997e030d6p-5},
+            {0x1.9999999999996p-4,      0x1.983d7795f4137p-4},
+            {0x1.9999999999997p-4,      0x1.983d7795f4137p-4},
+            {0x1.fffffffffffffp-4,      0x1.fd5992bc4b834p-4},
+            {0x1.0p-3,                  0x1.fd5992bc4b834p-4},
+            {0x1.fffffffffffffp-3,      0x1.f597ea69a1c86p-3},
+            {0x1.ffffffffffffcp-2,      0x1.d9353d7568aefp-2},
+            {0x1.ffffffffffffep-2,      0x1.d9353d7568af3p-2},
+            {0x1.ffffffffffffbp-1,      0x1.85efab514f393p-1},
+            {0x1.ffffffffffffep-1,      0x1.85efab514f393p-1},
+            {0x1.fffffffffffd3p0,       0x1.ed9505e1bc3cep-1},
+            {0x1.fffffffffffe1p0,       0x1.ed9505e1bc3cfp-1},
+            {0x1.ffffffffffed8p1,       0x1.ffa81708a0b4p-1},
+            {0x1.fffffffffff92p1,       0x1.ffa81708a0b41p-1},
+        };
+
+        for (double[] testCase: testCases)
+            failures+=testTanhCase(testCase[0], testCase[1]);
+
+        return failures;
+    }
+
+
+    public static void main(String [] argv) {
+        int failures = 0;
+
+        failures += testSinh();
+        failures += testCosh();
+        failures += testTanh();
+
+        if (failures > 0) {
+            System.err.println("Testing the hyperbolics incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StrictMath/HypotTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,633 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4851638
+ * @summary Tests for StrictMath.hypot
+ * @author Joseph D. Darcy
+ */
+
+/**
+ * The tests in ../Math/HypotTests.java test properties that should
+ * hold for any hypot implementation, including the FDLIBM-based one
+ * required for StrictMath.hypot.  Therefore, the test cases in
+ * ../Math/HypotTests.java are run against both the Math and
+ * StrictMath versions of hypot.  The role of this test is to verify
+ * that the FDLIBM hypot algorithm is being used by running golden
+ * file tests on values that may vary from one conforming hypot
+ * implementation to another.
+ */
+
+public class HypotTests {
+    private HypotTests(){}
+
+    static int testHypotCase(double input1, double input2, double expected) {
+        return Tests.test("StrictMath.hypot(double)", input1, input2,
+                          StrictMath.hypot(input1, input2), expected);
+    }
+
+    static int testHypot() {
+        int failures = 0;
+
+        double [][] testCases = {
+            {0x1.0p0,   0x1.ffffffffffab5p-1,   0x1.6a09e667f39edp0},
+            {0x1.0p0,   0x1.ffffffffffffbp0,    0x1.1e3779b97f4a6p1},
+            {0x1.0p0,   0x1.7ffffffffffffp1,    0x1.94c583ada5b51p1},
+            {0x1.0p0,   0x1.ffffffffffffdp1,    0x1.07e0f66afed06p2},
+            {0x1.0p0,   0x1.3fffffffffffdp2,    0x1.465655f122ff3p2},
+            {0x1.0p0,   0x1.4p2,                0x1.465655f122ff6p2},
+            {0x1.0p0,   0x1.7ffffffffffffp2,    0x1.854bfb363dc38p2},
+            {0x1.0p0,   0x1.8p2,                0x1.854bfb363dc39p2},
+            {0x1.0p0,   0x1.bfffffffffffep2,    0x1.c48c6001f0abdp2},
+            {0x1.0p0,   0x1.fffffffffffffp2,    0x1.01fe03f61badp3},
+            {0x1.0p0,   0x1.1fffffffffffap3,    0x1.21c5b70d9f81dp3},
+            {0x1.0p0,   0x1.3ffffffffffe5p3,    0x1.419894c2329d5p3},
+            {0x1.0p0,   0x1.3ffffffffffe7p3,    0x1.419894c2329d8p3},
+            {0x1.0p0,   0x1.5ffffffffff7ep3,    0x1.617398f2aa9c6p3},
+            {0x1.0p0,   0x1.5ffffffffff8dp3,    0x1.617398f2aa9d5p3},
+            {0x1.0p0,   0x1.7ffffffffff9bp3,    0x1.8154be27734c1p3},
+            {0x1.0p0,   0x1.8p3,                0x1.8154be2773526p3},
+            {0x1.0p0,   0x1.9fffffffffff4p3,    0x1.a13a9cb996644p3},
+            {0x1.0p0,   0x1.9ffffffffffffp3,    0x1.a13a9cb99664fp3},
+            {0x1.0p0,   0x1.bfffffffffffep3,    0x1.c12432fec0327p3},
+            {0x1.0p0,   0x1.cp3,                0x1.c12432fec0329p3},
+            {0x1.0p0,   0x1.dffffffffffbcp3,    0x1.e110c39105f6bp3},
+            {0x1.0p0,   0x1.ep3,                0x1.e110c39105fafp3},
+            {0x1.0p0,   0x1.ffffffffffeafp3,    0x1.007fe00ff5fc8p4},
+            {0x1.0p0,   0x1.0fffffffffff4p4,    0x1.10785dd689a1cp4},
+            {0x1.0p0,   0x1.0fffffffffffbp4,    0x1.10785dd689a23p4},
+            {0x1.0p0,   0x1.1ffffffffff92p4,    0x1.2071b0abcd7cap4},
+            {0x1.0p0,   0x1.1ffffffffff99p4,    0x1.2071b0abcd7d1p4},
+            {0x1.0p0,   0x1.2fffffffffffcp4,    0x1.306bb705ae7bfp4},
+            {0x1.0p0,   0x1.2ffffffffffffp4,    0x1.306bb705ae7c3p4},
+            {0x1.0p0,   0x1.3fffffffffffdp4,    0x1.4066560954a8bp4},
+            {0x1.0p0,   0x1.4fffffffffe14p4,    0x1.506177f548fcfp4},
+            {0x1.0p0,   0x1.5p4,                0x1.506177f5491bbp4},
+            {0x1.0p0,   0x1.5fffffffffffdp4,    0x1.605d0af9d3a42p4},
+            {0x1.0p0,   0x1.5fffffffffffep4,    0x1.605d0af9d3a42p4},
+            {0x1.0p0,   0x1.6fffffffffff8p4,    0x1.7059005e2c015p4},
+            {0x1.0p0,   0x1.6ffffffffffffp4,    0x1.7059005e2c01dp4},
+            {0x1.0p0,   0x1.7fffffffffffdp4,    0x1.80554bdc2dc4dp4},
+            {0x1.0p0,   0x1.7ffffffffffffp4,    0x1.80554bdc2dc4ep4},
+            {0x1.0p0,   0x1.8fffffffffe68p4,    0x1.9051e3235a2cp4},
+            {0x1.0p0,   0x1.9p4,                0x1.9051e3235a458p4},
+            {0x1.0p0,   0x1.9fffffffffff4p4,    0x1.a04ebd789d00cp4},
+            {0x1.0p0,   0x1.ap4,                0x1.a04ebd789d019p4},
+            {0x1.0p0,   0x1.afffffffffed8p4,    0x1.b04bd36b639fbp4},
+            {0x1.0p0,   0x1.affffffffff43p4,    0x1.b04bd36b63a66p4},
+            {0x1.0p0,   0x1.bfffffffffe3ep4,    0x1.c0491e9ab90fdp4},
+            {0x1.0p0,   0x1.cp4,                0x1.c0491e9ab92bfp4},
+            {0x1.0p0,   0x1.cfffffffffed8p4,    0x1.d0469986884d6p4},
+            {0x1.0p0,   0x1.cfffffffffee8p4,    0x1.d0469986884e5p4},
+            {0x1.0p0,   0x1.dfffffffffe5cp4,    0x1.e0443f6a33104p4},
+            {0x1.0p0,   0x1.dffffffffffffp4,    0x1.e0443f6a332a7p4},
+            {0x1.0p0,   0x1.efffffffffff8p4,    0x1.f0420c1e63084p4},
+            {0x1.0p0,   0x1.fp4,                0x1.f0420c1e6308dp4},
+            {0x1.0p0,   0x1.ffffffffffffdp4,    0x1.001ffe003ff5fp5},
+            {0x1.0p0,   0x1.07ffffffffed8p5,    0x1.081f05ef4d755p5},
+            {0x1.0p0,   0x1.07ffffffffee8p5,    0x1.081f05ef4d764p5},
+            {0x1.0p0,   0x1.0fffffffffff4p5,    0x1.101e1c7371c6bp5},
+            {0x1.0p0,   0x1.0fffffffffffbp5,    0x1.101e1c7371c72p5},
+            {0x1.0p0,   0x1.17ffffffffff8p5,    0x1.181d404cf7f51p5},
+            {0x1.0p0,   0x1.17ffffffffffdp5,    0x1.181d404cf7f56p5},
+            {0x1.0p0,   0x1.1fffffffffbf2p5,    0x1.201c705fa7a27p5},
+            {0x1.0p0,   0x1.1fffffffffc65p5,    0x1.201c705fa7a9ap5},
+            {0x1.0p0,   0x1.27ffffffffe08p5,    0x1.281babadfba01p5},
+            {0x1.0p0,   0x1.28p5,               0x1.281babadfbbf9p5},
+            {0x1.0p0,   0x1.2ffffffffff64p5,    0x1.301af15517357p5},
+            {0x1.0p0,   0x1.2ffffffffff6cp5,    0x1.301af1551735ep5},
+            {0x1.0p0,   0x1.37ffffffffc78p5,    0x1.381a40895d3f5p5},
+            {0x1.0p0,   0x1.37ffffffffc88p5,    0x1.381a40895d406p5},
+            {0x1.0p0,   0x1.3fffffffffffdp5,    0x1.4019989389b2dp5},
+            {0x1.0p0,   0x1.4p5,                0x1.4019989389b3p5},
+            {0x1.0p0,   0x1.47fffffffffe8p5,    0x1.4818f8ce34e19p5},
+            {0x1.0p0,   0x1.47ffffffffffap5,    0x1.4818f8ce34e2cp5},
+            {0x1.0p0,   0x1.4fffffffffa64p5,    0x1.501860a3b54bep5},
+            {0x1.0p0,   0x1.4fffffffffe47p5,    0x1.501860a3b58a1p5},
+            {0x1.0p0,   0x1.57ffffffffff8p5,    0x1.5817cf8c4c199p5},
+            {0x1.0p0,   0x1.57fffffffffffp5,    0x1.5817cf8c4c1ap5},
+            {0x1.0p0,   0x1.5fffffffffbeep5,    0x1.6017450c8d3e7p5},
+            {0x1.0p0,   0x1.6p5,                0x1.6017450c8d7f9p5},
+            {0x1.0p0,   0x1.67fffffffffe8p5,    0x1.6816c0b405afp5},
+            {0x1.0p0,   0x1.68p5,               0x1.6816c0b405b09p5},
+            {0x1.0p0,   0x1.6fffffffffb78p5,    0x1.7016421c06043p5},
+            {0x1.0p0,   0x1.7p5,                0x1.7016421c064cbp5},
+            {0x1.0p0,   0x1.77ffffffffffp5,     0x1.7815c8e69cc37p5},
+            {0x1.0p0,   0x1.77ffffffffffcp5,    0x1.7815c8e69cc43p5},
+            {0x1.0p0,   0x1.7ffffffffffffp5,    0x1.801554bda99c5p5},
+            {0x1.0p0,   0x1.87fffffffffdp5,     0x1.8814e55214271p5},
+            {0x1.0p0,   0x1.87ffffffffffcp5,    0x1.8814e5521429ep5},
+            {0x1.0p0,   0x1.8ffffffffffe8p5,    0x1.90147a5b16ce5p5},
+            {0x1.0p0,   0x1.8fffffffffffcp5,    0x1.90147a5b16cfap5},
+            {0x1.0p0,   0x1.97ffffffffffp5,     0x1.98141395a0592p5},
+            {0x1.0p0,   0x1.97fffffffffffp5,    0x1.98141395a05a1p5},
+            {0x1.0p0,   0x1.9fffffffff8f4p5,    0x1.a013b0c3c7377p5},
+            {0x1.0p0,   0x1.9fffffffffb18p5,    0x1.a013b0c3c759bp5},
+            {0x1.0p0,   0x1.a7fffffffffdp5,     0x1.a81351ac4f317p5},
+            {0x1.0p0,   0x1.a7ffffffffffp5,     0x1.a81351ac4f338p5},
+            {0x1.0p0,   0x1.afffffffff698p5,    0x1.b012f61a35d98p5},
+            {0x1.0p0,   0x1.bp5,                0x1.b012f61a367p5},
+            {0x1.0p0,   0x1.b7ffffffff85p5,     0x1.b8129ddc56b26p5},
+            {0x1.0p0,   0x1.b7ffffffff87p5,     0x1.b8129ddc56b45p5},
+            {0x1.0p0,   0x1.bfffffffffffdp5,    0x1.c01248c50d99cp5},
+            {0x1.0p0,   0x1.bfffffffffffep5,    0x1.c01248c50d99cp5},
+            {0x1.0p0,   0x1.c7ffffffffedp5,     0x1.c811f6a9e9676p5},
+            {0x1.0p0,   0x1.c8p5,               0x1.c811f6a9e97a6p5},
+            {0x1.0p0,   0x1.cffffffffffe8p5,    0x1.d011a7636789ep5},
+            {0x1.0p0,   0x1.d7ffffffffffp5,     0x1.d8115accb20f3p5},
+            {0x1.0p0,   0x1.d8p5,               0x1.d8115accb2103p5},
+            {0x1.0p0,   0x1.dfffffffffebcp5,    0x1.e01110c367a41p5},
+            {0x1.0p0,   0x1.ep5,                0x1.e01110c367b85p5},
+            {0x1.0p0,   0x1.e7fffffffffdp5,     0x1.e810c927681fap5},
+            {0x1.0p0,   0x1.e8p5,               0x1.e810c9276822ap5},
+            {0x1.0p0,   0x1.efffffffff7f8p5,    0x1.f01083daa4dadp5},
+            {0x1.0p0,   0x1.fp5,                0x1.f01083daa55b5p5},
+            {0x1.0p0,   0x1.f7ffffffffffp5,     0x1.f81040c0f9c6p5},
+            {0x1.0p0,   0x1.f8p5,               0x1.f81040c0f9c71p5},
+            {0x1.0p0,   0x1.fffffffffffffp5,    0x1.0007ffe000fffp6},
+            {0x1.0p0,   0x1.03fffffffffdp6,     0x1.0407e05f7d188p6},
+            {0x1.0p0,   0x1.03ffffffffffbp6,    0x1.0407e05f7d1b4p6},
+            {0x1.0p0,   0x1.07ffffffff7f8p6,    0x1.0807c1d34edd5p6},
+            {0x1.0p0,   0x1.07ffffffff808p6,    0x1.0807c1d34ede4p6},
+            {0x1.0p0,   0x1.0bffffffff65p6,     0x1.0c07a430870e5p6},
+            {0x1.0p0,   0x1.0bffffffff67p6,     0x1.0c07a43087104p6},
+            {0x1.0p0,   0x1.0fffffffffc54p6,    0x1.1007876cda509p6},
+            {0x1.0p0,   0x1.0fffffffffe0dp6,    0x1.1007876cda6c2p6},
+            {0x1.0p0,   0x1.13fffffffffdp6,     0x1.14076b7e954b4p6},
+            {0x1.0p0,   0x1.13ffffffffffep6,    0x1.14076b7e954e3p6},
+            {0x1.0p0,   0x1.17ffffffffff8p6,    0x1.1807505c9310dp6},
+            {0x1.0p0,   0x1.18p6,               0x1.1807505c93116p6},
+            {0x1.0p0,   0x1.1bfffffffecbp6,     0x1.1c0735fe3197ap6},
+            {0x1.0p0,   0x1.1bffffffff1dbp6,    0x1.1c0735fe31ea5p6},
+            {0x1.0p0,   0x1.1ffffffffebcap6,    0x1.20071c5b4ce64p6},
+            {0x1.0p0,   0x1.1fffffffffaf1p6,    0x1.20071c5b4dd8bp6},
+            {0x1.0p0,   0x1.23ffffffff83p6,     0x1.2407036c309fdp6},
+            {0x1.0p0,   0x1.23ffffffff85p6,     0x1.2407036c30a1cp6},
+            {0x1.0p0,   0x1.27ffffffffba8p6,    0x1.2806eb2991e76p6},
+            {0x1.0p0,   0x1.28p6,               0x1.2806eb29922cep6},
+            {0x1.0p0,   0x1.2bfffffffff7p6,     0x1.2c06d38c8b4ffp6},
+            {0x1.0p0,   0x1.2bfffffffff9p6,     0x1.2c06d38c8b52p6},
+            {0x1.0p0,   0x1.2fffffffffff4p6,    0x1.3006bc8e938c8p6},
+            {0x1.0p0,   0x1.2fffffffffffcp6,    0x1.3006bc8e938cfp6},
+            {0x1.0p0,   0x1.33ffffffff87p6,     0x1.3406a6297821ep6},
+            {0x1.0p0,   0x1.33ffffffff89p6,     0x1.3406a6297823dp6},
+            {0x1.0p0,   0x1.37ffffffff9d8p6,    0x1.380690575943dp6},
+            {0x1.0p0,   0x1.37ffffffff9eap6,    0x1.380690575944fp6},
+            {0x1.0p0,   0x1.3bffffffffffp6,     0x1.3c067b12a2013p6},
+            {0x1.0p0,   0x1.3cp6,               0x1.3c067b12a2024p6},
+            {0x1.0p0,   0x1.3fffffffffe19p6,    0x1.40066656044ep6},
+            {0x1.0p0,   0x1.4p6,                0x1.40066656046c7p6},
+            {0x1.0p0,   0x1.43ffffffff1dp6,     0x1.4406521c75c3p6},
+            {0x1.0p0,   0x1.43ffffffffccfp6,    0x1.4406521c7672fp6},
+            {0x1.0p0,   0x1.47ffffffff8a8p6,    0x1.48063e612ce7ap6},
+            {0x1.0p0,   0x1.47ffffffffcb9p6,    0x1.48063e612d28bp6},
+            {0x1.0p0,   0x1.4bfffffffe1fp6,     0x1.4c062b1f96823p6},
+            {0x1.0p0,   0x1.4cp6,               0x1.4c062b1f98633p6},
+            {0x1.0p0,   0x1.4ffffffffde04p6,    0x1.500618535d07dp6},
+            {0x1.0p0,   0x1.5p6,                0x1.500618535f279p6},
+            {0x1.0p0,   0x1.53fffffffef1p6,     0x1.540605f85c637p6},
+            {0x1.0p0,   0x1.53ffffffffdf3p6,    0x1.540605f85d51ap6},
+            {0x1.0p0,   0x1.57ffffffffff8p6,    0x1.5805f40aa0595p6},
+            {0x1.0p0,   0x1.5bffffffffffp6,     0x1.5c05e286636b5p6},
+            {0x1.0p0,   0x1.5bfffffffffffp6,    0x1.5c05e286636c4p6},
+            {0x1.0p0,   0x1.5ffffffffd9cep6,    0x1.6005d1680baa2p6},
+            {0x1.0p0,   0x1.5fffffffff873p6,    0x1.6005d1680d947p6},
+            {0x1.0p0,   0x1.63ffffffffa5p6,     0x1.6405c0ac30a35p6},
+            {0x1.0p0,   0x1.63ffffffffa7p6,     0x1.6405c0ac30a56p6},
+            {0x1.0p0,   0x1.67ffffffff988p6,    0x1.6805b04f83ac3p6},
+            {0x1.0p0,   0x1.68p6,               0x1.6805b04f8413bp6},
+            {0x1.0p0,   0x1.6bfffffffffep6,     0x1.6c05a04ee40c3p6},
+            {0x1.0p0,   0x1.6cp6,               0x1.6c05a04ee40e3p6},
+            {0x1.0p0,   0x1.6fffffffff018p6,    0x1.700590a74f9b5p6},
+            {0x1.0p0,   0x1.6fffffffffbe2p6,    0x1.700590a75057fp6},
+            {0x1.0p0,   0x1.73ffffffff4ap6,     0x1.74058155e9b72p6},
+            {0x1.0p0,   0x1.74p6,               0x1.74058155ea6d2p6},
+            {0x1.0p0,   0x1.77ffffffffffp6,     0x1.78057257f1868p6},
+            {0x1.0p0,   0x1.78p6,               0x1.78057257f1878p6},
+            {0x1.0p0,   0x1.7bfffffffffep6,     0x1.7c0563aac389bp6},
+            {0x1.0p0,   0x1.7bfffffffffe4p6,    0x1.7c0563aac389fp6},
+            {0x1.0p0,   0x1.7ffffffffffffp6,    0x1.8005554bda349p6},
+            {0x1.0p0,   0x1.8p6,                0x1.8005554bda34bp6},
+            {0x1.0p0,   0x1.83fffffffffap6,     0x1.84054738c9dcdp6},
+            {0x1.0p0,   0x1.84p6,               0x1.84054738c9e2dp6},
+            {0x1.0p0,   0x1.87ffffffff09p6,     0x1.8805396f3f494p6},
+            {0x1.0p0,   0x1.87ffffffff0bp6,     0x1.8805396f3f4b5p6},
+            {0x1.0p0,   0x1.8bfffffffffep6,     0x1.8c052bed02f7ap6},
+            {0x1.0p0,   0x1.8cp6,               0x1.8c052bed02f9bp6},
+            {0x1.0p0,   0x1.8fffffffff7c8p6,    0x1.90051eafee07bp6},
+            {0x1.0p0,   0x1.9p6,                0x1.90051eafee8b3p6},
+            {0x1.0p1,   0x1.fffffffffdcb5p-1,   0x1.1e3779b97f0b5p1},
+            {0x1.0p1,   0x1.ffffffffffab5p0,    0x1.6a09e667f39edp1},
+            {0x1.0p1,   0x1.7ffffffffffffp1,    0x1.cd82b446159f2p1},
+            {0x1.0p1,   0x1.8p1,                0x1.cd82b446159f3p1},
+            {0x1.0p1,   0x1.ffffffffffffbp1,    0x1.1e3779b97f4a6p2},
+            {0x1.0p1,   0x1.3fffffffffffdp2,    0x1.58a68a4a8d9fp2},
+            {0x1.0p1,   0x1.3fffffffffffep2,    0x1.58a68a4a8d9f1p2},
+            {0x1.0p1,   0x1.7ffffffffffffp2,    0x1.94c583ada5b51p2},
+            {0x1.0p1,   0x1.bfffffffffffep2,    0x1.d1ed52076fbe7p2},
+            {0x1.0p1,   0x1.cp2,                0x1.d1ed52076fbe9p2},
+            {0x1.0p1,   0x1.ffffffffffffdp2,    0x1.07e0f66afed06p3},
+            {0x1.0p1,   0x1.1fffffffffff2p3,    0x1.2706821902e8cp3},
+            {0x1.0p1,   0x1.2p3,                0x1.2706821902e9ap3},
+            {0x1.0p1,   0x1.3fffffffffffdp3,    0x1.465655f122ff3p3},
+            {0x1.0p1,   0x1.4p3,                0x1.465655f122ff6p3},
+            {0x1.0p1,   0x1.5ffffffffffd6p3,    0x1.65c55827df1a8p3},
+            {0x1.0p1,   0x1.7ffffffffffffp3,    0x1.854bfb363dc38p3},
+            {0x1.0p1,   0x1.8p3,                0x1.854bfb363dc39p3},
+            {0x1.0p1,   0x1.9ffffffffffe4p3,    0x1.a4e4efeda34c2p3},
+            {0x1.0p1,   0x1.ap3,                0x1.a4e4efeda34dep3},
+            {0x1.0p1,   0x1.bfffffffffffep3,    0x1.c48c6001f0abdp3},
+            {0x1.0p1,   0x1.dfffffffffffcp3,    0x1.e43f746f77956p3},
+            {0x1.0p1,   0x1.ep3,                0x1.e43f746f7795bp3},
+            {0x1.0p1,   0x1.fffffffffffffp3,    0x1.01fe03f61badp4},
+            {0x1.0p1,   0x1.0ffffffffffc4p4,    0x1.11e039f40ee2ap4},
+            {0x1.0p1,   0x1.0ffffffffffc7p4,    0x1.11e039f40ee2dp4},
+            {0x1.0p1,   0x1.1fffffffffffap4,    0x1.21c5b70d9f81dp4},
+            {0x1.0p1,   0x1.2fffffffffffcp4,    0x1.31adf859f9e5ap4},
+            {0x1.0p1,   0x1.2fffffffffffep4,    0x1.31adf859f9e5cp4},
+            {0x1.0p1,   0x1.3ffffffffffe5p4,    0x1.419894c2329d5p4},
+            {0x1.0p1,   0x1.3ffffffffffe7p4,    0x1.419894c2329d8p4},
+            {0x1.0p1,   0x1.4fffffffffff4p4,    0x1.518536f3ca668p4},
+            {0x1.0p1,   0x1.5p4,                0x1.518536f3ca675p4},
+            {0x1.0p1,   0x1.5ffffffffff7ep4,    0x1.617398f2aa9c6p4},
+            {0x1.0p1,   0x1.5ffffffffff8dp4,    0x1.617398f2aa9d5p4},
+            {0x1.0p1,   0x1.6ffffffffffb8p4,    0x1.716380ce70352p4},
+            {0x1.0p1,   0x1.7p4,                0x1.716380ce7039ap4},
+            {0x1.0p1,   0x1.7ffffffffff9bp4,    0x1.8154be27734c1p4},
+            {0x1.0p1,   0x1.8p4,                0x1.8154be2773526p4},
+            {0x1.0p1,   0x1.8ffffffffffe8p4,    0x1.9147284a4142fp4},
+            {0x1.0p1,   0x1.8ffffffffffffp4,    0x1.9147284a41446p4},
+            {0x1.0p1,   0x1.9fffffffffff4p4,    0x1.a13a9cb996644p4},
+            {0x1.0p1,   0x1.9ffffffffffffp4,    0x1.a13a9cb99664fp4},
+            {0x1.0p1,   0x1.affffffffff58p4,    0x1.b12efe0a8f113p4},
+            {0x1.0p1,   0x1.affffffffffd2p4,    0x1.b12efe0a8f18dp4},
+            {0x1.0p1,   0x1.bfffffffffffep4,    0x1.c12432fec0327p4},
+            {0x1.0p1,   0x1.cp4,                0x1.c12432fec0329p4},
+            {0x1.0p1,   0x1.cffffffffffe8p4,    0x1.d11a25cd6ed78p4},
+            {0x1.0p1,   0x1.dp4,                0x1.d11a25cd6ed91p4},
+            {0x1.0p1,   0x1.dffffffffffbcp4,    0x1.e110c39105f6bp4},
+            {0x1.0p1,   0x1.ep4,                0x1.e110c39105fafp4},
+            {0x1.0p1,   0x1.effffffffffe8p4,    0x1.f107fbd0adcf1p4},
+            {0x1.0p1,   0x1.efffffffffff8p4,    0x1.f107fbd0addp4},
+            {0x1.0p1,   0x1.ffffffffffeafp4,    0x1.007fe00ff5fc8p5},
+            {0x1.0p1,   0x1.07fffffffffe8p5,    0x1.087c01e7d5092p5},
+            {0x1.0p1,   0x1.08p5,               0x1.087c01e7d50abp5},
+            {0x1.0p1,   0x1.0fffffffffff4p5,    0x1.10785dd689a1cp5},
+            {0x1.0p1,   0x1.0fffffffffffbp5,    0x1.10785dd689a23p5},
+            {0x1.0p1,   0x1.17ffffffffed8p5,    0x1.1874eee5c5cb1p5},
+            {0x1.0p1,   0x1.17ffffffffee8p5,    0x1.1874eee5c5cc2p5},
+            {0x1.0p1,   0x1.1ffffffffff92p5,    0x1.2071b0abcd7cap5},
+            {0x1.0p1,   0x1.1ffffffffff99p5,    0x1.2071b0abcd7d1p5},
+            {0x1.0p1,   0x1.27ffffffffea8p5,    0x1.286e9f388de9fp5},
+            {0x1.0p1,   0x1.28p5,               0x1.286e9f388dff7p5},
+            {0x1.0p1,   0x1.2fffffffffffcp5,    0x1.306bb705ae7bfp5},
+            {0x1.0p1,   0x1.2ffffffffffffp5,    0x1.306bb705ae7c3p5},
+            {0x1.0p1,   0x1.37ffffffffff8p5,    0x1.3868f4e9108b9p5},
+            {0x1.0p1,   0x1.38p5,               0x1.3868f4e9108c1p5},
+            {0x1.0p1,   0x1.3fffffffffffdp5,    0x1.4066560954a8bp5},
+            {0x1.0p1,   0x1.47ffffffffe28p5,    0x1.4863d7d40ad39p5},
+            {0x1.0p1,   0x1.48p5,               0x1.4863d7d40af11p5},
+            {0x1.0p1,   0x1.4fffffffffe14p5,    0x1.506177f548fcfp5},
+            {0x1.0p1,   0x1.5p5,                0x1.506177f5491bbp5},
+            {0x1.0p1,   0x1.57ffffffffeb8p5,    0x1.585f34506bafbp5},
+            {0x1.0p1,   0x1.58p5,               0x1.585f34506bc43p5},
+            {0x1.0p1,   0x1.5fffffffffffdp5,    0x1.605d0af9d3a42p5},
+            {0x1.0p1,   0x1.5fffffffffffep5,    0x1.605d0af9d3a42p5},
+            {0x1.0p1,   0x1.67ffffffffda8p5,    0x1.685afa317791bp5},
+            {0x1.0p1,   0x1.68p5,               0x1.685afa3177b73p5},
+            {0x1.0p1,   0x1.6fffffffffff8p5,    0x1.7059005e2c015p5},
+            {0x1.0p1,   0x1.6ffffffffffffp5,    0x1.7059005e2c01dp5},
+            {0x1.0p1,   0x1.77ffffffffffp5,     0x1.78571c0982328p5},
+            {0x1.0p1,   0x1.78p5,               0x1.78571c0982339p5},
+            {0x1.0p1,   0x1.7fffffffffffdp5,    0x1.80554bdc2dc4dp5},
+            {0x1.0p1,   0x1.7ffffffffffffp5,    0x1.80554bdc2dc4ep5},
+            {0x1.0p1,   0x1.87fffffffffdp5,     0x1.88538e9ad8dacp5},
+            {0x1.0p1,   0x1.87fffffffffffp5,    0x1.88538e9ad8ddbp5},
+            {0x1.0p1,   0x1.8fffffffffe68p5,    0x1.9051e3235a2cp5},
+            {0x1.0p1,   0x1.9p5,                0x1.9051e3235a458p5},
+            {0x1.0p1,   0x1.97ffffffffffp5,     0x1.9850486a3f17p5},
+            {0x1.0p1,   0x1.97fffffffffffp5,    0x1.9850486a3f17fp5},
+            {0x1.0p1,   0x1.9fffffffffff4p5,    0x1.a04ebd789d00cp5},
+            {0x1.0p1,   0x1.ap5,                0x1.a04ebd789d019p5},
+            {0x1.0p1,   0x1.a7ffffffffe1p5,     0x1.a84d416a2354dp5},
+            {0x1.0p1,   0x1.a8p5,               0x1.a84d416a2373dp5},
+            {0x1.0p1,   0x1.afffffffffed8p5,    0x1.b04bd36b639fbp5},
+            {0x1.0p1,   0x1.affffffffff43p5,    0x1.b04bd36b63a66p5},
+            {0x1.0p1,   0x1.b7ffffffffd7p5,     0x1.b84a72b848951p5},
+            {0x1.0p1,   0x1.b7ffffffffe2bp5,    0x1.b84a72b848a0cp5},
+            {0x1.0p1,   0x1.bfffffffffe3ep5,    0x1.c0491e9ab90fdp5},
+            {0x1.0p1,   0x1.cp5,                0x1.c0491e9ab92bfp5},
+            {0x1.0p1,   0x1.c7fffffffffdp5,     0x1.c847d6695dbc5p5},
+            {0x1.0p1,   0x1.c8p5,               0x1.c847d6695dbf6p5},
+            {0x1.0p1,   0x1.cfffffffffed8p5,    0x1.d0469986884d6p5},
+            {0x1.0p1,   0x1.cfffffffffee8p5,    0x1.d0469986884e5p5},
+            {0x1.0p1,   0x1.d7ffffffffdfp5,     0x1.d845675f37721p5},
+            {0x1.0p1,   0x1.d8p5,               0x1.d845675f37931p5},
+            {0x1.0p1,   0x1.dfffffffffe5cp5,    0x1.e0443f6a33104p5},
+            {0x1.0p1,   0x1.dffffffffffffp5,    0x1.e0443f6a332a7p5},
+            {0x1.0p1,   0x1.e7fffffffff05p5,    0x1.e84321273f31ep5},
+            {0x1.0p1,   0x1.e7fffffffff1p5,     0x1.e84321273f328p5},
+            {0x1.0p1,   0x1.efffffffffff8p5,    0x1.f0420c1e63084p5},
+            {0x1.0p1,   0x1.fp5,                0x1.f0420c1e6308dp5},
+            {0x1.0p1,   0x1.f7ffffffffc3p5,     0x1.f840ffdf40effp5},
+            {0x1.0p1,   0x1.f7fffffffff08p5,    0x1.f840ffdf411d7p5},
+            {0x1.0p1,   0x1.ffffffffffffdp5,    0x1.001ffe003ff5fp6},
+            {0x1.0p1,   0x1.03fffffffffdp6,     0x1.041f800f9f928p6},
+            {0x1.0p1,   0x1.03ffffffffffap6,    0x1.041f800f9f953p6},
+            {0x1.0p1,   0x1.07ffffffffed8p6,    0x1.081f05ef4d755p6},
+            {0x1.0p1,   0x1.07ffffffffee8p6,    0x1.081f05ef4d764p6},
+            {0x1.0p1,   0x1.0bfffffffff5p6,     0x1.0c1e8f739cdcap6},
+            {0x1.0p1,   0x1.0bfffffffff7p6,     0x1.0c1e8f739cde9p6},
+            {0x1.0p1,   0x1.0fffffffffff4p6,    0x1.101e1c7371c6bp6},
+            {0x1.0p1,   0x1.0fffffffffffbp6,    0x1.101e1c7371c72p6},
+            {0x1.0p1,   0x1.13fffffffffdp6,     0x1.141dacc811a34p6},
+            {0x1.0p1,   0x1.13ffffffffffcp6,    0x1.141dacc811a6p6},
+            {0x1.0p1,   0x1.17ffffffffff8p6,    0x1.181d404cf7f51p6},
+            {0x1.0p1,   0x1.17ffffffffffdp6,    0x1.181d404cf7f56p6},
+            {0x1.0p1,   0x1.1bffffffffffp6,     0x1.1c1cd6dfae4a5p6},
+            {0x1.0p1,   0x1.1bffffffffffep6,    0x1.1c1cd6dfae4b4p6},
+            {0x1.0p1,   0x1.1fffffffffbf2p6,    0x1.201c705fa7a27p6},
+            {0x1.0p1,   0x1.1fffffffffc65p6,    0x1.201c705fa7a9ap6},
+            {0x1.0p1,   0x1.23fffffffffdp6,     0x1.241c0cae201cap6},
+            {0x1.0p1,   0x1.23ffffffffffp6,     0x1.241c0cae201ebp6},
+            {0x1.0p1,   0x1.27ffffffffe08p6,    0x1.281babadfba01p6},
+            {0x1.0p1,   0x1.28p6,               0x1.281babadfbbf9p6},
+            {0x1.0p1,   0x1.2bffffffffc1p6,     0x1.2c1b4d43ac4cfp6},
+            {0x1.0p1,   0x1.2bffffffffc3p6,     0x1.2c1b4d43ac4eep6},
+            {0x1.0p1,   0x1.2ffffffffff64p6,    0x1.301af15517357p6},
+            {0x1.0p1,   0x1.2ffffffffff6cp6,    0x1.301af1551735ep6},
+            {0x1.0p1,   0x1.33ffffffffadp6,     0x1.341a97c97b22ep6},
+            {0x1.0p1,   0x1.33ffffffffafp6,     0x1.341a97c97b24fp6},
+            {0x1.0p1,   0x1.37ffffffffc78p6,    0x1.381a40895d3f5p6},
+            {0x1.0p1,   0x1.37ffffffffc88p6,    0x1.381a40895d406p6},
+            {0x1.0p1,   0x1.3bffffffffffp6,     0x1.3c19eb7e71afcp6},
+            {0x1.0p1,   0x1.3bfffffffffffp6,    0x1.3c19eb7e71b0cp6},
+            {0x1.0p1,   0x1.3fffffffffffdp6,    0x1.4019989389b2dp6},
+            {0x1.0p1,   0x1.4p6,                0x1.4019989389b3p6},
+            {0x1.0p1,   0x1.43fffffffffdp6,     0x1.441947b4829e8p6},
+            {0x1.0p1,   0x1.43ffffffffff8p6,    0x1.441947b482a11p6},
+            {0x1.0p1,   0x1.47fffffffffe8p6,    0x1.4818f8ce34e19p6},
+            {0x1.0p1,   0x1.47ffffffffffap6,    0x1.4818f8ce34e2cp6},
+            {0x1.0p1,   0x1.4bffffffffffp6,     0x1.4c18abce6501fp6},
+            {0x1.0p1,   0x1.4bffffffffffcp6,    0x1.4c18abce6502cp6},
+            {0x1.0p1,   0x1.4fffffffffa64p6,    0x1.501860a3b54bep6},
+            {0x1.0p1,   0x1.4fffffffffe47p6,    0x1.501860a3b58a1p6},
+            {0x1.0p1,   0x1.53ffffffffd5p6,     0x1.5418173d9a501p6},
+            {0x1.0p1,   0x1.53ffffffffd7p6,     0x1.5418173d9a522p6},
+            {0x1.0p1,   0x1.57ffffffffff8p6,    0x1.5817cf8c4c199p6},
+            {0x1.0p1,   0x1.57fffffffffffp6,    0x1.5817cf8c4c1ap6},
+            {0x1.0p1,   0x1.5bffffffff83p6,     0x1.5c178980bc34bp6},
+            {0x1.0p1,   0x1.5bffffffff988p6,    0x1.5c178980bc4a3p6},
+            {0x1.0p1,   0x1.5fffffffffbeep6,    0x1.6017450c8d3e7p6},
+            {0x1.0p1,   0x1.6p6,                0x1.6017450c8d7f9p6},
+            {0x1.0p1,   0x1.63fffffffffdp6,     0x1.6417022204f99p6},
+            {0x1.0p1,   0x1.67fffffffffe8p6,    0x1.6816c0b405afp6},
+            {0x1.0p1,   0x1.68p6,               0x1.6816c0b405b09p6},
+            {0x1.0p1,   0x1.6bfffffffffep6,     0x1.6c1680b6059e8p6},
+            {0x1.0p1,   0x1.6cp6,               0x1.6c1680b605a08p6},
+            {0x1.0p1,   0x1.6fffffffffb78p6,    0x1.7016421c06043p6},
+            {0x1.0p1,   0x1.7p6,                0x1.7016421c064cbp6},
+            {0x1.0p1,   0x1.73fffffffffap6,     0x1.741604da8d2b9p6},
+            {0x1.0p1,   0x1.73ffffffffff8p6,    0x1.741604da8d311p6},
+            {0x1.0p1,   0x1.77ffffffffffp6,     0x1.7815c8e69cc37p6},
+            {0x1.0p1,   0x1.77ffffffffffcp6,    0x1.7815c8e69cc43p6},
+            {0x1.0p1,   0x1.7bfffffffffep6,     0x1.7c158e35adde4p6},
+            {0x1.0p1,   0x1.7bfffffffffe8p6,    0x1.7c158e35addecp6},
+            {0x1.0p1,   0x1.7ffffffffffffp6,    0x1.801554bda99c5p6},
+            {0x1.0p1,   0x1.83ffffffffdap6,     0x1.84151c74e35e4p6},
+            {0x1.0p1,   0x1.83ffffffffdep6,     0x1.84151c74e3625p6},
+            {0x1.0p1,   0x1.87fffffffffdp6,     0x1.8814e55214271p6},
+            {0x1.0p1,   0x1.87ffffffffffcp6,    0x1.8814e5521429ep6},
+            {0x1.0p1,   0x1.8bfffffffffep6,     0x1.8c14af4c540b6p6},
+            {0x1.0p1,   0x1.8bffffffffff6p6,    0x1.8c14af4c540cdp6},
+            {0x1.0p1,   0x1.8ffffffffffe8p6,    0x1.90147a5b16ce5p6},
+            {0x1.0p1,   0x1.8fffffffffffcp6,    0x1.90147a5b16cfap6},
+            {0x1.8p1,   0x1.ffffffffffffdp-1,   0x1.94c583ada5b53p1},
+            {0x1.8p1,   0x1.0p1,                0x1.cd82b446159f3p1},
+            {0x1.8p1,   0x1.7fffffffffff7p1,    0x1.0f876ccdf6cd6p2},
+            {0x1.8p1,   0x1.8p1,                0x1.0f876ccdf6cd9p2},
+            {0x1.8p1,   0x1.fffffffffffffp1,    0x1.4p2},
+            {0x1.8p1,   0x1.3ffffffffffe1p2,    0x1.752e50db3a387p2},
+            {0x1.8p1,   0x1.4p2,                0x1.752e50db3a3a2p2},
+            {0x1.8p1,   0x1.7ffffffffffffp2,    0x1.ad5336963eefap2},
+            {0x1.8p1,   0x1.bfffffffffffep2,    0x1.e768d399dc46dp2},
+            {0x1.8p1,   0x1.bffffffffffffp2,    0x1.e768d399dc46fp2},
+            {0x1.8p1,   0x1.fffffffffffffp2,    0x1.11687a8ae14a3p3},
+            {0x1.8p1,   0x1.1fffffffffff2p3,    0x1.2f9422c23c47p3},
+            {0x1.8p1,   0x1.1fffffffffff7p3,    0x1.2f9422c23c475p3},
+            {0x1.8p1,   0x1.3fffffffffff1p3,    0x1.4e16fdacff928p3},
+            {0x1.8p1,   0x1.3fffffffffff4p3,    0x1.4e16fdacff92bp3},
+            {0x1.8p1,   0x1.5ffffffffffffp3,    0x1.6cdb2bbb212ebp3},
+            {0x1.8p1,   0x1.7fffffffffffdp3,    0x1.8bd171a07e388p3},
+            {0x1.8p1,   0x1.7ffffffffffffp3,    0x1.8bd171a07e389p3},
+            {0x1.8p1,   0x1.9ffffffffffe4p3,    0x1.aaeee979b481cp3},
+            {0x1.8p1,   0x1.9ffffffffffecp3,    0x1.aaeee979b4825p3},
+            {0x1.8p1,   0x1.bffffffffffeep3,    0x1.ca2b9714180e5p3},
+            {0x1.8p1,   0x1.cp3,                0x1.ca2b9714180f7p3},
+            {0x1.8p1,   0x1.dfffffffffffcp3,    0x1.e98180e9b47edp3},
+            {0x1.8p1,   0x1.dfffffffffffep3,    0x1.e98180e9b47efp3},
+            {0x1.8p1,   0x1.fffffffffffffp3,    0x1.04760c95db31p4},
+            {0x1.8p1,   0x1.0fffffffffff4p4,    0x1.1433ec467efefp4},
+            {0x1.8p1,   0x1.1ffffffffffeap4,    0x1.23f8fc68ae515p4},
+            {0x1.8p1,   0x1.2p4,                0x1.23f8fc68ae52bp4},
+            {0x1.8p1,   0x1.2fffffffffffcp4,    0x1.33c42213ee0c5p4},
+            {0x1.8p1,   0x1.3p4,                0x1.33c42213ee0c9p4},
+            {0x1.8p1,   0x1.3ffffffffffd9p4,    0x1.439479381ec96p4},
+            {0x1.8p1,   0x1.3fffffffffff6p4,    0x1.439479381ecb3p4},
+            {0x1.8p1,   0x1.4ffffffffffc4p4,    0x1.53694801747d4p4},
+            {0x1.8p1,   0x1.4ffffffffffccp4,    0x1.53694801747dcp4},
+            {0x1.8p1,   0x1.5ffffffffffbep4,    0x1.6341f58bad9d2p4},
+            {0x1.8p1,   0x1.5ffffffffffc2p4,    0x1.6341f58bad9d7p4},
+            {0x1.8p1,   0x1.6fffffffffff8p4,    0x1.731e02ed21f18p4},
+            {0x1.8p1,   0x1.6ffffffffffffp4,    0x1.731e02ed21f2p4},
+            {0x1.8p1,   0x1.7fffffffffffdp4,    0x1.82fd05f129836p4},
+            {0x1.8p1,   0x1.7ffffffffffffp4,    0x1.82fd05f129837p4},
+            {0x1.8p1,   0x1.8ffffffffffa8p4,    0x1.92dea50d28578p4},
+            {0x1.8p1,   0x1.8ffffffffffffp4,    0x1.92dea50d285cep4},
+            {0x1.8p1,   0x1.9ffffffffffe4p4,    0x1.a2c2943e2866p4},
+            {0x1.8p1,   0x1.9fffffffffffcp4,    0x1.a2c2943e28678p4},
+            {0x1.8p1,   0x1.afffffffffff8p4,    0x1.b2a892946f42dp4},
+            {0x1.8p1,   0x1.afffffffffffep4,    0x1.b2a892946f434p4},
+            {0x1.8p1,   0x1.bffffffffffeep4,    0x1.c2906842b6bf3p4},
+            {0x1.8p1,   0x1.bfffffffffff2p4,    0x1.c2906842b6bf8p4},
+            {0x1.8p1,   0x1.cffffffffffe8p4,    0x1.d279e51208c72p4},
+            {0x1.8p1,   0x1.dp4,                0x1.d279e51208c8ap4},
+            {0x1.8p1,   0x1.dfffffffffff4p4,    0x1.e264df234beddp4},
+            {0x1.8p1,   0x1.dfffffffffffcp4,    0x1.e264df234bee4p4},
+            {0x1.8p1,   0x1.efffffffffff8p4,    0x1.f25131ed54d64p4},
+            {0x1.8p1,   0x1.fp4,                0x1.f25131ed54d6cp4},
+            {0x1.8p1,   0x1.fffffffffffffp4,    0x1.011f5eb54147p5},
+            {0x1.8p1,   0x1.07fffffffff88p5,    0x1.0916b2b5fff3ep5},
+            {0x1.8p1,   0x1.07fffffffffaap5,    0x1.0916b2b5fff6p5},
+            {0x1.8p1,   0x1.0ffffffffffc4p5,    0x1.110e8885865b8p5},
+            {0x1.8p1,   0x1.0ffffffffffccp5,    0x1.110e8885865c1p5},
+            {0x1.8p1,   0x1.17fffffffff58p5,    0x1.1906d51932b7ep5},
+            {0x1.8p1,   0x1.17fffffffff77p5,    0x1.1906d51932b9dp5},
+            {0x1.8p1,   0x1.1fffffffffffap5,    0x1.20ff8e9d967d6p5},
+            {0x1.8p1,   0x1.1fffffffffffep5,    0x1.20ff8e9d967dbp5},
+            {0x1.8p1,   0x1.27fffffffffc8p5,    0x1.28f8ac4cd98f2p5},
+            {0x1.8p1,   0x1.27fffffffffd8p5,    0x1.28f8ac4cd9903p5},
+            {0x1.8p1,   0x1.2ffffffffff7cp5,    0x1.30f2264b9c502p5},
+            {0x1.8p1,   0x1.2ffffffffffafp5,    0x1.30f2264b9c535p5},
+            {0x1.8p1,   0x1.37ffffffffff8p5,    0x1.38ebf58b30cb4p5},
+            {0x1.8p1,   0x1.37fffffffffffp5,    0x1.38ebf58b30cbcp5},
+            {0x1.8p1,   0x1.3fffffffffffdp5,    0x1.40e613b03f1dcp5},
+            {0x1.8p1,   0x1.3ffffffffffffp5,    0x1.40e613b03f1dfp5},
+            {0x1.8p1,   0x1.47fffffffffa1p5,    0x1.48e07afd169d5p5},
+            {0x1.8p1,   0x1.47fffffffffa8p5,    0x1.48e07afd169dbp5},
+            {0x1.8p1,   0x1.4ffffffffff84p5,    0x1.50db263f101e3p5},
+            {0x1.8p1,   0x1.4ffffffffff8cp5,    0x1.50db263f101ecp5},
+            {0x1.8p1,   0x1.57ffffffffff8p5,    0x1.58d610be831eep5},
+            {0x1.8p1,   0x1.58p5,               0x1.58d610be831f7p5},
+            {0x1.8p1,   0x1.5fffffffffffap5,    0x1.60d13630e611p5},
+            {0x1.8p1,   0x1.5fffffffffffep5,    0x1.60d13630e6113p5},
+            {0x1.8p1,   0x1.67fffffffffe8p5,    0x1.68cc92acc47abp5},
+            {0x1.8p1,   0x1.68p5,               0x1.68cc92acc47c3p5},
+            {0x1.8p1,   0x1.6fffffffffff8p5,    0x1.70c8229f43a38p5},
+            {0x1.8p1,   0x1.6fffffffffffap5,    0x1.70c8229f43a3ap5},
+            {0x1.8p1,   0x1.77ffffffffffp5,     0x1.78c3e2c2fb433p5},
+            {0x1.8p1,   0x1.77ffffffffffep5,    0x1.78c3e2c2fb441p5},
+            {0x1.8p1,   0x1.7ffffffffffffp5,    0x1.80bfd017f10a6p5},
+            {0x1.8p1,   0x1.87fffffffff5p5,     0x1.88bbe7dc8d9ap5},
+            {0x1.8p1,   0x1.88p5,               0x1.88bbe7dc8da5p5},
+            {0x1.8p1,   0x1.8ffffffffffe8p5,    0x1.90b8278768b67p5},
+            {0x1.8p1,   0x1.9p5,                0x1.90b8278768b8p5},
+            {0x1.8p1,   0x1.97fffffffff2bp5,    0x1.98b48cc1ce669p5},
+            {0x1.8p1,   0x1.97fffffffff3p5,     0x1.98b48cc1ce66dp5},
+            {0x1.8p1,   0x1.9ffffffffff34p5,    0x1.a0b11562e5efcp5},
+            {0x1.8p1,   0x1.ap5,                0x1.a0b11562e5fc8p5},
+            {0x1.8p1,   0x1.a7fffffffffdp5,     0x1.a8adbf6b63874p5},
+            {0x1.8p1,   0x1.a8p5,               0x1.a8adbf6b638a4p5},
+            {0x1.8p1,   0x1.affffffffffd8p5,    0x1.b0aa8901b442cp5},
+            {0x1.8p1,   0x1.affffffffffe8p5,    0x1.b0aa8901b443dp5},
+            {0x1.8p1,   0x1.b7ffffffffffp5,     0x1.b8a7706e94761p5},
+            {0x1.8p1,   0x1.b7ffffffffffep5,    0x1.b8a7706e9477p5},
+            {0x1.8p1,   0x1.bfffffffffffep5,    0x1.c0a4741a02dcap5},
+            {0x1.8p1,   0x1.cp5,                0x1.c0a4741a02dcdp5},
+            {0x1.8p1,   0x1.c7fffffffffdp5,     0x1.c8a1928885b75p5},
+            {0x1.8p1,   0x1.c7ffffffffff9p5,    0x1.c8a1928885b9fp5},
+            {0x1.8p1,   0x1.cffffffffff28p5,    0x1.d09eca58b7d2cp5},
+            {0x1.8p1,   0x1.dp5,                0x1.d09eca58b7e04p5},
+            {0x1.8p1,   0x1.d7ffffffffffp5,     0x1.d89c1a4115253p5},
+            {0x1.8p1,   0x1.d8p5,               0x1.d89c1a4115264p5},
+            {0x1.8p1,   0x1.dfffffffffffcp5,    0x1.e099810dfefd1p5},
+            {0x1.8p1,   0x1.e7fffffffffdp5,     0x1.e896fd9ff2afep5},
+            {0x1.8p1,   0x1.e7ffffffffffap5,    0x1.e896fd9ff2b29p5},
+            {0x1.8p1,   0x1.effffffffff98p5,    0x1.f0948ee9ebc7bp5},
+            {0x1.8p1,   0x1.effffffffffcap5,    0x1.f0948ee9ebcadp5},
+            {0x1.8p1,   0x1.f7fffffffff7p5,     0x1.f89233efeda08p5},
+            {0x1.8p1,   0x1.f7fffffffffb2p5,    0x1.f89233efeda4ap5},
+            {0x1.8p1,   0x1.ffffffffffda9p5,    0x1.0047f5e2d7ed7p6},
+            {0x1.8p1,   0x1.03ffffffffedp6,     0x1.0446dac6b5468p6},
+            {0x1.8p1,   0x1.04p6,               0x1.0446dac6b5598p6},
+            {0x1.8p1,   0x1.07fffffffffe8p6,    0x1.0845c83b5eb9bp6},
+            {0x1.8p1,   0x1.07ffffffffff9p6,    0x1.0845c83b5ebadp6},
+            {0x1.8p1,   0x1.0bffffffffe9bp6,    0x1.0c44bdded82bdp6},
+            {0x1.8p1,   0x1.0bffffffffebp6,     0x1.0c44bdded82d1p6},
+            {0x1.8p1,   0x1.0fffffffffed4p6,    0x1.1043bb54e5cc9p6},
+            {0x1.8p1,   0x1.0ffffffffff1fp6,    0x1.1043bb54e5d14p6},
+            {0x1.8p1,   0x1.13ffffffffe9p6,     0x1.1442c046a0ea6p6},
+            {0x1.8p1,   0x1.13fffffffff5ap6,    0x1.1442c046a0f7p6},
+            {0x1.8p1,   0x1.17fffffffffa8p6,    0x1.1841cc62174cbp6},
+            {0x1.8p1,   0x1.17fffffffffb8p6,    0x1.1841cc62174dap6},
+            {0x1.8p1,   0x1.1bffffffffffp6,     0x1.1c40df59f1a57p6},
+            {0x1.8p1,   0x1.1cp6,               0x1.1c40df59f1a67p6},
+            {0x1.8p1,   0x1.1fffffffffffap6,    0x1.203ff8e522535p6},
+            {0x1.8p1,   0x1.1ffffffffffffp6,    0x1.203ff8e52253bp6},
+            {0x1.8p1,   0x1.23fffffffffdp6,     0x1.243f18be9a334p6},
+            {0x1.8p1,   0x1.23ffffffffffbp6,    0x1.243f18be9a36p6},
+            {0x1.8p1,   0x1.27fffffffffe8p6,    0x1.283e3ea503c63p6},
+            {0x1.8p1,   0x1.27ffffffffff8p6,    0x1.283e3ea503c74p6},
+            {0x1.8p1,   0x1.2bffffffffdfp6,     0x1.2c3d6a5a83932p6},
+            {0x1.8p1,   0x1.2bffffffffe1p6,     0x1.2c3d6a5a83953p6},
+            {0x1.8p1,   0x1.2fffffffffffcp6,    0x1.303c9ba47e6d4p6},
+            {0x1.8p1,   0x1.3p6,                0x1.303c9ba47e6d8p6},
+            {0x1.8p1,   0x1.33fffffffffdp6,     0x1.343bd24b62468p6},
+            {0x1.8p1,   0x1.33fffffffffffp6,    0x1.343bd24b62498p6},
+            {0x1.8p1,   0x1.37ffffffffff8p6,    0x1.383b0e1a75c0ap6},
+            {0x1.8p1,   0x1.37fffffffffffp6,    0x1.383b0e1a75c12p6},
+            {0x1.8p1,   0x1.3bffffffffffp6,     0x1.3c3a4edfa9748p6},
+            {0x1.8p1,   0x1.3bffffffffffep6,    0x1.3c3a4edfa9756p6},
+            {0x1.8p1,   0x1.3fffffffffd4dp6,    0x1.4039946b6d79fp6},
+            {0x1.8p1,   0x1.3ffffffffffffp6,    0x1.4039946b6da51p6},
+            {0x1.8p1,   0x1.43fffffffff9p6,     0x1.4438de908abeap6},
+            {0x1.8p1,   0x1.43fffffffffbp6,     0x1.4438de908ac0bp6},
+            {0x1.8p1,   0x1.47ffffffffd08p6,    0x1.48382d23fccedp6},
+            {0x1.8p1,   0x1.47fffffffffa2p6,    0x1.48382d23fcf87p6},
+            {0x1.8p1,   0x1.4bffffffffcebp6,    0x1.4c377ffcd212fp6},
+            {0x1.8p1,   0x1.4bffffffffcfp6,     0x1.4c377ffcd2133p6},
+            {0x1.8p1,   0x1.4ffffffffff44p6,    0x1.5036d6f40ad53p6},
+            {0x1.8p1,   0x1.4ffffffffff9bp6,    0x1.5036d6f40adaap6},
+            {0x1.8p1,   0x1.53ffffffffedp6,     0x1.543631e47c1e1p6},
+            {0x1.8p1,   0x1.54p6,               0x1.543631e47c311p6},
+            {0x1.8p1,   0x1.57ffffffffd78p6,    0x1.583590aab542dp6},
+            {0x1.8p1,   0x1.58p6,               0x1.583590aab56b5p6},
+            {0x1.8p1,   0x1.5bffffffffc7p6,     0x1.5c34f324e60eep6},
+            {0x1.8p1,   0x1.5bffffffffc9p6,     0x1.5c34f324e610fp6},
+            {0x1.8p1,   0x1.5fffffffffffdp6,    0x1.60345932c760dp6},
+            {0x1.8p1,   0x1.5fffffffffffep6,    0x1.60345932c760dp6},
+            {0x1.8p1,   0x1.63fffffffff79p6,    0x1.6433c2b58421fp6},
+            {0x1.8p1,   0x1.63fffffffff9p6,     0x1.6433c2b584235p6},
+            {0x1.8p1,   0x1.67ffffffffda8p6,    0x1.68332f8fa63a6p6},
+            {0x1.8p1,   0x1.67fffffffff4dp6,    0x1.68332f8fa654bp6},
+            {0x1.8p1,   0x1.6bfffffffffep6,     0x1.6c329fa502ccfp6},
+            {0x1.8p1,   0x1.6cp6,               0x1.6c329fa502cefp6},
+            {0x1.8p1,   0x1.6fffffffffff8p6,    0x1.703212daa75f3p6},
+            {0x1.8p1,   0x1.6ffffffffffffp6,    0x1.703212daa75fbp6},
+            {0x1.8p1,   0x1.73fffffffffap6,     0x1.74318916ca409p6},
+            {0x1.8p1,   0x1.74p6,               0x1.74318916ca46ap6},
+            {0x1.8p1,   0x1.77ffffffffffp6,     0x1.78310240ba47p6},
+            {0x1.8p1,   0x1.78p6,               0x1.78310240ba481p6},
+            {0x1.8p1,   0x1.7bfffffffffep6,     0x1.7c307e40cff7fp6},
+            {0x1.8p1,   0x1.7bfffffffffe4p6,    0x1.7c307e40cff83p6},
+            {0x1.8p1,   0x1.7fffffffffff7p6,    0x1.802ffd005ff07p6},
+            {0x1.8p1,   0x1.7fffffffffff9p6,    0x1.802ffd005ff0ap6},
+            {0x1.8p1,   0x1.83fffffffffap6,     0x1.842f7e69adc1ep6},
+            {0x1.8p1,   0x1.83fffffffffffp6,    0x1.842f7e69adc7dp6},
+            {0x1.8p1,   0x1.87fffffffffdp6,     0x1.882f0267dfef4p6},
+            {0x1.8p1,   0x1.88p6,               0x1.882f0267dff24p6},
+            {0x1.8p1,   0x1.8bfffffffffep6,     0x1.8c2e88e6f449ap6},
+            {0x1.8p1,   0x1.8bffffffffff6p6,    0x1.8c2e88e6f44b1p6},
+            {0x1.8p1,   0x1.8ffffffffffe8p6,    0x1.902e11d3b5549p6},
+            {0x1.8p1,   0x1.8fffffffffffep6,    0x1.902e11d3b556p6},
+        };
+
+        for (double[] testCase: testCases)
+            failures+=testHypotCase(testCase[0], testCase[1], testCase[2]);
+
+        return failures;
+    }
+
+    public static void main(String [] argv) {
+        int failures = 0;
+
+        failures += testHypot();
+
+        if (failures > 0) {
+            System.err.println("Testing log1p incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StrictMath/Log10Tests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,724 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4074599
+ * @summary Tests for StrictMath.log10
+ * @author Joseph D. Darcy
+ */
+
+
+/**
+ * The tests in ../Math/Log10Tests.java test properties that should
+ * hold for any log10 implementation, including the FDLIBM-based one
+ * required for StrictMath.log10.  Therefore, the test cases in
+ * ../Math/Log10Tests.java are run against both the Math and
+ * StrictMath versions of log10.  The role of this test is to verify
+ * that the FDLIBM log10 algorithm is being used by running golden
+ * file tests on values that may vary from one conforming log10
+ * implementation to another.
+ */
+
+public class Log10Tests {
+    private Log10Tests(){}
+
+    static int testLog10Case(double input, double expected) {
+        return Tests.test("StrictMath.log10(double)", input,
+                          StrictMath.log10(input), expected);
+    }
+
+    static int testLog10() {
+        int failures = 0;
+        double [][] testCases = {
+            {0x1.3fffffffffec1p-297,    -0x1.653c6a27ae2f8p6},
+            {0x1.4p-297,                -0x1.653c6a27ae2f7p6},
+            {0x1.3fffffffffbe1p-296,    -0x1.640828f2a4382p6},
+            {0x1.4p-296,                -0x1.640828f2a437dp6},
+            {0x1.3fffffffffd52p-295,    -0x1.62d3e7bd9a406p6},
+            {0x1.4p-295,                -0x1.62d3e7bd9a403p6},
+            {0x1.3fffffffffa72p-294,    -0x1.619fa6889049p6},
+            {0x1.4p-294,                -0x1.619fa68890489p6},
+            {0x1.3fffffffff9bbp-293,    -0x1.606b655386518p6},
+            {0x1.4p-293,                -0x1.606b65538650fp6},
+            {0x1.3fffffffffbe4p-292,    -0x1.5f37241e7c59ap6},
+            {0x1.4p-292,                -0x1.5f37241e7c595p6},
+            {0x1.3ffffffffff7ep-291,    -0x1.5e02e2e97261cp6},
+            {0x1.4p-291,                -0x1.5e02e2e97261bp6},
+            {0x1.3fffffffffc9ep-290,    -0x1.5ccea1b4686a6p6},
+            {0x1.4p-290,                -0x1.5ccea1b4686a1p6},
+            {0x1.3fffffffffec7p-289,    -0x1.5b9a607f5e728p6},
+            {0x1.4p-289,                -0x1.5b9a607f5e727p6},
+            {0x1.3fffffffffbe7p-288,    -0x1.5a661f4a547b2p6},
+            {0x1.4p-288,                -0x1.5a661f4a547adp6},
+            {0x1.3fffffffff907p-287,    -0x1.5931de154a83cp6},
+            {0x1.4p-287,                -0x1.5931de154a833p6},
+            {0x1.3fffffffffd59p-286,    -0x1.57fd9ce0408bcp6},
+            {0x1.4p-286,                -0x1.57fd9ce0408b9p6},
+            {0x1.3fffffffffecap-285,    -0x1.56c95bab3694p6},
+            {0x1.4p-285,                -0x1.56c95bab3693fp6},
+            {0x1.3fffffffffbeap-284,    -0x1.55951a762c9cap6},
+            {0x1.4p-284,                -0x1.55951a762c9c5p6},
+            {0x1.3ffffffffff84p-283,    -0x1.5460d94122a4cp6},
+            {0x1.4p-283,                -0x1.5460d94122a4bp6},
+            {0x1.3fffffffffca4p-282,    -0x1.532c980c18ad6p6},
+            {0x1.4p-282,                -0x1.532c980c18ad1p6},
+            {0x1.3fffffffff9c4p-281,    -0x1.51f856d70eb6p6},
+            {0x1.4p-281,                -0x1.51f856d70eb57p6},
+            {0x1.3fffffffffe16p-280,    -0x1.50c415a204bep6},
+            {0x1.4p-280,                -0x1.50c415a204bddp6},
+            {0x1.3fffffffffd5ep-279,    -0x1.4f8fd46cfac66p6},
+            {0x1.4p-279,                -0x1.4f8fd46cfac63p6},
+            {0x1.3fffffffffd5fp-278,    -0x1.4e5b9337f0cecp6},
+            {0x1.4p-278,                -0x1.4e5b9337f0ce9p6},
+            {0x1.3fffffffffedp-277,     -0x1.4d275202e6d7p6},
+            {0x1.4p-277,                -0x1.4d275202e6d6fp6},
+            {0x1.3fffffffffbfp-276,     -0x1.4bf310cddcdfap6},
+            {0x1.4p-276,                -0x1.4bf310cddcdf5p6},
+            {0x1.3ffffffffff8ap-275,    -0x1.4abecf98d2e7bp6},
+            {0x1.4p-275,                -0x1.4abecf98d2e7bp6},
+            {0x1.3fffffffffd62p-274,    -0x1.498a8e63c8f04p6},
+            {0x1.4p-274,                -0x1.498a8e63c8f01p6},
+            {0x1.3fffffffff9cap-273,    -0x1.48564d2ebef9p6},
+            {0x1.4p-273,                -0x1.48564d2ebef87p6},
+            {0x1.3fffffffff6eap-272,    -0x1.47220bf9b501ap6},
+            {0x1.4p-272,                -0x1.47220bf9b500dp6},
+            {0x1.3fffffffffb3cp-271,    -0x1.45edcac4ab09ap6},
+            {0x1.4p-271,                -0x1.45edcac4ab093p6},
+            {0x1.3fffffffffd65p-270,    -0x1.44b9898fa111cp6},
+            {0x1.4p-270,                -0x1.44b9898fa1119p6},
+            {0x1.3fffffffffa85p-269,    -0x1.4385485a971a6p6},
+            {0x1.4p-269,                -0x1.4385485a9719fp6},
+            {0x1.3ffffffffe2c7p-268,    -0x1.425107258d24dp6},
+            {0x1.3fffffffffed7p-268,    -0x1.425107258d226p6},
+            {0x1.4p-268,                -0x1.425107258d225p6},
+            {0x1.3fffffffff916p-267,    -0x1.411cc5f0832b4p6},
+            {0x1.4p-267,                -0x1.411cc5f0832abp6},
+            {0x1.3fffffffffd68p-266,    -0x1.3fe884bb79334p6},
+            {0x1.4p-266,                -0x1.3fe884bb79331p6},
+            {0x1.3fffffffffe21p-265,    -0x1.3eb443866f3b9p6},
+            {0x1.4p-265,                -0x1.3eb443866f3b7p6},
+            {0x1.3fffffffffedap-264,    -0x1.3d8002516543ep6},
+            {0x1.4p-264,                -0x1.3d8002516543dp6},
+            {0x1.3fffffffffbfap-263,    -0x1.3c4bc11c5b4c9p6},
+            {0x1.4p-263,                -0x1.3c4bc11c5b4c3p6},
+            {0x1.3fffffffff862p-262,    -0x1.3b177fe751554p6},
+            {0x1.4p-262,                -0x1.3b177fe751549p6},
+            {0x1.3fffffffffa8bp-261,    -0x1.39e33eb2475d6p6},
+            {0x1.4p-261,                -0x1.39e33eb2475cfp6},
+            {0x1.3fffffffffeddp-260,    -0x1.38aefd7d3d656p6},
+            {0x1.4p-260,                -0x1.38aefd7d3d655p6},
+            {0x1.3fffffffffbfdp-259,    -0x1.377abc48336ep6},
+            {0x1.4p-259,                -0x1.377abc48336dbp6},
+            {0x1.3ffffffffff97p-258,    -0x1.36467b1329762p6},
+            {0x1.4p-258,                -0x1.36467b1329761p6},
+            {0x1.3fffffffffedfp-257,    -0x1.351239de1f7e8p6},
+            {0x1.4p-257,                -0x1.351239de1f7e7p6},
+            {0x1.3fffffffffeep-256,     -0x1.33ddf8a91586ep6},
+            {0x1.4p-256,                -0x1.33ddf8a91586dp6},
+            {0x1.3fffffffffcp-255,      -0x1.32a9b7740b8f8p6},
+            {0x1.4p-255,                -0x1.32a9b7740b8f3p6},
+            {0x1.3fffffffffd71p-254,    -0x1.3175763f0197cp6},
+            {0x1.4p-254,                -0x1.3175763f01979p6},
+            {0x1.3fffffffff588p-253,    -0x1.30413509f7a0ep6},
+            {0x1.4p-253,                -0x1.30413509f79ffp6},
+            {0x1.3fffffffff7b1p-252,    -0x1.2f0cf3d4eda9p6},
+            {0x1.4p-252,                -0x1.2f0cf3d4eda85p6},
+            {0x1.3fffffffffc03p-251,    -0x1.2dd8b29fe3b1p6},
+            {0x1.4p-251,                -0x1.2dd8b29fe3b0bp6},
+            {0x1.3fffffffff86bp-250,    -0x1.2ca4716ad9b9cp6},
+            {0x1.4p-250,                -0x1.2ca4716ad9b91p6},
+            {0x1.3fffffffffcbdp-249,    -0x1.2b703035cfc1cp6},
+            {0x1.4p-249,                -0x1.2b703035cfc17p6},
+            {0x1.3fffffffffee6p-248,    -0x1.2a3bef00c5c9ep6},
+            {0x1.4p-248,                -0x1.2a3bef00c5c9dp6},
+            {0x1.3fffffffffc06p-247,    -0x1.2907adcbbbd28p6},
+            {0x1.4p-247,                -0x1.2907adcbbbd23p6},
+            {0x1.3fffffffffd77p-246,    -0x1.27d36c96b1dacp6},
+            {0x1.4p-246,                -0x1.27d36c96b1da9p6},
+            {0x1.3fffffffffd78p-245,    -0x1.269f2b61a7e32p6},
+            {0x1.4p-245,                -0x1.269f2b61a7e2fp6},
+            {0x1.3ffffffffea0bp-244,    -0x1.256aea2c9ded3p6},
+            {0x1.3fffffffffee9p-244,    -0x1.256aea2c9deb6p6},
+            {0x1.4p-244,                -0x1.256aea2c9deb5p6},
+            {0x1.3fffffffffe32p-243,    -0x1.2436a8f793f3ep6},
+            {0x1.4p-243,                -0x1.2436a8f793f3bp6},
+            {0x1.3ffffffffffa3p-242,    -0x1.230267c289fc2p6},
+            {0x1.4p-242,                -0x1.230267c289fc1p6},
+            {0x1.3fffffffff591p-241,    -0x1.21ce268d80056p6},
+            {0x1.4p-241,                -0x1.21ce268d80047p6},
+            {0x1.3fffffffff9e3p-240,    -0x1.2099e558760d6p6},
+            {0x1.4p-240,                -0x1.2099e558760cdp6},
+            {0x1.3fffffffffc0cp-239,    -0x1.1f65a4236c158p6},
+            {0x1.4p-239,                -0x1.1f65a4236c153p6},
+            {0x1.3fffffffffd7dp-238,    -0x1.1e3162ee621dcp6},
+            {0x1.4p-238,                -0x1.1e3162ee621d9p6},
+            {0x1.3fffffffffd7ep-237,    -0x1.1cfd21b958262p6},
+            {0x1.4p-237,                -0x1.1cfd21b95825fp6},
+            {0x1.3fffffffffeefp-236,    -0x1.1bc8e0844e2e6p6},
+            {0x1.4p-236,                -0x1.1bc8e0844e2e5p6},
+            {0x1.3fffffffffc0fp-235,    -0x1.1a949f4f4437p6},
+            {0x1.4p-235,                -0x1.1a949f4f4436bp6},
+            {0x1.3ffffffffffa9p-234,    -0x1.19605e1a3a3f1p6},
+            {0x1.4p-234,                -0x1.19605e1a3a3f1p6},
+            {0x1.3ffffffffffaap-233,    -0x1.182c1ce530478p6},
+            {0x1.4p-233,                -0x1.182c1ce530477p6},
+            {0x1.3fffffffff2b7p-232,    -0x1.16f7dbb02651p6},
+            {0x1.4p-232,                -0x1.16f7dbb0264fdp6},
+            {0x1.3fffffffffef3p-231,    -0x1.15c39a7b1c584p6},
+            {0x1.4p-231,                -0x1.15c39a7b1c583p6},
+            {0x1.3fffffffff932p-230,    -0x1.148f594612612p6},
+            {0x1.4p-230,                -0x1.148f594612609p6},
+            {0x1.3fffffffffd84p-229,    -0x1.135b181108692p6},
+            {0x1.4p-229,                -0x1.135b18110868fp6},
+            {0x1.3fffffffffaa4p-228,    -0x1.1226d6dbfe71cp6},
+            {0x1.4p-228,                -0x1.1226d6dbfe715p6},
+            {0x1.3fffffffffef6p-227,    -0x1.10f295a6f479cp6},
+            {0x1.4p-227,                -0x1.10f295a6f479bp6},
+            {0x1.3fffffffffd86p-226,    -0x1.0fbe5471ea824p6},
+            {0x1.4p-226,                -0x1.0fbe5471ea821p6},
+            {0x1.3fffffffffd87p-225,    -0x1.0e8a133ce08aap6},
+            {0x1.4p-225,                -0x1.0e8a133ce08a7p6},
+            {0x1.3fffffffffef8p-224,    -0x1.0d55d207d692ep6},
+            {0x1.4p-224,                -0x1.0d55d207d692dp6},
+            {0x1.3fffffffffef9p-223,    -0x1.0c2190d2cc9b4p6},
+            {0x1.4p-223,                -0x1.0c2190d2cc9b3p6},
+            {0x1.3fffffffff42fp-222,    -0x1.0aed4f9dc2a4ap6},
+            {0x1.4p-222,                -0x1.0aed4f9dc2a39p6},
+            {0x1.3fffffffff658p-221,    -0x1.09b90e68b8accp6},
+            {0x1.4p-221,                -0x1.09b90e68b8abfp6},
+            {0x1.3fffffffffaaap-220,    -0x1.0884cd33aeb4cp6},
+            {0x1.4p-220,                -0x1.0884cd33aeb45p6},
+            {0x1.3fffffffffefcp-219,    -0x1.07508bfea4bccp6},
+            {0x1.4p-219,                -0x1.07508bfea4bcbp6},
+            {0x1.3fffffffffc1cp-218,    -0x1.061c4ac99ac56p6},
+            {0x1.4p-218,                -0x1.061c4ac99ac51p6},
+            {0x1.3fffffffffd8dp-217,    -0x1.04e8099490cdap6},
+            {0x1.4p-217,                -0x1.04e8099490cd7p6},
+            {0x1.3fffffffffaadp-216,    -0x1.03b3c85f86d65p6},
+            {0x1.3fffffffffefep-216,    -0x1.03b3c85f86d5ep6},
+            {0x1.4p-216,                -0x1.03b3c85f86d5dp6},
+            {0x1.3ffffffffdbbdp-215,    -0x1.027f872a7ce16p6},
+            {0x1.3fffffffffeffp-215,    -0x1.027f872a7cde4p6},
+            {0x1.4p-215,                -0x1.027f872a7cde3p6},
+            {0x1.3fffffffffc1fp-214,    -0x1.014b45f572e6ep6},
+            {0x1.4p-214,                -0x1.014b45f572e69p6},
+            {0x1.3ffffffffffb9p-213,    -0x1.001704c068efp6},
+            {0x1.4p-213,                -0x1.001704c068eefp6},
+            {0x1.3fffffffffdbfp-212,    -0x1.fdc58716bdefp5},
+            {0x1.4p-212,                -0x1.fdc58716bdeeap5},
+            {0x1.3ffffffffff3p-211,     -0x1.fb5d04aca9ff8p5},
+            {0x1.4p-211,                -0x1.fb5d04aca9ff6p5},
+            {0x1.3ffffffffffe9p-210,    -0x1.f8f4824296102p5},
+            {0x1.4p-210,                -0x1.f8f4824296102p5},
+            {0x1.3fffffffffd09p-209,    -0x1.f68bffd882216p5},
+            {0x1.4p-209,                -0x1.f68bffd88220ep5},
+            {0x1.3fffffffffdc2p-208,    -0x1.f4237d6e6e32p5},
+            {0x1.4p-208,                -0x1.f4237d6e6e31ap5},
+            {0x1.3fffffffff23fp-207,    -0x1.f1bafb045a44cp5},
+            {0x1.3fffffffffe7bp-207,    -0x1.f1bafb045a42ap5},
+            {0x1.4p-207,                -0x1.f1bafb045a426p5},
+            {0x1.3ffffffffffecp-206,    -0x1.ef52789a46532p5},
+            {0x1.4p-206,                -0x1.ef52789a46532p5},
+            {0x1.3fffffffffdc4p-205,    -0x1.ece9f63032644p5},
+            {0x1.4p-205,                -0x1.ece9f6303263ep5},
+            {0x1.3ffffffffe211p-204,    -0x1.ea8173c61e79ep5},
+            {0x1.3ffffffffff35p-204,    -0x1.ea8173c61e74cp5},
+            {0x1.4p-204,                -0x1.ea8173c61e74ap5},
+            {0x1.3ffffffffec25p-203,    -0x1.e818f15c0a88ep5},
+            {0x1.3fffffffffe7ep-203,    -0x1.e818f15c0a85ap5},
+            {0x1.4p-203,                -0x1.e818f15c0a856p5},
+            {0x1.3ffffffffdcadp-202,    -0x1.e5b06ef1f69c5p5},
+            {0x1.3fffffffffedbp-202,    -0x1.e5b06ef1f6966p5},
+            {0x1.4p-202,                -0x1.e5b06ef1f6962p5},
+            {0x1.3fffffffffd0fp-201,    -0x1.e347ec87e2a76p5},
+            {0x1.4p-201,                -0x1.e347ec87e2a6ep5},
+            {0x1.3fffffffffe8p-200,     -0x1.e0df6a1dceb7ep5},
+            {0x1.4p-200,                -0x1.e0df6a1dceb7ap5},
+            {0x1.3ffffffffff39p-199,    -0x1.de76e7b3bac88p5},
+            {0x1.4p-199,                -0x1.de76e7b3bac86p5},
+            {0x1.3fffffffffff2p-198,    -0x1.dc0e6549a6d92p5},
+            {0x1.4p-198,                -0x1.dc0e6549a6d92p5},
+            {0x1.3ffffffffff97p-197,    -0x1.d9a5e2df92eap5},
+            {0x1.4p-197,                -0x1.d9a5e2df92e9ep5},
+            {0x1.3fffffffffdcbp-196,    -0x1.d73d60757efbp5},
+            {0x1.4p-196,                -0x1.d73d60757efaap5},
+            {0x1.3ffffffffff3cp-195,    -0x1.d4d4de0b6b0b8p5},
+            {0x1.4p-195,                -0x1.d4d4de0b6b0b6p5},
+            {0x1.3fffffffffee1p-194,    -0x1.d26c5ba1571c6p5},
+            {0x1.4p-194,                -0x1.d26c5ba1571c2p5},
+            {0x1.3ffffffffff9ap-193,    -0x1.d003d937432dp5},
+            {0x1.4p-193,                -0x1.d003d937432cep5},
+            {0x1.3fffffffffdcep-192,    -0x1.cd9b56cd2f3ep5},
+            {0x1.4p-192,                -0x1.cd9b56cd2f3dap5},
+            {0x1.3fffffffffe87p-191,    -0x1.cb32d4631b4eap5},
+            {0x1.4p-191,                -0x1.cb32d4631b4e6p5},
+            {0x1.3fffffffffff8p-190,    -0x1.c8ca51f9075f2p5},
+            {0x1.4p-190,                -0x1.c8ca51f9075f2p5},
+            {0x1.3fffffffffff9p-189,    -0x1.c661cf8ef36fep5},
+            {0x1.4p-189,                -0x1.c661cf8ef36fep5},
+            {0x1.3fffffffffdd1p-188,    -0x1.c3f94d24df81p5},
+            {0x1.4p-188,                -0x1.c3f94d24df80ap5},
+            {0x1.3fffffffffe8ap-187,    -0x1.c190cabacb91ap5},
+            {0x1.4p-187,                -0x1.c190cabacb916p5},
+            {0x1.3ffffffffff43p-186,    -0x1.bf284850b7a24p5},
+            {0x1.4p-186,                -0x1.bf284850b7a22p5},
+            {0x1.3fffffffffffcp-185,    -0x1.bcbfc5e6a3b2ep5},
+            {0x1.4p-185,                -0x1.bcbfc5e6a3b2ep5},
+            {0x1.3ffffffffffa1p-184,    -0x1.ba57437c8fc3cp5},
+            {0x1.4p-184,                -0x1.ba57437c8fc3ap5},
+            {0x1.3fffffffffd79p-183,    -0x1.b7eec1127bd4ep5},
+            {0x1.4p-183,                -0x1.b7eec1127bd46p5},
+            {0x1.3fffffffffe32p-182,    -0x1.b5863ea867e58p5},
+            {0x1.4p-182,                -0x1.b5863ea867e52p5},
+            {0x1.3ffffffffe4a7p-181,    -0x1.b31dbc3e53faap5},
+            {0x1.3ffffffffffffp-181,    -0x1.b31dbc3e53f5ep5},
+            {0x1.4p-181,                -0x1.b31dbc3e53f5ep5},
+            {0x1.3fffffffffdd7p-180,    -0x1.b0b539d44007p5},
+            {0x1.4p-180,                -0x1.b0b539d44006ap5},
+            {0x1.3fffffffffa9bp-179,    -0x1.ae4cb76a2c185p5},
+            {0x1.3fffffffffe9p-179,     -0x1.ae4cb76a2c17ap5},
+            {0x1.4p-179,                -0x1.ae4cb76a2c177p5},
+            {0x1.3ffffffffe3f1p-178,    -0x1.abe43500182d1p5},
+            {0x1.3ffffffffff49p-178,    -0x1.abe4350018284p5},
+            {0x1.4p-178,                -0x1.abe4350018283p5},
+            {0x1.3fffffffffc69p-177,    -0x1.a97bb29604398p5},
+            {0x1.4p-177,                -0x1.a97bb2960438fp5},
+            {0x1.3fffffffffddap-176,    -0x1.a713302bf04ap5},
+            {0x1.4p-176,                -0x1.a713302bf049bp5},
+            {0x1.3fffffffffe93p-175,    -0x1.a4aaadc1dc5aap5},
+            {0x1.4p-175,                -0x1.a4aaadc1dc5a7p5},
+            {0x1.3fffffffff481p-174,    -0x1.a2422b57c86d3p5},
+            {0x1.3fffffffffe38p-174,    -0x1.a2422b57c86b8p5},
+            {0x1.4p-174,                -0x1.a2422b57c86b3p5},
+            {0x1.3fffffffffef1p-173,    -0x1.9fd9a8edb47c2p5},
+            {0x1.4p-173,                -0x1.9fd9a8edb47bfp5},
+            {0x1.3ffffffffffaap-172,    -0x1.9d712683a08ccp5},
+            {0x1.4p-172,                -0x1.9d712683a08cbp5},
+            {0x1.3fffffffffddep-171,    -0x1.9b08a4198c9dcp5},
+            {0x1.4p-171,                -0x1.9b08a4198c9d7p5},
+            {0x1.3ffffffffff4fp-170,    -0x1.98a021af78ae4p5},
+            {0x1.4p-170,                -0x1.98a021af78ae3p5},
+            {0x1.3fffffffffd27p-169,    -0x1.96379f4564bf6p5},
+            {0x1.4p-169,                -0x1.96379f4564befp5},
+            {0x1.3fffffffffdep-168,     -0x1.93cf1cdb50dp5},
+            {0x1.4p-168,                -0x1.93cf1cdb50cfbp5},
+            {0x1.3fffffffffe99p-167,    -0x1.91669a713ce0ap5},
+            {0x1.4p-167,                -0x1.91669a713ce07p5},
+            {0x1.3ffffffffff52p-166,    -0x1.8efe180728f14p5},
+            {0x1.4p-166,                -0x1.8efe180728f13p5},
+            {0x1.3fffffffffc72p-165,    -0x1.8c95959d15028p5},
+            {0x1.4p-165,                -0x1.8c95959d1501fp5},
+            {0x1.3ffffffffffbp-164,     -0x1.8a2d13330112cp5},
+            {0x1.4p-164,                -0x1.8a2d13330112bp5},
+            {0x1.3fffffffffd88p-163,    -0x1.87c490c8ed23ep5},
+            {0x1.4p-163,                -0x1.87c490c8ed237p5},
+            {0x1.3fffffffffe9dp-162,    -0x1.855c0e5ed9346p5},
+            {0x1.4p-162,                -0x1.855c0e5ed9343p5},
+            {0x1.3fffffffffefap-161,    -0x1.82f38bf4c5452p5},
+            {0x1.4p-161,                -0x1.82f38bf4c544fp5},
+            {0x1.3fffffffffd2ep-160,    -0x1.808b098ab1562p5},
+            {0x1.4p-160,                -0x1.808b098ab155bp5},
+            {0x1.3fffffffffe9fp-159,    -0x1.7e2287209d66ap5},
+            {0x1.4p-159,                -0x1.7e2287209d667p5},
+            {0x1.3ffffffffff58p-158,    -0x1.7bba04b689774p5},
+            {0x1.4p-158,                -0x1.7bba04b689773p5},
+            {0x1.3fffffffff099p-157,    -0x1.7951824c758aap5},
+            {0x1.3ffffffffff59p-157,    -0x1.7951824c7588p5},
+            {0x1.4p-157,                -0x1.7951824c7587fp5},
+            {0x1.3fffffffffd31p-156,    -0x1.76e8ffe261992p5},
+            {0x1.4p-156,                -0x1.76e8ffe26198bp5},
+            {0x1.3fffffffffdeap-155,    -0x1.74807d784da9cp5},
+            {0x1.4p-155,                -0x1.74807d784da97p5},
+            {0x1.3fffffffffea3p-154,    -0x1.7217fb0e39ba6p5},
+            {0x1.4p-154,                -0x1.7217fb0e39ba3p5},
+            {0x1.3fffffffffc7bp-153,    -0x1.6faf78a425cb8p5},
+            {0x1.3ffffffffff5cp-153,    -0x1.6faf78a425cbp5},
+            {0x1.4p-153,                -0x1.6faf78a425cafp5},
+            {0x1.3ffffffffffb9p-152,    -0x1.6d46f63a11dbcp5},
+            {0x1.4p-152,                -0x1.6d46f63a11dbbp5},
+            {0x1.3fffffffffa54p-151,    -0x1.6ade73cffded6p5},
+            {0x1.4p-151,                -0x1.6ade73cffdec7p5},
+            {0x1.3fffffffffbc5p-150,    -0x1.6875f165e9fdfp5},
+            {0x1.3fffffffffea6p-150,    -0x1.6875f165e9fd6p5},
+            {0x1.4p-150,                -0x1.6875f165e9fd3p5},
+            {0x1.3ffffffffff5fp-149,    -0x1.660d6efbd60ep5},
+            {0x1.4p-149,                -0x1.660d6efbd60dfp5},
+            {0x1.3fffffffffdefp-148,    -0x1.63a4ec91c21fp5},
+            {0x1.4p-148,                -0x1.63a4ec91c21ebp5},
+            {0x1.3fffffffffea8p-147,    -0x1.613c6a27ae2fap5},
+            {0x1.4p-147,                -0x1.613c6a27ae2f7p5},
+            {0x1.3ffffffffff61p-146,    -0x1.5ed3e7bd9a404p5},
+            {0x1.4p-146,                -0x1.5ed3e7bd9a403p5},
+            {0x1.3ffffffffff62p-145,    -0x1.5c6b65538651p5},
+            {0x1.4p-145,                -0x1.5c6b65538650fp5},
+            {0x1.3ffffffffffbfp-144,    -0x1.5a02e2e97261cp5},
+            {0x1.4p-144,                -0x1.5a02e2e97261bp5},
+            {0x1.3fffffffffcdfp-143,    -0x1.579a607f5e73p5},
+            {0x1.4p-143,                -0x1.579a607f5e727p5},
+            {0x1.3fffffffffd98p-142,    -0x1.5531de154a83ap5},
+            {0x1.4p-142,                -0x1.5531de154a833p5},
+            {0x1.3fffffffffe51p-141,    -0x1.52c95bab36944p5},
+            {0x1.4p-141,                -0x1.52c95bab3693fp5},
+            {0x1.3ffffffffffc2p-140,    -0x1.5060d94122a4cp5},
+            {0x1.4p-140,                -0x1.5060d94122a4bp5},
+            {0x1.3fffffffffdf6p-139,    -0x1.4df856d70eb5cp5},
+            {0x1.4p-139,                -0x1.4df856d70eb57p5},
+            {0x1.3fffffffffeafp-138,    -0x1.4b8fd46cfac66p5},
+            {0x1.4p-138,                -0x1.4b8fd46cfac63p5},
+            {0x1.3ffffffffff68p-137,    -0x1.49275202e6d7p5},
+            {0x1.4p-137,                -0x1.49275202e6d6fp5},
+            {0x1.3ffffffffffc5p-136,    -0x1.46becf98d2e7bp5},
+            {0x1.4p-136,                -0x1.46becf98d2e7bp5},
+            {0x1.3fffffffffdf9p-135,    -0x1.44564d2ebef8cp5},
+            {0x1.4p-135,                -0x1.44564d2ebef87p5},
+            {0x1.3fffffffffeb2p-134,    -0x1.41edcac4ab096p5},
+            {0x1.4p-134,                -0x1.41edcac4ab093p5},
+            {0x1.3ffffffffff6bp-133,    -0x1.3f85485a971ap5},
+            {0x1.4p-133,                -0x1.3f85485a9719fp5},
+            {0x1.3ffffffffe699p-132,    -0x1.3d1cc5f0832f2p5},
+            {0x1.3ffffffffff1p-132,     -0x1.3d1cc5f0832aep5},
+            {0x1.4p-132,                -0x1.3d1cc5f0832abp5},
+            {0x1.3ffffffffffc9p-131,    -0x1.3ab443866f3b8p5},
+            {0x1.4p-131,                -0x1.3ab443866f3b7p5},
+            {0x1.3fffffffffda1p-130,    -0x1.384bc11c5b4cap5},
+            {0x1.4p-130,                -0x1.384bc11c5b4c3p5},
+            {0x1.3ffffffffed15p-129,    -0x1.35e33eb247604p5},
+            {0x1.3ffffffffff6ep-129,    -0x1.35e33eb2475dp5},
+            {0x1.4p-129,                -0x1.35e33eb2475cfp5},
+            {0x1.3ffffffffdd9dp-128,    -0x1.337abc483373bp5},
+            {0x1.3fffffffffd46p-128,    -0x1.337abc48336e2p5},
+            {0x1.4p-128,                -0x1.337abc48336dbp5},
+            {0x1.3fffffffffdffp-127,    -0x1.311239de1f7ecp5},
+            {0x1.4p-127,                -0x1.311239de1f7e7p5},
+            {0x1.3fffffffff391p-126,    -0x1.2ea9b7740b916p5},
+            {0x1.3ffffffffff7p-126,     -0x1.2ea9b7740b8f4p5},
+            {0x1.4p-126,                -0x1.2ea9b7740b8f3p5},
+            {0x1.3ffffffffff71p-125,    -0x1.2c413509f7ap5},
+            {0x1.4p-125,                -0x1.2c413509f79ffp5},
+            {0x1.3fffffffffc91p-124,    -0x1.29d8b29fe3b14p5},
+            {0x1.4p-124,                -0x1.29d8b29fe3b0bp5},
+            {0x1.3fffffffffd4ap-123,    -0x1.27703035cfc1ep5},
+            {0x1.4p-123,                -0x1.27703035cfc17p5},
+            {0x1.3fffffffffe03p-122,    -0x1.2507adcbbbd28p5},
+            {0x1.4p-122,                -0x1.2507adcbbbd23p5},
+            {0x1.3fffffffffebcp-121,    -0x1.229f2b61a7e32p5},
+            {0x1.4p-121,                -0x1.229f2b61a7e2fp5},
+            {0x1.3ffffffffff19p-120,    -0x1.2036a8f793f3ep5},
+            {0x1.4p-120,                -0x1.2036a8f793f3bp5},
+            {0x1.3fffffffffd4dp-119,    -0x1.1dce268d8004ep5},
+            {0x1.4p-119,                -0x1.1dce268d80047p5},
+            {0x1.3fffffffffebep-118,    -0x1.1b65a4236c156p5},
+            {0x1.4p-118,                -0x1.1b65a4236c153p5},
+            {0x1.3ffffffffff77p-117,    -0x1.18fd21b95826p5},
+            {0x1.4p-117,                -0x1.18fd21b95825fp5},
+            {0x1.3ffffffffffd4p-116,    -0x1.16949f4f4436bp5},
+            {0x1.4p-116,                -0x1.16949f4f4436bp5},
+            {0x1.3fffffffffe08p-115,    -0x1.142c1ce53047cp5},
+            {0x1.4p-115,                -0x1.142c1ce530477p5},
+            {0x1.3fffffffffe09p-114,    -0x1.11c39a7b1c588p5},
+            {0x1.4p-114,                -0x1.11c39a7b1c583p5},
+            {0x1.3fffffffffec2p-113,    -0x1.0f5b181108692p5},
+            {0x1.4p-113,                -0x1.0f5b18110868fp5},
+            {0x1.3ffffffffff7bp-112,    -0x1.0cf295a6f479cp5},
+            {0x1.4p-112,                -0x1.0cf295a6f479bp5},
+            {0x1.3ffffffffffd8p-111,    -0x1.0a8a133ce08a8p5},
+            {0x1.4p-111,                -0x1.0a8a133ce08a7p5},
+            {0x1.3fffffffffa73p-110,    -0x1.082190d2cc9c2p5},
+            {0x1.4p-110,                -0x1.082190d2cc9b3p5},
+            {0x1.3fffffffffec5p-109,    -0x1.05b90e68b8ac2p5},
+            {0x1.4p-109,                -0x1.05b90e68b8abfp5},
+            {0x1.3ffffffffedddp-108,    -0x1.03508bfea4bfep5},
+            {0x1.3ffffffffff7ep-108,    -0x1.03508bfea4bccp5},
+            {0x1.4p-108,                -0x1.03508bfea4bcbp5},
+            {0x1.3ffffffffde65p-107,    -0x1.00e8099490d35p5},
+            {0x1.3fffffffffe0ep-107,    -0x1.00e8099490cdcp5},
+            {0x1.4p-107,                -0x1.00e8099490cd7p5},
+            {0x1.3ffffffffed3dp-106,    -0x1.fcff0e54f9c2fp4},
+            {0x1.3fffffffffe82p-106,    -0x1.fcff0e54f9bcep4},
+            {0x1.4p-106,                -0x1.fcff0e54f9bc6p4},
+            {0x1.3fffffffffff3p-105,    -0x1.f82e0980d1ddep4},
+            {0x1.4p-105,                -0x1.f82e0980d1ddep4},
+            {0x1.3ffffffffff98p-104,    -0x1.f35d04aca9ff8p4},
+            {0x1.4p-104,                -0x1.f35d04aca9ff6p4},
+            {0x1.3ffffffffe3b7p-103,    -0x1.ee8bffd8822abp4},
+            {0x1.3ffffffffffc7p-103,    -0x1.ee8bffd88221p4},
+            {0x1.4p-103,                -0x1.ee8bffd88220ep4},
+            {0x1.3fffffffffdcdp-102,    -0x1.e9bafb045a432p4},
+            {0x1.4p-102,                -0x1.e9bafb045a426p4},
+            {0x1.3ffffffffff3ep-101,    -0x1.e4e9f63032642p4},
+            {0x1.4p-101,                -0x1.e4e9f6303263ep4},
+            {0x1.3ffffffffe301p-100,    -0x1.e018f15c0a8f8p4},
+            {0x1.3fffffffffff7p-100,    -0x1.e018f15c0a856p4},
+            {0x1.4p-100,                -0x1.e018f15c0a856p4},
+            {0x1.3fffffffffd73p-99,     -0x1.db47ec87e2a7cp4},
+            {0x1.4p-99,                 -0x1.db47ec87e2a6ep4},
+            {0x1.3ffffffffdd9dp-98,     -0x1.d676e7b3bad46p4},
+            {0x1.3fffffffffee4p-98,     -0x1.d676e7b3bac8cp4},
+            {0x1.4p-98,                 -0x1.d676e7b3bac86p4},
+            {0x1.3ffffffffff9dp-97,     -0x1.d1a5e2df92eap4},
+            {0x1.4p-97,                 -0x1.d1a5e2df92e9ep4},
+            {0x1.3fffffffffffap-96,     -0x1.ccd4de0b6b0b6p4},
+            {0x1.4p-96,                 -0x1.ccd4de0b6b0b6p4},
+            {0x1.3ffffffffffcdp-95,     -0x1.c803d937432dp4},
+            {0x1.4p-95,                 -0x1.c803d937432cep4},
+            {0x1.3ffffffffffcep-94,     -0x1.c332d4631b4e8p4},
+            {0x1.4p-94,                 -0x1.c332d4631b4e6p4},
+            {0x1.3fffffffffe8cp-93,     -0x1.be61cf8ef3706p4},
+            {0x1.4p-93,                 -0x1.be61cf8ef36fep4},
+            {0x1.3fffffffff983p-92,     -0x1.b990cabacb93ap4},
+            {0x1.3ffffffffff45p-92,     -0x1.b990cabacb91ap4},
+            {0x1.4p-92,                 -0x1.b990cabacb916p4},
+            {0x1.3fffffffffffep-91,     -0x1.b4bfc5e6a3b2ep4},
+            {0x1.4p-91,                 -0x1.b4bfc5e6a3b2ep4},
+            {0x1.3fffffffffdd6p-90,     -0x1.afeec1127bd52p4},
+            {0x1.4p-90,                 -0x1.afeec1127bd46p4},
+            {0x1.3fffffffffeebp-89,     -0x1.ab1dbc3e53f64p4},
+            {0x1.4p-89,                 -0x1.ab1dbc3e53f5ep4},
+            {0x1.3ffffffffffa4p-88,     -0x1.a64cb76a2c178p4},
+            {0x1.4p-88,                 -0x1.a64cb76a2c177p4},
+            {0x1.3fffffffffa9bp-87,     -0x1.a17bb296043acp4},
+            {0x1.3fffffffffd7cp-87,     -0x1.a17bb2960439cp4},
+            {0x1.4p-87,                 -0x1.a17bb2960438fp4},
+            {0x1.3fffffffffe91p-86,     -0x1.9caaadc1dc5aep4},
+            {0x1.3ffffffffffc5p-86,     -0x1.9caaadc1dc5a8p4},
+            {0x1.3fffffffffe36p-85,     -0x1.97d9a8edb47c8p4},
+            {0x1.3ffffffffffa7p-84,     -0x1.9308a4198c9d8p4},
+            {0x1.3ffffffffff7ap-83,     -0x1.8e379f4564bf2p4},
+            {0x1.3ffffffffffd7p-82,     -0x1.89669a713ce08p4},
+            {0x1.3fffffffffe95p-81,     -0x1.8495959d15026p4},
+            {0x1.3ffffffffff4ep-80,     -0x1.7fc490c8ed23ap4},
+            {0x1.3ffffffffeafbp-79,     -0x1.7af38bf4c54c3p4},
+            {0x1.3ffffffffffd9p-79,     -0x1.7af38bf4c544fp4},
+            {0x1.3fffffffffe3bp-78,     -0x1.762287209d67p4},
+            {0x1.3ffffffffde65p-77,     -0x1.7151824c7593ap4},
+            {0x1.3fffffffffef4p-77,     -0x1.7151824c75884p4},
+            {0x1.3ffffffffffadp-76,     -0x1.6c807d784da98p4},
+            {0x1.3fffffffffb8bp-75,     -0x1.67af78a425cc7p4},
+            {0x1.3ffffffffffaep-75,     -0x1.67af78a425cbp4},
+            {0x1.3ffffffffffddp-74,     -0x1.62de73cffdec8p4},
+            {0x1.3fffffffffe3fp-73,     -0x1.5e0d6efbd60e8p4},
+            {0x1.3ffffffffff54p-72,     -0x1.593c6a27ae2fap4},
+            {0x1.3ffffffffffb1p-71,     -0x1.546b65538651p4},
+            {0x1.3fffffffff571p-70,     -0x1.4f9a607f5e762p4},
+            {0x1.3fffffffffde5p-70,     -0x1.4f9a607f5e732p4},
+            {0x1.3fffffffffe9ep-69,     -0x1.4ac95bab36946p4},
+            {0x1.3ffffffffffb3p-68,     -0x1.45f856d70eb58p4},
+            {0x1.3ffffffffe1d7p-67,     -0x1.41275202e6e16p4},
+            {0x1.3ffffffffffb4p-67,     -0x1.41275202e6d7p4},
+            {0x1.3fffffffffe44p-66,     -0x1.3c564d2ebef9p4},
+            {0x1.3fffffffffd5fp-65,     -0x1.3785485a971aep4},
+            {0x1.3fffffffffaadp-64,     -0x1.32b443866f3d5p4},
+            {0x1.3fffffffffefep-64,     -0x1.32b443866f3bcp4},
+            {0x1.3ffffffffeb35p-63,     -0x1.2de33eb247643p4},
+            {0x1.3ffffffffffb7p-63,     -0x1.2de33eb2475dp4},
+            {0x1.3ffffffffffe6p-62,     -0x1.291239de1f7e8p4},
+            {0x1.3fffffffffdecp-61,     -0x1.24413509f7a0ap4},
+            {0x1.3ffffffffff5dp-60,     -0x1.1f703035cfc1ap4},
+            {0x1.3ffffffffffbap-59,     -0x1.1a9f2b61a7e3p4},
+            {0x1.3fffffffffd92p-58,     -0x1.15ce268d80054p4},
+            {0x1.3ffffffffff03p-57,     -0x1.10fd21b958264p4},
+            {0x1.3ffffffffe6e9p-56,     -0x1.0c2c1ce530503p4},
+            {0x1.3ffffffffffbcp-56,     -0x1.0c2c1ce530478p4},
+            {0x1.3ffffffffe2c7p-55,     -0x1.075b181108731p4},
+            {0x1.3ffffffffff61p-55,     -0x1.075b181108692p4},
+            {0x1.3ffffffffffecp-54,     -0x1.028a133ce08a8p4},
+            {0x1.3fffffffff14fp-53,     -0x1.fb721cd171621p3},
+            {0x1.3fffffffffff8p-53,     -0x1.fb721cd17157ep3},
+            {0x1.3ffffffffdd9dp-52,     -0x1.f1d0132921b2dp3},
+            {0x1.3ffffffffffe2p-52,     -0x1.f1d01329219bp3},
+            {0x1.3ffffffffebebp-51,     -0x1.e82e0980d1ebdp3},
+            {0x1.3fffffffffe2dp-51,     -0x1.e82e0980d1df2p3},
+            {0x1.3ffffffffff7p-50,      -0x1.de8bffd882214p3},
+            {0x1.3fffffffffaadp-49,     -0x1.d4e9f6303267ap3},
+            {0x1.3ffffffffffcdp-49,     -0x1.d4e9f6303264p3},
+            {0x1.3fffffffffd77p-48,     -0x1.cb47ec87e2a8ap3},
+            {0x1.3fffffffffda5p-48,     -0x1.cb47ec87e2a89p3},
+            {0x1.3ffffffffff16p-47,     -0x1.c1a5e2df92ea8p3},
+            {0x1.3fffffffff983p-46,     -0x1.b803d93743316p3},
+            {0x1.3ffffffffffcfp-46,     -0x1.b803d937432dp3},
+            {0x1.3ffffffffffa2p-45,     -0x1.ae61cf8ef3702p3},
+            {0x1.3fffffffffbc5p-44,     -0x1.a4bfc5e6a3b5ep3},
+            {0x1.3ffffffffffffp-44,     -0x1.a4bfc5e6a3b2ep3},
+            {0x1.3fffffffffdd7p-43,     -0x1.9b1dbc3e53f76p3},
+            {0x1.3fffffffffebep-42,     -0x1.917bb2960439cp3},
+            {0x1.3ffffffffe3f1p-41,     -0x1.87d9a8edb48f7p3},
+            {0x1.3ffffffffff77p-41,     -0x1.87d9a8edb47c4p3},
+            {0x1.3fffffffff23fp-40,     -0x1.7e379f4564c87p3},
+            {0x1.3ffffffffffbdp-40,     -0x1.7e379f4564bf2p3},
+            {0x1.3fffffffffe36p-39,     -0x1.7495959d15032p3},
+            {0x1.3ffffffffecdbp-38,     -0x1.6af38bf4c5523p3},
+            {0x1.3ffffffffffa7p-38,     -0x1.6af38bf4c5452p3},
+            {0x1.3ffffffffffd6p-37,     -0x1.6151824c7588p3},
+            {0x1.3ffffffffffeep-36,     -0x1.57af78a425cafp3},
+            {0x1.3ffffffffdcadp-35,     -0x1.4e0d6efbd6268p3},
+            {0x1.3ffffffffffefp-35,     -0x1.4e0d6efbd60ep3},
+            {0x1.3fffffffffe68p-34,     -0x1.446b65538652p3},
+            {0x1.3ffffffffeafbp-33,     -0x1.3ac95bab36a28p3},
+            {0x1.3ffffffffffd9p-33,     -0x1.3ac95bab3694p3},
+            {0x1.3ffffffffffdap-32,     -0x1.31275202e6d7p3},
+            {0x1.3fffffffffcb5p-31,     -0x1.2785485a971c4p3},
+            {0x1.3ffffffffffc4p-31,     -0x1.2785485a971a2p3},
+            {0x1.3fffffffffec7p-30,     -0x1.1de33eb2475dcp3},
+            {0x1.3ffffffffffaep-29,     -0x1.14413509f7a02p3},
+            {0x1.3ffffffffd9a3p-28,     -0x1.0a9f2b61a7fd9p3},
+            {0x1.3ffffffffffddp-28,     -0x1.0a9f2b61a7e3p3},
+            {0x1.3fffffffff32fp-27,     -0x1.00fd21b9582edp3},
+            {0x1.3fffffffffe6dp-27,     -0x1.00fd21b95827p3},
+            {0x1.3ffffffffffe4p-26,     -0x1.eeb6302210d2p2},
+            {0x1.3ffffffffeb35p-25,     -0x1.db721cd17174dp2},
+            {0x1.3fffffffffffcp-25,     -0x1.db721cd17157ep2},
+            {0x1.3ffffffffde65p-24,     -0x1.c82e0980d20cap2},
+            {0x1.3fffffffffeafp-24,     -0x1.c82e0980d1dfcp2},
+            {0x1.3ffffffffed3dp-23,     -0x1.b4e9f630327ep2},
+            {0x1.3ffffffffff7fp-23,     -0x1.b4e9f6303264ap2},
+            {0x1.3ffffffffffdcp-22,     -0x1.a1a5e2df92ea2p2},
+            {0x1.3ffffffffe91bp-21,     -0x1.8e61cf8ef38fbp2},
+            {0x1.3ffffffffffffp-21,     -0x1.8e61cf8ef36fep2},
+            {0x1.3fffffffffeb2p-20,     -0x1.7b1dbc3e53f7bp2},
+            {0x1.3ffffffffe3b7p-19,     -0x1.67d9a8edb4a33p2},
+            {0x1.3ffffffffff3dp-19,     -0x1.67d9a8edb47dp2},
+            {0x1.3ffffffffe6e9p-18,     -0x1.5495959d1524dp2},
+            {0x1.3fffffffffff6p-18,     -0x1.5495959d1502p2},
+            {0x1.3ffffffffdb5bp-17,     -0x1.4151824c75badp2},
+            {0x1.3ffffffffffebp-17,     -0x1.4151824c7588p2},
+            {0x1.3ffffffffe301p-16,     -0x1.2e0d6efbd6364p2},
+            {0x1.3ffffffffff11p-16,     -0x1.2e0d6efbd60f3p2},
+            {0x1.3fffffffff14fp-15,     -0x1.1ac95bab36a85p2},
+            {0x1.3ffffffffff57p-15,     -0x1.1ac95bab3694ep2},
+            {0x1.3fffffffff481p-14,     -0x1.0785485a9729fp2},
+            {0x1.3fffffffffff9p-14,     -0x1.0785485a971ap2},
+            {0x1.3fffffffff571p-13,     -0x1.e8826a13ef5d4p1},
+            {0x1.3fffffffffff1p-13,     -0x1.e8826a13ef4p1},
+            {0x1.3fffffffffc7bp-12,     -0x1.c1fa4372b055ap1},
+            {0x1.3ffffffffffcfp-12,     -0x1.c1fa4372b04c6p1},
+            {0x1.3fffffffff189p-11,     -0x1.9b721cd171802p1},
+            {0x1.3fffffffffffep-11,     -0x1.9b721cd17157ep1},
+            {0x1.3ffffffffe211p-10,     -0x1.74e9f63032b72p1},
+            {0x1.3fffffffffff3p-10,     -0x1.74e9f6303264p1},
+            {0x1.3fffffffffbc5p-9,      -0x1.4e61cf8ef37bbp1},
+            {0x1.3fffffffffff4p-9,      -0x1.4e61cf8ef37p1},
+            {0x1.3fffffffff391p-8,      -0x1.27d9a8edb49e8p1},
+            {0x1.3ffffffffffe9p-8,      -0x1.27d9a8edb47c2p1},
+            {0x1.3fffffffffaadp-7,      -0x1.0151824c7596cp1},
+            {0x1.3ffffffffffeap-7,      -0x1.0151824c75882p1},
+            {0x1.3fffffffffc7bp-6,      -0x1.b592b7566d3b6p0},
+            {0x1.3fffffffffff2p-6,      -0x1.b592b7566d282p0},
+            {0x1.3fffffffffda5p-5,      -0x1.68826a13ef4dp0},
+            {0x1.3fffffffffff6p-5,      -0x1.68826a13ef402p0},
+            {0x1.3fffffffffb8bp-4,      -0x1.1b721cd17170ap0},
+            {0x1.3ffffffffffffp-4,      -0x1.1b721cd17157ep0},
+            {0x1.3fffffffffcb5p-3,      -0x1.9cc39f1de7047p-1},
+            {0x1.3fffffffffff2p-3,      -0x1.9cc39f1de6e06p-1},
+            {0x1.3fffffffffc7bp-2,      -0x1.02a30498eb36fp-1},
+            {0x1.4p-2,                  -0x1.02a30498eb0fep-1},
+            {0x1.3fffffffffda5p-1,      -0x1.a209a84fbd684p-3},
+            {0x1.3fffffffffffcp-1,      -0x1.a209a84fbd002p-3},
+            {0x1.3fffffffffff3p0,       0x1.8cf18388647c5p-4},
+            {0x1.3fffffffffffdp0,       0x1.8cf18388647fbp-4},
+            {0x1.3ffffffffff7bp1,       0x1.977d95ec10b4ap-2},
+            {0x1.3fffffffffffcp1,       0x1.977d95ec10bfcp-2},
+            {0x1.3ffffffffff2bp2,       0x1.65df657b0426dp-1},
+            {0x1.3fffffffffff3p2,       0x1.65df657b042f8p-1},
+            {0x1.3fffffffffc83p4,       0x1.4d104d427dd4ap0},
+            {0x1.3fffffffffff1p4,       0x1.4d104d427de7ap0},
+            {0x1.4p4,                   0x1.4d104d427de8p0},
+            {0x1.3ffffffffff2bp5,       0x1.9a209a84fbcb6p0},
+            {0x1.4p5,                   0x1.9a209a84fbdp0},
+            {0x1.3fffffffffd23p6,       0x1.e730e7c779a81p0},
+            {0x1.3fffffffffffep6,       0x1.e730e7c779b7ep0},
+            {0x1.4p6,                   0x1.e730e7c779b7fp0},
+            {0x1.3ffffffffece3p7,       0x1.1a209a84fb9aep1},
+            {0x1.4p7,                   0x1.1a209a84fbdp1},
+            {0x1.3fffffffffeb3p8,       0x1.40a8c1263ac06p1},
+            {0x1.3ffffffffff71p8,       0x1.40a8c1263ac26p1},
+            {0x1.4p8,                   0x1.40a8c1263ac3fp1},
+            {0x1.3fffffffffe3bp9,       0x1.6730e7c779b31p1},
+            {0x1.3fffffffffffcp9,       0x1.6730e7c779b7ep1},
+            {0x1.4p9,                   0x1.6730e7c779b7fp1},
+            {0x1.3fffffffff657p10,      0x1.8db90e68b8912p1},
+            {0x1.3ffffffffff67p10,      0x1.8db90e68b8aa4p1},
+            {0x1.4p10,                  0x1.8db90e68b8abfp1},
+            {0x1.3fffffffff8ffp11,      0x1.b4413509f78c8p1},
+            {0x1.3ffffffffffecp11,      0x1.b4413509f79fcp1},
+            {0x1.4p11,                  0x1.b4413509f79ffp1},
+            {0x1.3fffffffffd23p12,      0x1.dac95bab368cp1},
+            {0x1.3ffffffffff5dp12,      0x1.dac95bab36922p1},
+            {0x1.4p12,                  0x1.dac95bab3693fp1},
+            {0x1.3fffffffffe13p13,      0x1.00a8c1263ac15p2},
+            {0x1.3fffffffffee2p13,      0x1.00a8c1263ac26p2},
+            {0x1.4p13,                  0x1.00a8c1263ac3fp2},
+            {0x1.3fffffffff193p14,      0x1.13ecd476da29fp2},
+            {0x1.3ffffffffffc9p14,      0x1.13ecd476da3dap2},
+            {0x1.4p14,                  0x1.13ecd476da3dfp2},
+            {0x1.3fffffffff5b7p15,      0x1.2730e7c779a9bp2},
+            {0x1.3ffffffffff1dp15,      0x1.2730e7c779b6cp2},
+            {0x1.4p15,                  0x1.2730e7c779b7fp2},
+            {0x1.3ffffffffec2fp16,      0x1.3a74fb1819167p2},
+            {0x1.3ffffffffffedp16,      0x1.3a74fb181931ep2},
+            {0x1.4p16,                  0x1.3a74fb181931fp2},
+            {0x1.3fffffffffb07p17,      0x1.4db90e68b8a51p2},
+            {0x1.3fffffffffecep17,      0x1.4db90e68b8aa4p2},
+            {0x1.4p17,                  0x1.4db90e68b8abfp2},
+            {0x1.3ffffffffff2bp18,      0x1.60fd21b95824dp2},
+            {0x1.3ffffffffffb5p18,      0x1.60fd21b958258p2},
+            {0x1.4p18,                  0x1.60fd21b95825fp2},
+            {0x1.3ffffffffffe4p19,      0x1.74413509f79fcp2},
+            {0x1.4p19,                  0x1.74413509f79ffp2},
+            {0x1.3fffffffff6cfp20,      0x1.8785485a970d3p2},
+            {0x1.3ffffffffffd9p20,      0x1.8785485a9719cp2},
+            {0x1.4p20,                  0x1.8785485a9719fp2},
+            {0x1.3ffffffffed47p21,      0x1.9ac95bab3679fp2},
+            {0x1.3fffffffffebap21,      0x1.9ac95bab36922p2},
+            {0x1.4p21,                  0x1.9ac95bab3693fp2},
+            {0x1.3fffffffff16bp22,      0x1.ae0d6efbd5f9bp2},
+            {0x1.3ffffffffff8ap22,      0x1.ae0d6efbd60d4p2},
+            {0x1.4p22,                  0x1.ae0d6efbd60dfp2},
+            {0x1.3ffffffffe667p23,      0x1.c151824c75646p2},
+            {0x1.3fffffffffffep23,      0x1.c151824c7587ep2},
+            {0x1.4p23,                  0x1.c151824c7587fp2},
+            {0x1.3fffffffffff3p24,      0x1.d495959d1501ep2},
+            {0x1.4p24,                  0x1.d495959d1501fp2},
+            {0x1.3fffffffffadfp25,      0x1.e7d9a8edb474dp2},
+            {0x1.3fffffffffebdp25,      0x1.e7d9a8edb47a2p2},
+            {0x1.4p25,                  0x1.e7d9a8edb47bfp2},
+        };
+
+        for (double[] testCase: testCases)
+            failures+=testLog10Case(testCase[0], testCase[1]);
+
+        return failures;
+    }
+
+    public static void main(String [] argv) {
+        int failures = 0;
+
+        failures += testLog10();
+
+        if (failures > 0) {
+            System.err.println("Testing log10 incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StrictMath/Log1pTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4851638
+ * @summary Tests for StrictMath.log1p
+ * @author Joseph D. Darcy
+ */
+
+/**
+ * The tests in ../Math/Log1pTests.java test properties that should
+ * hold for any log1p implementation, including the FDLIBM-based one
+ * required for StrictMath.log1p.  Therefore, the test cases in
+ * ../Math/Log1pTests.java are run against both the Math and
+ * StrictMath versions of log1p.  The role of this test is to verify
+ * that the FDLIBM log1p algorithm is being used by running golden
+ * file tests on values that may vary from one conforming log1p
+ * implementation to another.
+ */
+
+public class Log1pTests {
+    private Log1pTests(){}
+
+    static int testLog1pCase(double input, double expected) {
+        return Tests.test("StrictMath.log1p(double)", input,
+                          StrictMath.log1p(input), expected);
+    }
+
+    static int testLog1p() {
+        int failures = 0;
+
+        double [][] testCases = {
+            {0x1.fffffffffffffp-54,     0x1.fffffffffffffp-54},
+            {0x1.fffffffffcc48p-15,     0x1.fffc000aa74f3p-15},
+            {0x1.ffffffffff224p-14,     0x1.fff8002aa8ccfp-14},
+            {0x1.ffffffffff90cp-13,     0x1.fff000aaa23bdp-13},
+            {0x1.fffffffffffcep-4,      0x1.e27076e2af2bap-4},
+            {0x1.fffffffffffffp-2,      0x1.9f323ecbf984bp-2},
+            {0x1.ffffffffffffdp-1,      0x1.62e42fefa39eep-1},
+            {0x1.0p1,                   0x1.193ea7aad030ap0},
+            {0x1.ffffffffffffbp1,       0x1.9c041f7ed8d31p0},
+            {0x1.fffffffffffffp2,       0x1.193ea7aad030ap1},
+            {0x1.fffffffffffe1p3,       0x1.6aa6bc1fa7f73p1},
+            {0x1.fffffffffffe1p4,       0x1.bf8d8f4d5b8cap1},
+            {0x1.ffffffffffff1p5,       0x1.0b29293942974p2},
+            {0x1.fffffffffff41p6,       0x1.37072a9b5b6b4p2},
+            {0x1.ffffffffffe65p7,       0x1.63241004e8fdep2},
+            {0x1.ffffffffffca1p8,       0x1.8f60adf041b73p2},
+            {0x1.fffffffffffffp9,       0x1.bbad39ebe1ccp2},
+            {0x1.fffffffffffffp10,      0x1.e801c1698ba43p2},
+            {0x1.ffffffffff2dep11,      0x1.0a2d23e3bb54bp3},
+            {0x1.ffffffffff18dp12,      0x1.205a66eeb4f81p3},
+            {0x1.ffffffffffff9p13,      0x1.368829f0af2dcp3},
+            {0x1.fffffffffbc1ep14,      0x1.4cb62cf069217p3},
+            {0x1.ffffffffffff5p16,      0x1.791282ee99d8ep3},
+            {0x1.fffffffffba46p17,      0x1.8f40bded96cd1p3},
+            {0x1.ffffffffffff7p18,      0x1.a56efcec920cbp3},
+            {0x1.ffffffffffff7p19,      0x1.bb9d3deb8c76ap3},
+            {0x1.ffffffffffff9p20,      0x1.d1cb7fea86bcap3},
+            {0x1.ffffffffffff7p24,      0x1.1542457b37d42p4},
+            {0x1.fffffffffffe7p29,      0x1.4cb5ecf0e964fp4},
+            {0x1.ffffffffffff9p30,      0x1.57cd0e704682p4},
+            {0x1.ffffffffffffbp34,      0x1.8429946e1cf5dp4},
+            {0x1.fffffffffffedp35,      0x1.8f40b5ed9912dp4},
+            {0x1.fffffffffffefp39,      0x1.bb9d3beb8c96ap4},
+            {0x1.fffffffffffe1p40,      0x1.c6b45d6b09abap4},
+            {0x1.fffffffffffe3p44,      0x1.f310e368fe17fp4},
+            {0x1.ffffffffffff5p45,      0x1.fe2804e87b34cp4},
+            {0x1.fffffffffffc5p66,      0x1.7386e22edf4a5p5},
+            {0x1.fffffffffff98p90,      0x1.f89c7428bca5fp5},
+            {0x1.a36e2eb1c317dp-14,     0x1.a368d0657ee51p-14},
+            {0x1.0624dd2f18d5cp-10,     0x1.060354f8c2226p-10},
+            {0x1.ffffffffffffdp-1,      0x1.62e42fefa39eep-1},
+            {0x1.8ffffffffffccp6,       0x1.275e2271bba28p2},
+            {0x1.f3fffffffff1p9,        0x1.ba2909ce4f846p2},
+            {0x1.387ffffffffa8p13,      0x1.26bbed6fbd838p3},
+            {0x1.869ffffffffe4p16,      0x1.7069f7a2d94f4p3},
+            {0x1.e847fffffff3ep19,      0x1.ba18abb1dedbcp3},
+            {0x1.312cfffffff23p23,      0x1.01e3b85ec299p4},
+            {0x1.7d783ffffff17p26,      0x1.26bb1bbe0482ap4},
+            {0x1.dcd64ffffffcep29,      0x1.4b927f3304b3ap4},
+            {0x1.2a05f1ffffa3p33,       0x1.7069e2aa317fep4},
+            {0x1.74876e7ffffbep36,      0x1.9541462195ffap4},
+            {0x1.d1a94a1fffddp39,       0x1.ba18a999000a6p4},
+            {0x1.2309ce53ffed2p43,      0x1.def00d106aa4ep4},
+            {0x1.6bcc41e8ffe73p46,      0x1.01e3b843eaa6cp5},
+            {0x1.c6bf52633fe7dp49,      0x1.144f69ff9ffbep5},
+            {0x1.1c37937e07fffp53,      0x1.26bb1bbb55515p5},
+            {0x1.6345785d89f12p56,      0x1.3926cd770aa62p5},
+            {0x1.bc16d674ec76ap59,      0x1.4b927f32bffb6p5},
+            {0x1.158e460913c51p63,      0x1.5dfe30ee75504p5},
+            {0x1.5af1d78b58badp66,      0x1.7069e2aa2aa58p5},
+            {0x1.b1ae4d6e2ecd4p69,      0x1.82d59465dffap5},
+            {0x1.0f0cf064dd066p73,      0x1.95414621954d6p5},
+            {0x1.52d02c7e14a9p76,       0x1.a7acf7dd4aa4cp5},
+            {0x1.a784379d99c19p79,      0x1.ba18a998fff98p5},
+            {0x1.08b2a2c27fb5p83,       0x1.cc845b54b54bap5},
+            {0x1.4adf4b7320322p86,      0x1.def00d106aa42p5},
+            {0x1.9d971e4fe7b91p89,      0x1.f15bbecc1ff6ap5},
+            {0x1.027e72f1f0ea3p93,      0x1.01e3b843eaa63p6},
+            {0x1.431e0fae6d44bp96,      0x1.0b199121c5512p6},
+            {0x1.93e5939a086bcp99,      0x1.144f69ff9ffb4p6},
+            {0x1.f8def8808ac86p102,     0x1.1d8542dd7aa65p6},
+            {0x1.3b8b5b5056dc7p106,     0x1.26bb1bbb55514p6},
+            {0x1.8a6e32246c76cp109,     0x1.2ff0f4992ffb8p6},
+            {0x1.ed09bead86a07p112,     0x1.3926cd770aa41p6},
+            {0x1.3426172c74d33p116,     0x1.425ca654e550ep6},
+            {0x1.812f9cf791f1ep119,     0x1.4b927f32bffb4p6},
+            {0x1.e17b8435758f2p122,     0x1.54c858109aa3ep6},
+            {0x1.2ced32a169cfap126,     0x1.5dfe30ee754fap6},
+            {0x1.78287f49c497cp129,     0x1.673409cc4ffbp6},
+            {0x1.d6329f1c3492ep132,     0x1.7069e2aa2aa3p6},
+            {0x1.25dfa371a14b8p136,     0x1.799fbb88054f2p6},
+            {0x1.6f578c4e09f0ap139,     0x1.82d59465dffa8p6},
+            {0x1.cb2d6f618c4b4p142,     0x1.8c0b6d43baa4cp6},
+            {0x1.1efc659cf77abp146,     0x1.95414621954eap6},
+            {0x1.66bb7f0435c5bp149,     0x1.9e771eff6ffa6p6},
+            {0x1.c06a5ec5428a4p152,     0x1.a7acf7dd4aa36p6},
+            {0x1.18427b3b49fc9p156,     0x1.b0e2d0bb254f6p6},
+            {0x1.5e531a0a1c729p159,     0x1.ba18a998fff9cp6},
+            {0x1.b5e7e08ca3686p162,     0x1.c34e8276daa4p6},
+            {0x1.11b0ec57e6492p166,     0x1.cc845b54b54f2p6},
+            {0x1.561d276ddfd7dp169,     0x1.d5ba34328ff9ap6},
+            {0x1.aba471495757bp172,     0x1.def00d106aa3p6},
+            {0x1.0b46c6cdd6a8ep176,     0x1.e825e5ee454ddp6},
+            {0x1.4e1878814c5f4p179,     0x1.f15bbecc1ff88p6},
+            {0x1.a19e96a19f65ap182,     0x1.fa9197a9faa2ep6},
+            {0x1.05031e2503cfcp186,     0x1.01e3b843eaa71p7},
+            {0x1.4643e5ae441d2p189,     0x1.067ea4b2d7fb6p7},
+            {0x1.97d4df19d5c5dp192,     0x1.0b199121c5516p7},
+            {0x1.fdca16e04ae24p195,     0x1.0fb47d90b2a65p7},
+            {0x1.3e9e4e4c2f2dap199,     0x1.144f69ff9ffc4p7},
+            {0x1.8e45e1df3ac31p202,     0x1.18ea566e8d514p7},
+            {0x1.f1d75a5709306p205,     0x1.1d8542dd7aa63p7},
+            {0x1.372698766608cp209,     0x1.22202f4c67fcp7},
+            {0x1.84f03e93fef5p212,      0x1.26bb1bbb55508p7},
+            {0x1.e62c4e38fdba1p215,     0x1.2b56082a42a4bp7},
+            {0x1.2fdbb0e39f6b8p219,     0x1.2ff0f4992ffb6p7},
+            {0x1.7bd29d1c875a2p222,     0x1.348be1081d50cp7},
+            {0x1.dac74463a76e9p225,     0x1.3926cd770aa42p7},
+            {0x1.28bc8abe48f57p229,     0x1.3dc1b9e5f7fap7},
+            {0x1.72ebad6ddc67ep232,     0x1.425ca654e550ep7},
+            {0x1.cfa698c952a3ap235,     0x1.46f792c3d2a53p7},
+            {0x1.21c81f7dd42b1p239,     0x1.4b927f32bffb6p7},
+            {0x1.6a3a275d4926bp242,     0x1.502d6ba1ad50ap7},
+            {0x1.c4c8b134970ddp245,     0x1.54c858109aa0ep7},
+            {0x1.61bcca711985dp252,     0x1.5dfe30ee75508p7},
+            {0x1.ba2bfd0d5fe2ap255,     0x1.62991d5d62a5cp7},
+            {0x1.59725db2728b7p262,     0x1.6bcef63b3d4fcp7},
+            {0x1.afcef51f0fa33p265,     0x1.7069e2aa2aa5ap7},
+            {0x1.0de1593368f8cp269,     0x1.7504cf1917f95p7},
+            {0x1.5159af804425ep272,     0x1.799fbb88055p7},
+            {0x1.a5b01b605409p275,      0x1.7e3aa7f6f2a3ep7},
+            {0x1.078e111c34e5bp279,     0x1.82d59465dff9fp7},
+            {0x1.497195634225fp282,     0x1.877080d4cd4f4p7},
+            {0x1.9bcdfabc13053p285,     0x1.8c0b6d43baa4ep7},
+            {0x1.0160bcb58c08cp289,     0x1.90a659b2a7fa7p7},
+            {0x1.41b8ebe2eec13p292,     0x1.95414621954f4p7},
+            {0x1.922726dbaa542p295,     0x1.99dc329082a46p7},
+            {0x1.f6b0f09295714p298,     0x1.9e771eff6ffa3p7},
+            {0x1.3a2e965b9d0b2p302,     0x1.a3120b6e5d4eep7},
+            {0x1.88ba3bf284dd1p305,     0x1.a7acf7dd4aa4ep7},
+            {0x1.32d17ed576f35p312,     0x1.b0e2d0bb254ep7},
+            {0x1.7f85de8ad56bep315,     0x1.b57dbd2a12a44p7},
+            {0x1.df67562d87c5cp318,     0x1.ba18a998fff65p7},
+            {0x1.2ba095dc76db7p322,     0x1.beb39607ed4fp7},
+            {0x1.7688bb5394bd3p325,     0x1.c34e8276daa48p7},
+            {0x1.d42aea2878b45p328,     0x1.c7e96ee5c7f87p7},
+            {0x1.249ad2594989p332,      0x1.cc845b54b54a6p7},
+        };
+
+        for (double[] testCase: testCases)
+            failures+=testLog1pCase(testCase[0], testCase[1]);
+
+        return failures;
+    }
+
+    public static void main(String [] argv) {
+        int failures = 0;
+
+        failures += testLog1p();
+
+        if (failures > 0) {
+            System.err.println("Testing log1p incurred "
+                               + failures + " failures.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StrictMath/Tests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ *
+ *
+ * Shared static test method for StrictMath tests.
+ */
+
+
+public class Tests {
+    private Tests(){}
+
+    static int test(String testName,
+                    double input,
+                    double result,
+                    double expected) {
+        if (Double.compare(expected, result ) != 0) {
+            System.err.println("Failure for " + testName + ":\n" +
+                               "\tFor input "   + input    + "\t(" + Double.toHexString(input) + ")\n" +
+                               "\texpected  " + expected + "\t(" + Double.toHexString(expected) + ")\n" +
+                               "\tgot       " + result   + "\t(" + Double.toHexString(result) + ").");
+            return 1;
+        }
+        else
+            return 0;
+    }
+
+    static int test(String testName, double input1,  double input2,
+                    double result, double expected) {
+        if (Double.compare(expected, result ) != 0) {
+            System.err.println("Failure for " + testName + ":\n" +
+                               "\tFor input "   + input1   + "\t(" + Double.toHexString(input1) + "), " +
+                                                + input2   + "\t(" + Double.toHexString(input2) + ")\n" +
+                               "\texpected  " + expected + "\t(" + Double.toHexString(expected) + ")\n" +
+                               "\tgot       " + result   + "\t(" + Double.toHexString(result) + ").");
+            return 1;
+        }
+        else
+            return 0;
+    }
+
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ToString.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2000 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4031762
+ * @summary Test the primitive wrappers static toString()
+ */
+
+import java.util.Random;
+
+public class ToString {
+
+    private static Random generator = new Random();
+
+    public static void main(String args[]) throws Exception {
+        // boolean wrapper
+        boolean b = false;
+        Boolean B = new Boolean(b);
+        if (!B.toString().equals(Boolean.toString(b)))
+            throw new RuntimeException("Boolean wrapper toString() failure.");
+        b = true;
+        B = new Boolean(b);
+        if (!B.toString().equals(Boolean.toString(b)))
+            throw new RuntimeException("Boolean wrapper toString() failure.");
+
+        // char wrapper
+        for(int x=0; x<100; x++) {
+            char c = (char)generator.nextInt();
+            Character C = new Character(c);
+            if (!C.toString().equals(Character.toString(c)))
+                throw new RuntimeException("Character wrapper toString() failure.");
+        }
+
+        // byte wrapper
+        for(int x=0; x<100; x++) {
+            byte y = (byte)generator.nextInt();
+            Byte Y = new Byte(y);
+            if (!Y.toString().equals(Byte.toString(y)))
+                throw new RuntimeException("Byte wrapper toString() failure.");
+        }
+
+        // short wrapper
+        for(int x=0; x<100; x++) {
+            short s = (short)generator.nextInt();
+            Short S = new Short(s);
+            if (!S.toString().equals(Short.toString(s)))
+                throw new RuntimeException("Short wrapper toString() failure.");
+        }
+
+        // int wrapper
+        for(int x=0; x<100; x++) {
+            int i = generator.nextInt();
+            Integer I = new Integer(i);
+            if (!I.toString().equals(Integer.toString(i)))
+                throw new RuntimeException("Integer wrapper toString() failure.");
+        }
+
+        // long wrapper
+        for(int x=0; x<100; x++) {
+            long l = generator.nextLong();
+            Long L = new Long(l);
+            if (!L.toString().equals(Long.toString(l)))
+                throw new RuntimeException("Long wrapper toString() failure.");
+        }
+
+        // float wrapper
+        for(int x=0; x<100; x++) {
+            float f = generator.nextFloat();
+            Float F = new Float(f);
+            if (!F.toString().equals(Float.toString(f)))
+                throw new RuntimeException("Float wrapper toString() failure.");
+        }
+
+        // double wrapper
+        for(int x=0; x<100; x++) {
+            double d = generator.nextDouble();
+            Double D = new Double(d);
+            if (!D.toString().equals(Double.toString(d)))
+                throw new RuntimeException("Double wrapper toString() failure.");
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/AnnotationTypeMismatchException/FoundType.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6179014
+ * @summary AnnotationTypeMismatchException.foundType method shouldn't loop.
+ * @author Scott Seligman
+ * @run main/timeout=30 FoundType
+ */
+
+import java.lang.annotation.*;
+
+public class FoundType {
+
+    private static final String TYPE = "a.halting.Problem";
+
+    public static void main(String[] args) {
+        AnnotationTypeMismatchException ex =
+            new AnnotationTypeMismatchException(null, TYPE);
+        if (!TYPE.equals(ex.foundType()))
+            throw new Error();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/Missing/A.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * Class to have a missing annotation applied for running MissingTest.
+ */
+@Missing
+@Marker
+public class A {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/Missing/B.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * Class to have an indirectly missing annotation applied for for
+ * running MisssingTest.
+ */
+@MissingWrapper(@Missing)
+@Marker
+public class B {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/Missing/C.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * Class to have a missing annotation applied for running MissingTest.
+ */
+public class C {
+    public void method1(@Missing @Marker Object param1) {
+        return;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/Missing/D.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * Class to have a missing annotation applied for running MissingTest.
+ */
+public class D {
+    public void method1(@MissingWrapper(@Missing) @Marker Object param1) {
+        return;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/Missing/Marker.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.*;
+
+/**
+ * A marker annotation.  Used so that at least one annotation will be
+ * present on the classes tested by MissingTest.
+ */
+@Retention(RUNTIME)
+public @interface Marker {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/Missing/Missing.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.*;
+
+/**
+ * The class file for this annotation type is missing when MissingTest
+ * is run.
+ */
+@Retention(RUNTIME)
+public @interface Missing {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/Missing/MissingTest.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6322301
+ * @summary Verify when missing annotation classes cause exceptions
+ * @author Joseph D. Darcy
+ * @compile MissingTest.java A.java B.java C.java D.java Marker.java Missing.java MissingWrapper.java
+ * @clean Missing
+ * @run main MissingTest
+ */
+
+import java.lang.reflect.*;
+
+/**
+ * This test verifies that a missing annotation class leads to the
+ * expected exceptional behavior; a missing directly applied
+ * annotation is currently ignored but a missing annotation value
+ * inside another annotation throws an exception.
+ *
+ * To be run as intended, the annotation type Missing should *not* be
+ * on the classpath when the test is run; with jtreg, it is deleted by
+ * the @clean directive.
+ */
+public class MissingTest {
+    /**
+     * For the annotated element argument, get all its annotations and
+     * see whether or not an exception is throw upon reading the
+     * annotations.  Additionally, verify at least one annotation is
+     * present.
+     */
+    private static void testAnnotation(AnnotatedElement element,
+                                boolean exceptionExpected) {
+        java.lang.annotation.Annotation[] annotations;
+        try {
+            annotations = element.getAnnotations();
+            if (exceptionExpected) {
+                System.err.println("Error: Did not get an exception reading annotations on "
+                                   + element);
+                System.err.println("Annotations found: "
+                                   + java.util.Arrays.toString(annotations));
+                throw new RuntimeException();
+            }
+            if (annotations.length == 0) {
+                System.err.println("Error: no annotations found on " + element);
+                throw new RuntimeException();
+            }
+        } catch (Throwable t) {
+            if (!exceptionExpected) {
+                System.err.println("Error: Got an unexpected exception reading annotations on "
+                                   + element);
+                throw new RuntimeException(t);
+            }
+        }
+    }
+
+    /**
+     * For the annotated element argument, get all its annotations and
+     * see whether or not an exception is throw upon reading the
+     * annotations.  Additionally, verify at least one annotation is
+     * present.
+     */
+    private static void testParameterAnnotation(Method m,
+                                                boolean exceptionExpected) {
+        java.lang.annotation.Annotation[][] annotationsArray;
+        try {
+            annotationsArray = m.getParameterAnnotations();
+            if (exceptionExpected) {
+                System.err.println("Error: Did not get an exception reading annotations on method"
+                                   + m);
+                System.err.println("Annotations found: "
+                                   + java.util.Arrays.toString(annotationsArray));
+                throw new RuntimeException();
+            }
+            if (annotationsArray.length == 0 ) {
+                System.err.println("Error: no parameters for " + m);
+                throw new RuntimeException();
+            } else {
+                java.lang.annotation.Annotation[] annotations = annotationsArray[0];
+                if (annotations.length == 0) {
+                    System.err.println("Error: no annotations on " + m);
+                    throw new RuntimeException();
+                }
+            }
+        } catch (Throwable t) {
+            if (!exceptionExpected) {
+                System.err.println("Error: Got an unexpected exception reading annotations on "
+                                   + m);
+                throw new RuntimeException(t);
+            }
+        }
+    }
+
+    public static void main(String argv[]) throws Exception {
+        // Class A has a directly applied annotation whose class is
+        // missing.
+        testAnnotation(A.class, false);
+
+        // Class B has a directly applied annotation whose value
+        // includes to an annotation class that is missing.
+        testAnnotation(B.class, true);
+
+
+        // Class C has a directly applied parameter annotation whose
+        // class is missing.
+        testParameterAnnotation(C.class.getDeclaredMethod("method1", Object.class),
+                                false);
+
+        // Class D has a directly applied parameter annotation whose value
+        // includes to an annotation class that is missing.
+        testParameterAnnotation(D.class.getDeclaredMethod("method1", Object.class),
+                                true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/Missing/MissingWrapper.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.*;
+
+/**
+ * Annotation wrapper around an annotation whose class will be missing
+ * when MissingTest is run.
+ */
+@Retention(RUNTIME)
+public @interface MissingWrapper {
+    Missing value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/PackageMain.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.annotation.Documented;
+
+public class PackageMain {
+    public static void main(String[] args) throws Exception {
+        Class<?> c = Class.forName("foo.bar.Baz");
+        System.out.println("c=" + c);
+        System.out.println("cl=" + c.getClassLoader());
+        Package p = c.getPackage();
+        System.out.println("p=" + p);
+        Documented d = p.getAnnotation(Documented.class);
+        if (d == null) throw new Error();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/RecursiveAnnotation.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     5037685
+ * @summary Under certain circumstances, recursive annotations disappeared
+ * @author  Josh Bloch
+ */
+
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+@Rat public class RecursiveAnnotation {
+    public static void main(String[] args) {
+        if (!RecursiveAnnotation.class.isAnnotationPresent(Rat.class))
+            throw new RuntimeException("RecursiveAnnotation");
+
+        if (!Rat.class.isAnnotationPresent(Rat.class))
+            throw new RuntimeException("Rat");
+    }
+}
+
+@Retention(RUNTIME) @Rat @interface Rat { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/UnitTest.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,4983 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     4906359 4963461 4965058 4965039 4986770
+ * @summary Unit test for annotation reading
+ * @author  Josh Bloch
+ * @compile -source 1.5 UnitTest.java
+ * @run main UnitTest
+ */
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.*;
+import java.util.*;
+import java.lang.reflect.*;
+import java.io.*;
+
+public class UnitTest {
+    private static final Class[] X = new Class[0];
+    private static final Class[] Y = { int.class };
+
+    static int numTests = 0;
+
+    public static void main(String[] args) throws Exception {
+
+        // *** TESTS ON ANNOTATED METHODS ***
+
+        // MULTIMEMBER SCALAR TYPES ON METHOD
+        checkScalarTypes(UnitTest.class.getMethod("scalarTypesMethod", X));
+        checkScalarTypesOverrideDefault(UnitTest.class.getMethod("scalarTypesOverrideDefaultMethod", X));
+        checkScalarTypesAcceptDefault(UnitTest.class.getMethod("scalarTypesAcceptDefaultMethod", X));
+
+        // MULTIMEMBER ARRAY TYPES ON METHOD
+        checkArrayTypes0(UnitTest.class.getMethod("emptyArrayTypesMethod", X));
+        checkArrayTypes1(UnitTest.class.getMethod("singleElementArrayTypesMethod", X));
+        checkArrayTypes2(UnitTest.class.getMethod("twoElementArrayTypesMethod", X));
+        checkArrayTypesAcceptDefault(UnitTest.class.getMethod("arrayTypesAcceptDefaultMethod", X));
+        checkArrayTypesOverrideDefault(UnitTest.class.getMethod("arrayTypesOverrideDefaultMethod", X));
+
+        // MARKER TYPE ON METHOD
+        checkMarker(UnitTest.class.getMethod("markerMethod", X));
+
+        // SINGLE-MEMBER SCALAR TYPES ON METHOD
+        checkSingleMemberByte(UnitTest.class.getMethod("SingleMemberByte", X));
+        checkSingleMemberShort(UnitTest.class.getMethod("SingleMemberShort", X));
+        checkSingleMemberInt(UnitTest.class.getMethod("SingleMemberInt", X));
+        checkSingleMemberLong(UnitTest.class.getMethod("SingleMemberLong", X));
+        checkSingleMemberChar(UnitTest.class.getMethod("SingleMemberChar", X));
+        checkSingleMemberFloat(UnitTest.class.getMethod("SingleMemberFloat", X));
+        checkSingleMemberDouble(UnitTest.class.getMethod("SingleMemberDouble", X));
+        checkSingleMemberBoolean(UnitTest.class.getMethod("SingleMemberBoolean", X));
+        checkSingleMemberString(UnitTest.class.getMethod("SingleMemberString", X));
+        checkSingleMemberClass(UnitTest.class.getMethod("SingleMemberClass", X));
+        checkSingleMemberEnum(UnitTest.class.getMethod("SingleMemberEnum", X));
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-OVERRIDE ON METHOD
+        checkSingleMemberByteOvrdDef(UnitTest.class.getMethod("SingleMemberByteOvrdDef", X));
+        checkSingleMemberShortOvrdDef(UnitTest.class.getMethod("SingleMemberShortOvrdDef", X));
+        checkSingleMemberIntOvrdDef(UnitTest.class.getMethod("SingleMemberIntOvrdDef", X));
+        checkSingleMemberLongOvrdDef(UnitTest.class.getMethod("SingleMemberLongOvrdDef", X));
+        checkSingleMemberCharOvrdDef(UnitTest.class.getMethod("SingleMemberCharOvrdDef", X));
+        checkSingleMemberFloatOvrdDef(UnitTest.class.getMethod("SingleMemberFloatOvrdDef", X));
+        checkSingleMemberDoubleOvrdDef(UnitTest.class.getMethod("SingleMemberDoubleOvrdDef", X));
+        checkSingleMemberBooleanOvrdDef(UnitTest.class.getMethod("SingleMemberBooleanOvrdDef", X));
+        checkSingleMemberStringOvrdDef(UnitTest.class.getMethod("SingleMemberStringOvrdDef", X));
+        checkSingleMemberClassOvrdDef(UnitTest.class.getMethod("SingleMemberClassOvrdDef", X));
+        checkSingleMemberEnumOvrdDef(UnitTest.class.getMethod("SingleMemberEnumOvrdDef", X));
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-ACCEPT ON METHOD
+        checkSingleMemberByteAcceptDef(UnitTest.class.getMethod("SingleMemberByteAcceptDef", X));
+        checkSingleMemberShortAcceptDef(UnitTest.class.getMethod("SingleMemberShortAcceptDef", X));
+        checkSingleMemberIntAcceptDef(UnitTest.class.getMethod("SingleMemberIntAcceptDef", X));
+        checkSingleMemberLongAcceptDef(UnitTest.class.getMethod("SingleMemberLongAcceptDef", X));
+        checkSingleMemberCharAcceptDef(UnitTest.class.getMethod("SingleMemberCharAcceptDef", X));
+        checkSingleMemberFloatAcceptDef(UnitTest.class.getMethod("SingleMemberFloatAcceptDef", X));
+        checkSingleMemberDoubleAcceptDef(UnitTest.class.getMethod("SingleMemberDoubleAcceptDef", X));
+        checkSingleMemberBooleanAcceptDef(UnitTest.class.getMethod("SingleMemberBooleanAcceptDef", X));
+        checkSingleMemberStringAcceptDef(UnitTest.class.getMethod("SingleMemberStringAcceptDef", X));
+        checkSingleMemberClassAcceptDef(UnitTest.class.getMethod("SingleMemberClassAcceptDef", X));
+        checkSingleMemberEnumAcceptDef(UnitTest.class.getMethod("SingleMemberEnumAcceptDef", X));
+
+        // SINGLE-MEMBER ARRAY TYPES (EMPTY ARRAY) ON METHOD
+        checkSingleMemberByteArrEmpty(UnitTest.class.getMethod("SingleMemberByteArrEmpty", X));
+        checkSingleMemberShortArrEmpty(UnitTest.class.getMethod("SingleMemberShortArrEmpty", X));
+        checkSingleMemberIntArrEmpty(UnitTest.class.getMethod("SingleMemberIntArrEmpty", X));
+        checkSingleMemberLongArrEmpty(UnitTest.class.getMethod("SingleMemberLongArrEmpty", X));
+        checkSingleMemberCharArrEmpty(UnitTest.class.getMethod("SingleMemberCharArrEmpty", X));
+        checkSingleMemberFloatArrEmpty(UnitTest.class.getMethod("SingleMemberFloatArrEmpty", X));
+        checkSingleMemberDoubleArrEmpty(UnitTest.class.getMethod("SingleMemberDoubleArrEmpty", X));
+        checkSingleMemberBooleanArrEmpty(UnitTest.class.getMethod("SingleMemberBooleanArrEmpty", X));
+        checkSingleMemberStringArrEmpty(UnitTest.class.getMethod("SingleMemberStringArrEmpty", X));
+        checkSingleMemberClassArrEmpty(UnitTest.class.getMethod("SingleMemberClassArrEmpty", X));
+        checkSingleMemberEnumArrEmpty(UnitTest.class.getMethod("SingleMemberEnumArrEmpty", X));
+
+        // SINGLE-MEMBER ARRAY TYPES (ONE-ELEMENT ARRAY) ON METHOD
+        checkSingleMemberByteArrOne(UnitTest.class.getMethod("SingleMemberByteArrOne", X));
+        checkSingleMemberShortArrOne(UnitTest.class.getMethod("SingleMemberShortArrOne", X));
+        checkSingleMemberIntArrOne(UnitTest.class.getMethod("SingleMemberIntArrOne", X));
+        checkSingleMemberLongArrOne(UnitTest.class.getMethod("SingleMemberLongArrOne", X));
+        checkSingleMemberCharArrOne(UnitTest.class.getMethod("SingleMemberCharArrOne", X));
+        checkSingleMemberFloatArrOne(UnitTest.class.getMethod("SingleMemberFloatArrOne", X));
+        checkSingleMemberDoubleArrOne(UnitTest.class.getMethod("SingleMemberDoubleArrOne", X));
+        checkSingleMemberBooleanArrOne(UnitTest.class.getMethod("SingleMemberBooleanArrOne", X));
+        checkSingleMemberStringArrOne(UnitTest.class.getMethod("SingleMemberStringArrOne", X));
+        checkSingleMemberClassArrOne(UnitTest.class.getMethod("SingleMemberClassArrOne", X));
+        checkSingleMemberEnumArrOne(UnitTest.class.getMethod("SingleMemberEnumArrOne", X));
+
+        // SINGLE-MEMBER ARRAY TYPES (TWO-ELEMENT ARRAY) ON METHOD
+        checkSingleMemberByteArrTwo(UnitTest.class.getMethod("SingleMemberByteArrTwo", X));
+        checkSingleMemberShortArrTwo(UnitTest.class.getMethod("SingleMemberShortArrTwo", X));
+        checkSingleMemberIntArrTwo(UnitTest.class.getMethod("SingleMemberIntArrTwo", X));
+        checkSingleMemberLongArrTwo(UnitTest.class.getMethod("SingleMemberLongArrTwo", X));
+        checkSingleMemberCharArrTwo(UnitTest.class.getMethod("SingleMemberCharArrTwo", X));
+        checkSingleMemberFloatArrTwo(UnitTest.class.getMethod("SingleMemberFloatArrTwo", X));
+        checkSingleMemberDoubleArrTwo(UnitTest.class.getMethod("SingleMemberDoubleArrTwo", X));
+        checkSingleMemberBooleanArrTwo(UnitTest.class.getMethod("SingleMemberBooleanArrTwo", X));
+        checkSingleMemberStringArrTwo(UnitTest.class.getMethod("SingleMemberStringArrTwo", X));
+        checkSingleMemberClassArrTwo(UnitTest.class.getMethod("SingleMemberClassArrTwo", X));
+        checkSingleMemberEnumArrTwo(UnitTest.class.getMethod("SingleMemberEnumArrTwo", X));
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (OVERRIDE)ON METHOD
+        checkSingleMemberByteArrOvrdDef(UnitTest.class.getMethod("SingleMemberByteArrOvrdDef", X));
+        checkSingleMemberShortArrOvrdDef(UnitTest.class.getMethod("SingleMemberShortArrOvrdDef", X));
+        checkSingleMemberIntArrOvrdDef(UnitTest.class.getMethod("SingleMemberIntArrOvrdDef", X));
+        checkSingleMemberLongArrOvrdDef(UnitTest.class.getMethod("SingleMemberLongArrOvrdDef", X));
+        checkSingleMemberCharArrOvrdDef(UnitTest.class.getMethod("SingleMemberCharArrOvrdDef", X));
+        checkSingleMemberFloatArrOvrdDef(UnitTest.class.getMethod("SingleMemberFloatArrOvrdDef", X));
+        checkSingleMemberDoubleArrOvrdDef(UnitTest.class.getMethod("SingleMemberDoubleArrOvrdDef", X));
+        checkSingleMemberBooleanArrOvrdDef(UnitTest.class.getMethod("SingleMemberBooleanArrOvrdDef", X));
+        checkSingleMemberStringArrOvrdDef(UnitTest.class.getMethod("SingleMemberStringArrOvrdDef", X));
+        checkSingleMemberClassArrOvrdDef(UnitTest.class.getMethod("SingleMemberClassArrOvrdDef", X));
+        checkSingleMemberEnumArrOvrdDef(UnitTest.class.getMethod("SingleMemberEnumArrOvrdDef", X));
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (ACCEPT)ON METHOD
+        checkSingleMemberByteArrAcceptDef(UnitTest.class.getMethod("SingleMemberByteArrAcceptDef", X));
+        checkSingleMemberShortArrAcceptDef(UnitTest.class.getMethod("SingleMemberShortArrAcceptDef", X));
+        checkSingleMemberIntArrAcceptDef(UnitTest.class.getMethod("SingleMemberIntArrAcceptDef", X));
+        checkSingleMemberLongArrAcceptDef(UnitTest.class.getMethod("SingleMemberLongArrAcceptDef", X));
+        checkSingleMemberCharArrAcceptDef(UnitTest.class.getMethod("SingleMemberCharArrAcceptDef", X));
+        checkSingleMemberFloatArrAcceptDef(UnitTest.class.getMethod("SingleMemberFloatArrAcceptDef", X));
+        checkSingleMemberDoubleArrAcceptDef(UnitTest.class.getMethod("SingleMemberDoubleArrAcceptDef", X));
+        checkSingleMemberBooleanArrAcceptDef(UnitTest.class.getMethod("SingleMemberBooleanArrAcceptDef", X));
+        checkSingleMemberStringArrAcceptDef(UnitTest.class.getMethod("SingleMemberStringArrAcceptDef", X));
+        checkSingleMemberClassArrAcceptDef(UnitTest.class.getMethod("SingleMemberClassArrAcceptDef", X));
+        checkSingleMemberEnumArrAcceptDef(UnitTest.class.getMethod("SingleMemberEnumArrAcceptDef", X));
+
+        // *** TESTS ON ANNOTATED FIELDS ***
+
+        // MULTIMEMBER SCALAR TYPES ON FIELD
+        checkScalarTypes(UnitTest.class.getField("scalarTypesField"));
+        checkScalarTypesAcceptDefault(UnitTest.class.getField("scalarTypesAcceptDefaultField"));
+        checkScalarTypesOverrideDefault(UnitTest.class.getField("scalarTypesOverrideDefaultField"));
+
+        // MULTIMEMBER ARRAY TYPES ON FIELD
+        checkArrayTypes0(UnitTest.class.getField("emptyArrayTypesField"));
+        checkArrayTypes1(UnitTest.class.getField("singleElementArrayTypesField"));
+        checkArrayTypes2(UnitTest.class.getField("twoElementArrayTypesField"));
+        checkArrayTypesAcceptDefault(UnitTest.class.getField("arrayTypesAcceptDefaultField"));
+        checkArrayTypesOverrideDefault(UnitTest.class.getField("arrayTypesOverrideDefaultField"));
+
+        // MARKER TYPE ON FIELD
+        checkMarker(UnitTest.class.getField("markerField"));
+
+        // SINGLE-MEMBER SCALAR TYPES ON FIELD
+        checkSingleMemberByte(UnitTest.class.getField("SingleMemberByteField"));
+        checkSingleMemberShort(UnitTest.class.getField("SingleMemberShortField"));
+        checkSingleMemberInt(UnitTest.class.getField("SingleMemberIntField"));
+        checkSingleMemberLong(UnitTest.class.getField("SingleMemberLongField"));
+        checkSingleMemberChar(UnitTest.class.getField("SingleMemberCharField"));
+        checkSingleMemberFloat(UnitTest.class.getField("SingleMemberFloatField"));
+        checkSingleMemberDouble(UnitTest.class.getField("SingleMemberDoubleField"));
+        checkSingleMemberBoolean(UnitTest.class.getField("SingleMemberBooleanField"));
+        checkSingleMemberString(UnitTest.class.getField("SingleMemberStringField"));
+        checkSingleMemberClass(UnitTest.class.getField("SingleMemberClassField"));
+        checkSingleMemberEnum(UnitTest.class.getField("SingleMemberEnumField"));
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-OVERRIDE ON FIELD
+        checkSingleMemberByteOvrdDef(UnitTest.class.getField("SingleMemberByteOvrdDefField"));
+        checkSingleMemberShortOvrdDef(UnitTest.class.getField("SingleMemberShortOvrdDefField"));
+        checkSingleMemberIntOvrdDef(UnitTest.class.getField("SingleMemberIntOvrdDefField"));
+        checkSingleMemberLongOvrdDef(UnitTest.class.getField("SingleMemberLongOvrdDefField"));
+        checkSingleMemberCharOvrdDef(UnitTest.class.getField("SingleMemberCharOvrdDefField"));
+        checkSingleMemberFloatOvrdDef(UnitTest.class.getField("SingleMemberFloatOvrdDefField"));
+        checkSingleMemberDoubleOvrdDef(UnitTest.class.getField("SingleMemberDoubleOvrdDefField"));
+        checkSingleMemberBooleanOvrdDef(UnitTest.class.getField("SingleMemberBooleanOvrdDefField"));
+        checkSingleMemberStringOvrdDef(UnitTest.class.getField("SingleMemberStringOvrdDefField"));
+        checkSingleMemberClassOvrdDef(UnitTest.class.getField("SingleMemberClassOvrdDefField"));
+        checkSingleMemberEnumOvrdDef(UnitTest.class.getField("SingleMemberEnumOvrdDefField"));
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-ACCEPT ON FIELD
+        checkSingleMemberByteAcceptDef(UnitTest.class.getField("SingleMemberByteAcceptDefField"));
+        checkSingleMemberShortAcceptDef(UnitTest.class.getField("SingleMemberShortAcceptDefField"));
+        checkSingleMemberIntAcceptDef(UnitTest.class.getField("SingleMemberIntAcceptDefField"));
+        checkSingleMemberLongAcceptDef(UnitTest.class.getField("SingleMemberLongAcceptDefField"));
+        checkSingleMemberCharAcceptDef(UnitTest.class.getField("SingleMemberCharAcceptDefField"));
+        checkSingleMemberFloatAcceptDef(UnitTest.class.getField("SingleMemberFloatAcceptDefField"));
+        checkSingleMemberDoubleAcceptDef(UnitTest.class.getField("SingleMemberDoubleAcceptDefField"));
+        checkSingleMemberBooleanAcceptDef(UnitTest.class.getField("SingleMemberBooleanAcceptDefField"));
+        checkSingleMemberStringAcceptDef(UnitTest.class.getField("SingleMemberStringAcceptDefField"));
+        checkSingleMemberClassAcceptDef(UnitTest.class.getField("SingleMemberClassAcceptDefField"));
+        checkSingleMemberEnumAcceptDef(UnitTest.class.getField("SingleMemberEnumAcceptDefField"));
+
+        // SINGLE-MEMBER ARRAY TYPES (EMPTY ARRAY) ON FIELD
+        checkSingleMemberByteArrEmpty(UnitTest.class.getField("SingleMemberByteArrEmptyField"));
+        checkSingleMemberShortArrEmpty(UnitTest.class.getField("SingleMemberShortArrEmptyField"));
+        checkSingleMemberIntArrEmpty(UnitTest.class.getField("SingleMemberIntArrEmptyField"));
+        checkSingleMemberLongArrEmpty(UnitTest.class.getField("SingleMemberLongArrEmptyField"));
+        checkSingleMemberCharArrEmpty(UnitTest.class.getField("SingleMemberCharArrEmptyField"));
+        checkSingleMemberFloatArrEmpty(UnitTest.class.getField("SingleMemberFloatArrEmptyField"));
+        checkSingleMemberDoubleArrEmpty(UnitTest.class.getField("SingleMemberDoubleArrEmptyField"));
+        checkSingleMemberBooleanArrEmpty(UnitTest.class.getField("SingleMemberBooleanArrEmptyField"));
+        checkSingleMemberStringArrEmpty(UnitTest.class.getField("SingleMemberStringArrEmptyField"));
+        checkSingleMemberClassArrEmpty(UnitTest.class.getField("SingleMemberClassArrEmptyField"));
+        checkSingleMemberEnumArrEmpty(UnitTest.class.getField("SingleMemberEnumArrEmptyField"));
+
+        // SINGLE-MEMBER ARRAY TYPES (ONE-ELEMENT ARRAY) ON FIELD
+        checkSingleMemberByteArrOne(UnitTest.class.getField("SingleMemberByteArrOneField"));
+        checkSingleMemberShortArrOne(UnitTest.class.getField("SingleMemberShortArrOneField"));
+        checkSingleMemberIntArrOne(UnitTest.class.getField("SingleMemberIntArrOneField"));
+        checkSingleMemberLongArrOne(UnitTest.class.getField("SingleMemberLongArrOneField"));
+        checkSingleMemberCharArrOne(UnitTest.class.getField("SingleMemberCharArrOneField"));
+        checkSingleMemberFloatArrOne(UnitTest.class.getField("SingleMemberFloatArrOneField"));
+        checkSingleMemberDoubleArrOne(UnitTest.class.getField("SingleMemberDoubleArrOneField"));
+        checkSingleMemberBooleanArrOne(UnitTest.class.getField("SingleMemberBooleanArrOneField"));
+        checkSingleMemberStringArrOne(UnitTest.class.getField("SingleMemberStringArrOneField"));
+        checkSingleMemberClassArrOne(UnitTest.class.getField("SingleMemberClassArrOneField"));
+        checkSingleMemberEnumArrOne(UnitTest.class.getField("SingleMemberEnumArrOneField"));
+
+        // SINGLE-MEMBER ARRAY TYPES (TWO-ELEMENT ARRAY) ON FIELD
+        checkSingleMemberByteArrTwo(UnitTest.class.getField("SingleMemberByteArrTwoField"));
+        checkSingleMemberShortArrTwo(UnitTest.class.getField("SingleMemberShortArrTwoField"));
+        checkSingleMemberIntArrTwo(UnitTest.class.getField("SingleMemberIntArrTwoField"));
+        checkSingleMemberLongArrTwo(UnitTest.class.getField("SingleMemberLongArrTwoField"));
+        checkSingleMemberCharArrTwo(UnitTest.class.getField("SingleMemberCharArrTwoField"));
+        checkSingleMemberFloatArrTwo(UnitTest.class.getField("SingleMemberFloatArrTwoField"));
+        checkSingleMemberDoubleArrTwo(UnitTest.class.getField("SingleMemberDoubleArrTwoField"));
+        checkSingleMemberBooleanArrTwo(UnitTest.class.getField("SingleMemberBooleanArrTwoField"));
+        checkSingleMemberStringArrTwo(UnitTest.class.getField("SingleMemberStringArrTwoField"));
+        checkSingleMemberClassArrTwo(UnitTest.class.getField("SingleMemberClassArrTwoField"));
+        checkSingleMemberEnumArrTwo(UnitTest.class.getField("SingleMemberEnumArrTwoField"));
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (OVERRIDE)ON FIELD
+        checkSingleMemberByteArrOvrdDef(UnitTest.class.getField("SingleMemberByteArrOvrdDefField"));
+        checkSingleMemberShortArrOvrdDef(UnitTest.class.getField("SingleMemberShortArrOvrdDefField"));
+        checkSingleMemberIntArrOvrdDef(UnitTest.class.getField("SingleMemberIntArrOvrdDefField"));
+        checkSingleMemberLongArrOvrdDef(UnitTest.class.getField("SingleMemberLongArrOvrdDefField"));
+        checkSingleMemberCharArrOvrdDef(UnitTest.class.getField("SingleMemberCharArrOvrdDefField"));
+        checkSingleMemberFloatArrOvrdDef(UnitTest.class.getField("SingleMemberFloatArrOvrdDefField"));
+        checkSingleMemberDoubleArrOvrdDef(UnitTest.class.getField("SingleMemberDoubleArrOvrdDefField"));
+        checkSingleMemberBooleanArrOvrdDef(UnitTest.class.getField("SingleMemberBooleanArrOvrdDefField"));
+        checkSingleMemberStringArrOvrdDef(UnitTest.class.getField("SingleMemberStringArrOvrdDefField"));
+        checkSingleMemberClassArrOvrdDef(UnitTest.class.getField("SingleMemberClassArrOvrdDefField"));
+        checkSingleMemberEnumArrOvrdDef(UnitTest.class.getField("SingleMemberEnumArrOvrdDefField"));
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (ACCEPT)ON FIELD
+        checkSingleMemberByteArrAcceptDef(UnitTest.class.getField("SingleMemberByteArrAcceptDefField"));
+        checkSingleMemberShortArrAcceptDef(UnitTest.class.getField("SingleMemberShortArrAcceptDefField"));
+        checkSingleMemberIntArrAcceptDef(UnitTest.class.getField("SingleMemberIntArrAcceptDefField"));
+        checkSingleMemberLongArrAcceptDef(UnitTest.class.getField("SingleMemberLongArrAcceptDefField"));
+        checkSingleMemberCharArrAcceptDef(UnitTest.class.getField("SingleMemberCharArrAcceptDefField"));
+        checkSingleMemberFloatArrAcceptDef(UnitTest.class.getField("SingleMemberFloatArrAcceptDefField"));
+        checkSingleMemberDoubleArrAcceptDef(UnitTest.class.getField("SingleMemberDoubleArrAcceptDefField"));
+        checkSingleMemberBooleanArrAcceptDef(UnitTest.class.getField("SingleMemberBooleanArrAcceptDefField"));
+        checkSingleMemberStringArrAcceptDef(UnitTest.class.getField("SingleMemberStringArrAcceptDefField"));
+        checkSingleMemberClassArrAcceptDef(UnitTest.class.getField("SingleMemberClassArrAcceptDefField"));
+        checkSingleMemberEnumArrAcceptDef(UnitTest.class.getField("SingleMemberEnumArrAcceptDefField"));
+
+        // *** TESTS ON ANNOTATED ENUM CONSTS ***
+
+        // MULTIMEMBER SCALAR TYPES ON ENUM CONST
+        checkScalarTypes(TestType.class.getField("scalarTypesField"));
+        checkScalarTypesAcceptDefault(TestType.class.getField("scalarTypesAcceptDefaultField"));
+        checkScalarTypesOverrideDefault(TestType.class.getField("scalarTypesOverrideDefaultField"));
+
+        // MULTIMEMBER ARRAY TYPES ON ENUM CONST
+        checkArrayTypes0(TestType.class.getField("emptyArrayTypesField"));
+        checkArrayTypes1(TestType.class.getField("singleElementArrayTypesField"));
+        checkArrayTypes2(TestType.class.getField("twoElementArrayTypesField"));
+        checkArrayTypesAcceptDefault(TestType.class.getField("arrayTypesAcceptDefaultField"));
+        checkArrayTypesOverrideDefault(TestType.class.getField("arrayTypesOverrideDefaultField"));
+
+        // MARKER TYPE ON CLASS
+        checkMarker(TestType.class.getField("marker"));
+
+        // SINGLE-MEMBER SCALAR TYPES ON CLASS
+        checkSingleMemberByte(TestType.class.getField("SingleMemberByte"));
+        checkSingleMemberShort(TestType.class.getField("SingleMemberShort"));
+        checkSingleMemberInt(TestType.class.getField("SingleMemberInt"));
+        checkSingleMemberLong(TestType.class.getField("SingleMemberLong"));
+        checkSingleMemberChar(TestType.class.getField("SingleMemberChar"));
+        checkSingleMemberFloat(TestType.class.getField("SingleMemberFloat"));
+        checkSingleMemberDouble(TestType.class.getField("SingleMemberDouble"));
+        checkSingleMemberBoolean(TestType.class.getField("SingleMemberBoolean"));
+        checkSingleMemberString(TestType.class.getField("SingleMemberString"));
+        checkSingleMemberClass(TestType.class.getField("SingleMemberClass"));
+        checkSingleMemberEnum(TestType.class.getField("SingleMemberEnum"));
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-OVERRIDE ON CLASS
+        checkSingleMemberByteOvrdDef(TestType.class.getField("SingleMemberByteOvrdDef"));
+        checkSingleMemberShortOvrdDef(TestType.class.getField("SingleMemberShortOvrdDef"));
+        checkSingleMemberIntOvrdDef(TestType.class.getField("SingleMemberIntOvrdDef"));
+        checkSingleMemberLongOvrdDef(TestType.class.getField("SingleMemberLongOvrdDef"));
+        checkSingleMemberCharOvrdDef(TestType.class.getField("SingleMemberCharOvrdDef"));
+        checkSingleMemberFloatOvrdDef(TestType.class.getField("SingleMemberFloatOvrdDef"));
+        checkSingleMemberDoubleOvrdDef(TestType.class.getField("SingleMemberDoubleOvrdDef"));
+        checkSingleMemberBooleanOvrdDef(TestType.class.getField("SingleMemberBooleanOvrdDef"));
+        checkSingleMemberStringOvrdDef(TestType.class.getField("SingleMemberStringOvrdDef"));
+        checkSingleMemberClassOvrdDef(TestType.class.getField("SingleMemberClassOvrdDef"));
+        checkSingleMemberEnumOvrdDef(TestType.class.getField("SingleMemberEnumOvrdDef"));
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-ACCEPT ON CLASS
+        checkSingleMemberByteAcceptDef(TestType.class.getField("SingleMemberByteAcceptDef"));
+        checkSingleMemberShortAcceptDef(TestType.class.getField("SingleMemberShortAcceptDef"));
+        checkSingleMemberIntAcceptDef(TestType.class.getField("SingleMemberIntAcceptDef"));
+        checkSingleMemberLongAcceptDef(TestType.class.getField("SingleMemberLongAcceptDef"));
+        checkSingleMemberCharAcceptDef(TestType.class.getField("SingleMemberCharAcceptDef"));
+        checkSingleMemberFloatAcceptDef(TestType.class.getField("SingleMemberFloatAcceptDef"));
+        checkSingleMemberDoubleAcceptDef(TestType.class.getField("SingleMemberDoubleAcceptDef"));
+        checkSingleMemberBooleanAcceptDef(TestType.class.getField("SingleMemberBooleanAcceptDef"));
+        checkSingleMemberStringAcceptDef(TestType.class.getField("SingleMemberStringAcceptDef"));
+        checkSingleMemberClassAcceptDef(TestType.class.getField("SingleMemberClassAcceptDef"));
+        checkSingleMemberEnumAcceptDef(TestType.class.getField("SingleMemberEnumAcceptDef"));
+
+        // SINGLE-MEMBER ARRAY TYPES (TestType.class.getField("EMPTY ARRAY) ON CLASS
+        checkSingleMemberByteArrEmpty(TestType.class.getField("SingleMemberByteArrEmpty"));
+        checkSingleMemberShortArrEmpty(TestType.class.getField("SingleMemberShortArrEmpty"));
+        checkSingleMemberIntArrEmpty(TestType.class.getField("SingleMemberIntArrEmpty"));
+        checkSingleMemberLongArrEmpty(TestType.class.getField("SingleMemberLongArrEmpty"));
+        checkSingleMemberCharArrEmpty(TestType.class.getField("SingleMemberCharArrEmpty"));
+        checkSingleMemberFloatArrEmpty(TestType.class.getField("SingleMemberFloatArrEmpty"));
+        checkSingleMemberDoubleArrEmpty(TestType.class.getField("SingleMemberDoubleArrEmpty"));
+        checkSingleMemberBooleanArrEmpty(TestType.class.getField("SingleMemberBooleanArrEmpty"));
+        checkSingleMemberStringArrEmpty(TestType.class.getField("SingleMemberStringArrEmpty"));
+        checkSingleMemberClassArrEmpty(TestType.class.getField("SingleMemberClassArrEmpty"));
+        checkSingleMemberEnumArrEmpty(TestType.class.getField("SingleMemberEnumArrEmpty"));
+
+        // SINGLE-MEMBER ARRAY TYPES (TestType.class.getField("ONE-ELEMENT ARRAY) ON CLASS
+        checkSingleMemberByteArrOne(TestType.class.getField("SingleMemberByteArrOne"));
+        checkSingleMemberShortArrOne(TestType.class.getField("SingleMemberShortArrOne"));
+        checkSingleMemberIntArrOne(TestType.class.getField("SingleMemberIntArrOne"));
+        checkSingleMemberLongArrOne(TestType.class.getField("SingleMemberLongArrOne"));
+        checkSingleMemberCharArrOne(TestType.class.getField("SingleMemberCharArrOne"));
+        checkSingleMemberFloatArrOne(TestType.class.getField("SingleMemberFloatArrOne"));
+        checkSingleMemberDoubleArrOne(TestType.class.getField("SingleMemberDoubleArrOne"));
+        checkSingleMemberBooleanArrOne(TestType.class.getField("SingleMemberBooleanArrOne"));
+        checkSingleMemberStringArrOne(TestType.class.getField("SingleMemberStringArrOne"));
+        checkSingleMemberClassArrOne(TestType.class.getField("SingleMemberClassArrOne"));
+        checkSingleMemberEnumArrOne(TestType.class.getField("SingleMemberEnumArrOne"));
+
+        // SINGLE-MEMBER ARRAY TYPES (TestType.class.getField("TWO-ELEMENT ARRAY) ON CLASS
+        checkSingleMemberByteArrTwo(TestType.class.getField("SingleMemberByteArrTwo"));
+        checkSingleMemberShortArrTwo(TestType.class.getField("SingleMemberShortArrTwo"));
+        checkSingleMemberIntArrTwo(TestType.class.getField("SingleMemberIntArrTwo"));
+        checkSingleMemberLongArrTwo(TestType.class.getField("SingleMemberLongArrTwo"));
+        checkSingleMemberCharArrTwo(TestType.class.getField("SingleMemberCharArrTwo"));
+        checkSingleMemberFloatArrTwo(TestType.class.getField("SingleMemberFloatArrTwo"));
+        checkSingleMemberDoubleArrTwo(TestType.class.getField("SingleMemberDoubleArrTwo"));
+        checkSingleMemberBooleanArrTwo(TestType.class.getField("SingleMemberBooleanArrTwo"));
+        checkSingleMemberStringArrTwo(TestType.class.getField("SingleMemberStringArrTwo"));
+        checkSingleMemberClassArrTwo(TestType.class.getField("SingleMemberClassArrTwo"));
+        checkSingleMemberEnumArrTwo(TestType.class.getField("SingleMemberEnumArrTwo"));
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (TestType.class.getField("OVERRIDE)ON CLASS
+        checkSingleMemberByteArrOvrdDef(TestType.class.getField("SingleMemberByteArrOvrdDef"));
+        checkSingleMemberShortArrOvrdDef(TestType.class.getField("SingleMemberShortArrOvrdDef"));
+        checkSingleMemberIntArrOvrdDef(TestType.class.getField("SingleMemberIntArrOvrdDef"));
+        checkSingleMemberLongArrOvrdDef(TestType.class.getField("SingleMemberLongArrOvrdDef"));
+        checkSingleMemberCharArrOvrdDef(TestType.class.getField("SingleMemberCharArrOvrdDef"));
+        checkSingleMemberFloatArrOvrdDef(TestType.class.getField("SingleMemberFloatArrOvrdDef"));
+        checkSingleMemberDoubleArrOvrdDef(TestType.class.getField("SingleMemberDoubleArrOvrdDef"));
+        checkSingleMemberBooleanArrOvrdDef(TestType.class.getField("SingleMemberBooleanArrOvrdDef"));
+        checkSingleMemberStringArrOvrdDef(TestType.class.getField("SingleMemberStringArrOvrdDef"));
+        checkSingleMemberClassArrOvrdDef(TestType.class.getField("SingleMemberClassArrOvrdDef"));
+        checkSingleMemberEnumArrOvrdDef(TestType.class.getField("SingleMemberEnumArrOvrdDef"));
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (TestType.class.getField("ACCEPT)ON CLASS
+        checkSingleMemberByteArrAcceptDef(TestType.class.getField("SingleMemberByteArrAcceptDef"));
+        checkSingleMemberShortArrAcceptDef(TestType.class.getField("SingleMemberShortArrAcceptDef"));
+        checkSingleMemberIntArrAcceptDef(TestType.class.getField("SingleMemberIntArrAcceptDef"));
+        checkSingleMemberLongArrAcceptDef(TestType.class.getField("SingleMemberLongArrAcceptDef"));
+        checkSingleMemberCharArrAcceptDef(TestType.class.getField("SingleMemberCharArrAcceptDef"));
+        checkSingleMemberFloatArrAcceptDef(TestType.class.getField("SingleMemberFloatArrAcceptDef"));
+        checkSingleMemberDoubleArrAcceptDef(TestType.class.getField("SingleMemberDoubleArrAcceptDef"));
+        checkSingleMemberBooleanArrAcceptDef(TestType.class.getField("SingleMemberBooleanArrAcceptDef"));
+        checkSingleMemberStringArrAcceptDef(TestType.class.getField("SingleMemberStringArrAcceptDef"));
+        checkSingleMemberClassArrAcceptDef(TestType.class.getField("SingleMemberClassArrAcceptDef"));
+        checkSingleMemberEnumArrAcceptDef(TestType.class.getField("SingleMemberEnumArrAcceptDef"));
+
+        // *** TESTS ON ANNOTATED CONSTRUCTORS ***
+
+        // MULTIMEMBER SCALAR TYPES ON CONSTRUCTOR
+        checkScalarTypes(UnitTest.class.getConstructor(new Class[]{Iterator.class}));
+        checkScalarTypesOverrideDefault(UnitTest.class.getConstructor(new Class[]{Map.class}));
+        checkScalarTypesAcceptDefault(UnitTest.class.getConstructor(new Class[]{Set.class}));
+
+        // MULTIMEMBER ARRAY TYPES ON CONSTRUCTOR
+        checkArrayTypes0(UnitTest.class.getConstructor(new Class[]{List.class}));
+        checkArrayTypes1(UnitTest.class.getConstructor(new Class[]{Collection.class}));
+        checkArrayTypes2(UnitTest.class.getConstructor(new Class[]{SortedSet.class}));
+        checkArrayTypesAcceptDefault(UnitTest.class.getConstructor(new Class[]{SortedMap.class}));
+        checkArrayTypesOverrideDefault(UnitTest.class.getConstructor(new Class[]{RandomAccess.class}));
+
+        // MARKER TYPE ON CONSTRUCTOR
+        checkMarker(UnitTest.class.getConstructor(new Class[] { }));
+
+        // SINGLE-MEMBER SCALAR TYPES ON CONSTRUCTOR
+        checkSingleMemberByte(UnitTest.class.getConstructor(new Class[] { byte.class }));
+        checkSingleMemberShort(UnitTest.class.getConstructor(new Class[] { short.class }));
+        checkSingleMemberInt(UnitTest.class.getConstructor(new Class[] { int.class }));
+        checkSingleMemberLong(UnitTest.class.getConstructor(new Class[] { long.class }));
+        checkSingleMemberChar(UnitTest.class.getConstructor(new Class[] { char.class }));
+        checkSingleMemberFloat(UnitTest.class.getConstructor(new Class[] { float.class }));
+        checkSingleMemberDouble(UnitTest.class.getConstructor(new Class[] { double.class }));
+        checkSingleMemberBoolean(UnitTest.class.getConstructor(new Class[] { boolean.class }));
+        checkSingleMemberString(UnitTest.class.getConstructor(new Class[] { String.class }));
+        checkSingleMemberClass(UnitTest.class.getConstructor(new Class[] { Class.class }));
+        checkSingleMemberEnum(UnitTest.class.getConstructor(new Class[] { Enum.class }));
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-OVERRIDE ON CONSTRUCTOR
+        checkSingleMemberByteOvrdDef(UnitTest.class.getConstructor(new Class[] { byte.class, Set.class }));
+        checkSingleMemberShortOvrdDef(UnitTest.class.getConstructor(new Class[] { short.class, Set.class }));
+        checkSingleMemberIntOvrdDef(UnitTest.class.getConstructor(new Class[] { int.class, Set.class }));
+        checkSingleMemberLongOvrdDef(UnitTest.class.getConstructor(new Class[] { long.class, Set.class }));
+        checkSingleMemberCharOvrdDef(UnitTest.class.getConstructor(new Class[] { char.class, Set.class }));
+        checkSingleMemberFloatOvrdDef(UnitTest.class.getConstructor(new Class[] { float.class, Set.class }));
+        checkSingleMemberDoubleOvrdDef(UnitTest.class.getConstructor(new Class[] { double.class, Set.class }));
+        checkSingleMemberBooleanOvrdDef(UnitTest.class.getConstructor(new Class[] { boolean.class, Set.class }));
+        checkSingleMemberStringOvrdDef(UnitTest.class.getConstructor(new Class[] { String.class, Set.class }));
+        checkSingleMemberClassOvrdDef(UnitTest.class.getConstructor(new Class[] { Class.class, Set.class }));
+        checkSingleMemberEnumOvrdDef(UnitTest.class.getConstructor(new Class[] { Enum.class, Set.class }));
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-ACCEPT ON CONSTRUCTOR
+        checkSingleMemberByteAcceptDef(UnitTest.class.getConstructor(new Class[] { byte.class, Map.class }));
+        checkSingleMemberShortAcceptDef(UnitTest.class.getConstructor(new Class[] { short.class, Map.class }));
+        checkSingleMemberIntAcceptDef(UnitTest.class.getConstructor(new Class[] { int.class, Map.class }));
+        checkSingleMemberLongAcceptDef(UnitTest.class.getConstructor(new Class[] { long.class, Map.class }));
+        checkSingleMemberCharAcceptDef(UnitTest.class.getConstructor(new Class[] { char.class, Map.class }));
+        checkSingleMemberFloatAcceptDef(UnitTest.class.getConstructor(new Class[] { float.class, Map.class }));
+        checkSingleMemberDoubleAcceptDef(UnitTest.class.getConstructor(new Class[] { double.class, Map.class }));
+        checkSingleMemberBooleanAcceptDef(UnitTest.class.getConstructor(new Class[] { boolean.class, Map.class }));
+        checkSingleMemberStringAcceptDef(UnitTest.class.getConstructor(new Class[] { String.class, Map.class }));
+        checkSingleMemberClassAcceptDef(UnitTest.class.getConstructor(new Class[] { Class.class, Map.class }));
+        checkSingleMemberEnumAcceptDef(UnitTest.class.getConstructor(new Class[] { Enum.class, Map.class }));
+
+        // SINGLE-MEMBER ARRAY TYPES (EMPTY ARRAY) ON CONSTRUCTOR
+        checkSingleMemberByteArrEmpty(UnitTest.class.getConstructor(new Class[] { byte[].class }));
+        checkSingleMemberShortArrEmpty(UnitTest.class.getConstructor(new Class[] { short[].class }));
+        checkSingleMemberIntArrEmpty(UnitTest.class.getConstructor(new Class[] { int[].class }));
+        checkSingleMemberLongArrEmpty(UnitTest.class.getConstructor(new Class[] { long[].class }));
+        checkSingleMemberCharArrEmpty(UnitTest.class.getConstructor(new Class[] { char[].class }));
+        checkSingleMemberFloatArrEmpty(UnitTest.class.getConstructor(new Class[] { float[].class }));
+        checkSingleMemberDoubleArrEmpty(UnitTest.class.getConstructor(new Class[] { double[].class }));
+        checkSingleMemberBooleanArrEmpty(UnitTest.class.getConstructor(new Class[] { boolean[].class }));
+        checkSingleMemberStringArrEmpty(UnitTest.class.getConstructor(new Class[] { String[].class }));
+        checkSingleMemberClassArrEmpty(UnitTest.class.getConstructor(new Class[] { Class[].class }));
+        checkSingleMemberEnumArrEmpty(UnitTest.class.getConstructor(new Class[] { Enum[].class }));
+
+        // SINGLE-MEMBER ARRAY TYPES (ONE-ELEMENT ARRAY) ON CONSTRUCTOR
+        checkSingleMemberByteArrOne(UnitTest.class.getConstructor(new Class[] { byte[].class, Set.class }));
+        checkSingleMemberShortArrOne(UnitTest.class.getConstructor(new Class[] { short[].class, Set.class }));
+        checkSingleMemberIntArrOne(UnitTest.class.getConstructor(new Class[] { int[].class, Set.class }));
+        checkSingleMemberLongArrOne(UnitTest.class.getConstructor(new Class[] { long[].class, Set.class }));
+        checkSingleMemberCharArrOne(UnitTest.class.getConstructor(new Class[] { char[].class, Set.class }));
+        checkSingleMemberFloatArrOne(UnitTest.class.getConstructor(new Class[] { float[].class, Set.class }));
+        checkSingleMemberDoubleArrOne(UnitTest.class.getConstructor(new Class[] { double[].class, Set.class }));
+        checkSingleMemberBooleanArrOne(UnitTest.class.getConstructor(new Class[] { boolean[].class, Set.class }));
+        checkSingleMemberStringArrOne(UnitTest.class.getConstructor(new Class[] { String[].class, Set.class }));
+        checkSingleMemberClassArrOne(UnitTest.class.getConstructor(new Class[] { Class[].class, Set.class }));
+        checkSingleMemberEnumArrOne(UnitTest.class.getConstructor(new Class[] { Enum[].class, Set.class }));
+
+        // SINGLE-MEMBER ARRAY TYPES (TWO-ELEMENT ARRAY) ON CONSTRUCTOR
+        checkSingleMemberByteArrTwo(UnitTest.class.getConstructor(new Class[] { byte[].class, Map.class }));
+        checkSingleMemberShortArrTwo(UnitTest.class.getConstructor(new Class[] { short[].class, Map.class }));
+        checkSingleMemberIntArrTwo(UnitTest.class.getConstructor(new Class[] { int[].class, Map.class }));
+        checkSingleMemberLongArrTwo(UnitTest.class.getConstructor(new Class[] { long[].class, Map.class }));
+        checkSingleMemberCharArrTwo(UnitTest.class.getConstructor(new Class[] { char[].class, Map.class }));
+        checkSingleMemberFloatArrTwo(UnitTest.class.getConstructor(new Class[] { float[].class, Map.class }));
+        checkSingleMemberDoubleArrTwo(UnitTest.class.getConstructor(new Class[] { double[].class, Map.class }));
+        checkSingleMemberBooleanArrTwo(UnitTest.class.getConstructor(new Class[] { boolean[].class, Map.class }));
+        checkSingleMemberStringArrTwo(UnitTest.class.getConstructor(new Class[] { String[].class, Map.class }));
+        checkSingleMemberClassArrTwo(UnitTest.class.getConstructor(new Class[] { Class[].class, Map.class }));
+        checkSingleMemberEnumArrTwo(UnitTest.class.getConstructor(new Class[] { Enum[].class, Map.class }));
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (OVERRIDE)ON CONSTRUCTOR
+        checkSingleMemberByteArrOvrdDef(UnitTest.class.getConstructor(new Class[] { byte[].class, List.class }));
+        checkSingleMemberShortArrOvrdDef(UnitTest.class.getConstructor(new Class[] { short[].class, List.class }));
+        checkSingleMemberIntArrOvrdDef(UnitTest.class.getConstructor(new Class[] { int[].class, List.class }));
+        checkSingleMemberLongArrOvrdDef(UnitTest.class.getConstructor(new Class[] { long[].class, List.class }));
+        checkSingleMemberCharArrOvrdDef(UnitTest.class.getConstructor(new Class[] { char[].class, List.class }));
+        checkSingleMemberFloatArrOvrdDef(UnitTest.class.getConstructor(new Class[] { float[].class, List.class }));
+        checkSingleMemberDoubleArrOvrdDef(UnitTest.class.getConstructor(new Class[] { double[].class, List.class }));
+        checkSingleMemberBooleanArrOvrdDef(UnitTest.class.getConstructor(new Class[] { boolean[].class, List.class }));
+        checkSingleMemberStringArrOvrdDef(UnitTest.class.getConstructor(new Class[] { String[].class, List.class }));
+        checkSingleMemberClassArrOvrdDef(UnitTest.class.getConstructor(new Class[] { Class[].class, List.class }));
+        checkSingleMemberEnumArrOvrdDef(UnitTest.class.getConstructor(new Class[] { Enum[].class, List.class }));
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (ACCEPT)ON CONSTRUCTOR
+        checkSingleMemberByteArrAcceptDef(UnitTest.class.getConstructor(new Class[] { byte[].class, Collection.class }));
+        checkSingleMemberShortArrAcceptDef(UnitTest.class.getConstructor(new Class[] { short[].class, Collection.class }));
+        checkSingleMemberIntArrAcceptDef(UnitTest.class.getConstructor(new Class[] { int[].class, Collection.class }));
+        checkSingleMemberLongArrAcceptDef(UnitTest.class.getConstructor(new Class[] { long[].class, Collection.class }));
+        checkSingleMemberCharArrAcceptDef(UnitTest.class.getConstructor(new Class[] { char[].class, Collection.class }));
+        checkSingleMemberFloatArrAcceptDef(UnitTest.class.getConstructor(new Class[] { float[].class, Collection.class }));
+        checkSingleMemberDoubleArrAcceptDef(UnitTest.class.getConstructor(new Class[] { double[].class, Collection.class }));
+        checkSingleMemberBooleanArrAcceptDef(UnitTest.class.getConstructor(new Class[] { boolean[].class, Collection.class }));
+        checkSingleMemberStringArrAcceptDef(UnitTest.class.getConstructor(new Class[] { String[].class, Collection.class }));
+        checkSingleMemberClassArrAcceptDef(UnitTest.class.getConstructor(new Class[] { Class[].class, Collection.class }));
+        checkSingleMemberEnumArrAcceptDef(UnitTest.class.getConstructor(new Class[] { Enum[].class, Collection.class }));
+
+        // *** TESTS ON ANNOTATED PARAMETERS ***
+
+        // MULTIMEMBER SCALAR TYPES ON PARAM
+        checkScalarTypesParam(UnitTest.class.getMethod("scalarTypesParam", Y));
+        checkScalarTypesOverrideDefaultParam(UnitTest.class.getMethod("scalarTypesOverrideDefaultParam", Y));
+        checkScalarTypesAcceptDefaultParam(UnitTest.class.getMethod("scalarTypesAcceptDefaultParam", Y));
+
+        // MULTIMEMBER ARRAY TYPES ON PARAM
+        checkArrayTypes0Param(UnitTest.class.getMethod("emptyArrayTypesParam", Y));
+        checkArrayTypes1Param(UnitTest.class.getMethod("singleElementArrayTypesParam", Y));
+        checkArrayTypes2Param(UnitTest.class.getMethod("twoElementArrayTypesParam", Y));
+        checkArrayTypesAcceptDefaultParam(UnitTest.class.getMethod("arrayTypesAcceptDefaultParam", Y));
+        checkArrayTypesOverrideDefaultParam(UnitTest.class.getMethod("arrayTypesOverrideDefaultParam", Y));
+
+        // MARKER TYPE ON PARAMETER
+        checkMarkerParam(UnitTest.class.getMethod("markerParam", Y));
+
+        // SINGLE-MEMBER SCALAR TYPES ON PARAMETER
+        checkSingleMemberByteParam(UnitTest.class.getMethod("SingleMemberByteParam", Y));
+        checkSingleMemberShortParam(UnitTest.class.getMethod("SingleMemberShortParam", Y));
+        checkSingleMemberIntParam(UnitTest.class.getMethod("SingleMemberIntParam", Y));
+        checkSingleMemberLongParam(UnitTest.class.getMethod("SingleMemberLongParam", Y));
+        checkSingleMemberCharParam(UnitTest.class.getMethod("SingleMemberCharParam", Y));
+        checkSingleMemberFloatParam(UnitTest.class.getMethod("SingleMemberFloatParam", Y));
+        checkSingleMemberDoubleParam(UnitTest.class.getMethod("SingleMemberDoubleParam", Y));
+        checkSingleMemberBooleanParam(UnitTest.class.getMethod("SingleMemberBooleanParam", Y));
+        checkSingleMemberStringParam(UnitTest.class.getMethod("SingleMemberStringParam", Y));
+        checkSingleMemberClassParam(UnitTest.class.getMethod("SingleMemberClassParam", Y));
+        checkSingleMemberEnumParam(UnitTest.class.getMethod("SingleMemberEnumParam", Y));
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-OVERRIDE ON PARAMETER
+        checkSingleMemberByteOvrdDefParam(UnitTest.class.getMethod("SingleMemberByteOvrdDefParam", Y));
+        checkSingleMemberShortOvrdDefParam(UnitTest.class.getMethod("SingleMemberShortOvrdDefParam", Y));
+        checkSingleMemberIntOvrdDefParam(UnitTest.class.getMethod("SingleMemberIntOvrdDefParam", Y));
+        checkSingleMemberLongOvrdDefParam(UnitTest.class.getMethod("SingleMemberLongOvrdDefParam", Y));
+        checkSingleMemberCharOvrdDefParam(UnitTest.class.getMethod("SingleMemberCharOvrdDefParam", Y));
+        checkSingleMemberFloatOvrdDefParam(UnitTest.class.getMethod("SingleMemberFloatOvrdDefParam", Y));
+        checkSingleMemberDoubleOvrdDefParam(UnitTest.class.getMethod("SingleMemberDoubleOvrdDefParam", Y));
+        checkSingleMemberBooleanOvrdDefParam(UnitTest.class.getMethod("SingleMemberBooleanOvrdDefParam", Y));
+        checkSingleMemberStringOvrdDefParam(UnitTest.class.getMethod("SingleMemberStringOvrdDefParam", Y));
+        checkSingleMemberClassOvrdDefParam(UnitTest.class.getMethod("SingleMemberClassOvrdDefParam", Y));
+        checkSingleMemberEnumOvrdDefParam(UnitTest.class.getMethod("SingleMemberEnumOvrdDefParam", Y));
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-ACCEPT ON PARAMETER
+        checkSingleMemberByteAcceptDefParam(UnitTest.class.getMethod("SingleMemberByteAcceptDefParam", Y));
+        checkSingleMemberShortAcceptDefParam(UnitTest.class.getMethod("SingleMemberShortAcceptDefParam", Y));
+        checkSingleMemberIntAcceptDefParam(UnitTest.class.getMethod("SingleMemberIntAcceptDefParam", Y));
+        checkSingleMemberLongAcceptDefParam(UnitTest.class.getMethod("SingleMemberLongAcceptDefParam", Y));
+        checkSingleMemberCharAcceptDefParam(UnitTest.class.getMethod("SingleMemberCharAcceptDefParam", Y));
+        checkSingleMemberFloatAcceptDefParam(UnitTest.class.getMethod("SingleMemberFloatAcceptDefParam", Y));
+        checkSingleMemberDoubleAcceptDefParam(UnitTest.class.getMethod("SingleMemberDoubleAcceptDefParam", Y));
+        checkSingleMemberBooleanAcceptDefParam(UnitTest.class.getMethod("SingleMemberBooleanAcceptDefParam", Y));
+        checkSingleMemberStringAcceptDefParam(UnitTest.class.getMethod("SingleMemberStringAcceptDefParam", Y));
+        checkSingleMemberClassAcceptDefParam(UnitTest.class.getMethod("SingleMemberClassAcceptDefParam", Y));
+        checkSingleMemberEnumAcceptDefParam(UnitTest.class.getMethod("SingleMemberEnumAcceptDefParam", Y));
+
+        // SINGLE-MEMBER ARRAY TYPES Param(UnitTest.class.getMethod("EMPTY ARRAY) ON PARAMETER
+        checkSingleMemberByteArrEmptyParam(UnitTest.class.getMethod("SingleMemberByteArrEmptyParam", Y));
+        checkSingleMemberShortArrEmptyParam(UnitTest.class.getMethod("SingleMemberShortArrEmptyParam", Y));
+        checkSingleMemberIntArrEmptyParam(UnitTest.class.getMethod("SingleMemberIntArrEmptyParam", Y));
+        checkSingleMemberLongArrEmptyParam(UnitTest.class.getMethod("SingleMemberLongArrEmptyParam", Y));
+        checkSingleMemberCharArrEmptyParam(UnitTest.class.getMethod("SingleMemberCharArrEmptyParam", Y));
+        checkSingleMemberFloatArrEmptyParam(UnitTest.class.getMethod("SingleMemberFloatArrEmptyParam", Y));
+        checkSingleMemberDoubleArrEmptyParam(UnitTest.class.getMethod("SingleMemberDoubleArrEmptyParam", Y));
+        checkSingleMemberBooleanArrEmptyParam(UnitTest.class.getMethod("SingleMemberBooleanArrEmptyParam", Y));
+        checkSingleMemberStringArrEmptyParam(UnitTest.class.getMethod("SingleMemberStringArrEmptyParam", Y));
+        checkSingleMemberClassArrEmptyParam(UnitTest.class.getMethod("SingleMemberClassArrEmptyParam", Y));
+        checkSingleMemberEnumArrEmptyParam(UnitTest.class.getMethod("SingleMemberEnumArrEmptyParam", Y));
+
+        // SINGLE-MEMBER ARRAY TYPES Param(UnitTest.class.getMethod("ONE-ELEMENT ARRAY) ON PARAMETER
+        checkSingleMemberByteArrOneParam(UnitTest.class.getMethod("SingleMemberByteArrOneParam", Y));
+        checkSingleMemberShortArrOneParam(UnitTest.class.getMethod("SingleMemberShortArrOneParam", Y));
+        checkSingleMemberIntArrOneParam(UnitTest.class.getMethod("SingleMemberIntArrOneParam", Y));
+        checkSingleMemberLongArrOneParam(UnitTest.class.getMethod("SingleMemberLongArrOneParam", Y));
+        checkSingleMemberCharArrOneParam(UnitTest.class.getMethod("SingleMemberCharArrOneParam", Y));
+        checkSingleMemberFloatArrOneParam(UnitTest.class.getMethod("SingleMemberFloatArrOneParam", Y));
+        checkSingleMemberDoubleArrOneParam(UnitTest.class.getMethod("SingleMemberDoubleArrOneParam", Y));
+        checkSingleMemberBooleanArrOneParam(UnitTest.class.getMethod("SingleMemberBooleanArrOneParam", Y));
+        checkSingleMemberStringArrOneParam(UnitTest.class.getMethod("SingleMemberStringArrOneParam", Y));
+        checkSingleMemberClassArrOneParam(UnitTest.class.getMethod("SingleMemberClassArrOneParam", Y));
+        checkSingleMemberEnumArrOneParam(UnitTest.class.getMethod("SingleMemberEnumArrOneParam", Y));
+
+        // SINGLE-MEMBER ARRAY TYPES Param(UnitTest.class.getMethod("TWO-ELEMENT ARRAY) ON PARAMETER
+        checkSingleMemberByteArrTwoParam(UnitTest.class.getMethod("SingleMemberByteArrTwoParam", Y));
+        checkSingleMemberShortArrTwoParam(UnitTest.class.getMethod("SingleMemberShortArrTwoParam", Y));
+        checkSingleMemberIntArrTwoParam(UnitTest.class.getMethod("SingleMemberIntArrTwoParam", Y));
+        checkSingleMemberLongArrTwoParam(UnitTest.class.getMethod("SingleMemberLongArrTwoParam", Y));
+        checkSingleMemberCharArrTwoParam(UnitTest.class.getMethod("SingleMemberCharArrTwoParam", Y));
+        checkSingleMemberFloatArrTwoParam(UnitTest.class.getMethod("SingleMemberFloatArrTwoParam", Y));
+        checkSingleMemberDoubleArrTwoParam(UnitTest.class.getMethod("SingleMemberDoubleArrTwoParam", Y));
+        checkSingleMemberBooleanArrTwoParam(UnitTest.class.getMethod("SingleMemberBooleanArrTwoParam", Y));
+        checkSingleMemberStringArrTwoParam(UnitTest.class.getMethod("SingleMemberStringArrTwoParam", Y));
+        checkSingleMemberClassArrTwoParam(UnitTest.class.getMethod("SingleMemberClassArrTwoParam", Y));
+        checkSingleMemberEnumArrTwoParam(UnitTest.class.getMethod("SingleMemberEnumArrTwoParam", Y));
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT Param(UnitTest.class.getMethod("OVERRIDE)ON PARAMETER
+        checkSingleMemberByteArrOvrdDefParam(UnitTest.class.getMethod("SingleMemberByteArrOvrdDefParam", Y));
+        checkSingleMemberShortArrOvrdDefParam(UnitTest.class.getMethod("SingleMemberShortArrOvrdDefParam", Y));
+        checkSingleMemberIntArrOvrdDefParam(UnitTest.class.getMethod("SingleMemberIntArrOvrdDefParam", Y));
+        checkSingleMemberLongArrOvrdDefParam(UnitTest.class.getMethod("SingleMemberLongArrOvrdDefParam", Y));
+        checkSingleMemberCharArrOvrdDefParam(UnitTest.class.getMethod("SingleMemberCharArrOvrdDefParam", Y));
+        checkSingleMemberFloatArrOvrdDefParam(UnitTest.class.getMethod("SingleMemberFloatArrOvrdDefParam", Y));
+        checkSingleMemberDoubleArrOvrdDefParam(UnitTest.class.getMethod("SingleMemberDoubleArrOvrdDefParam", Y));
+        checkSingleMemberBooleanArrOvrdDefParam(UnitTest.class.getMethod("SingleMemberBooleanArrOvrdDefParam", Y));
+        checkSingleMemberStringArrOvrdDefParam(UnitTest.class.getMethod("SingleMemberStringArrOvrdDefParam", Y));
+        checkSingleMemberClassArrOvrdDefParam(UnitTest.class.getMethod("SingleMemberClassArrOvrdDefParam", Y));
+        checkSingleMemberEnumArrOvrdDefParam(UnitTest.class.getMethod("SingleMemberEnumArrOvrdDefParam", Y));
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT Param(UnitTest.class.getMethod("ACCEPT)ON PARAMETER
+        checkSingleMemberByteArrAcceptDefParam(UnitTest.class.getMethod("SingleMemberByteArrAcceptDefParam", Y));
+        checkSingleMemberShortArrAcceptDefParam(UnitTest.class.getMethod("SingleMemberShortArrAcceptDefParam", Y));
+        checkSingleMemberIntArrAcceptDefParam(UnitTest.class.getMethod("SingleMemberIntArrAcceptDefParam", Y));
+        checkSingleMemberLongArrAcceptDefParam(UnitTest.class.getMethod("SingleMemberLongArrAcceptDefParam", Y));
+        checkSingleMemberCharArrAcceptDefParam(UnitTest.class.getMethod("SingleMemberCharArrAcceptDefParam", Y));
+        checkSingleMemberFloatArrAcceptDefParam(UnitTest.class.getMethod("SingleMemberFloatArrAcceptDefParam", Y));
+        checkSingleMemberDoubleArrAcceptDefParam(UnitTest.class.getMethod("SingleMemberDoubleArrAcceptDefParam", Y));
+        checkSingleMemberBooleanArrAcceptDefParam(UnitTest.class.getMethod("SingleMemberBooleanArrAcceptDefParam", Y));
+        checkSingleMemberStringArrAcceptDefParam(UnitTest.class.getMethod("SingleMemberStringArrAcceptDefParam", Y));
+        checkSingleMemberClassArrAcceptDefParam(UnitTest.class.getMethod("SingleMemberClassArrAcceptDefParam", Y));
+        checkSingleMemberEnumArrAcceptDefParam(UnitTest.class.getMethod("SingleMemberEnumArrAcceptDefParam", Y));
+
+        // *** TESTS ON ANNOTATED CLASSES ***
+
+        // MULTIMEMBER SCALAR TYPES ON CLASS
+        checkScalarTypes(scalarTypesClass.class);
+        checkScalarTypesOverrideDefault(scalarTypesOverrideDefaultClass.class);
+        checkScalarTypesAcceptDefault(scalarTypesAcceptDefaultClass.class);
+
+        // MULTIMEMBER ARRAY TYPES ON CLASS
+        checkArrayTypes0(emptyArrayTypesClass.class);
+        checkArrayTypes1(singleElementArrayTypesClass.class);
+        checkArrayTypes2(twoElementArrayTypesClass.class);
+        checkArrayTypesOverrideDefault(arrayTypesOverrideDefaultClass.class);
+        checkArrayTypesAcceptDefault(arrayTypesAcceptDefaultClass.class);
+
+        // MARKER TYPE ON CLASS
+        checkMarker(markerClass.class);
+
+        // SINGLE-MEMBER SCALAR TYPES ON CLASS
+        checkSingleMemberByte(SingleMemberByteClass.class);
+        checkSingleMemberShort(SingleMemberShortClass.class);
+        checkSingleMemberInt(SingleMemberIntClass.class);
+        checkSingleMemberLong(SingleMemberLongClass.class);
+        checkSingleMemberChar(SingleMemberCharClass.class);
+        checkSingleMemberFloat(SingleMemberFloatClass.class);
+        checkSingleMemberDouble(SingleMemberDoubleClass.class);
+        checkSingleMemberBoolean(SingleMemberBooleanClass.class);
+        checkSingleMemberString(SingleMemberStringClass.class);
+        checkSingleMemberClass(SingleMemberClassClass.class);
+        checkSingleMemberEnum(SingleMemberEnumClass.class);
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-OVERRIDE ON CLASS
+        checkSingleMemberByteOvrdDef(SingleMemberByteOvrdDefClass.class);
+        checkSingleMemberShortOvrdDef(SingleMemberShortOvrdDefClass.class);
+        checkSingleMemberIntOvrdDef(SingleMemberIntOvrdDefClass.class);
+        checkSingleMemberLongOvrdDef(SingleMemberLongOvrdDefClass.class);
+        checkSingleMemberCharOvrdDef(SingleMemberCharOvrdDefClass.class);
+        checkSingleMemberFloatOvrdDef(SingleMemberFloatOvrdDefClass.class);
+        checkSingleMemberDoubleOvrdDef(SingleMemberDoubleOvrdDefClass.class);
+        checkSingleMemberBooleanOvrdDef(SingleMemberBooleanOvrdDefClass.class);
+        checkSingleMemberStringOvrdDef(SingleMemberStringOvrdDefClass.class);
+        checkSingleMemberClassOvrdDef(SingleMemberClassOvrdDefClass.class);
+        checkSingleMemberEnumOvrdDef(SingleMemberEnumOvrdDefClass.class);
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-ACCEPT ON CLASS
+        checkSingleMemberByteAcceptDef(SingleMemberByteAcceptDefClass.class);
+        checkSingleMemberShortAcceptDef(SingleMemberShortAcceptDefClass.class);
+        checkSingleMemberIntAcceptDef(SingleMemberIntAcceptDefClass.class);
+        checkSingleMemberLongAcceptDef(SingleMemberLongAcceptDefClass.class);
+        checkSingleMemberCharAcceptDef(SingleMemberCharAcceptDefClass.class);
+        checkSingleMemberFloatAcceptDef(SingleMemberFloatAcceptDefClass.class);
+        checkSingleMemberDoubleAcceptDef(SingleMemberDoubleAcceptDefClass.class);
+        checkSingleMemberBooleanAcceptDef(SingleMemberBooleanAcceptDefClass.class);
+        checkSingleMemberStringAcceptDef(SingleMemberStringAcceptDefClass.class);
+        checkSingleMemberClassAcceptDef(SingleMemberClassAcceptDefClass.class);
+        checkSingleMemberEnumAcceptDef(SingleMemberEnumAcceptDefClass.class);
+
+        // SINGLE-MEMBER ARRAY TYPES (EMPTY ARRAY) ON CLASS
+        checkSingleMemberByteArrEmpty(SingleMemberByteArrEmptyClass.class);
+        checkSingleMemberShortArrEmpty(SingleMemberShortArrEmptyClass.class);
+        checkSingleMemberIntArrEmpty(SingleMemberIntArrEmptyClass.class);
+        checkSingleMemberLongArrEmpty(SingleMemberLongArrEmptyClass.class);
+        checkSingleMemberCharArrEmpty(SingleMemberCharArrEmptyClass.class);
+        checkSingleMemberFloatArrEmpty(SingleMemberFloatArrEmptyClass.class);
+        checkSingleMemberDoubleArrEmpty(SingleMemberDoubleArrEmptyClass.class);
+        checkSingleMemberBooleanArrEmpty(SingleMemberBooleanArrEmptyClass.class);
+        checkSingleMemberStringArrEmpty(SingleMemberStringArrEmptyClass.class);
+        checkSingleMemberClassArrEmpty(SingleMemberClassArrEmptyClass.class);
+        checkSingleMemberEnumArrEmpty(SingleMemberEnumArrEmptyClass.class);
+
+        // SINGLE-MEMBER ARRAY TYPES (ONE-ELEMENT ARRAY) ON CLASS
+        checkSingleMemberByteArrOne(SingleMemberByteArrOneClass.class);
+        checkSingleMemberShortArrOne(SingleMemberShortArrOneClass.class);
+        checkSingleMemberIntArrOne(SingleMemberIntArrOneClass.class);
+        checkSingleMemberLongArrOne(SingleMemberLongArrOneClass.class);
+        checkSingleMemberCharArrOne(SingleMemberCharArrOneClass.class);
+        checkSingleMemberFloatArrOne(SingleMemberFloatArrOneClass.class);
+        checkSingleMemberDoubleArrOne(SingleMemberDoubleArrOneClass.class);
+        checkSingleMemberBooleanArrOne(SingleMemberBooleanArrOneClass.class);
+        checkSingleMemberStringArrOne(SingleMemberStringArrOneClass.class);
+        checkSingleMemberClassArrOne(SingleMemberClassArrOneClass.class);
+        checkSingleMemberEnumArrOne(SingleMemberEnumArrOneClass.class);
+
+        // SINGLE-MEMBER ARRAY TYPES (TWO-ELEMENT ARRAY) ON CLASS
+        checkSingleMemberByteArrTwo(SingleMemberByteArrTwoClass.class);
+        checkSingleMemberShortArrTwo(SingleMemberShortArrTwoClass.class);
+        checkSingleMemberIntArrTwo(SingleMemberIntArrTwoClass.class);
+        checkSingleMemberLongArrTwo(SingleMemberLongArrTwoClass.class);
+        checkSingleMemberCharArrTwo(SingleMemberCharArrTwoClass.class);
+        checkSingleMemberFloatArrTwo(SingleMemberFloatArrTwoClass.class);
+        checkSingleMemberDoubleArrTwo(SingleMemberDoubleArrTwoClass.class);
+        checkSingleMemberBooleanArrTwo(SingleMemberBooleanArrTwoClass.class);
+        checkSingleMemberStringArrTwo(SingleMemberStringArrTwoClass.class);
+        checkSingleMemberClassArrTwo(SingleMemberClassArrTwoClass.class);
+        checkSingleMemberEnumArrTwo(SingleMemberEnumArrTwoClass.class);
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (OVERRIDE)ON CLASS
+        checkSingleMemberByteArrOvrdDef(SingleMemberByteArrOvrdDefClass.class);
+        checkSingleMemberShortArrOvrdDef(SingleMemberShortArrOvrdDefClass.class);
+        checkSingleMemberIntArrOvrdDef(SingleMemberIntArrOvrdDefClass.class);
+        checkSingleMemberLongArrOvrdDef(SingleMemberLongArrOvrdDefClass.class);
+        checkSingleMemberCharArrOvrdDef(SingleMemberCharArrOvrdDefClass.class);
+        checkSingleMemberFloatArrOvrdDef(SingleMemberFloatArrOvrdDefClass.class);
+        checkSingleMemberDoubleArrOvrdDef(SingleMemberDoubleArrOvrdDefClass.class);
+        checkSingleMemberBooleanArrOvrdDef(SingleMemberBooleanArrOvrdDefClass.class);
+        checkSingleMemberStringArrOvrdDef(SingleMemberStringArrOvrdDefClass.class);
+        checkSingleMemberClassArrOvrdDef(SingleMemberClassArrOvrdDefClass.class);
+        checkSingleMemberEnumArrOvrdDef(SingleMemberEnumArrOvrdDefClass.class);
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (ACCEPT)ON CLASS
+        checkSingleMemberByteArrAcceptDef(SingleMemberByteArrAcceptDefClass.class);
+        checkSingleMemberShortArrAcceptDef(SingleMemberShortArrAcceptDefClass.class);
+        checkSingleMemberIntArrAcceptDef(SingleMemberIntArrAcceptDefClass.class);
+        checkSingleMemberLongArrAcceptDef(SingleMemberLongArrAcceptDefClass.class);
+        checkSingleMemberCharArrAcceptDef(SingleMemberCharArrAcceptDefClass.class);
+        checkSingleMemberFloatArrAcceptDef(SingleMemberFloatArrAcceptDefClass.class);
+        checkSingleMemberDoubleArrAcceptDef(SingleMemberDoubleArrAcceptDefClass.class);
+        checkSingleMemberBooleanArrAcceptDef(SingleMemberBooleanArrAcceptDefClass.class);
+        checkSingleMemberStringArrAcceptDef(SingleMemberStringArrAcceptDefClass.class);
+        checkSingleMemberClassArrAcceptDef(SingleMemberClassArrAcceptDefClass.class);
+        checkSingleMemberEnumArrAcceptDef(SingleMemberEnumArrAcceptDefClass.class);
+
+        // *** TESTS FOR EQUALS AND HASHCODE - POSITIVE
+
+        // MULTIMEMBER SCALAR TYPES
+        checkEquals(scalarTypesClass.class, UnitTest.class.getField("scalarTypesField"),
+                    ScalarTypes.class);
+        checkEquals(scalarTypesOverrideDefaultClass.class, UnitTest.class.getField("scalarTypesOverrideDefaultField"),
+                    ScalarTypesWithDefault.class);
+        checkEquals(scalarTypesAcceptDefaultClass.class, UnitTest.class.getField("scalarTypesAcceptDefaultField"),
+                    ScalarTypesWithDefault.class);
+
+        // MULTIMEMBER ARRAY TYPES
+        checkEquals(emptyArrayTypesClass.class, UnitTest.class.getField("emptyArrayTypesField"),
+                    ArrayTypes.class);
+        checkEquals(singleElementArrayTypesClass.class, UnitTest.class.getField("singleElementArrayTypesField"),
+                    ArrayTypes.class);
+        checkEquals(twoElementArrayTypesClass.class, UnitTest.class.getField("twoElementArrayTypesField"),
+                    ArrayTypes.class);
+        checkEquals(arrayTypesOverrideDefaultClass.class, UnitTest.class.getField("arrayTypesOverrideDefaultField"),
+                    ArrayTypesWithDefault.class);
+        checkEquals(arrayTypesAcceptDefaultClass.class, UnitTest.class.getField("arrayTypesAcceptDefaultField"),
+                    ArrayTypesWithDefault.class);
+
+        // MARKER TYPE
+        checkEquals(markerClass.class, UnitTest.class.getField("markerField"),
+                    Marker.class);
+
+        // SINGLE-MEMBER SCALAR TYPES
+        checkEquals(SingleMemberByteClass.class, UnitTest.class.getField("SingleMemberByteField"),
+                    SingleMemberByte.class);
+        checkEquals(SingleMemberShortClass.class, UnitTest.class.getField("SingleMemberShortField"),
+                    SingleMemberShort.class);
+        checkEquals(SingleMemberIntClass.class, UnitTest.class.getField("SingleMemberIntField"),
+                    SingleMemberInt.class);
+        checkEquals(SingleMemberLongClass.class, UnitTest.class.getField("SingleMemberLongField"),
+                    SingleMemberLong.class);
+        checkEquals(SingleMemberCharClass.class, UnitTest.class.getField("SingleMemberCharField"),
+                    SingleMemberChar.class);
+        checkEquals(SingleMemberFloatClass.class, UnitTest.class.getField("SingleMemberFloatField"),
+                    SingleMemberFloat.class);
+        checkEquals(SingleMemberDoubleClass.class, UnitTest.class.getField("SingleMemberDoubleField"),
+                    SingleMemberDouble.class);
+        checkEquals(SingleMemberBooleanClass.class, UnitTest.class.getField("SingleMemberBooleanField"),
+                    SingleMemberBoolean.class);
+        checkEquals(SingleMemberStringClass.class, UnitTest.class.getField("SingleMemberStringField"),
+                    SingleMemberString.class);
+        checkEquals(SingleMemberClassClass.class, UnitTest.class.getField("SingleMemberClassField"),
+                    SingleMemberClass.class);
+        checkEquals(SingleMemberEnumClass.class, UnitTest.class.getField("SingleMemberEnumField"),
+                    SingleMemberEnum.class);
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-OVERRIDE
+        checkEquals(SingleMemberByteOvrdDefClass.class, UnitTest.class.getField("SingleMemberByteOvrdDefField"),
+                    SingleMemberByteWithDef.class);
+        checkEquals(SingleMemberShortOvrdDefClass.class, UnitTest.class.getField("SingleMemberShortOvrdDefField"),
+                    SingleMemberShortWithDef.class);
+        checkEquals(SingleMemberIntOvrdDefClass.class, UnitTest.class.getField("SingleMemberIntOvrdDefField"),
+                    SingleMemberIntWithDef.class);
+        checkEquals(SingleMemberLongOvrdDefClass.class, UnitTest.class.getField("SingleMemberLongOvrdDefField"),
+                    SingleMemberLongWithDef.class);
+        checkEquals(SingleMemberCharOvrdDefClass.class, UnitTest.class.getField("SingleMemberCharOvrdDefField"),
+                    SingleMemberCharWithDef.class);
+        checkEquals(SingleMemberFloatOvrdDefClass.class, UnitTest.class.getField("SingleMemberFloatOvrdDefField"),
+                    SingleMemberFloatWithDef.class);
+        checkEquals(SingleMemberDoubleOvrdDefClass.class, UnitTest.class.getField("SingleMemberDoubleOvrdDefField"),
+                    SingleMemberDoubleWithDef.class);
+        checkEquals(SingleMemberBooleanOvrdDefClass.class, UnitTest.class.getField("SingleMemberBooleanOvrdDefField"),
+                    SingleMemberBooleanWithDef.class);
+        checkEquals(SingleMemberStringOvrdDefClass.class, UnitTest.class.getField("SingleMemberStringOvrdDefField"),
+                    SingleMemberStringWithDef.class);
+        checkEquals(SingleMemberClassOvrdDefClass.class, UnitTest.class.getField("SingleMemberClassOvrdDefField"),
+                    SingleMemberClassWithDef.class);
+        checkEquals(SingleMemberEnumOvrdDefClass.class, UnitTest.class.getField("SingleMemberEnumOvrdDefField"),
+                    SingleMemberEnumWithDef.class);
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-ACCEPT
+        checkEquals(SingleMemberByteAcceptDefClass.class, UnitTest.class.getField("SingleMemberByteAcceptDefField"),
+                    SingleMemberByteWithDef.class);
+        checkEquals(SingleMemberShortAcceptDefClass.class, UnitTest.class.getField("SingleMemberShortAcceptDefField"),
+                    SingleMemberShortWithDef.class);
+        checkEquals(SingleMemberIntAcceptDefClass.class, UnitTest.class.getField("SingleMemberIntAcceptDefField"),
+                    SingleMemberIntWithDef.class);
+        checkEquals(SingleMemberLongAcceptDefClass.class, UnitTest.class.getField("SingleMemberLongAcceptDefField"),
+                    SingleMemberLongWithDef.class);
+        checkEquals(SingleMemberCharAcceptDefClass.class, UnitTest.class.getField("SingleMemberCharAcceptDefField"),
+                    SingleMemberCharWithDef.class);
+        checkEquals(SingleMemberFloatAcceptDefClass.class, UnitTest.class.getField("SingleMemberFloatAcceptDefField"),
+                    SingleMemberFloatWithDef.class);
+        checkEquals(SingleMemberDoubleAcceptDefClass.class, UnitTest.class.getField("SingleMemberDoubleAcceptDefField"),
+                    SingleMemberDoubleWithDef.class);
+        checkEquals(SingleMemberBooleanAcceptDefClass.class, UnitTest.class.getField("SingleMemberBooleanAcceptDefField"),
+                    SingleMemberBooleanWithDef.class);
+        checkEquals(SingleMemberStringAcceptDefClass.class, UnitTest.class.getField("SingleMemberStringAcceptDefField"),
+                    SingleMemberStringWithDef.class);
+        checkEquals(SingleMemberClassAcceptDefClass.class, UnitTest.class.getField("SingleMemberClassAcceptDefField"),
+                    SingleMemberClassWithDef.class);
+        checkEquals(SingleMemberEnumAcceptDefClass.class, UnitTest.class.getField("SingleMemberEnumAcceptDefField"),
+                    SingleMemberEnumWithDef.class);
+
+        // SINGLE-MEMBER ARRAY TYPES (EMPTY ARRAY)
+        checkEquals(SingleMemberByteArrEmptyClass.class, UnitTest.class.getField("SingleMemberByteArrEmptyField"),
+                    SingleMemberByteArray.class);
+        checkEquals(SingleMemberShortArrEmptyClass.class, UnitTest.class.getField("SingleMemberShortArrEmptyField"),
+                    SingleMemberShortArray.class);
+        checkEquals(SingleMemberIntArrEmptyClass.class, UnitTest.class.getField("SingleMemberIntArrEmptyField"),
+                    SingleMemberIntArray.class);
+        checkEquals(SingleMemberLongArrEmptyClass.class, UnitTest.class.getField("SingleMemberLongArrEmptyField"),
+                    SingleMemberLongArray.class);
+        checkEquals(SingleMemberCharArrEmptyClass.class, UnitTest.class.getField("SingleMemberCharArrEmptyField"),
+                    SingleMemberCharArray.class);
+        checkEquals(SingleMemberFloatArrEmptyClass.class, UnitTest.class.getField("SingleMemberFloatArrEmptyField"),
+                    SingleMemberFloatArray.class);
+        checkEquals(SingleMemberDoubleArrEmptyClass.class, UnitTest.class.getField("SingleMemberDoubleArrEmptyField"),
+                    SingleMemberDoubleArray.class);
+        checkEquals(SingleMemberBooleanArrEmptyClass.class, UnitTest.class.getField("SingleMemberBooleanArrEmptyField"),
+                    SingleMemberBooleanArray.class);
+        checkEquals(SingleMemberStringArrEmptyClass.class, UnitTest.class.getField("SingleMemberStringArrEmptyField"),
+                    SingleMemberStringArray.class);
+        checkEquals(SingleMemberClassArrEmptyClass.class, UnitTest.class.getField("SingleMemberClassArrEmptyField"),
+                    SingleMemberClassArray.class);
+        checkEquals(SingleMemberEnumArrEmptyClass.class, UnitTest.class.getField("SingleMemberEnumArrEmptyField"),
+                    SingleMemberEnumArray.class);
+
+        // SINGLE-MEMBER ARRAY TYPES (ONE-ELEMENT ARRAY)
+        checkEquals(SingleMemberByteArrOneClass.class, UnitTest.class.getField("SingleMemberByteArrOneField"),
+                    SingleMemberByteArray.class);
+        checkEquals(SingleMemberShortArrOneClass.class, UnitTest.class.getField("SingleMemberShortArrOneField"),
+                    SingleMemberShortArray.class);
+        checkEquals(SingleMemberIntArrOneClass.class, UnitTest.class.getField("SingleMemberIntArrOneField"),
+                    SingleMemberIntArray.class);
+        checkEquals(SingleMemberLongArrOneClass.class, UnitTest.class.getField("SingleMemberLongArrOneField"),
+                    SingleMemberLongArray.class);
+        checkEquals(SingleMemberCharArrOneClass.class, UnitTest.class.getField("SingleMemberCharArrOneField"),
+                    SingleMemberCharArray.class);
+        checkEquals(SingleMemberFloatArrOneClass.class, UnitTest.class.getField("SingleMemberFloatArrOneField"),
+                    SingleMemberFloatArray.class);
+        checkEquals(SingleMemberDoubleArrOneClass.class, UnitTest.class.getField("SingleMemberDoubleArrOneField"),
+                    SingleMemberDoubleArray.class);
+        checkEquals(SingleMemberBooleanArrOneClass.class, UnitTest.class.getField("SingleMemberBooleanArrOneField"),
+                    SingleMemberBooleanArray.class);
+        checkEquals(SingleMemberStringArrOneClass.class, UnitTest.class.getField("SingleMemberStringArrOneField"),
+                    SingleMemberStringArray.class);
+        checkEquals(SingleMemberClassArrOneClass.class, UnitTest.class.getField("SingleMemberClassArrOneField"),
+                    SingleMemberClassArray.class);
+        checkEquals(SingleMemberEnumArrOneClass.class, UnitTest.class.getField("SingleMemberEnumArrOneField"),
+                    SingleMemberEnumArray.class);
+
+        // SINGLE-MEMBER ARRAY TYPES (TWO-ELEMENT ARRAY)
+        checkEquals(SingleMemberByteArrTwoClass.class, UnitTest.class.getField("SingleMemberByteArrTwoField"),
+                    SingleMemberByteArray.class);
+        checkEquals(SingleMemberShortArrTwoClass.class, UnitTest.class.getField("SingleMemberShortArrTwoField"),
+                    SingleMemberShortArray.class);
+        checkEquals(SingleMemberIntArrTwoClass.class, UnitTest.class.getField("SingleMemberIntArrTwoField"),
+                    SingleMemberIntArray.class);
+        checkEquals(SingleMemberLongArrTwoClass.class, UnitTest.class.getField("SingleMemberLongArrTwoField"),
+                    SingleMemberLongArray.class);
+        checkEquals(SingleMemberCharArrTwoClass.class, UnitTest.class.getField("SingleMemberCharArrTwoField"),
+                    SingleMemberCharArray.class);
+        checkEquals(SingleMemberFloatArrTwoClass.class, UnitTest.class.getField("SingleMemberFloatArrTwoField"),
+                    SingleMemberFloatArray.class);
+        checkEquals(SingleMemberDoubleArrTwoClass.class, UnitTest.class.getField("SingleMemberDoubleArrTwoField"),
+                    SingleMemberDoubleArray.class);
+        checkEquals(SingleMemberBooleanArrTwoClass.class, UnitTest.class.getField("SingleMemberBooleanArrTwoField"),
+                    SingleMemberBooleanArray.class);
+        checkEquals(SingleMemberStringArrTwoClass.class, UnitTest.class.getField("SingleMemberStringArrTwoField"),
+                    SingleMemberStringArray.class);
+        checkEquals(SingleMemberClassArrTwoClass.class, UnitTest.class.getField("SingleMemberClassArrTwoField"),
+                    SingleMemberClassArray.class);
+        checkEquals(SingleMemberEnumArrTwoClass.class, UnitTest.class.getField("SingleMemberEnumArrTwoField"),
+                    SingleMemberEnumArray.class);
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (OVERRIDE)
+        checkEquals(SingleMemberByteArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberByteArrOvrdDefField"),
+                    SingleMemberByteArrayDef.class);
+        checkEquals(SingleMemberShortArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberShortArrOvrdDefField"),
+                    SingleMemberShortArrayDef.class);
+        checkEquals(SingleMemberIntArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberIntArrOvrdDefField"),
+                    SingleMemberIntArrayDef.class);
+        checkEquals(SingleMemberLongArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberLongArrOvrdDefField"),
+                    SingleMemberLongArrayDef.class);
+        checkEquals(SingleMemberCharArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberCharArrOvrdDefField"),
+                    SingleMemberCharArrayDef.class);
+        checkEquals(SingleMemberFloatArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberFloatArrOvrdDefField"),
+                    SingleMemberFloatArrayDef.class);
+        checkEquals(SingleMemberDoubleArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberDoubleArrOvrdDefField"),
+                    SingleMemberDoubleArrayDef.class);
+        checkEquals(SingleMemberBooleanArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberBooleanArrOvrdDefField"),
+                    SingleMemberBooleanArrayDef.class);
+        checkEquals(SingleMemberStringArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberStringArrOvrdDefField"),
+                    SingleMemberStringArrayDef.class);
+        checkEquals(SingleMemberClassArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberClassArrOvrdDefField"),
+                    SingleMemberClassArrayDef.class);
+        checkEquals(SingleMemberEnumArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberEnumArrOvrdDefField"),
+                    SingleMemberEnumArrayDef.class);
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (ACCEPT)
+        checkEquals(SingleMemberByteArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberByteArrAcceptDefField"),
+                    SingleMemberByteArrayDef.class);
+        checkEquals(SingleMemberShortArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberShortArrAcceptDefField"),
+                    SingleMemberShortArrayDef.class);
+        checkEquals(SingleMemberIntArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberIntArrAcceptDefField"),
+                    SingleMemberIntArrayDef.class);
+        checkEquals(SingleMemberLongArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberLongArrAcceptDefField"),
+                    SingleMemberLongArrayDef.class);
+        checkEquals(SingleMemberCharArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberCharArrAcceptDefField"),
+                    SingleMemberCharArrayDef.class);
+        checkEquals(SingleMemberFloatArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberFloatArrAcceptDefField"),
+                    SingleMemberFloatArrayDef.class);
+        checkEquals(SingleMemberDoubleArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberDoubleArrAcceptDefField"),
+                    SingleMemberDoubleArrayDef.class);
+        checkEquals(SingleMemberBooleanArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberBooleanArrAcceptDefField"),
+                    SingleMemberBooleanArrayDef.class);
+        checkEquals(SingleMemberStringArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberStringArrAcceptDefField"),
+                    SingleMemberStringArrayDef.class);
+        checkEquals(SingleMemberClassArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberClassArrAcceptDefField"),
+                    SingleMemberClassArrayDef.class);
+        checkEquals(SingleMemberEnumArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberEnumArrAcceptDefField"),
+                    SingleMemberEnumArrayDef.class);
+
+        // *** TESTS FOR EQUALS AND HASHCODE - NEGATIVE
+
+        // MULTIMEMBER SCALAR TYPES
+        checkUnequals(scalarTypesOverrideDefaultClass.class, UnitTest.class.getField("scalarTypesAcceptDefaultField"),
+                    ScalarTypesWithDefault.class);
+        checkUnequals(scalarTypesAcceptDefaultClass.class, UnitTest.class.getField("scalarTypesOverrideDefaultField"),
+                    ScalarTypesWithDefault.class);
+
+        // MULTIMEMBER ARRAY TYPES
+        checkUnequals(emptyArrayTypesClass.class, UnitTest.class.getField("singleElementArrayTypesField"),
+                    ArrayTypes.class);
+        checkUnequals(singleElementArrayTypesClass.class, UnitTest.class.getField("twoElementArrayTypesField"),
+                    ArrayTypes.class);
+        checkUnequals(twoElementArrayTypesClass.class, UnitTest.class.getField("singleElementArrayTypesField"),
+                    ArrayTypes.class);
+        checkUnequals(arrayTypesOverrideDefaultClass.class, UnitTest.class.getField("arrayTypesAcceptDefaultField"),
+                    ArrayTypesWithDefault.class);
+        checkUnequals(arrayTypesAcceptDefaultClass.class, UnitTest.class.getField("arrayTypesOverrideDefaultField"),
+                    ArrayTypesWithDefault.class);
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-OVERRIDE
+        checkUnequals(SingleMemberByteOvrdDefClass.class, UnitTest.class.getField("SingleMemberByteAcceptDefField"),
+                    SingleMemberByteWithDef.class);
+        checkUnequals(SingleMemberShortOvrdDefClass.class, UnitTest.class.getField("SingleMemberShortAcceptDefField"),
+                    SingleMemberShortWithDef.class);
+        checkUnequals(SingleMemberIntOvrdDefClass.class, UnitTest.class.getField("SingleMemberIntAcceptDefField"),
+                    SingleMemberIntWithDef.class);
+        checkUnequals(SingleMemberLongOvrdDefClass.class, UnitTest.class.getField("SingleMemberLongAcceptDefField"),
+                    SingleMemberLongWithDef.class);
+        checkUnequals(SingleMemberCharOvrdDefClass.class, UnitTest.class.getField("SingleMemberCharAcceptDefField"),
+                    SingleMemberCharWithDef.class);
+        checkUnequals(SingleMemberFloatOvrdDefClass.class, UnitTest.class.getField("SingleMemberFloatAcceptDefField"),
+                    SingleMemberFloatWithDef.class);
+        checkUnequals(SingleMemberDoubleOvrdDefClass.class, UnitTest.class.getField("SingleMemberDoubleAcceptDefField"),
+                    SingleMemberDoubleWithDef.class);
+        checkUnequals(SingleMemberBooleanOvrdDefClass.class, UnitTest.class.getField("SingleMemberBooleanAcceptDefField"),
+                    SingleMemberBooleanWithDef.class);
+        checkUnequals(SingleMemberStringOvrdDefClass.class, UnitTest.class.getField("SingleMemberStringAcceptDefField"),
+                    SingleMemberStringWithDef.class);
+        checkUnequals(SingleMemberClassOvrdDefClass.class, UnitTest.class.getField("SingleMemberClassAcceptDefField"),
+                    SingleMemberClassWithDef.class);
+        checkUnequals(SingleMemberEnumOvrdDefClass.class, UnitTest.class.getField("SingleMemberEnumAcceptDefField"),
+                    SingleMemberEnumWithDef.class);
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-ACCEPT
+        checkUnequals(SingleMemberByteAcceptDefClass.class, UnitTest.class.getField("SingleMemberByteOvrdDefField"),
+                    SingleMemberByteWithDef.class);
+        checkUnequals(SingleMemberShortAcceptDefClass.class, UnitTest.class.getField("SingleMemberShortOvrdDefField"),
+                    SingleMemberShortWithDef.class);
+        checkUnequals(SingleMemberIntAcceptDefClass.class, UnitTest.class.getField("SingleMemberIntOvrdDefField"),
+                    SingleMemberIntWithDef.class);
+        checkUnequals(SingleMemberLongAcceptDefClass.class, UnitTest.class.getField("SingleMemberLongOvrdDefField"),
+                    SingleMemberLongWithDef.class);
+        checkUnequals(SingleMemberCharAcceptDefClass.class, UnitTest.class.getField("SingleMemberCharOvrdDefField"),
+                    SingleMemberCharWithDef.class);
+        checkUnequals(SingleMemberFloatAcceptDefClass.class, UnitTest.class.getField("SingleMemberFloatOvrdDefField"),
+                    SingleMemberFloatWithDef.class);
+        checkUnequals(SingleMemberDoubleAcceptDefClass.class, UnitTest.class.getField("SingleMemberDoubleOvrdDefField"),
+                    SingleMemberDoubleWithDef.class);
+        checkUnequals(SingleMemberBooleanAcceptDefClass.class, UnitTest.class.getField("SingleMemberBooleanOvrdDefField"),
+                    SingleMemberBooleanWithDef.class);
+        checkUnequals(SingleMemberStringAcceptDefClass.class, UnitTest.class.getField("SingleMemberStringOvrdDefField"),
+                    SingleMemberStringWithDef.class);
+        checkUnequals(SingleMemberClassAcceptDefClass.class, UnitTest.class.getField("SingleMemberClassOvrdDefField"),
+                    SingleMemberClassWithDef.class);
+        checkUnequals(SingleMemberEnumAcceptDefClass.class, UnitTest.class.getField("SingleMemberEnumOvrdDefField"),
+                    SingleMemberEnumWithDef.class);
+
+        // SINGLE-MEMBER ARRAY TYPES (EMPTY ARRAY)
+        checkUnequals(SingleMemberByteArrEmptyClass.class, UnitTest.class.getField("SingleMemberByteArrOneField"),
+                    SingleMemberByteArray.class);
+        checkUnequals(SingleMemberShortArrEmptyClass.class, UnitTest.class.getField("SingleMemberShortArrOneField"),
+                    SingleMemberShortArray.class);
+        checkUnequals(SingleMemberIntArrEmptyClass.class, UnitTest.class.getField("SingleMemberIntArrOneField"),
+                    SingleMemberIntArray.class);
+        checkUnequals(SingleMemberLongArrEmptyClass.class, UnitTest.class.getField("SingleMemberLongArrOneField"),
+                    SingleMemberLongArray.class);
+        checkUnequals(SingleMemberCharArrEmptyClass.class, UnitTest.class.getField("SingleMemberCharArrOneField"),
+                    SingleMemberCharArray.class);
+        checkUnequals(SingleMemberFloatArrEmptyClass.class, UnitTest.class.getField("SingleMemberFloatArrOneField"),
+                    SingleMemberFloatArray.class);
+        checkUnequals(SingleMemberDoubleArrEmptyClass.class, UnitTest.class.getField("SingleMemberDoubleArrOneField"),
+                    SingleMemberDoubleArray.class);
+        checkUnequals(SingleMemberBooleanArrEmptyClass.class, UnitTest.class.getField("SingleMemberBooleanArrOneField"),
+                    SingleMemberBooleanArray.class);
+        checkUnequals(SingleMemberStringArrEmptyClass.class, UnitTest.class.getField("SingleMemberStringArrOneField"),
+                    SingleMemberStringArray.class);
+        checkUnequals(SingleMemberClassArrEmptyClass.class, UnitTest.class.getField("SingleMemberClassArrOneField"),
+                    SingleMemberClassArray.class);
+        checkUnequals(SingleMemberEnumArrEmptyClass.class, UnitTest.class.getField("SingleMemberEnumArrOneField"),
+                    SingleMemberEnumArray.class);
+
+        // SINGLE-MEMBER ARRAY TYPES (ONE-ELEMENT ARRAY)
+        checkUnequals(SingleMemberByteArrOneClass.class, UnitTest.class.getField("SingleMemberByteArrTwoField"),
+                    SingleMemberByteArray.class);
+        checkUnequals(SingleMemberShortArrOneClass.class, UnitTest.class.getField("SingleMemberShortArrTwoField"),
+                    SingleMemberShortArray.class);
+        checkUnequals(SingleMemberIntArrOneClass.class, UnitTest.class.getField("SingleMemberIntArrTwoField"),
+                    SingleMemberIntArray.class);
+        checkUnequals(SingleMemberLongArrOneClass.class, UnitTest.class.getField("SingleMemberLongArrTwoField"),
+                    SingleMemberLongArray.class);
+        checkUnequals(SingleMemberCharArrOneClass.class, UnitTest.class.getField("SingleMemberCharArrTwoField"),
+                    SingleMemberCharArray.class);
+        checkUnequals(SingleMemberFloatArrOneClass.class, UnitTest.class.getField("SingleMemberFloatArrTwoField"),
+                    SingleMemberFloatArray.class);
+        checkUnequals(SingleMemberDoubleArrOneClass.class, UnitTest.class.getField("SingleMemberDoubleArrTwoField"),
+                    SingleMemberDoubleArray.class);
+        checkUnequals(SingleMemberBooleanArrOneClass.class, UnitTest.class.getField("SingleMemberBooleanArrTwoField"),
+                    SingleMemberBooleanArray.class);
+        checkUnequals(SingleMemberStringArrOneClass.class, UnitTest.class.getField("SingleMemberStringArrTwoField"),
+                    SingleMemberStringArray.class);
+        checkUnequals(SingleMemberClassArrOneClass.class, UnitTest.class.getField("SingleMemberClassArrTwoField"),
+                    SingleMemberClassArray.class);
+        checkUnequals(SingleMemberEnumArrOneClass.class, UnitTest.class.getField("SingleMemberEnumArrTwoField"),
+                    SingleMemberEnumArray.class);
+
+        // SINGLE-MEMBER ARRAY TYPES (TWO-ELEMENT ARRAY)
+        checkUnequals(SingleMemberByteArrTwoClass.class, UnitTest.class.getField("SingleMemberByteArrOneField"),
+                    SingleMemberByteArray.class);
+        checkUnequals(SingleMemberShortArrTwoClass.class, UnitTest.class.getField("SingleMemberShortArrOneField"),
+                    SingleMemberShortArray.class);
+        checkUnequals(SingleMemberIntArrTwoClass.class, UnitTest.class.getField("SingleMemberIntArrOneField"),
+                    SingleMemberIntArray.class);
+        checkUnequals(SingleMemberLongArrTwoClass.class, UnitTest.class.getField("SingleMemberLongArrOneField"),
+                    SingleMemberLongArray.class);
+        checkUnequals(SingleMemberCharArrTwoClass.class, UnitTest.class.getField("SingleMemberCharArrOneField"),
+                    SingleMemberCharArray.class);
+        checkUnequals(SingleMemberFloatArrTwoClass.class, UnitTest.class.getField("SingleMemberFloatArrOneField"),
+                    SingleMemberFloatArray.class);
+        checkUnequals(SingleMemberDoubleArrTwoClass.class, UnitTest.class.getField("SingleMemberDoubleArrOneField"),
+                    SingleMemberDoubleArray.class);
+        checkUnequals(SingleMemberBooleanArrTwoClass.class, UnitTest.class.getField("SingleMemberBooleanArrOneField"),
+                    SingleMemberBooleanArray.class);
+        checkUnequals(SingleMemberStringArrTwoClass.class, UnitTest.class.getField("SingleMemberStringArrOneField"),
+                    SingleMemberStringArray.class);
+        checkUnequals(SingleMemberClassArrTwoClass.class, UnitTest.class.getField("SingleMemberClassArrOneField"),
+                    SingleMemberClassArray.class);
+        checkUnequals(SingleMemberEnumArrTwoClass.class, UnitTest.class.getField("SingleMemberEnumArrOneField"),
+                    SingleMemberEnumArray.class);
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (OVERRIDE)
+        checkUnequals(SingleMemberByteArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberByteArrAcceptDefField"),
+                    SingleMemberByteArrayDef.class);
+        checkUnequals(SingleMemberShortArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberShortArrAcceptDefField"),
+                    SingleMemberShortArrayDef.class);
+        checkUnequals(SingleMemberIntArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberIntArrAcceptDefField"),
+                    SingleMemberIntArrayDef.class);
+        checkUnequals(SingleMemberLongArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberLongArrAcceptDefField"),
+                    SingleMemberLongArrayDef.class);
+        checkUnequals(SingleMemberCharArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberCharArrAcceptDefField"),
+                    SingleMemberCharArrayDef.class);
+        checkUnequals(SingleMemberFloatArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberFloatArrAcceptDefField"),
+                    SingleMemberFloatArrayDef.class);
+        checkUnequals(SingleMemberDoubleArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberDoubleArrAcceptDefField"),
+                    SingleMemberDoubleArrayDef.class);
+        checkUnequals(SingleMemberBooleanArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberBooleanArrAcceptDefField"),
+                    SingleMemberBooleanArrayDef.class);
+        checkUnequals(SingleMemberStringArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberStringArrAcceptDefField"),
+                    SingleMemberStringArrayDef.class);
+        checkUnequals(SingleMemberClassArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberClassArrAcceptDefField"),
+                    SingleMemberClassArrayDef.class);
+        checkUnequals(SingleMemberEnumArrOvrdDefClass.class, UnitTest.class.getField("SingleMemberEnumArrAcceptDefField"),
+                    SingleMemberEnumArrayDef.class);
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (ACCEPT)
+        checkUnequals(SingleMemberByteArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberByteArrOvrdDefField"),
+                    SingleMemberByteArrayDef.class);
+        checkUnequals(SingleMemberShortArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberShortArrOvrdDefField"),
+                    SingleMemberShortArrayDef.class);
+        checkUnequals(SingleMemberIntArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberIntArrOvrdDefField"),
+                    SingleMemberIntArrayDef.class);
+        checkUnequals(SingleMemberLongArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberLongArrOvrdDefField"),
+                    SingleMemberLongArrayDef.class);
+        checkUnequals(SingleMemberCharArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberCharArrOvrdDefField"),
+                    SingleMemberCharArrayDef.class);
+        checkUnequals(SingleMemberFloatArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberFloatArrOvrdDefField"),
+                    SingleMemberFloatArrayDef.class);
+        checkUnequals(SingleMemberDoubleArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberDoubleArrOvrdDefField"),
+                    SingleMemberDoubleArrayDef.class);
+        checkUnequals(SingleMemberBooleanArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberBooleanArrOvrdDefField"),
+                    SingleMemberBooleanArrayDef.class);
+        checkUnequals(SingleMemberStringArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberStringArrOvrdDefField"),
+                    SingleMemberStringArrayDef.class);
+        checkUnequals(SingleMemberClassArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberClassArrOvrdDefField"),
+                    SingleMemberClassArrayDef.class);
+        checkUnequals(SingleMemberEnumArrAcceptDefClass.class, UnitTest.class.getField("SingleMemberEnumArrOvrdDefField"),
+                    SingleMemberEnumArrayDef.class);
+
+        // *** TESTS FOR SERIALIZATION AND DESERIALIZATION
+
+        // MULTIMEMBER SCALAR TYPES
+        checkSerialization(scalarTypesClass.class, ScalarTypes.class);
+        checkSerialization(scalarTypesOverrideDefaultClass.class, ScalarTypesWithDefault.class);
+        checkSerialization(scalarTypesAcceptDefaultClass.class, ScalarTypesWithDefault.class);
+
+        // MULTIMEMBER ARRAY TYPES
+        checkSerialization(emptyArrayTypesClass.class, ArrayTypes.class);
+        checkSerialization(singleElementArrayTypesClass.class, ArrayTypes.class);
+        checkSerialization(twoElementArrayTypesClass.class, ArrayTypes.class);
+        checkSerialization(arrayTypesOverrideDefaultClass.class, ArrayTypesWithDefault.class);
+        checkSerialization(arrayTypesAcceptDefaultClass.class, ArrayTypesWithDefault.class);
+
+        // MARKER TYPE
+        checkSerialization(markerClass.class, Marker.class);
+
+        // SINGLE-MEMBER SCALAR TYPES
+        checkSerialization(SingleMemberByteClass.class, SingleMemberByte.class);
+        checkSerialization(SingleMemberShortClass.class, SingleMemberShort.class);
+        checkSerialization(SingleMemberIntClass.class, SingleMemberInt.class);
+        checkSerialization(SingleMemberLongClass.class, SingleMemberLong.class);
+        checkSerialization(SingleMemberCharClass.class, SingleMemberChar.class);
+        checkSerialization(SingleMemberFloatClass.class, SingleMemberFloat.class);
+        checkSerialization(SingleMemberDoubleClass.class, SingleMemberDouble.class);
+        checkSerialization(SingleMemberBooleanClass.class, SingleMemberBoolean.class);
+        checkSerialization(SingleMemberStringClass.class, SingleMemberString.class);
+        checkSerialization(SingleMemberClassClass.class, SingleMemberClass.class);
+        checkSerialization(SingleMemberEnumClass.class, SingleMemberEnum.class);
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-OVERRIDE
+        checkSerialization(SingleMemberByteOvrdDefClass.class, SingleMemberByteWithDef.class);
+        checkSerialization(SingleMemberShortOvrdDefClass.class, SingleMemberShortWithDef.class);
+        checkSerialization(SingleMemberIntOvrdDefClass.class, SingleMemberIntWithDef.class);
+        checkSerialization(SingleMemberLongOvrdDefClass.class, SingleMemberLongWithDef.class);
+        checkSerialization(SingleMemberCharOvrdDefClass.class, SingleMemberCharWithDef.class);
+        checkSerialization(SingleMemberFloatOvrdDefClass.class, SingleMemberFloatWithDef.class);
+        checkSerialization(SingleMemberDoubleOvrdDefClass.class, SingleMemberDoubleWithDef.class);
+        checkSerialization(SingleMemberBooleanOvrdDefClass.class, SingleMemberBooleanWithDef.class);
+        checkSerialization(SingleMemberStringOvrdDefClass.class, SingleMemberStringWithDef.class);
+        checkSerialization(SingleMemberClassOvrdDefClass.class, SingleMemberClassWithDef.class);
+        checkSerialization(SingleMemberEnumOvrdDefClass.class, SingleMemberEnumWithDef.class);
+
+        // SINGLE-MEMBER SCALAR TYPES WITH DEFAULT-ACCEPT
+        checkSerialization(SingleMemberByteAcceptDefClass.class, SingleMemberByteWithDef.class);
+        checkSerialization(SingleMemberShortAcceptDefClass.class, SingleMemberShortWithDef.class);
+        checkSerialization(SingleMemberIntAcceptDefClass.class, SingleMemberIntWithDef.class);
+        checkSerialization(SingleMemberLongAcceptDefClass.class, SingleMemberLongWithDef.class);
+        checkSerialization(SingleMemberCharAcceptDefClass.class, SingleMemberCharWithDef.class);
+        checkSerialization(SingleMemberFloatAcceptDefClass.class, SingleMemberFloatWithDef.class);
+        checkSerialization(SingleMemberDoubleAcceptDefClass.class, SingleMemberDoubleWithDef.class);
+        checkSerialization(SingleMemberBooleanAcceptDefClass.class, SingleMemberBooleanWithDef.class);
+        checkSerialization(SingleMemberStringAcceptDefClass.class, SingleMemberStringWithDef.class);
+        checkSerialization(SingleMemberClassAcceptDefClass.class, SingleMemberClassWithDef.class);
+        checkSerialization(SingleMemberEnumAcceptDefClass.class, SingleMemberEnumWithDef.class);
+
+        // SINGLE-MEMBER ARRAY TYPES (EMPTY ARRAY)
+        checkSerialization(SingleMemberByteArrEmptyClass.class, SingleMemberByteArray.class);
+        checkSerialization(SingleMemberShortArrEmptyClass.class, SingleMemberShortArray.class);
+        checkSerialization(SingleMemberIntArrEmptyClass.class, SingleMemberIntArray.class);
+        checkSerialization(SingleMemberLongArrEmptyClass.class, SingleMemberLongArray.class);
+        checkSerialization(SingleMemberCharArrEmptyClass.class, SingleMemberCharArray.class);
+        checkSerialization(SingleMemberFloatArrEmptyClass.class, SingleMemberFloatArray.class);
+        checkSerialization(SingleMemberDoubleArrEmptyClass.class, SingleMemberDoubleArray.class);
+        checkSerialization(SingleMemberBooleanArrEmptyClass.class, SingleMemberBooleanArray.class);
+        checkSerialization(SingleMemberStringArrEmptyClass.class, SingleMemberStringArray.class);
+        checkSerialization(SingleMemberClassArrEmptyClass.class, SingleMemberClassArray.class);
+        checkSerialization(SingleMemberEnumArrEmptyClass.class, SingleMemberEnumArray.class);
+
+        // SINGLE-MEMBER ARRAY TYPES (ONE-ELEMENT ARRAY)
+        checkSerialization(SingleMemberByteArrOneClass.class, SingleMemberByteArray.class);
+        checkSerialization(SingleMemberShortArrOneClass.class, SingleMemberShortArray.class);
+        checkSerialization(SingleMemberIntArrOneClass.class, SingleMemberIntArray.class);
+        checkSerialization(SingleMemberLongArrOneClass.class, SingleMemberLongArray.class);
+        checkSerialization(SingleMemberCharArrOneClass.class, SingleMemberCharArray.class);
+        checkSerialization(SingleMemberFloatArrOneClass.class, SingleMemberFloatArray.class);
+        checkSerialization(SingleMemberDoubleArrOneClass.class, SingleMemberDoubleArray.class);
+        checkSerialization(SingleMemberBooleanArrOneClass.class, SingleMemberBooleanArray.class);
+        checkSerialization(SingleMemberStringArrOneClass.class, SingleMemberStringArray.class);
+        checkSerialization(SingleMemberClassArrOneClass.class, SingleMemberClassArray.class);
+        checkSerialization(SingleMemberEnumArrOneClass.class, SingleMemberEnumArray.class);
+
+        // SINGLE-MEMBER ARRAY TYPES (TWO-ELEMENT ARRAY)
+        checkSerialization(SingleMemberByteArrTwoClass.class, SingleMemberByteArray.class);
+        checkSerialization(SingleMemberShortArrTwoClass.class, SingleMemberShortArray.class);
+        checkSerialization(SingleMemberIntArrTwoClass.class, SingleMemberIntArray.class);
+        checkSerialization(SingleMemberLongArrTwoClass.class, SingleMemberLongArray.class);
+        checkSerialization(SingleMemberCharArrTwoClass.class, SingleMemberCharArray.class);
+        checkSerialization(SingleMemberFloatArrTwoClass.class, SingleMemberFloatArray.class);
+        checkSerialization(SingleMemberDoubleArrTwoClass.class, SingleMemberDoubleArray.class);
+        checkSerialization(SingleMemberBooleanArrTwoClass.class, SingleMemberBooleanArray.class);
+        checkSerialization(SingleMemberStringArrTwoClass.class, SingleMemberStringArray.class);
+        checkSerialization(SingleMemberClassArrTwoClass.class, SingleMemberClassArray.class);
+        checkSerialization(SingleMemberEnumArrTwoClass.class, SingleMemberEnumArray.class);
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (OVERRIDE)
+        checkSerialization(SingleMemberByteArrOvrdDefClass.class, SingleMemberByteArrayDef.class);
+        checkSerialization(SingleMemberShortArrOvrdDefClass.class, SingleMemberShortArrayDef.class);
+        checkSerialization(SingleMemberIntArrOvrdDefClass.class, SingleMemberIntArrayDef.class);
+        checkSerialization(SingleMemberLongArrOvrdDefClass.class, SingleMemberLongArrayDef.class);
+        checkSerialization(SingleMemberCharArrOvrdDefClass.class, SingleMemberCharArrayDef.class);
+        checkSerialization(SingleMemberFloatArrOvrdDefClass.class, SingleMemberFloatArrayDef.class);
+        checkSerialization(SingleMemberDoubleArrOvrdDefClass.class, SingleMemberDoubleArrayDef.class);
+        checkSerialization(SingleMemberBooleanArrOvrdDefClass.class, SingleMemberBooleanArrayDef.class);
+        checkSerialization(SingleMemberStringArrOvrdDefClass.class, SingleMemberStringArrayDef.class);
+        checkSerialization(SingleMemberClassArrOvrdDefClass.class, SingleMemberClassArrayDef.class);
+        checkSerialization(SingleMemberEnumArrOvrdDefClass.class, SingleMemberEnumArrayDef.class);
+
+        // SINGLE-MEMBER ARRAY TYPES WITH DEFAULT (ACCEPT)
+        checkSerialization(SingleMemberByteArrAcceptDefClass.class, SingleMemberByteArrayDef.class);
+        checkSerialization(SingleMemberShortArrAcceptDefClass.class, SingleMemberShortArrayDef.class);
+        checkSerialization(SingleMemberIntArrAcceptDefClass.class, SingleMemberIntArrayDef.class);
+        checkSerialization(SingleMemberLongArrAcceptDefClass.class, SingleMemberLongArrayDef.class);
+        checkSerialization(SingleMemberCharArrAcceptDefClass.class, SingleMemberCharArrayDef.class);
+        checkSerialization(SingleMemberFloatArrAcceptDefClass.class, SingleMemberFloatArrayDef.class);
+        checkSerialization(SingleMemberDoubleArrAcceptDefClass.class, SingleMemberDoubleArrayDef.class);
+        checkSerialization(SingleMemberBooleanArrAcceptDefClass.class, SingleMemberBooleanArrayDef.class);
+        checkSerialization(SingleMemberStringArrAcceptDefClass.class, SingleMemberStringArrayDef.class);
+        checkSerialization(SingleMemberClassArrAcceptDefClass.class, SingleMemberClassArrayDef.class);
+        checkSerialization(SingleMemberEnumArrAcceptDefClass.class, SingleMemberEnumArrayDef.class);
+
+        // *** TESTS FOR ANNOTATION INHERITANCE AND ENUMERATING DECLARED ANNOTATIONS
+
+        // Inheritance tests
+        checkInheritence(Grandpa.class, true, true);
+        checkInheritence(Dad.class,     true, false);
+        checkInheritence(Son.class,     true, true);
+
+        // Declared annotations tests
+        checkDeclaredAnnotations(Grandpa.class, true, true);
+        checkDeclaredAnnotations(Dad.class,     false, false);
+        checkDeclaredAnnotations(Son.class,     false, true);
+
+        // Generate summary
+        System.out.println("\n" + numTests + " tests completed");
+        if (failCount != 0)
+            throw new Exception("Failure count: " + failCount);
+        else
+            System.out.println("Success.");
+    }
+
+    static int failCount = 0;
+
+    private static void fail(String test) {
+        System.out.println("Failure: " + test);
+        failCount++;
+    }
+
+    // ANNOTATION-VERIFICATION METHODS
+
+    // Scalar multi-member
+
+    static void checkScalarTypes(AnnotatedElement e) {
+        try {
+            checkScalarTypes(e.getAnnotation(ScalarTypes.class), e);
+        } catch(Throwable t) {
+            fail("ScalarTypes " + e + ": " + t);
+            t.printStackTrace();
+        }
+    }
+
+    static void checkScalarTypes(ScalarTypes st, AnnotatedElement e) throws Exception {
+        numTests++;
+        if (!(st.b()    == 1            &&
+              st.s()    == 2            &&
+              st.i()    == 3            &&
+              st.l()    == 4L           &&
+              st.c()    == '5'          &&
+              st.f()    == 6.0f         &&
+              st.d()    == 7.0          &&
+              st.bool() == true         &&
+              st.str().equals("custom") &&
+              st.cls()  == Map.class    &&
+              st.e()    == Stooge.MOE   &&
+              st.a().x() == 1 && st.a().y() == 2))
+            fail("ScalarTypes" + e);
+    }
+
+    static void checkScalarTypesOverrideDefault(AnnotatedElement e) {
+        try {
+            checkScalarTypesOverrideDefault(e.getAnnotation(ScalarTypesWithDefault.class), e);
+        } catch(Throwable t) {
+            fail("ScalarTypesOverrideDefaults" + e + ": " + t);
+        }
+    }
+
+    static void checkScalarTypesOverrideDefault(ScalarTypesWithDefault st, AnnotatedElement e) {
+        numTests++;
+        if (!(st.b()    == 1            &&
+              st.s()    == 2            &&
+              st.i()    == 3            &&
+              st.l()    == 4L           &&
+              st.c()    == '5'          &&
+              st.f()    == 6.0f         &&
+              st.d()    == 7.0          &&
+              st.bool() == true         &&
+              st.str().equals("custom") &&
+              st.cls()  == Map.class    &&
+              st.e()    == Stooge.MOE))
+            fail("ScalarTypesOverrideDefaults" + e);
+    }
+
+    static void checkScalarTypesAcceptDefault(AnnotatedElement e) {
+        try {
+            checkScalarTypesAcceptDefault(e.getAnnotation(ScalarTypesWithDefault.class), e);
+        } catch(Throwable t) {
+            fail("ScalarTypesAcceptDefaults" + e + ": " + t);
+        }
+    }
+
+    static void checkScalarTypesAcceptDefault(ScalarTypesWithDefault st, AnnotatedElement e) {
+        numTests++;
+        if (!(st.b()    == 11            &&
+              st.s()    == 12            &&
+              st.i()    == 13            &&
+              st.l()    == 14L           &&
+              st.c()    == 'V'           &&
+              st.f()    == 16.0f         &&
+              st.d()    == 17.0          &&
+              st.bool() == false         &&
+              st.str().equals("default") &&
+              st.cls()   == Class.class  &&
+              st.e()    == Stooge.LARRY  &&
+              st.a().x() == 11 && st.a().y() == 12))
+            fail("ScalarTypesAcceptDefaults" + e);
+    }
+
+    // Array multi-member
+
+    static void checkArrayTypes0(AnnotatedElement e) {
+        try {
+            checkArrayTypes0(e.getAnnotation(ArrayTypes.class), e);
+        } catch(Throwable t) {
+            fail("ArrayTypes(Empty)" + e + ": " + t);
+        }
+    }
+
+    static void checkArrayTypes0(ArrayTypes at, AnnotatedElement e) {
+        numTests++;
+        if (!(at.b().length == 0 &&
+              at.s().length == 0 &&
+              at.i().length == 0 &&
+              at.l().length == 0 &&
+              at.c().length == 0 &&
+              at.f().length == 0 &&
+              at.d().length == 0 &&
+              at.bool().length == 0 &&
+              at.str().length == 0 &&
+              at.cls().length == 0 &&
+              at.e().length == 0 &&
+              at.a().length == 0)) {
+            fail("ArrayTypes(Empty)" + e);
+        }
+    }
+
+    static void checkArrayTypes1(AnnotatedElement e) {
+        try {
+            checkArrayTypes1(e.getAnnotation(ArrayTypes.class), e);
+        } catch(Throwable t) {
+            fail("ArrayTypes(One element)" + e + ": " + t);
+        }
+    }
+
+    static void checkArrayTypes1(ArrayTypes at, AnnotatedElement e) {
+        numTests++;
+        if (!(at.b()[0]    == 1            &&
+              at.s()[0]    == 2            &&
+              at.i()[0]    == 3            &&
+              at.l()[0]    == 4L           &&
+              at.c()[0]    == '5'          &&
+              at.f()[0]    == 6.0f         &&
+              at.d()[0]    == 7.0          &&
+              at.bool()[0] == true         &&
+              at.str()[0].equals("custom") &&
+              at.cls()[0]  == Map.class    &&
+              at.e()[0]    == Stooge.MOE   &&
+              at.a()[0].x() == 1 && at.a()[0].y() == 2 &&
+
+              at.b().length==1    && at.s().length==1   && at.i().length==1 &&
+              at.l().length==1    && at.c().length==1   && at.d().length==1 &&
+              at.bool().length==1 && at.str().length==1 &&
+              at.cls().length==1  && at.cls().length==1 && at.a().length==1))
+            fail("ArrayTypes(One element)" + e);
+    }
+
+    static void checkArrayTypes2(AnnotatedElement e) {
+        try {
+            checkArrayTypes2(e.getAnnotation(ArrayTypes.class), e);
+        } catch(Throwable t) {
+            fail("ArrayTypes(Two element)" + e + ": " + t);
+        }
+    }
+
+    static void checkArrayTypes2(ArrayTypes at, AnnotatedElement e) {
+        numTests++;
+        if (!(at.b()[0]    == 1            && at.b()[1]    == 2            &&
+              at.s()[0]    == 2            && at.s()[1]    == 3            &&
+              at.i()[0]    == 3            && at.i()[1]    == 4            &&
+              at.l()[0]    == 4L           && at.l()[1]    == 5L           &&
+              at.c()[0]    == '5'          && at.c()[1]    == '6'          &&
+              at.f()[0]    == 6.0f         && at.f()[1]    == 7.0f         &&
+              at.d()[0]    == 7.0          && at.d()[1]    == 8.0          &&
+              at.bool()[0] == true         && at.bool()[1] == false        &&
+              at.str()[0].equals("custom") && at.str()[1].equals("paint")  &&
+              at.cls()[0]  == Map.class    && at.cls()[1]  == Set.class    &&
+              at.e()[0]    == Stooge.MOE   && at.e()[1]    == Stooge.CURLY &&
+              at.a()[0].x() == 1 && at.a()[0].y() == 2 && at.a()[1].x() == 3 && at.a()[1].y() == 4 &&
+
+              at.b().length==2    && at.s().length==2   && at.i().length==2 &&
+              at.l().length==2    && at.c().length==2   && at.d().length==2 &&
+              at.bool().length==2 && at.str().length==2 &&
+              at.cls().length==2  && at.cls().length==2 && at.a().length==2))
+            fail("ArrayTypes(Two element)" + e);
+    }
+
+    static void checkArrayTypesOverrideDefault(AnnotatedElement e) {
+        try {
+            checkArrayTypesOverrideDefault(e.getAnnotation(ArrayTypesWithDefault.class), e);
+        } catch(Throwable t) {
+            fail("ArrayTypesOverrideDefault" + e + ": " + t);
+        }
+    }
+
+    static void checkArrayTypesOverrideDefault(ArrayTypesWithDefault at, AnnotatedElement e) {
+        numTests++;
+        if (!(at.b()[0]    == 1            &&
+              at.s()[0]    == 2            &&
+              at.i()[0]    == 3            &&
+              at.l()[0]    == 4L           &&
+              at.c()[0]    == '5'          &&
+              at.f()[0]    == 6.0f         &&
+              at.d()[0]    == 7.0          &&
+              at.bool()[0] == true         &&
+              at.str()[0].equals("custom") &&
+              at.cls()[0]  == Map.class    &&
+              at.e()[0]    == Stooge.MOE   &&
+              at.a()[0].x() == 1 && at.a()[0].y() == 2 &&
+
+              at.b().length==1    && at.s().length==1   && at.i().length==1 &&
+              at.l().length==1    && at.c().length==1   && at.d().length==1 &&
+              at.bool().length==1 && at.str().length==1 &&
+              at.cls().length==1  && at.cls().length==1))
+            fail("ArrayTypesOverrideDefault" + e);
+    }
+
+    static void checkArrayTypesAcceptDefault(AnnotatedElement e) {
+        try {
+            checkArrayTypesAcceptDefault(e.getAnnotation(ArrayTypesWithDefault.class), e);
+        } catch(Throwable t) {
+            fail("ArrayTypesAcceptDefault" + e + ": " + t);
+        }
+    }
+
+    static void checkArrayTypesAcceptDefault(ArrayTypesWithDefault at, AnnotatedElement e) {
+        numTests++;
+        if (!(at.b()[0]    == 11            &&
+              at.s()[0]    == 12            &&
+              at.i()[0]    == 13            &&
+              at.l()[0]    == 14L           &&
+              at.c()[0]    == 'V'           &&
+              at.f()[0]    == 16.0f         &&
+              at.d()[0]    == 17.0          &&
+              at.bool()[0] == false         &&
+              at.str()[0].equals("default") &&
+              at.cls()[0]  == Class.class   &&
+              at.e()[0]    == Stooge.LARRY  &&
+              at.a()[0].x() == 11 && at.a()[0].y() == 12 &&
+
+              at.b().length==1    && at.s().length==1   && at.i().length==1 &&
+              at.l().length==1    && at.c().length==1   && at.d().length==1 &&
+              at.bool().length==1 && at.str().length==1 &&
+              at.cls().length==1  && at.cls().length==1))
+            fail("ArrayTypesAcceptDefault" + e);
+    }
+
+    // Scalar multi-member for parameters
+
+    static void checkScalarTypesParam(Method m) {
+        try {
+            checkScalarTypes((ScalarTypes) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("ScalarTypes" + m + ": " + t);
+        }
+    }
+
+    static void checkScalarTypesOverrideDefaultParam(Method m) {
+        try {
+            checkScalarTypesOverrideDefault((ScalarTypesWithDefault) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("ScalarTypesOverrideDefaults" + m + ": " + t);
+        }
+    }
+
+    static void checkScalarTypesAcceptDefaultParam(Method m) {
+        try {
+            checkScalarTypesAcceptDefault((ScalarTypesWithDefault) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("ScalarTypesAcceptDefaults" + m + ": " + t);
+        }
+    }
+
+    // Array multi-member for parameters
+
+    static void checkArrayTypes0Param(Method m) {
+        try {
+            checkArrayTypes0((ArrayTypes) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("ArrayTypes(Empty)" + m + ": " + t);
+        }
+    }
+
+    static void checkArrayTypes1Param(Method m) {
+        try {
+            checkArrayTypes1((ArrayTypes) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("ArrayTypes(One Element)" + m + ": " + t);
+        }
+    }
+
+    static void checkArrayTypes2Param(Method m) {
+        try {
+            checkArrayTypes2((ArrayTypes) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("ArrayTypes(Two Elements)" + m + ": " + t);
+        }
+    }
+
+    static void checkArrayTypesOverrideDefaultParam(Method m) {
+        try {
+            checkArrayTypesOverrideDefault((ArrayTypesWithDefault) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("ArrayTypesOverrideDefault" + m + ": " + t);
+        }
+    }
+
+    static void checkArrayTypesAcceptDefaultParam(Method m) {
+        try {
+            checkArrayTypesAcceptDefault((ArrayTypesWithDefault) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("ArrayTypesAcceptDefault" + m + ": " + t);
+        }
+    }
+
+    // marker type on parameter
+    static void checkMarkerParam(Method m) {
+        try {
+            checkMarker((Marker) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("Marker" + m + ": " + t);
+        }
+    }
+
+    // single-member scalar types on parameter
+    static void checkSingleMemberByteParam(Method m) {
+        try {
+            checkSingleMemberByte((SingleMemberByte) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberByte" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortParam(Method m) {
+        try {
+            checkSingleMemberShort((SingleMemberShort) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberShort" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntParam(Method m) {
+        try {
+            checkSingleMemberInt((SingleMemberInt) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberInt" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongParam(Method m) {
+        try {
+            checkSingleMemberLong((SingleMemberLong) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberLong" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharParam(Method m) {
+        try {
+            checkSingleMemberChar((SingleMemberChar) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberChar" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatParam(Method m) {
+        try {
+            checkSingleMemberFloat((SingleMemberFloat) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberFloat" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleParam(Method m) {
+        try {
+            checkSingleMemberDouble((SingleMemberDouble) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberDouble" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanParam(Method m) {
+        try {
+            checkSingleMemberBoolean((SingleMemberBoolean) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberBoolean" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringParam(Method m) {
+        try {
+            checkSingleMemberString((SingleMemberString) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberString" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassParam(Method m) {
+        try {
+            checkSingleMemberClass((SingleMemberClass) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberClass" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumParam(Method m) {
+        try {
+            checkSingleMemberEnum((SingleMemberEnum) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberEnum" + m + ": " + t);
+        }
+    }
+
+    // single-member scalar types with default-override on parameter
+    static void checkSingleMemberByteOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberByteOvrdDef((SingleMemberByteWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberByteOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberShortOvrdDef((SingleMemberShortWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberShortOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberIntOvrdDef((SingleMemberIntWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberIntOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberLongOvrdDef((SingleMemberLongWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberLongOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberCharOvrdDef((SingleMemberCharWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberCharOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberFloatOvrdDef((SingleMemberFloatWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberFloatOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberDoubleOvrdDef((SingleMemberDoubleWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberBooleanOvrdDef((SingleMemberBooleanWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberStringOvrdDef((SingleMemberStringWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberStringOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberClassOvrdDef((SingleMemberClassWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberClassOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberEnumOvrdDef((SingleMemberEnumWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberEnumOvrdDef" + m + ": " + t);
+        }
+    }
+
+    // single-member scalar types with default-accept on PARAMETER
+    static void checkSingleMemberByteAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberByteAcceptDef((SingleMemberByteWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberByteAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberShortAcceptDef((SingleMemberShortWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberShortAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberIntAcceptDef((SingleMemberIntWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberIntAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberLongAcceptDef((SingleMemberLongWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberLongAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberCharAcceptDef((SingleMemberCharWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberCharAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberFloatAcceptDef((SingleMemberFloatWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberFloatAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberDoubleAcceptDef((SingleMemberDoubleWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberBooleanAcceptDef((SingleMemberBooleanWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberStringAcceptDef((SingleMemberStringWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberStringAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberClassAcceptDef((SingleMemberClassWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberClassAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberEnumAcceptDef((SingleMemberEnumWithDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberEnumAcceptDef" + m + ": " + t);
+        }
+    }
+
+    // single-member array types (empty array) parameter
+    static void checkSingleMemberByteArrEmptyParam(Method m) {
+        try {
+            checkSingleMemberByteArrEmpty((SingleMemberByteArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberByteArrEmpty" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortArrEmptyParam(Method m) {
+        try {
+            checkSingleMemberShortArrEmpty((SingleMemberShortArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberShortArrEmpty" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntArrEmptyParam(Method m) {
+        try {
+            checkSingleMemberIntArrEmpty((SingleMemberIntArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberIntArrEmpty" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongArrEmptyParam(Method m) {
+        try {
+            checkSingleMemberLongArrEmpty((SingleMemberLongArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberLongArrEmpty" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharArrEmptyParam(Method m) {
+        try {
+            checkSingleMemberCharArrEmpty((SingleMemberCharArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberCharArrEmpty" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatArrEmptyParam(Method m) {
+        try {
+            checkSingleMemberFloatArrEmpty((SingleMemberFloatArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberFloatArrEmpty" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleArrEmptyParam(Method m) {
+        try {
+            checkSingleMemberDoubleArrEmpty((SingleMemberDoubleArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleArrEmpty" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanArrEmptyParam(Method m) {
+        try {
+            checkSingleMemberBooleanArrEmpty((SingleMemberBooleanArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanArrEmpty" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringArrEmptyParam(Method m) {
+        try {
+            checkSingleMemberStringArrEmpty((SingleMemberStringArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberStringArrEmpty" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassArrEmptyParam(Method m) {
+        try {
+            checkSingleMemberClassArrEmpty((SingleMemberClassArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberClassArrEmpty" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumArrEmptyParam(Method m) {
+        try {
+            checkSingleMemberEnumArrEmpty((SingleMemberEnumArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberEnumArrEmpty" + m + ": " + t);
+        }
+    }
+
+    // single-member array types (one-element array) on parameter
+    static void checkSingleMemberByteArrOneParam(Method m) {
+        try {
+            checkSingleMemberByteArrOne((SingleMemberByteArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberByteArrOne" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortArrOneParam(Method m) {
+        try {
+            checkSingleMemberShortArrOne((SingleMemberShortArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberShortArrOne" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntArrOneParam(Method m) {
+        try {
+            checkSingleMemberIntArrOne((SingleMemberIntArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberIntArrOne" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongArrOneParam(Method m) {
+        try {
+            checkSingleMemberLongArrOne((SingleMemberLongArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberLongArrOne" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharArrOneParam(Method m) {
+        try {
+            checkSingleMemberCharArrOne((SingleMemberCharArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberCharArrOne" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatArrOneParam(Method m) {
+        try {
+            checkSingleMemberFloatArrOne((SingleMemberFloatArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberFloatArrOne" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleArrOneParam(Method m) {
+        try {
+            checkSingleMemberDoubleArrOne((SingleMemberDoubleArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleArrOne" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanArrOneParam(Method m) {
+        try {
+            checkSingleMemberBooleanArrOne((SingleMemberBooleanArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanArrOne" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringArrOneParam(Method m) {
+        try {
+            checkSingleMemberStringArrOne((SingleMemberStringArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberStringArrOne" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassArrOneParam(Method m) {
+        try {
+            checkSingleMemberClassArrOne((SingleMemberClassArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberClassArrOne" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumArrOneParam(Method m) {
+        try {
+            checkSingleMemberEnumArrOne((SingleMemberEnumArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberEnumArrOne" + m + ": " + t);
+        }
+    }
+
+    // single-member array types (two-element array) on parameter
+    static void checkSingleMemberByteArrTwoParam(Method m) {
+        try {
+            checkSingleMemberByteArrTwo((SingleMemberByteArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberByteArrTwo" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortArrTwoParam(Method m) {
+        try {
+            checkSingleMemberShortArrTwo((SingleMemberShortArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberShortArrTwo" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntArrTwoParam(Method m) {
+        try {
+            checkSingleMemberIntArrTwo((SingleMemberIntArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberIntArrTwo" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongArrTwoParam(Method m) {
+        try {
+            checkSingleMemberLongArrTwo((SingleMemberLongArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberLongArrTwo" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharArrTwoParam(Method m) {
+        try {
+            checkSingleMemberCharArrTwo((SingleMemberCharArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberCharArrTwo" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatArrTwoParam(Method m) {
+        try {
+            checkSingleMemberFloatArrTwo((SingleMemberFloatArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberFloatArrTwo" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleArrTwoParam(Method m) {
+        try {
+            checkSingleMemberDoubleArrTwo((SingleMemberDoubleArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleArrTwo" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanArrTwoParam(Method m) {
+        try {
+            checkSingleMemberBooleanArrTwo((SingleMemberBooleanArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanArrTwo" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringArrTwoParam(Method m) {
+        try {
+            checkSingleMemberStringArrTwo((SingleMemberStringArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberStringArrTwo" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassArrTwoParam(Method m) {
+        try {
+            checkSingleMemberClassArrTwo((SingleMemberClassArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberClassArrTwo" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumArrTwoParam(Method m) {
+        try {
+            checkSingleMemberEnumArrTwo((SingleMemberEnumArray) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberEnumArrTwo" + m + ": " + t);
+        }
+    }
+
+    // single-member array types with default (override)on parameter
+    static void checkSingleMemberByteArrOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberByteArrOvrdDef((SingleMemberByteArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberByteArrOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortArrOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberShortArrOvrdDef((SingleMemberShortArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberShortArrOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntArrOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberIntArrOvrdDef((SingleMemberIntArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberIntArrOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongArrOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberLongArrOvrdDef((SingleMemberLongArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberLongArrOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharArrOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberCharArrOvrdDef((SingleMemberCharArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberCharArrOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatArrOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberFloatArrOvrdDef((SingleMemberFloatArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberFloatArrOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleArrOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberDoubleArrOvrdDef((SingleMemberDoubleArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleArrOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanArrOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberBooleanArrOvrdDef((SingleMemberBooleanArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanArrOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringArrOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberStringArrOvrdDef((SingleMemberStringArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberStringArrOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassArrOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberClassArrOvrdDef((SingleMemberClassArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberClassArrOvrdDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumArrOvrdDefParam(Method m) {
+        try {
+            checkSingleMemberEnumArrOvrdDef((SingleMemberEnumArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberEnumArrOvrdDef" + m + ": " + t);
+        }
+    }
+
+    // single-member array types with default (accept)on parameter
+    static void checkSingleMemberByteArrAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberByteArrAcceptDef((SingleMemberByteArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberByteArrAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortArrAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberShortArrAcceptDef((SingleMemberShortArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberShortArrAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntArrAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberIntArrAcceptDef((SingleMemberIntArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberIntArrAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongArrAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberLongArrAcceptDef((SingleMemberLongArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberLongArrAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharArrAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberCharArrAcceptDef((SingleMemberCharArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberCharArrAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatArrAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberFloatArrAcceptDef((SingleMemberFloatArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberFloatArrAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleArrAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberDoubleArrAcceptDef((SingleMemberDoubleArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleArrAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanArrAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberBooleanArrAcceptDef((SingleMemberBooleanArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanArrAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringArrAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberStringArrAcceptDef((SingleMemberStringArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberStringArrAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassArrAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberClassArrAcceptDef((SingleMemberClassArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberClassArrAcceptDef" + m + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumArrAcceptDefParam(Method m) {
+        try {
+            checkSingleMemberEnumArrAcceptDef((SingleMemberEnumArrayDef) m.getParameterAnnotations()[0][0], m);
+        } catch(Throwable t) {
+            fail("SingleMemberEnumArrAcceptDef" + m + ": " + t);
+        }
+    }
+
+    // Marker
+    static void checkMarker(AnnotatedElement e) {
+        checkMarker(e.getAnnotation(Marker.class), e);
+    }
+    static void checkMarker(Marker m, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (m == null) fail("Marker " + e);
+        } catch(Throwable t) {
+            fail("Marker " + e + ": " + t);
+        }
+    }
+
+    // Single-member
+
+    static void checkSingleMemberByte(AnnotatedElement e) {
+        checkSingleMemberByte(e.getAnnotation(SingleMemberByte.class), e);
+    }
+    static void checkSingleMemberByte(SingleMemberByte a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 1) fail("SingleMemberByte " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberByte " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShort(AnnotatedElement e) {
+        checkSingleMemberShort(e.getAnnotation(SingleMemberShort.class), e);
+    }
+    static void checkSingleMemberShort(SingleMemberShort a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 2) fail("SingleMemberShort " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberShort " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberInt(AnnotatedElement e) {
+        checkSingleMemberInt(e.getAnnotation(SingleMemberInt.class), e);
+    }
+    static void checkSingleMemberInt(SingleMemberInt a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 3) fail("SingleMemberInt " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberInt " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLong(AnnotatedElement e) {
+        checkSingleMemberLong(e.getAnnotation(SingleMemberLong.class), e);
+    }
+    static void checkSingleMemberLong(SingleMemberLong a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 4L) fail("SingleMemberLong " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberLong " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberChar(AnnotatedElement e) {
+        checkSingleMemberChar(e.getAnnotation(SingleMemberChar.class), e);
+    }
+    static void checkSingleMemberChar(SingleMemberChar a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != '5') fail("SingleMemberChar " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberChar " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloat(AnnotatedElement e) {
+        checkSingleMemberFloat(e.getAnnotation(SingleMemberFloat.class), e);
+    }
+    static void checkSingleMemberFloat(SingleMemberFloat a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 6.0f) fail("SingleMemberFloat " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberFloat " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDouble(AnnotatedElement e) {
+        checkSingleMemberDouble(e.getAnnotation(SingleMemberDouble.class), e);
+    }
+    static void checkSingleMemberDouble(SingleMemberDouble a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 7.0) fail("SingleMemberDouble " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberDouble " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBoolean(AnnotatedElement e) {
+        checkSingleMemberBoolean(e.getAnnotation(SingleMemberBoolean.class), e);
+    }
+    static void checkSingleMemberBoolean(SingleMemberBoolean a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (!a.value()) fail("SingleMemberBoolean " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberBoolean " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberString(AnnotatedElement e) {
+        checkSingleMemberString(e.getAnnotation(SingleMemberString.class), e);
+    }
+    static void checkSingleMemberString(SingleMemberString a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (!(a.value().equals("custom"))) fail("SingleMemberString " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberString " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClass(AnnotatedElement e) {
+        checkSingleMemberClass(e.getAnnotation(SingleMemberClass.class), e);
+    }
+    static void checkSingleMemberClass(SingleMemberClass a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != Map.class) fail("SingleMemberClass " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberClass " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnum(AnnotatedElement e) {
+        checkSingleMemberEnum(e.getAnnotation(SingleMemberEnum.class), e);
+    }
+    static void checkSingleMemberEnum(SingleMemberEnum a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != Stooge.MOE) fail("SingleMemberEnum " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberEnum " + e + ": " + t);
+        }
+    }
+
+    // Single-member with default (Override)
+
+    static void checkSingleMemberByteOvrdDef(AnnotatedElement e) {
+        checkSingleMemberByteOvrdDef(e.getAnnotation(SingleMemberByteWithDef.class), e);
+    }
+    static void checkSingleMemberByteOvrdDef(SingleMemberByteWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 1) fail("SingleMemberByteOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberByteOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortOvrdDef(AnnotatedElement e) {
+        checkSingleMemberShortOvrdDef(e.getAnnotation(SingleMemberShortWithDef.class), e);
+    }
+    static void checkSingleMemberShortOvrdDef(SingleMemberShortWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 2) fail("SingleMemberShortOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberShortOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntOvrdDef(AnnotatedElement e) {
+        checkSingleMemberIntOvrdDef(e.getAnnotation(SingleMemberIntWithDef.class), e);
+    }
+    static void checkSingleMemberIntOvrdDef(SingleMemberIntWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 3) fail("SingleMemberIntOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberIntOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongOvrdDef(AnnotatedElement e) {
+        checkSingleMemberLongOvrdDef(e.getAnnotation(SingleMemberLongWithDef.class), e);
+    }
+    static void checkSingleMemberLongOvrdDef(SingleMemberLongWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 4L) fail("SingleMemberLongOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberLongOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharOvrdDef(AnnotatedElement e) {
+        checkSingleMemberCharOvrdDef(e.getAnnotation(SingleMemberCharWithDef.class), e);
+    }
+    static void checkSingleMemberCharOvrdDef(SingleMemberCharWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != '5') fail("SingleMemberCharOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberCharOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatOvrdDef(AnnotatedElement e) {
+        checkSingleMemberFloatOvrdDef(e.getAnnotation(SingleMemberFloatWithDef.class), e);
+    }
+    static void checkSingleMemberFloatOvrdDef(SingleMemberFloatWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 6.0f) fail("SingleMemberFloatOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberFloatOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleOvrdDef(AnnotatedElement e) {
+        checkSingleMemberDoubleOvrdDef(e.getAnnotation(SingleMemberDoubleWithDef.class), e);
+    }
+    static void checkSingleMemberDoubleOvrdDef(SingleMemberDoubleWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 7.0) fail("SingleMemberDoubleOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanOvrdDef(AnnotatedElement e) {
+        checkSingleMemberBooleanOvrdDef(e.getAnnotation(SingleMemberBooleanWithDef.class), e);
+    }
+    static void checkSingleMemberBooleanOvrdDef(SingleMemberBooleanWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (!a.value()) fail("SingleMemberBooleanOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringOvrdDef(AnnotatedElement e) {
+        checkSingleMemberStringOvrdDef(e.getAnnotation(SingleMemberStringWithDef.class), e);
+    }
+    static void checkSingleMemberStringOvrdDef(SingleMemberStringWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (!(a.value().equals("custom"))) fail("SingleMemberStringOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberStringOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassOvrdDef(AnnotatedElement e) {
+        checkSingleMemberClassOvrdDef(e.getAnnotation(SingleMemberClassWithDef.class), e);
+    }
+    static void checkSingleMemberClassOvrdDef(SingleMemberClassWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != Map.class) fail("SingleMemberClassOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberClassOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumOvrdDef(AnnotatedElement e) {
+        checkSingleMemberEnumOvrdDef(e.getAnnotation(SingleMemberEnumWithDef.class), e);
+    }
+    static void checkSingleMemberEnumOvrdDef(SingleMemberEnumWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != Stooge.MOE) fail("SingleMemberEnumOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberEnumOvrdDef " + e + ": " + t);
+        }
+    }
+
+    // Single-member with default (Accept)
+
+    static void checkSingleMemberByteAcceptDef(AnnotatedElement e) {
+        checkSingleMemberByteAcceptDef(e.getAnnotation(SingleMemberByteWithDef.class), e);
+    }
+    static void checkSingleMemberByteAcceptDef(SingleMemberByteWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 11) fail("SingleMemberByteAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberByteAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortAcceptDef(AnnotatedElement e) {
+        checkSingleMemberShortAcceptDef(e.getAnnotation(SingleMemberShortWithDef.class), e);
+    }
+    static void checkSingleMemberShortAcceptDef(SingleMemberShortWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 12) fail("SingleMemberShortAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberShortAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntAcceptDef(AnnotatedElement e) {
+        checkSingleMemberIntAcceptDef(e.getAnnotation(SingleMemberIntWithDef.class), e);
+    }
+    static void checkSingleMemberIntAcceptDef(SingleMemberIntWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 13) fail("SingleMemberIntAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberIntAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongAcceptDef(AnnotatedElement e) {
+        checkSingleMemberLongAcceptDef(e.getAnnotation(SingleMemberLongWithDef.class), e);
+    }
+    static void checkSingleMemberLongAcceptDef(SingleMemberLongWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 14L) fail("SingleMemberLongAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberLongAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharAcceptDef(AnnotatedElement e) {
+        checkSingleMemberCharAcceptDef(e.getAnnotation(SingleMemberCharWithDef.class), e);
+    }
+    static void checkSingleMemberCharAcceptDef(SingleMemberCharWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 'V') fail("SingleMemberCharAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberCharAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatAcceptDef(AnnotatedElement e) {
+        checkSingleMemberFloatAcceptDef(e.getAnnotation(SingleMemberFloatWithDef.class), e);
+    }
+    static void checkSingleMemberFloatAcceptDef(SingleMemberFloatWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 16.0f) fail("SingleMemberFloatAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberFloatAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleAcceptDef(AnnotatedElement e) {
+        checkSingleMemberDoubleAcceptDef(e.getAnnotation(SingleMemberDoubleWithDef.class), e);
+    }
+    static void checkSingleMemberDoubleAcceptDef(SingleMemberDoubleWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != 17.0) fail("SingleMemberDoubleAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanAcceptDef(AnnotatedElement e) {
+        checkSingleMemberBooleanAcceptDef(e.getAnnotation(SingleMemberBooleanWithDef.class), e);
+    }
+    static void checkSingleMemberBooleanAcceptDef(SingleMemberBooleanWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value()) fail("SingleMemberBooleanAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringAcceptDef(AnnotatedElement e) {
+        checkSingleMemberStringAcceptDef(e.getAnnotation(SingleMemberStringWithDef.class), e);
+    }
+    static void checkSingleMemberStringAcceptDef(SingleMemberStringWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (!(a.value().equals("default"))) fail("SingleMemberStringAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberStringAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassAcceptDef(AnnotatedElement e) {
+        checkSingleMemberClassAcceptDef(e.getAnnotation(SingleMemberClassWithDef.class), e);
+    }
+    static void checkSingleMemberClassAcceptDef(SingleMemberClassWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != Class.class) fail("SingleMemberClassAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberClassAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumAcceptDef(AnnotatedElement e) {
+        checkSingleMemberEnumAcceptDef(e.getAnnotation(SingleMemberEnumWithDef.class), e);
+    }
+    static void checkSingleMemberEnumAcceptDef(SingleMemberEnumWithDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value() != Stooge.LARRY) fail("SingleMemberEnumAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberEnumAcceptDef " + e + ": " + t);
+        }
+    }
+
+    // Single member array (empty array)
+    static void checkSingleMemberByteArrEmpty(AnnotatedElement e) {
+        checkSingleMemberByteArrEmpty(e.getAnnotation(SingleMemberByteArray.class), e);
+    }
+    static void checkSingleMemberByteArrEmpty(SingleMemberByteArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 0) fail("SingleMemberByteArrEmpty " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberByteArrEmpty " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortArrEmpty(AnnotatedElement e) {
+        checkSingleMemberShortArrEmpty(e.getAnnotation(SingleMemberShortArray.class), e);
+    }
+    static void checkSingleMemberShortArrEmpty(SingleMemberShortArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 0) fail("SingleMemberShortArrEmpty " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberShortArrEmpty " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntArrEmpty(AnnotatedElement e) {
+        checkSingleMemberIntArrEmpty(e.getAnnotation(SingleMemberIntArray.class), e);
+    }
+    static void checkSingleMemberIntArrEmpty(SingleMemberIntArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 0) fail("SingleMemberIntArrEmpty " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberIntArrEmpty " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongArrEmpty(AnnotatedElement e) {
+        checkSingleMemberLongArrEmpty(e.getAnnotation(SingleMemberLongArray.class), e);
+    }
+    static void checkSingleMemberLongArrEmpty(SingleMemberLongArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 0) fail("SingleMemberLongArrEmpty " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberLongArrEmpty " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharArrEmpty(AnnotatedElement e) {
+        checkSingleMemberCharArrEmpty(e.getAnnotation(SingleMemberCharArray.class), e);
+    }
+    static void checkSingleMemberCharArrEmpty(SingleMemberCharArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 0) fail("SingleMemberCharArrEmpty " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberCharArrEmpty " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatArrEmpty(AnnotatedElement e) {
+        checkSingleMemberFloatArrEmpty(e.getAnnotation(SingleMemberFloatArray.class), e);
+    }
+    static void checkSingleMemberFloatArrEmpty(SingleMemberFloatArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 0) fail("SingleMemberFloatArrEmpty " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberFloatArrEmpty " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleArrEmpty(AnnotatedElement e) {
+        checkSingleMemberDoubleArrEmpty(e.getAnnotation(SingleMemberDoubleArray.class), e);
+    }
+    static void checkSingleMemberDoubleArrEmpty(SingleMemberDoubleArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 0) fail("SingleMemberDoubleArrEmpty " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleArrEmpty " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanArrEmpty(AnnotatedElement e) {
+        checkSingleMemberBooleanArrEmpty(e.getAnnotation(SingleMemberBooleanArray.class), e);
+    }
+    static void checkSingleMemberBooleanArrEmpty(SingleMemberBooleanArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 0) fail("SingleMemberBooleanArrEmpty " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanArrEmpty " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringArrEmpty(AnnotatedElement e) {
+        checkSingleMemberStringArrEmpty(e.getAnnotation(SingleMemberStringArray.class), e);
+    }
+    static void checkSingleMemberStringArrEmpty(SingleMemberStringArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 0) fail("SingleMemberStringArrEmpty " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberStringArrEmpty " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassArrEmpty(AnnotatedElement e) {
+        checkSingleMemberClassArrEmpty(e.getAnnotation(SingleMemberClassArray.class), e);
+    }
+    static void checkSingleMemberClassArrEmpty(SingleMemberClassArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 0) fail("SingleMemberClassArrEmpty " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberClassArrEmpty " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumArrEmpty(AnnotatedElement e) {
+        checkSingleMemberEnumArrEmpty(e.getAnnotation(SingleMemberEnumArray.class), e);
+    }
+    static void checkSingleMemberEnumArrEmpty(SingleMemberEnumArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 0) fail("SingleMemberEnumArrEmpty " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberEnumArrEmpty " + e + ": " + t);
+        }
+    }
+
+    // Single member array (one element array)
+    static void checkSingleMemberByteArrOne(AnnotatedElement e) {
+        checkSingleMemberByteArrOne(e.getAnnotation(SingleMemberByteArray.class), e);
+    }
+    static void checkSingleMemberByteArrOne(SingleMemberByteArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != (byte)1)
+                fail("SingleMemberByteArrOne " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberByteArrOne " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortArrOne(AnnotatedElement e) {
+        checkSingleMemberShortArrOne(e.getAnnotation(SingleMemberShortArray.class), e);
+    }
+    static void checkSingleMemberShortArrOne(SingleMemberShortArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != (short)2)
+                fail("SingleMemberShortArrOne " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberShortArrOne " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntArrOne(AnnotatedElement e) {
+        checkSingleMemberIntArrOne(e.getAnnotation(SingleMemberIntArray.class), e);
+    }
+    static void checkSingleMemberIntArrOne(SingleMemberIntArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 3)
+                fail("SingleMemberIntArrOne " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberIntArrOne " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongArrOne(AnnotatedElement e) {
+        checkSingleMemberLongArrOne(e.getAnnotation(SingleMemberLongArray.class), e);
+    }
+    static void checkSingleMemberLongArrOne(SingleMemberLongArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 4L)
+                fail("SingleMemberLongArrOne " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberLongArrOne " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharArrOne(AnnotatedElement e) {
+        checkSingleMemberCharArrOne(e.getAnnotation(SingleMemberCharArray.class), e);
+    }
+    static void checkSingleMemberCharArrOne(SingleMemberCharArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != '5')
+                fail("SingleMemberCharArrOne " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberCharArrOne " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatArrOne(AnnotatedElement e) {
+        checkSingleMemberFloatArrOne(e.getAnnotation(SingleMemberFloatArray.class), e);
+    }
+    static void checkSingleMemberFloatArrOne(SingleMemberFloatArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 6.0f)
+                fail("SingleMemberFloatArrOne " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberFloatArrOne " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleArrOne(AnnotatedElement e) {
+        checkSingleMemberDoubleArrOne(e.getAnnotation(SingleMemberDoubleArray.class), e);
+    }
+    static void checkSingleMemberDoubleArrOne(SingleMemberDoubleArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 7.0)
+                fail("SingleMemberDoubleArrOne " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleArrOne " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanArrOne(AnnotatedElement e) {
+        checkSingleMemberBooleanArrOne(e.getAnnotation(SingleMemberBooleanArray.class), e);
+    }
+    static void checkSingleMemberBooleanArrOne(SingleMemberBooleanArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || !a.value()[0])
+                fail("SingleMemberBooleanArrOne " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanArrOne " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringArrOne(AnnotatedElement e) {
+        checkSingleMemberStringArrOne(e.getAnnotation(SingleMemberStringArray.class), e);
+    }
+    static void checkSingleMemberStringArrOne(SingleMemberStringArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || !(a.value()[0].equals("custom")))
+                fail("SingleMemberStringArrOne " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberStringArrOne " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassArrOne(AnnotatedElement e) {
+        checkSingleMemberClassArrOne(e.getAnnotation(SingleMemberClassArray.class), e);
+    }
+    static void checkSingleMemberClassArrOne(SingleMemberClassArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != Map.class)
+                fail("SingleMemberClassArrOne " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberClassArrOne " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumArrOne(AnnotatedElement e) {
+        checkSingleMemberEnumArrOne(e.getAnnotation(SingleMemberEnumArray.class), e);
+    }
+    static void checkSingleMemberEnumArrOne(SingleMemberEnumArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != Stooge.MOE)
+                fail("SingleMemberEnumArrOne " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberEnumArrOne " + e + ": " + t);
+        }
+    }
+
+    // Single member array (two element array)
+    static void checkSingleMemberByteArrTwo(AnnotatedElement e) {
+        checkSingleMemberByteArrTwo(e.getAnnotation(SingleMemberByteArray.class), e);
+    }
+    static void checkSingleMemberByteArrTwo(SingleMemberByteArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 2 || a.value()[0] != (byte)1 || a.value()[1] != (byte)2)
+                fail("SingleMemberByteArrTwo " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberByteArrTwo " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortArrTwo(AnnotatedElement e) {
+        checkSingleMemberShortArrTwo(e.getAnnotation(SingleMemberShortArray.class), e);
+    }
+    static void checkSingleMemberShortArrTwo(SingleMemberShortArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 2 || a.value()[0] != (short)2 || a.value()[1] != (short)3)
+                fail("SingleMemberShortArrTwo " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberShortArrTwo " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntArrTwo(AnnotatedElement e) {
+        checkSingleMemberIntArrTwo(e.getAnnotation(SingleMemberIntArray.class), e);
+    }
+    static void checkSingleMemberIntArrTwo(SingleMemberIntArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 2 || a.value()[0] != 3 || a.value()[1] != 4)
+                fail("SingleMemberIntArrTwo " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberIntArrTwo " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongArrTwo(AnnotatedElement e) {
+        checkSingleMemberLongArrTwo(e.getAnnotation(SingleMemberLongArray.class), e);
+    }
+    static void checkSingleMemberLongArrTwo(SingleMemberLongArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 2 || a.value()[0] != 4L || a.value()[1] != 5L)
+                fail("SingleMemberLongArrTwo " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberLongArrTwo " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharArrTwo(AnnotatedElement e) {
+        checkSingleMemberCharArrTwo(e.getAnnotation(SingleMemberCharArray.class), e);
+    }
+    static void checkSingleMemberCharArrTwo(SingleMemberCharArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 2 || a.value()[0] != '5' || a.value()[1] != '6')
+                fail("SingleMemberCharArrTwo " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberCharArrTwo " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatArrTwo(AnnotatedElement e) {
+        checkSingleMemberFloatArrTwo(e.getAnnotation(SingleMemberFloatArray.class), e);
+    }
+    static void checkSingleMemberFloatArrTwo(SingleMemberFloatArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 2 || a.value()[0] != 6.0f || a.value()[1] != 7.0f)
+                fail("SingleMemberFloatArrTwo " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberFloatArrTwo " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleArrTwo(AnnotatedElement e) {
+        checkSingleMemberDoubleArrTwo(e.getAnnotation(SingleMemberDoubleArray.class), e);
+    }
+    static void checkSingleMemberDoubleArrTwo(SingleMemberDoubleArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 2 || a.value()[0] != 7.0 || a.value()[1] != 8.0)
+                fail("SingleMemberDoubleArrTwo " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleArrTwo " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanArrTwo(AnnotatedElement e) {
+        checkSingleMemberBooleanArrTwo(e.getAnnotation(SingleMemberBooleanArray.class), e);
+    }
+    static void checkSingleMemberBooleanArrTwo(SingleMemberBooleanArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 2 || !a.value()[0] || a.value()[1])
+                fail("SingleMemberBooleanArrTwo " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanArrTwo " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringArrTwo(AnnotatedElement e) {
+        checkSingleMemberStringArrTwo(e.getAnnotation(SingleMemberStringArray.class), e);
+    }
+    static void checkSingleMemberStringArrTwo(SingleMemberStringArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 2 || !(a.value()[0].equals("custom")) || !(a.value()[1].equals("paint")))
+                fail("SingleMemberStringArrTwo " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberStringArrTwo " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassArrTwo(AnnotatedElement e) {
+        checkSingleMemberClassArrTwo(e.getAnnotation(SingleMemberClassArray.class), e);
+    }
+    static void checkSingleMemberClassArrTwo(SingleMemberClassArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 2 || a.value()[0] != Map.class || a.value()[1] != Set.class)
+                fail("SingleMemberClassArrTwo " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberClassArrTwo " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumArrTwo(AnnotatedElement e) {
+        checkSingleMemberEnumArrTwo(e.getAnnotation(SingleMemberEnumArray.class), e);
+    }
+    static void checkSingleMemberEnumArrTwo(SingleMemberEnumArray a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 2 || a.value()[0] != Stooge.MOE || a.value()[1] != Stooge.CURLY)
+                fail("SingleMemberEnumArrTwo " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberEnumArrTwo " + e + ": " + t);
+        }
+    }
+
+    // Single member array with default (override)
+    static void checkSingleMemberByteArrOvrdDef(AnnotatedElement e) {
+        checkSingleMemberByteArrOvrdDef(e.getAnnotation(SingleMemberByteArrayDef.class), e);
+    }
+    static void checkSingleMemberByteArrOvrdDef(SingleMemberByteArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != (byte)1)
+                fail("SingleMemberByteArrOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberByteArrOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortArrOvrdDef(AnnotatedElement e) {
+        checkSingleMemberShortArrOvrdDef(e.getAnnotation(SingleMemberShortArrayDef.class), e);
+    }
+    static void checkSingleMemberShortArrOvrdDef(SingleMemberShortArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != (short)2)
+                fail("SingleMemberShortArrOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberShortArrOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntArrOvrdDef(AnnotatedElement e) {
+        checkSingleMemberIntArrOvrdDef(e.getAnnotation(SingleMemberIntArrayDef.class), e);
+    }
+    static void checkSingleMemberIntArrOvrdDef(SingleMemberIntArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 3)
+                fail("SingleMemberIntArrOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberIntArrOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongArrOvrdDef(AnnotatedElement e) {
+        checkSingleMemberLongArrOvrdDef(e.getAnnotation(SingleMemberLongArrayDef.class), e);
+    }
+    static void checkSingleMemberLongArrOvrdDef(SingleMemberLongArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 4L)
+                fail("SingleMemberLongArrOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberLongArrOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharArrOvrdDef(AnnotatedElement e) {
+        checkSingleMemberCharArrOvrdDef(e.getAnnotation(SingleMemberCharArrayDef.class), e);
+    }
+    static void checkSingleMemberCharArrOvrdDef(SingleMemberCharArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != '5')
+                fail("SingleMemberCharArrOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberCharArrOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatArrOvrdDef(AnnotatedElement e) {
+        checkSingleMemberFloatArrOvrdDef(e.getAnnotation(SingleMemberFloatArrayDef.class), e);
+    }
+    static void checkSingleMemberFloatArrOvrdDef(SingleMemberFloatArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 6.0f)
+                fail("SingleMemberFloatArrOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberFloatArrOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleArrOvrdDef(AnnotatedElement e) {
+        checkSingleMemberDoubleArrOvrdDef(e.getAnnotation(SingleMemberDoubleArrayDef.class), e);
+    }
+    static void checkSingleMemberDoubleArrOvrdDef(SingleMemberDoubleArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 7.0)
+                fail("SingleMemberDoubleArrOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleArrOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanArrOvrdDef(AnnotatedElement e) {
+        checkSingleMemberBooleanArrOvrdDef(e.getAnnotation(SingleMemberBooleanArrayDef.class), e);
+    }
+    static void checkSingleMemberBooleanArrOvrdDef(SingleMemberBooleanArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || !a.value()[0])
+                fail("SingleMemberBooleanArrOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanArrOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringArrOvrdDef(AnnotatedElement e) {
+        checkSingleMemberStringArrOvrdDef(e.getAnnotation(SingleMemberStringArrayDef.class), e);
+    }
+    static void checkSingleMemberStringArrOvrdDef(SingleMemberStringArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || !(a.value()[0].equals("custom")))
+                fail("SingleMemberStringArrOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberStringArrOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassArrOvrdDef(AnnotatedElement e) {
+        checkSingleMemberClassArrOvrdDef(e.getAnnotation(SingleMemberClassArrayDef.class), e);
+    }
+    static void checkSingleMemberClassArrOvrdDef(SingleMemberClassArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != Map.class)
+                fail("SingleMemberClassArrOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberClassArrOvrdDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumArrOvrdDef(AnnotatedElement e) {
+        checkSingleMemberEnumArrOvrdDef(e.getAnnotation(SingleMemberEnumArrayDef.class), e);
+    }
+    static void checkSingleMemberEnumArrOvrdDef(SingleMemberEnumArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != Stooge.MOE)
+                fail("SingleMemberEnumArrOvrdDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberEnumArrOvrdDef " + e + ": " + t);
+        }
+    }
+
+    // Single member array with default (accept)
+    static void checkSingleMemberByteArrAcceptDef(AnnotatedElement e) {
+        checkSingleMemberByteArrAcceptDef(e.getAnnotation(SingleMemberByteArrayDef.class), e);
+    }
+    static void checkSingleMemberByteArrAcceptDef(SingleMemberByteArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != (byte)11)
+                fail("SingleMemberByteArrAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberByteArrAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberShortArrAcceptDef(AnnotatedElement e) {
+        checkSingleMemberShortArrAcceptDef(e.getAnnotation(SingleMemberShortArrayDef.class), e);
+    }
+    static void checkSingleMemberShortArrAcceptDef(SingleMemberShortArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != (short)12)
+                fail("SingleMemberShortArrAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberShortArrAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberIntArrAcceptDef(AnnotatedElement e) {
+        checkSingleMemberIntArrAcceptDef(e.getAnnotation(SingleMemberIntArrayDef.class), e);
+    }
+    static void checkSingleMemberIntArrAcceptDef(SingleMemberIntArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 13)
+                fail("SingleMemberIntArrAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberIntArrAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberLongArrAcceptDef(AnnotatedElement e) {
+        checkSingleMemberLongArrAcceptDef(e.getAnnotation(SingleMemberLongArrayDef.class), e);
+    }
+    static void checkSingleMemberLongArrAcceptDef(SingleMemberLongArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 14L)
+                fail("SingleMemberLongArrAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberLongArrAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberCharArrAcceptDef(AnnotatedElement e) {
+        checkSingleMemberCharArrAcceptDef(e.getAnnotation(SingleMemberCharArrayDef.class), e);
+    }
+    static void checkSingleMemberCharArrAcceptDef(SingleMemberCharArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 'V')
+                fail("SingleMemberCharArrAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberCharArrAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberFloatArrAcceptDef(AnnotatedElement e) {
+        checkSingleMemberFloatArrAcceptDef(e.getAnnotation(SingleMemberFloatArrayDef.class), e);
+    }
+    static void checkSingleMemberFloatArrAcceptDef(SingleMemberFloatArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 16.0f)
+                fail("SingleMemberFloatArrAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberFloatArrAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberDoubleArrAcceptDef(AnnotatedElement e) {
+        checkSingleMemberDoubleArrAcceptDef(e.getAnnotation(SingleMemberDoubleArrayDef.class), e);
+    }
+    static void checkSingleMemberDoubleArrAcceptDef(SingleMemberDoubleArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != 17.0)
+                fail("SingleMemberDoubleArrAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberDoubleArrAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberBooleanArrAcceptDef(AnnotatedElement e) {
+        checkSingleMemberBooleanArrAcceptDef(e.getAnnotation(SingleMemberBooleanArrayDef.class), e);
+    }
+    static void checkSingleMemberBooleanArrAcceptDef(SingleMemberBooleanArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0])
+                fail("SingleMemberBooleanArrAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberBooleanArrAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberStringArrAcceptDef(AnnotatedElement e) {
+        checkSingleMemberStringArrAcceptDef(e.getAnnotation(SingleMemberStringArrayDef.class), e);
+    }
+    static void checkSingleMemberStringArrAcceptDef(SingleMemberStringArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || !(a.value()[0].equals("default")))
+                fail("SingleMemberStringArrAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberStringArrAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberClassArrAcceptDef(AnnotatedElement e) {
+        checkSingleMemberClassArrAcceptDef(e.getAnnotation(SingleMemberClassArrayDef.class), e);
+    }
+    static void checkSingleMemberClassArrAcceptDef(SingleMemberClassArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != Class.class)
+                fail("SingleMemberClassArrAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberClassArrAcceptDef " + e + ": " + t);
+        }
+    }
+
+    static void checkSingleMemberEnumArrAcceptDef(AnnotatedElement e) {
+        checkSingleMemberEnumArrAcceptDef(e.getAnnotation(SingleMemberEnumArrayDef.class), e);
+    }
+    static void checkSingleMemberEnumArrAcceptDef(SingleMemberEnumArrayDef a, AnnotatedElement e) {
+        numTests++;
+        try {
+            if (a.value().length != 1 || a.value()[0] != Stooge.LARRY)
+                fail("SingleMemberEnumArrAcceptDef " + e + " = " + a.value());
+        } catch(Throwable t) {
+            fail("SingleMemberEnumArrAcceptDef " + e + ": " + t);
+        }
+    }
+
+    // Verfification methods for equals/hashCode/serialization
+
+    static <T extends Annotation> void checkEquals(AnnotatedElement e1, AnnotatedElement e2, Class<T> annoType) {
+        numTests++;
+        T a1 = e1.getAnnotation(annoType);
+        T a2 = e2.getAnnotation(annoType);
+        try {
+            if (!a1.equals(a2))
+                fail(a1 + " != " + a2);
+            if (a1.hashCode() != a2.hashCode())
+                fail(a1 + ".hashCode() [" + a1.hashCode() + "] != " + a2 + " .hashCode()["+ a2.hashCode()+"]");
+            if (!(a1.toString().equals(a2.toString())))
+                fail(a1 + ".toString() != " + a2 + ".toString()");
+        } catch(Throwable t) {
+            fail(a1 + " == " + a2 + ": " + t);
+        }
+    }
+
+    static <T extends Annotation> void checkUnequals(AnnotatedElement e1, AnnotatedElement e2, Class<T> annoType) {
+        numTests++;
+        T a1 = e1.getAnnotation(annoType);
+        T a2 = e2.getAnnotation(annoType);
+        try {
+            if (a1.equals(a2))
+                fail(a1 + " == " + a2);
+            if (a1.hashCode() == a2.hashCode())
+                fail(a1 + ".hashCode() [" + a1.hashCode() + "] == " + a2 + " .hashCode()[" + a2.hashCode() + "]");
+            if (a1.toString().equals(a2.toString()))
+                fail(a1 + ".toString() == " + a2 + ".toString()");
+        } catch(Throwable t) {
+            fail(a1 + " != " + a2 + ": " + t);
+        }
+    }
+
+    // Verfification method for serialization/deserialization
+
+    static <T extends Annotation> void checkSerialization(AnnotatedElement e, Class<T> annoType) {
+        numTests++;
+        T a1 = e.getAnnotation(annoType);
+        Object a2 = deepCopy(a1);
+        try {
+            if (!a1.equals(a2))
+                fail("Serialization: " + a1 + " != " + a2);
+            if (a1.hashCode() != a2.hashCode())
+                fail("Serialization: " + a1 + ".hashCode() [" + a1.hashCode() + "] != " + a2 + " .hashCode()["+a2.hashCode()+"]");
+            if (!(a1.toString().equals(a2.toString())))
+                fail("Serialization: " + a1 + ".toString() != " + a2 + ".toString()");
+        } catch(Throwable t) {
+            fail("Serialization: " + a1 + " == " + a2 + ": " + t);
+        }
+    }
+
+    private static Object deepCopy(Object original) {
+        try {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(bos);
+            oos.writeObject(original);
+            oos.flush();
+            ByteArrayInputStream bin = new ByteArrayInputStream(
+                bos.toByteArray());
+            ObjectInputStream ois = new ObjectInputStream(bin);
+            return ois.readObject();
+        } catch(Exception e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    // Verification method for inheritance test
+    static void checkInheritence(AnnotatedElement e, boolean shouldHaveFoo, boolean shouldHaveBar) {
+        numTests++;
+        try {
+            boolean hasFoo = e.isAnnotationPresent(Foo.class);
+            boolean hasBar = e.isAnnotationPresent(Bar.class);
+            if (hasFoo != shouldHaveFoo || hasBar != shouldHaveBar)
+                fail("Inheritance(1): " + e +" - Foo: " + hasFoo + ", Bar: " + hasBar);
+
+            // Now test getAnnotations
+            hasFoo = hasBar = false;
+            Annotation[] allAnnotations = e.getAnnotations();
+            for (Annotation a : allAnnotations) {
+                if (a instanceof Foo)
+                    hasFoo = true;
+                else if (a instanceof Bar)
+                    hasBar = true;
+            }
+            if (hasFoo != shouldHaveFoo ||hasBar != shouldHaveBar)
+                fail("Inheritance(2): " + e +" - Foo: " + hasFoo + ", Bar: " + hasBar);
+        } catch(Throwable t) {
+            fail("Inheritance: " + e +": " + t);
+        }
+    }
+
+    // Verification method for declared annotations test
+    static void checkDeclaredAnnotations(AnnotatedElement e, boolean shouldHaveFoo, boolean shouldHaveBar) {
+        numTests++;
+        try {
+            boolean hasFoo = false;
+            boolean hasBar = false;
+            Annotation[] declaredAnnotations = e.getDeclaredAnnotations();
+            for (Annotation a : declaredAnnotations) {
+                if (a instanceof Foo)
+                    hasFoo = true;
+                else if (a instanceof Bar)
+                    hasBar = true;
+            }
+            if (hasFoo != shouldHaveFoo ||hasBar != shouldHaveBar)
+                fail("Declared annotations: " + e +" - Foo: " + hasFoo + ", Bar: " + hasBar);
+        } catch(Throwable t) {
+            fail("Declared annotations: " + e +": " + t);
+        }
+    }
+
+
+    // ANNOTATED METHODS
+
+    @ScalarTypes (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    @Point(x = 1, y = 2)
+    )
+    public void scalarTypesMethod() { }
+
+    @ScalarTypesWithDefault ( )
+    public void scalarTypesAcceptDefaultMethod() { }
+
+    @ScalarTypesWithDefault (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE
+    )
+    public void scalarTypesOverrideDefaultMethod() { }
+
+    @ArrayTypes (
+        b =    { },
+        s =    { },
+        i =    { },
+        l =    { },
+        c =    { },
+        f =    { },
+        d =    { },
+        bool = { },
+        str =  { },
+        cls =  { },
+        e =    { },
+        a =    { }
+    )
+    public void emptyArrayTypesMethod() { }
+
+    @ArrayTypes (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    { @Point(x = 1, y = 2) }
+    )
+    public void singleElementArrayTypesMethod() { }
+
+    @ArrayTypes (
+        b =    { 1, 2 },
+        s =    { 2, 3 },
+        i =    { 3, 4 },
+        l =    { 4L, 5L },
+        c =    { '5', '6' },
+        f =    { 6.0f, 7.0f },
+        d =    { 7.0, 8.0 },
+        bool = { true, false },
+        str =  { "custom", "paint" },
+        cls =  { Map.class, Set.class },
+        e =    { Stooge.MOE, Stooge.CURLY },
+        a =    { @Point(x = 1, y = 2),  @Point(x = 3, y = 4) }
+    )
+    public void twoElementArrayTypesMethod() { }
+
+    @ArrayTypesWithDefault (
+    )
+    public void arrayTypesAcceptDefaultMethod() { }
+
+    @ArrayTypesWithDefault (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    { @Point(x = 1, y = 2) }
+    )
+    public void arrayTypesOverrideDefaultMethod() { }
+
+    // Marker
+    @Marker public void markerMethod() { }
+
+    // Single-member (shorthand)
+    @SingleMemberByte(1)          public void SingleMemberByte()    {}
+    @SingleMemberShort(2)         public void SingleMemberShort()   {}
+    @SingleMemberInt(3)           public void SingleMemberInt()     {}
+    @SingleMemberLong(4L)         public void SingleMemberLong()    {}
+    @SingleMemberChar('5')        public void SingleMemberChar()    {}
+    @SingleMemberFloat(6.0f)      public void SingleMemberFloat()   {}
+    @SingleMemberDouble(7.0)      public void SingleMemberDouble()  {}
+    @SingleMemberBoolean(true)    public void SingleMemberBoolean() {}
+    @SingleMemberString("custom") public void SingleMemberString()  {}
+    @SingleMemberClass(Map.class) public void SingleMemberClass()   {}
+    @SingleMemberEnum(Stooge.MOE)        public void SingleMemberEnum()    {}
+
+    // Single-member with default (Override)
+    @SingleMemberByteWithDef(1)          public void SingleMemberByteOvrdDef()    {}
+    @SingleMemberShortWithDef(2)         public void SingleMemberShortOvrdDef()   {}
+    @SingleMemberIntWithDef(3)           public void SingleMemberIntOvrdDef()     {}
+    @SingleMemberLongWithDef(4L)         public void SingleMemberLongOvrdDef()    {}
+    @SingleMemberCharWithDef('5')        public void SingleMemberCharOvrdDef()    {}
+    @SingleMemberFloatWithDef(6.0f)      public void SingleMemberFloatOvrdDef()   {}
+    @SingleMemberDoubleWithDef(7.0)      public void SingleMemberDoubleOvrdDef()  {}
+    @SingleMemberBooleanWithDef(true)    public void SingleMemberBooleanOvrdDef() {}
+    @SingleMemberStringWithDef("custom") public void SingleMemberStringOvrdDef()  {}
+    @SingleMemberClassWithDef(Map.class) public void SingleMemberClassOvrdDef()   {}
+    @SingleMemberEnumWithDef(Stooge.MOE)        public void SingleMemberEnumOvrdDef()    {}
+
+    // Single-member with default (Accept)
+    @SingleMemberByteWithDef    public void SingleMemberByteAcceptDef()    {}
+    @SingleMemberShortWithDef   public void SingleMemberShortAcceptDef()   {}
+    @SingleMemberIntWithDef     public void SingleMemberIntAcceptDef()     {}
+    @SingleMemberLongWithDef    public void SingleMemberLongAcceptDef()    {}
+    @SingleMemberCharWithDef    public void SingleMemberCharAcceptDef()    {}
+    @SingleMemberFloatWithDef   public void SingleMemberFloatAcceptDef()   {}
+    @SingleMemberDoubleWithDef  public void SingleMemberDoubleAcceptDef()  {}
+    @SingleMemberBooleanWithDef public void SingleMemberBooleanAcceptDef() {}
+    @SingleMemberStringWithDef  public void SingleMemberStringAcceptDef()  {}
+    @SingleMemberClassWithDef   public void SingleMemberClassAcceptDef()   {}
+    @SingleMemberEnumWithDef    public void SingleMemberEnumAcceptDef()    {}
+
+    // Single member array (empty array)
+    @SingleMemberByteArray({})   public void SingleMemberByteArrEmpty()    {}
+    @SingleMemberShortArray({})  public void SingleMemberShortArrEmpty()   {}
+    @SingleMemberIntArray({})    public void SingleMemberIntArrEmpty()     {}
+    @SingleMemberLongArray({})   public void SingleMemberLongArrEmpty()    {}
+    @SingleMemberCharArray({})   public void SingleMemberCharArrEmpty()    {}
+    @SingleMemberFloatArray({})  public void SingleMemberFloatArrEmpty()   {}
+    @SingleMemberDoubleArray({}) public void SingleMemberDoubleArrEmpty()  {}
+    @SingleMemberBooleanArray({})public void SingleMemberBooleanArrEmpty() {}
+    @SingleMemberStringArray({}) public void SingleMemberStringArrEmpty()  {}
+    @SingleMemberClassArray({})  public void SingleMemberClassArrEmpty()   {}
+    @SingleMemberEnumArray({})   public void SingleMemberEnumArrEmpty()    {}
+
+    // Single member array (one-element shorthand)
+    @SingleMemberByteArray(1)          public void SingleMemberByteArrOne()    {}
+    @SingleMemberShortArray(2)         public void SingleMemberShortArrOne()   {}
+    @SingleMemberIntArray(3)           public void SingleMemberIntArrOne()     {}
+    @SingleMemberLongArray(4L)         public void SingleMemberLongArrOne()    {}
+    @SingleMemberCharArray('5')        public void SingleMemberCharArrOne()    {}
+    @SingleMemberFloatArray(6.0f)      public void SingleMemberFloatArrOne()   {}
+    @SingleMemberDoubleArray(7.0)      public void SingleMemberDoubleArrOne()  {}
+    @SingleMemberBooleanArray(true)    public void SingleMemberBooleanArrOne() {}
+    @SingleMemberStringArray("custom") public void SingleMemberStringArrOne()  {}
+    @SingleMemberClassArray(Map.class) public void SingleMemberClassArrOne()   {}
+    @SingleMemberEnumArray(Stooge.MOE)        public void SingleMemberEnumArrOne()    {}
+
+    // Single member array (two elements)
+    @SingleMemberByteArray({1, 2})           public void SingleMemberByteArrTwo()   {}
+    @SingleMemberShortArray({2, 3})          public void SingleMemberShortArrTwo()  {}
+    @SingleMemberIntArray({3, 4})            public void SingleMemberIntArrTwo()    {}
+    @SingleMemberLongArray({4L, 5L})         public void SingleMemberLongArrTwo()   {}
+    @SingleMemberCharArray({'5', '6'})       public void SingleMemberCharArrTwo()   {}
+    @SingleMemberFloatArray({6.0f, 7.0f})    public void SingleMemberFloatArrTwo()  {}
+    @SingleMemberDoubleArray({7.0, 8.0})     public void SingleMemberDoubleArrTwo() {}
+    @SingleMemberBooleanArray({true, false}) public void SingleMemberBooleanArrTwo(){}
+    @SingleMemberStringArray({"custom", "paint"})      public void SingleMemberStringArrTwo(){}
+    @SingleMemberClassArray({Map.class, Set.class})    public void SingleMemberClassArrTwo() {}
+    @SingleMemberEnumArray({Stooge.MOE, Stooge.CURLY})               public void SingleMemberEnumArrTwo()  {}
+
+    // Single member array with default (override)
+    @SingleMemberByteArrayDef(1)          public void SingleMemberByteArrOvrdDef()   {}
+    @SingleMemberShortArrayDef(2)         public void SingleMemberShortArrOvrdDef()  {}
+    @SingleMemberIntArrayDef(3)           public void SingleMemberIntArrOvrdDef()    {}
+    @SingleMemberLongArrayDef(4L)         public void SingleMemberLongArrOvrdDef()   {}
+    @SingleMemberCharArrayDef('5')        public void SingleMemberCharArrOvrdDef()   {}
+    @SingleMemberFloatArrayDef(6.0f)      public void SingleMemberFloatArrOvrdDef()  {}
+    @SingleMemberDoubleArrayDef(7.0)      public void SingleMemberDoubleArrOvrdDef() {}
+    @SingleMemberBooleanArrayDef(true)    public void SingleMemberBooleanArrOvrdDef(){}
+    @SingleMemberStringArrayDef("custom") public void SingleMemberStringArrOvrdDef() {}
+    @SingleMemberClassArrayDef(Map.class) public void SingleMemberClassArrOvrdDef()  {}
+    @SingleMemberEnumArrayDef(Stooge.MOE)        public void SingleMemberEnumArrOvrdDef()   {}
+
+    // Single member array with default - accept
+    @SingleMemberByteArrayDef    public void SingleMemberByteArrAcceptDef()    {}
+    @SingleMemberShortArrayDef   public void SingleMemberShortArrAcceptDef()   {}
+    @SingleMemberIntArrayDef     public void SingleMemberIntArrAcceptDef()     {}
+    @SingleMemberLongArrayDef    public void SingleMemberLongArrAcceptDef()    {}
+    @SingleMemberCharArrayDef    public void SingleMemberCharArrAcceptDef()    {}
+    @SingleMemberFloatArrayDef   public void SingleMemberFloatArrAcceptDef()   {}
+    @SingleMemberDoubleArrayDef  public void SingleMemberDoubleArrAcceptDef()  {}
+    @SingleMemberBooleanArrayDef public void SingleMemberBooleanArrAcceptDef() {}
+    @SingleMemberStringArrayDef  public void SingleMemberStringArrAcceptDef()  {}
+    @SingleMemberClassArrayDef   public void SingleMemberClassArrAcceptDef()   {}
+    @SingleMemberEnumArrayDef    public void SingleMemberEnumArrAcceptDef()    {}
+
+    // ANNOTATED FIELDS
+    @ScalarTypes (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    @Point(x = 1, y = 2)
+    )
+    public int scalarTypesField;
+
+    @ScalarTypesWithDefault ( )
+    public int scalarTypesAcceptDefaultField;
+
+    @ScalarTypesWithDefault (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE
+    )
+    public int scalarTypesOverrideDefaultField;
+
+    @ArrayTypes (
+        b =    { },
+        s =    { },
+        i =    { },
+        l =    { },
+        c =    { },
+        f =    { },
+        d =    { },
+        bool = { },
+        str =  { },
+        cls =  { },
+        e =    { },
+        a =    { }
+    )
+    public int emptyArrayTypesField;
+
+    @ArrayTypes (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    { @Point(x = 1, y = 2) }
+    )
+    public int singleElementArrayTypesField;
+
+    @ArrayTypes (
+        b =    { 1, 2 },
+        s =    { 2, 3 },
+        i =    { 3, 4 },
+        l =    { 4L, 5L },
+        c =    { '5', '6' },
+        f =    { 6.0f, 7.0f },
+        d =    { 7.0, 8.0 },
+        bool = { true, false },
+        str =  { "custom", "paint" },
+        cls =  { Map.class, Set.class },
+        e =    { Stooge.MOE, Stooge.CURLY },
+        a =    { @Point(x = 1, y = 2), @Point(x = 3, y = 4) }
+    )
+    public int twoElementArrayTypesField;
+
+    @ArrayTypesWithDefault ( )
+    public int arrayTypesAcceptDefaultField;
+
+    @ArrayTypesWithDefault (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    { @Point(x = 1, y = 2) }
+    )
+    public int arrayTypesOverrideDefaultField;
+
+    @Marker public int markerField;
+
+    // Single-member (shorthand)
+    @SingleMemberByte(1)          public int SingleMemberByteField;
+    @SingleMemberShort(2)         public int SingleMemberShortField;
+    @SingleMemberInt(3)           public int SingleMemberIntField;
+    @SingleMemberLong(4L)         public int SingleMemberLongField;
+    @SingleMemberChar('5')        public int SingleMemberCharField;
+    @SingleMemberFloat(6.0f)      public int SingleMemberFloatField;
+    @SingleMemberDouble(7.0)      public int SingleMemberDoubleField;
+    @SingleMemberBoolean(true)    public int SingleMemberBooleanField;
+    @SingleMemberString("custom") public int SingleMemberStringField;
+    @SingleMemberClass(Map.class) public int SingleMemberClassField;
+    @SingleMemberEnum(Stooge.MOE)        public int SingleMemberEnumField;
+
+    // Single-member with default (Override)
+    @SingleMemberByteWithDef(1)          public int SingleMemberByteOvrdDefField;
+    @SingleMemberShortWithDef(2)         public int SingleMemberShortOvrdDefField;
+    @SingleMemberIntWithDef(3)           public int SingleMemberIntOvrdDefField;
+    @SingleMemberLongWithDef(4L)         public int SingleMemberLongOvrdDefField;
+    @SingleMemberCharWithDef('5')        public int SingleMemberCharOvrdDefField;
+    @SingleMemberFloatWithDef(6.0f)      public int SingleMemberFloatOvrdDefField;
+    @SingleMemberDoubleWithDef(7.0)      public int SingleMemberDoubleOvrdDefField;
+    @SingleMemberBooleanWithDef(true)    public int SingleMemberBooleanOvrdDefField;
+    @SingleMemberStringWithDef("custom") public int SingleMemberStringOvrdDefField;
+    @SingleMemberClassWithDef(Map.class) public int SingleMemberClassOvrdDefField;
+    @SingleMemberEnumWithDef(Stooge.MOE)        public int SingleMemberEnumOvrdDefField;
+
+    // Single-member with default (Accept)
+    @SingleMemberByteWithDef    public int SingleMemberByteAcceptDefField;
+    @SingleMemberShortWithDef   public int SingleMemberShortAcceptDefField;
+    @SingleMemberIntWithDef     public int SingleMemberIntAcceptDefField;
+    @SingleMemberLongWithDef    public int SingleMemberLongAcceptDefField;
+    @SingleMemberCharWithDef    public int SingleMemberCharAcceptDefField;
+    @SingleMemberFloatWithDef   public int SingleMemberFloatAcceptDefField;
+    @SingleMemberDoubleWithDef  public int SingleMemberDoubleAcceptDefField;
+    @SingleMemberBooleanWithDef public int SingleMemberBooleanAcceptDefField;
+    @SingleMemberStringWithDef  public int SingleMemberStringAcceptDefField;
+    @SingleMemberClassWithDef   public int SingleMemberClassAcceptDefField;
+    @SingleMemberEnumWithDef    public int SingleMemberEnumAcceptDefField;
+
+    // Single member array (empty array)
+    @SingleMemberByteArray({})   public int SingleMemberByteArrEmptyField;
+    @SingleMemberShortArray({})  public int SingleMemberShortArrEmptyField;
+    @SingleMemberIntArray({})    public int SingleMemberIntArrEmptyField;
+    @SingleMemberLongArray({})   public int SingleMemberLongArrEmptyField;
+    @SingleMemberCharArray({})   public int SingleMemberCharArrEmptyField;
+    @SingleMemberFloatArray({})  public int SingleMemberFloatArrEmptyField;
+    @SingleMemberDoubleArray({}) public int SingleMemberDoubleArrEmptyField;
+    @SingleMemberBooleanArray({})public int SingleMemberBooleanArrEmptyField;
+    @SingleMemberStringArray({}) public int SingleMemberStringArrEmptyField;
+    @SingleMemberClassArray({})  public int SingleMemberClassArrEmptyField;
+    @SingleMemberEnumArray({})   public int SingleMemberEnumArrEmptyField;
+
+    // Single member array (one-element shorthand)
+    @SingleMemberByteArray(1)          public int SingleMemberByteArrOneField;
+    @SingleMemberShortArray(2)         public int SingleMemberShortArrOneField;
+    @SingleMemberIntArray(3)           public int SingleMemberIntArrOneField;
+    @SingleMemberLongArray(4L)         public int SingleMemberLongArrOneField;
+    @SingleMemberCharArray('5')        public int SingleMemberCharArrOneField;
+    @SingleMemberFloatArray(6.0f)      public int SingleMemberFloatArrOneField;
+    @SingleMemberDoubleArray(7.0)      public int SingleMemberDoubleArrOneField;
+    @SingleMemberBooleanArray(true)    public int SingleMemberBooleanArrOneField;
+    @SingleMemberStringArray("custom") public int SingleMemberStringArrOneField;
+    @SingleMemberClassArray(Map.class) public int SingleMemberClassArrOneField;
+    @SingleMemberEnumArray(Stooge.MOE)        public int SingleMemberEnumArrOneField;
+
+    // Single member array (two elements)
+    @SingleMemberByteArray({1, 2})         public int SingleMemberByteArrTwoField;
+    @SingleMemberShortArray({2, 3})        public int SingleMemberShortArrTwoField;
+    @SingleMemberIntArray({3, 4})          public int SingleMemberIntArrTwoField;
+    @SingleMemberLongArray({4L, 5L})       public int SingleMemberLongArrTwoField;
+    @SingleMemberCharArray({'5', '6'})     public int SingleMemberCharArrTwoField;
+    @SingleMemberFloatArray({6.0f, 7.0f})  public int SingleMemberFloatArrTwoField;
+    @SingleMemberDoubleArray({7.0, 8.0})   public int SingleMemberDoubleArrTwoField;
+    @SingleMemberBooleanArray({true,false})         public int SingleMemberBooleanArrTwoField;
+    @SingleMemberStringArray({"custom", "paint"})   public int SingleMemberStringArrTwoField;
+    @SingleMemberClassArray({Map.class, Set.class}) public int SingleMemberClassArrTwoField;
+    @SingleMemberEnumArray({Stooge.MOE, Stooge.CURLY})            public int SingleMemberEnumArrTwoField;
+
+    // Single member array with default (override)
+    @SingleMemberByteArrayDef(1)        public int SingleMemberByteArrOvrdDefField;
+    @SingleMemberShortArrayDef(2)       public int SingleMemberShortArrOvrdDefField;
+    @SingleMemberIntArrayDef(3)         public int SingleMemberIntArrOvrdDefField;
+    @SingleMemberLongArrayDef(4L)       public int SingleMemberLongArrOvrdDefField;
+    @SingleMemberCharArrayDef('5')      public int SingleMemberCharArrOvrdDefField;
+    @SingleMemberFloatArrayDef(6.0f)    public int SingleMemberFloatArrOvrdDefField;
+    @SingleMemberDoubleArrayDef(7.0)    public int SingleMemberDoubleArrOvrdDefField;
+    @SingleMemberBooleanArrayDef(true)  public int SingleMemberBooleanArrOvrdDefField;
+    @SingleMemberStringArrayDef("custom") public int SingleMemberStringArrOvrdDefField;
+    @SingleMemberClassArrayDef(Map.class) public int SingleMemberClassArrOvrdDefField;
+    @SingleMemberEnumArrayDef(Stooge.MOE)        public int SingleMemberEnumArrOvrdDefField;
+
+    // Single member array with default - accept
+    @SingleMemberByteArrayDef    public int SingleMemberByteArrAcceptDefField;
+    @SingleMemberShortArrayDef   public int SingleMemberShortArrAcceptDefField;
+    @SingleMemberIntArrayDef     public int SingleMemberIntArrAcceptDefField;
+    @SingleMemberLongArrayDef    public int SingleMemberLongArrAcceptDefField;
+    @SingleMemberCharArrayDef    public int SingleMemberCharArrAcceptDefField;
+    @SingleMemberFloatArrayDef   public int SingleMemberFloatArrAcceptDefField;
+    @SingleMemberDoubleArrayDef  public int SingleMemberDoubleArrAcceptDefField;
+    @SingleMemberBooleanArrayDef public int SingleMemberBooleanArrAcceptDefField;
+    @SingleMemberStringArrayDef  public int SingleMemberStringArrAcceptDefField;
+    @SingleMemberClassArrayDef   public int SingleMemberClassArrAcceptDefField;
+    @SingleMemberEnumArrayDef    public int SingleMemberEnumArrAcceptDefField;
+
+    // ANNOTATED ENUM CONSTANTS
+    enum TestType {
+    @ScalarTypes (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    @Point(x = 1, y = 2)
+    )
+    scalarTypesField,
+
+    @ScalarTypesWithDefault ( )
+    scalarTypesAcceptDefaultField,
+
+    @ScalarTypesWithDefault (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE
+    )
+    scalarTypesOverrideDefaultField,
+
+    @ArrayTypes (
+        b =    { },
+        s =    { },
+        i =    { },
+        l =    { },
+        c =    { },
+        f =    { },
+        d =    { },
+        bool = { },
+        str =  { },
+        cls =  { },
+        e =    { },
+        a  =   { }
+    )
+    emptyArrayTypesField,
+
+    @ArrayTypes (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    @Point(x = 1, y = 2)
+    )
+    singleElementArrayTypesField,
+
+    @ArrayTypes (
+        b =    { 1, 2 },
+        s =    { 2, 3 },
+        i =    { 3, 4 },
+        l =    { 4L, 5L },
+        c =    { '5', '6' },
+        f =    { 6.0f, 7.0f },
+        d =    { 7.0, 8.0 },
+        bool = { true, false },
+        str =  { "custom", "paint" },
+        cls =  { Map.class, Set.class },
+        e =    { Stooge.MOE, Stooge.CURLY },
+        a =    { @Point(x = 1, y = 2),  @Point(x = 3, y = 4) }
+    )
+    twoElementArrayTypesField,
+
+    @ArrayTypesWithDefault ( )
+    arrayTypesAcceptDefaultField,
+
+    @ArrayTypesWithDefault (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    { @Point(x = 1, y = 2) }
+    )
+    arrayTypesOverrideDefaultField,
+
+    // marker
+    @Marker marker,
+
+    // Single-member (shorthand)
+    @SingleMemberByte(1)          SingleMemberByte,
+    @SingleMemberShort(2)         SingleMemberShort,
+    @SingleMemberInt(3)           SingleMemberInt,
+    @SingleMemberLong(4L)         SingleMemberLong,
+    @SingleMemberChar('5')        SingleMemberChar,
+    @SingleMemberFloat(6.0f)      SingleMemberFloat,
+    @SingleMemberDouble(7.0)      SingleMemberDouble,
+    @SingleMemberBoolean(true)    SingleMemberBoolean,
+    @SingleMemberString("custom") SingleMemberString,
+    @SingleMemberClass(Map.class) SingleMemberClass,
+    @SingleMemberEnum(Stooge.MOE)        SingleMemberEnum,
+
+    // Single-member with default (Override)
+    @SingleMemberByteWithDef(1)          SingleMemberByteOvrdDef,
+    @SingleMemberShortWithDef(2)         SingleMemberShortOvrdDef,
+    @SingleMemberIntWithDef(3)           SingleMemberIntOvrdDef,
+    @SingleMemberLongWithDef(4L)         SingleMemberLongOvrdDef,
+    @SingleMemberCharWithDef('5')        SingleMemberCharOvrdDef,
+    @SingleMemberFloatWithDef(6.0f)      SingleMemberFloatOvrdDef,
+    @SingleMemberDoubleWithDef(7.0)      SingleMemberDoubleOvrdDef,
+    @SingleMemberBooleanWithDef(true)    SingleMemberBooleanOvrdDef,
+    @SingleMemberStringWithDef("custom") SingleMemberStringOvrdDef,
+    @SingleMemberClassWithDef(Map.class) SingleMemberClassOvrdDef,
+    @SingleMemberEnumWithDef(Stooge.MOE)        SingleMemberEnumOvrdDef,
+
+    // Single-member with default (Accept)
+    @SingleMemberByteWithDef    SingleMemberByteAcceptDef,
+    @SingleMemberShortWithDef   SingleMemberShortAcceptDef,
+    @SingleMemberIntWithDef     SingleMemberIntAcceptDef,
+    @SingleMemberLongWithDef    SingleMemberLongAcceptDef,
+    @SingleMemberCharWithDef    SingleMemberCharAcceptDef,
+    @SingleMemberFloatWithDef   SingleMemberFloatAcceptDef,
+    @SingleMemberDoubleWithDef  SingleMemberDoubleAcceptDef,
+    @SingleMemberBooleanWithDef SingleMemberBooleanAcceptDef,
+    @SingleMemberStringWithDef  SingleMemberStringAcceptDef,
+    @SingleMemberClassWithDef   SingleMemberClassAcceptDef,
+    @SingleMemberEnumWithDef    SingleMemberEnumAcceptDef,
+
+    // Single member array (empty array)
+    @SingleMemberByteArray({})   SingleMemberByteArrEmpty,
+    @SingleMemberShortArray({})  SingleMemberShortArrEmpty,
+    @SingleMemberIntArray({})    SingleMemberIntArrEmpty,
+    @SingleMemberLongArray({})   SingleMemberLongArrEmpty,
+    @SingleMemberCharArray({})   SingleMemberCharArrEmpty,
+    @SingleMemberFloatArray({})  SingleMemberFloatArrEmpty,
+    @SingleMemberDoubleArray({}) SingleMemberDoubleArrEmpty,
+    @SingleMemberBooleanArray({})SingleMemberBooleanArrEmpty,
+    @SingleMemberStringArray({}) SingleMemberStringArrEmpty,
+    @SingleMemberClassArray({})  SingleMemberClassArrEmpty,
+    @SingleMemberEnumArray({})   SingleMemberEnumArrEmpty,
+
+    // Single member array (one-element shorthand)
+    @SingleMemberByteArray(1)          SingleMemberByteArrOne,
+    @SingleMemberShortArray(2)         SingleMemberShortArrOne,
+    @SingleMemberIntArray(3)           SingleMemberIntArrOne,
+    @SingleMemberLongArray(4L)         SingleMemberLongArrOne,
+    @SingleMemberCharArray('5')        SingleMemberCharArrOne,
+    @SingleMemberFloatArray(6.0f)      SingleMemberFloatArrOne,
+    @SingleMemberDoubleArray(7.0)      SingleMemberDoubleArrOne,
+    @SingleMemberBooleanArray(true)    SingleMemberBooleanArrOne,
+    @SingleMemberStringArray("custom") SingleMemberStringArrOne,
+    @SingleMemberClassArray(Map.class) SingleMemberClassArrOne,
+    @SingleMemberEnumArray(Stooge.MOE)        SingleMemberEnumArrOne,
+
+    // Single member array (two elements)
+    @SingleMemberByteArray({1, 2})         SingleMemberByteArrTwo,
+    @SingleMemberShortArray({2, 3})        SingleMemberShortArrTwo,
+    @SingleMemberIntArray({3, 4})          SingleMemberIntArrTwo,
+    @SingleMemberLongArray({4L, 5L})       SingleMemberLongArrTwo,
+    @SingleMemberCharArray({'5', '6'})     SingleMemberCharArrTwo,
+    @SingleMemberFloatArray({6.0f, 7.0f})  SingleMemberFloatArrTwo,
+    @SingleMemberDoubleArray({7.0, 8.0})   SingleMemberDoubleArrTwo,
+    @SingleMemberBooleanArray({true,false})         SingleMemberBooleanArrTwo,
+    @SingleMemberStringArray({"custom", "paint"})   SingleMemberStringArrTwo,
+    @SingleMemberClassArray({Map.class, Set.class}) SingleMemberClassArrTwo,
+    @SingleMemberEnumArray({Stooge.MOE, Stooge.CURLY})            SingleMemberEnumArrTwo,
+
+    // Single member array with default (override)
+    @SingleMemberByteArrayDef(1)        SingleMemberByteArrOvrdDef,
+    @SingleMemberShortArrayDef(2)       SingleMemberShortArrOvrdDef,
+    @SingleMemberIntArrayDef(3)         SingleMemberIntArrOvrdDef,
+    @SingleMemberLongArrayDef(4L)       SingleMemberLongArrOvrdDef,
+    @SingleMemberCharArrayDef('5')      SingleMemberCharArrOvrdDef,
+    @SingleMemberFloatArrayDef(6.0f)    SingleMemberFloatArrOvrdDef,
+    @SingleMemberDoubleArrayDef(7.0)    SingleMemberDoubleArrOvrdDef,
+    @SingleMemberBooleanArrayDef(true)  SingleMemberBooleanArrOvrdDef,
+    @SingleMemberStringArrayDef("custom") SingleMemberStringArrOvrdDef,
+    @SingleMemberClassArrayDef(Map.class) SingleMemberClassArrOvrdDef,
+    @SingleMemberEnumArrayDef(Stooge.MOE)        SingleMemberEnumArrOvrdDef,
+
+    // Single member array with default - accept
+    @SingleMemberByteArrayDef    SingleMemberByteArrAcceptDef,
+    @SingleMemberShortArrayDef   SingleMemberShortArrAcceptDef,
+    @SingleMemberIntArrayDef     SingleMemberIntArrAcceptDef,
+    @SingleMemberLongArrayDef    SingleMemberLongArrAcceptDef,
+    @SingleMemberCharArrayDef    SingleMemberCharArrAcceptDef,
+    @SingleMemberFloatArrayDef   SingleMemberFloatArrAcceptDef,
+    @SingleMemberDoubleArrayDef  SingleMemberDoubleArrAcceptDef,
+    @SingleMemberBooleanArrayDef SingleMemberBooleanArrAcceptDef,
+    @SingleMemberStringArrayDef  SingleMemberStringArrAcceptDef,
+    @SingleMemberClassArrayDef   SingleMemberClassArrAcceptDef,
+    @SingleMemberEnumArrayDef    SingleMemberEnumArrAcceptDef,
+    }
+
+    // ANNOTATED CONSTRUCTORS
+
+    @ScalarTypes (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    @Point(x = 1, y = 2)
+    )
+    public UnitTest(Iterator it) { } // scalar types
+
+    @ScalarTypesWithDefault ( )
+    public UnitTest(Set s) { } // scalarTypesAcceptDefault
+
+    @ScalarTypesWithDefault (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE
+    )
+    public UnitTest(Map s) { } // scalarTypesOverrideDefault
+
+    @ArrayTypes (
+        b =    { },
+        s =    { },
+        i =    { },
+        l =    { },
+        c =    { },
+        f =    { },
+        d =    { },
+        bool = { },
+        str =  { },
+        cls =  { },
+        e =    { },
+        a =    { }
+    )
+    public UnitTest(List l){ } // emptyArrayTypes
+
+    @ArrayTypes (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    @Point(x = 1, y = 2)
+    )
+    public UnitTest(Collection c) { } // singleElementArrayTypes
+
+    @ArrayTypes (
+        b =    { 1, 2 },
+        s =    { 2, 3 },
+        i =    { 3, 4 },
+        l =    { 4L, 5L },
+        c =    { '5', '6' },
+        f =    { 6.0f, 7.0f },
+        d =    { 7.0, 8.0 },
+        bool = { true, false },
+        str =  { "custom", "paint" },
+        cls =  { Map.class, Set.class },
+        e =    { Stooge.MOE, Stooge.CURLY },
+        a =    { @Point(x = 1, y = 2),  @Point(x = 3, y = 4) }
+    )
+    public UnitTest(SortedSet ss) { } // twoElementArrayTypes
+
+    @ArrayTypesWithDefault ( )
+    public UnitTest(SortedMap sm) { } // arrayTypesAcceptDefault
+
+    @ArrayTypesWithDefault (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    { @Point(x = 1, y = 2) }
+    )
+    public UnitTest(RandomAccess r) { } // arrayTypesOverrideDefault
+
+    // Marker
+    @Marker public UnitTest() { } // marker
+
+    // Single-member (shorthand)
+    @SingleMemberByte(1)          public UnitTest(byte b)    { }
+    @SingleMemberShort(2)         public UnitTest(short s)   { }
+    @SingleMemberInt(3)           public UnitTest(int i)     { }
+    @SingleMemberLong(4L)         public UnitTest(long l)    { }
+    @SingleMemberChar('5')        public UnitTest(char c)    { }
+    @SingleMemberFloat(6.0f)      public UnitTest(float f)   { }
+    @SingleMemberDouble(7.0)      public UnitTest(double d)  { }
+    @SingleMemberBoolean(true)    public UnitTest(boolean b) { }
+    @SingleMemberString("custom") public UnitTest(String s)  { }
+    @SingleMemberClass(Map.class) public UnitTest(Class c)   { }
+    @SingleMemberEnum(Stooge.MOE)        public UnitTest(Enum e)    { }
+
+    // Single-member with default (Override)
+    @SingleMemberByteWithDef(1)          public UnitTest(byte b, Set s)    { }
+    @SingleMemberShortWithDef(2)         public UnitTest(short s, Set x)   { }
+    @SingleMemberIntWithDef(3)           public UnitTest(int i, Set s)     { }
+    @SingleMemberLongWithDef(4L)         public UnitTest(long l, Set s)    { }
+    @SingleMemberCharWithDef('5')        public UnitTest(char c, Set s)    { }
+    @SingleMemberFloatWithDef(6.0f)      public UnitTest(float f, Set s)   { }
+    @SingleMemberDoubleWithDef(7.0)      public UnitTest(double d, Set s)  { }
+    @SingleMemberBooleanWithDef(true)    public UnitTest(boolean b, Set s) { }
+    @SingleMemberStringWithDef("custom") public UnitTest(String s, Set x)  { }
+    @SingleMemberClassWithDef(Map.class) public UnitTest(Class c, Set s)   { }
+    @SingleMemberEnumWithDef(Stooge.MOE)        public UnitTest(Enum e, Set s)    { }
+
+    // Single-member with default (Accept)
+    @SingleMemberByteWithDef    public UnitTest(byte b, Map m)    { }
+    @SingleMemberShortWithDef   public UnitTest(short s, Map m)   { }
+    @SingleMemberIntWithDef     public UnitTest(int i, Map m)     { }
+    @SingleMemberLongWithDef    public UnitTest(long l, Map m)    { }
+    @SingleMemberCharWithDef    public UnitTest(char c, Map m)    { }
+    @SingleMemberFloatWithDef   public UnitTest(float f, Map m)   { }
+    @SingleMemberDoubleWithDef  public UnitTest(double d, Map m)  { }
+    @SingleMemberBooleanWithDef public UnitTest(boolean b, Map m) { }
+    @SingleMemberStringWithDef  public UnitTest(String s, Map m)  { }
+    @SingleMemberClassWithDef   public UnitTest(Class c, Map m)   { }
+    @SingleMemberEnumWithDef    public UnitTest(Enum e, Map m)    { }
+
+    // Single member array (empty array)
+    @SingleMemberByteArray({})   public UnitTest(byte[] b)    { }
+    @SingleMemberShortArray({})  public UnitTest(short[] s)   { }
+    @SingleMemberIntArray({})    public UnitTest(int[] i)     { }
+    @SingleMemberLongArray({})   public UnitTest(long[] l)    { }
+    @SingleMemberCharArray({})   public UnitTest(char[] c)    { }
+    @SingleMemberFloatArray({})  public UnitTest(float[] f)   { }
+    @SingleMemberDoubleArray({}) public UnitTest(double[] d)  { }
+    @SingleMemberBooleanArray({})public UnitTest(boolean[] b) { }
+    @SingleMemberStringArray({}) public UnitTest(String[] s)  { }
+    @SingleMemberClassArray({})  public UnitTest(Class[] c)   { }
+    @SingleMemberEnumArray({})   public UnitTest(Enum[] e)    { }
+
+    // Single member array (one-element shorthand)
+    @SingleMemberByteArray(1)          public UnitTest(byte[] b, Set s)    { }
+    @SingleMemberShortArray(2)         public UnitTest(short[] s, Set x)   { }
+    @SingleMemberIntArray(3)           public UnitTest(int[] i, Set s)     { }
+    @SingleMemberLongArray(4L)         public UnitTest(long[] l, Set s)    { }
+    @SingleMemberCharArray('5')        public UnitTest(char[] c, Set s)    { }
+    @SingleMemberFloatArray(6.0f)      public UnitTest(float[] f, Set s)   { }
+    @SingleMemberDoubleArray(7.0)      public UnitTest(double[] d, Set s)  { }
+    @SingleMemberBooleanArray(true)    public UnitTest(boolean[] b, Set s) { }
+    @SingleMemberStringArray("custom") public UnitTest(String[] s, Set x)  { }
+    @SingleMemberClassArray(Map.class) public UnitTest(Class[] c, Set s)   { }
+    @SingleMemberEnumArray(Stooge.MOE)        public UnitTest(Enum[] e, Set s)    { }
+
+    // Single member array (two elements)
+    @SingleMemberByteArray({1, 2})           public UnitTest(byte[] b, Map m)    { }
+    @SingleMemberShortArray({2, 3})          public UnitTest(short[] s, Map m)   { }
+    @SingleMemberIntArray({3, 4})            public UnitTest(int[] i, Map m)     { }
+    @SingleMemberLongArray({4L, 5L})         public UnitTest(long[] l, Map m)    { }
+    @SingleMemberCharArray({'5', '6'})       public UnitTest(char[] c, Map m)    { }
+    @SingleMemberFloatArray({6.0f, 7.0f})    public UnitTest(float[] f, Map m)   { }
+    @SingleMemberDoubleArray({7.0, 8.0})     public UnitTest(double[] d, Map m)  { }
+    @SingleMemberBooleanArray({true, false}) public UnitTest(boolean[] b, Map m) { }
+    @SingleMemberStringArray({"custom", "paint"})  public UnitTest(String[] s, Map m)  { }
+    @SingleMemberClassArray({Map.class,Set.class}) public UnitTest(Class[] c, Map m) { }
+    @SingleMemberEnumArray({Stooge.MOE, Stooge.CURLY})           public UnitTest(Enum[] e, Map m)  { }
+
+
+    // Single member array with default (override)
+    @SingleMemberByteArrayDef(1)          public UnitTest(byte[] b, List l)    { }
+    @SingleMemberShortArrayDef(2)         public UnitTest(short[] s, List l)   { }
+    @SingleMemberIntArrayDef(3)           public UnitTest(int[] i, List l)     { }
+    @SingleMemberLongArrayDef(4L)         public UnitTest(long[] l, List x)    { }
+    @SingleMemberCharArrayDef('5')        public UnitTest(char[] c, List l)    { }
+    @SingleMemberFloatArrayDef(6.0f)      public UnitTest(float[] f, List l)   { }
+    @SingleMemberDoubleArrayDef(7.0)      public UnitTest(double[] d, List l)  { }
+    @SingleMemberBooleanArrayDef(true)    public UnitTest(boolean[] b, List l) { }
+    @SingleMemberStringArrayDef("custom") public UnitTest(String[] s, List l)  { }
+    @SingleMemberClassArrayDef(Map.class) public UnitTest(Class[] c, List l)   { }
+    @SingleMemberEnumArrayDef(Stooge.MOE)        public UnitTest(Enum[] e, List l)    { }
+
+    // Single member array with default - accept
+    @SingleMemberByteArrayDef    public UnitTest(byte[] b, Collection c)    { }
+    @SingleMemberShortArrayDef   public UnitTest(short[] s, Collection c)   { }
+    @SingleMemberIntArrayDef     public UnitTest(int[] i, Collection c)     { }
+    @SingleMemberLongArrayDef    public UnitTest(long[] l, Collection c)    { }
+    @SingleMemberCharArrayDef    public UnitTest(char[] c, Collection x)    { }
+    @SingleMemberFloatArrayDef   public UnitTest(float[] f, Collection c)   { }
+    @SingleMemberDoubleArrayDef  public UnitTest(double[] d, Collection c)  { }
+    @SingleMemberBooleanArrayDef public UnitTest(boolean[] b, Collection c) { }
+    @SingleMemberStringArrayDef  public UnitTest(String[] s, Collection c)  { }
+    @SingleMemberClassArrayDef   public UnitTest(Class[] c, Collection x)   { }
+    @SingleMemberEnumArrayDef    public UnitTest(Enum[] e, Collection c)    { }
+
+    // ANNOTATED PARAMETERS
+
+    public void scalarTypesParam(
+    @ScalarTypes (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    @Point(x = 1, y = 2)
+    )
+    int x) { }
+
+
+    public void scalarTypesAcceptDefaultParam(
+    @ScalarTypesWithDefault int x) { }
+
+    public void scalarTypesOverrideDefaultParam(
+    @ScalarTypesWithDefault (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE
+    )
+    int x) { }
+
+    public void emptyArrayTypesParam(
+    @ArrayTypes (
+        b = { },
+        s = { },
+        i = { },
+        l = { },
+        c = { },
+        f = { },
+        d = { },
+        bool = { },
+        str = { },
+        cls = { },
+        e = { },
+        a = { }
+    )
+    int x) { }
+
+    public void singleElementArrayTypesParam(
+    @ArrayTypes (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    @Point(x = 1, y = 2)
+    )
+    int x) { }
+
+    public void twoElementArrayTypesParam(
+    @ArrayTypes (
+        b = { 1, 2 },
+        s = { 2, 3 },
+        i = { 3, 4 },
+        l = { 4L, 5L },
+        c = { '5', '6' },
+        f = { 6.0f, 7.0f },
+        d = { 7.0, 8.0 },
+        bool = { true, false },
+        str = { "custom", "paint" },
+        cls = { Map.class, Set.class },
+        e = { Stooge.MOE, Stooge.CURLY },
+        a = { @Point(x = 1, y = 2),  @Point(x = 3, y = 4) }
+    )
+    int x) { }
+
+    public void arrayTypesAcceptDefaultParam(
+    @ArrayTypesWithDefault
+    int x) { }
+
+    public void arrayTypesOverrideDefaultParam(
+    @ArrayTypesWithDefault (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    { @Point(x = 1, y = 2) }
+    )
+    int x) { }
+
+    // Marker
+    public void markerParam(@Marker int x) { }
+
+    // Single-member (shorthand)
+    public void SingleMemberByteParam(@SingleMemberByte(1) int x) {}
+    public void SingleMemberShortParam(@SingleMemberShort(2) int x) {}
+    public void SingleMemberIntParam(@SingleMemberInt(3) int x) {}
+    public void SingleMemberLongParam(@SingleMemberLong(4L) int x) {}
+    public void SingleMemberCharParam(@SingleMemberChar('5') int x) {}
+    public void SingleMemberFloatParam(@SingleMemberFloat(6.0f) int x) {}
+    public void SingleMemberDoubleParam(@SingleMemberDouble(7.0) int x) {}
+    public void SingleMemberBooleanParam(@SingleMemberBoolean(true) int x) {}
+    public void SingleMemberStringParam(@SingleMemberString("custom") int x) {}
+    public void SingleMemberClassParam(@SingleMemberClass(Map.class) int x) {}
+    public void SingleMemberEnumParam(@SingleMemberEnum(Stooge.MOE) int x) {}
+
+    // Single-member with default (Override)
+    public void SingleMemberByteOvrdDefParam(@SingleMemberByteWithDef(1) int x) {}
+    public void SingleMemberShortOvrdDefParam(@SingleMemberShortWithDef(2) int x) {}
+    public void SingleMemberIntOvrdDefParam(@SingleMemberIntWithDef(3) int x) {}
+    public void SingleMemberLongOvrdDefParam(@SingleMemberLongWithDef(4L) int x) {}
+    public void SingleMemberCharOvrdDefParam(@SingleMemberCharWithDef('5') int x) {}
+    public void SingleMemberFloatOvrdDefParam(@SingleMemberFloatWithDef(6.0f) int x) {}
+    public void SingleMemberDoubleOvrdDefParam(@SingleMemberDoubleWithDef(7.0) int x) {}
+    public void SingleMemberBooleanOvrdDefParam(@SingleMemberBooleanWithDef(true) int x) {}
+    public void SingleMemberStringOvrdDefParam(@SingleMemberStringWithDef("custom") int x) {}
+    public void SingleMemberClassOvrdDefParam(@SingleMemberClassWithDef(Map.class)  int x) {}
+    public void SingleMemberEnumOvrdDefParam(@SingleMemberEnumWithDef(Stooge.MOE) int x) {}
+
+    // Single-member with default (Accept)
+    public void SingleMemberByteAcceptDefParam(@SingleMemberByteWithDef int x) {}
+    public void SingleMemberShortAcceptDefParam(@SingleMemberShortWithDef int x) {}
+    public void SingleMemberIntAcceptDefParam(@SingleMemberIntWithDef int x) {}
+    public void SingleMemberLongAcceptDefParam(@SingleMemberLongWithDef int x) {}
+    public void SingleMemberCharAcceptDefParam(@SingleMemberCharWithDef int x) {}
+    public void SingleMemberFloatAcceptDefParam(@SingleMemberFloatWithDef int x) {}
+    public void SingleMemberDoubleAcceptDefParam(@SingleMemberDoubleWithDef int x) {}
+    public void SingleMemberBooleanAcceptDefParam(@SingleMemberBooleanWithDef int x){}
+    public void SingleMemberStringAcceptDefParam(@SingleMemberStringWithDef int x) {}
+    public void SingleMemberClassAcceptDefParam(@SingleMemberClassWithDef int x) {}
+    public void SingleMemberEnumAcceptDefParam(@SingleMemberEnumWithDef int x) {}
+
+    // Single member array (empty array)
+    public void SingleMemberByteArrEmptyParam(@SingleMemberByteArray({}) int x) {}
+    public void SingleMemberShortArrEmptyParam(@SingleMemberShortArray({}) int x) {}
+    public void SingleMemberIntArrEmptyParam(@SingleMemberIntArray({}) int x) {}
+    public void SingleMemberLongArrEmptyParam(@SingleMemberLongArray({}) int x) {}
+    public void SingleMemberCharArrEmptyParam(@SingleMemberCharArray({}) int x) {}
+    public void SingleMemberFloatArrEmptyParam(@SingleMemberFloatArray({}) int x) {}
+    public void SingleMemberDoubleArrEmptyParam(@SingleMemberDoubleArray({}) int x) {}
+    public void SingleMemberBooleanArrEmptyParam(@SingleMemberBooleanArray({}) int x) {}
+    public void SingleMemberStringArrEmptyParam(@SingleMemberStringArray({}) int x) {}
+    public void SingleMemberClassArrEmptyParam(@SingleMemberClassArray({}) int x) {}
+    public void SingleMemberEnumArrEmptyParam(@SingleMemberEnumArray({}) int x) {}
+
+    // Single member array (one-element shorthand)
+    public void SingleMemberByteArrOneParam(@SingleMemberByteArray(1) int x) {}
+    public void SingleMemberShortArrOneParam(@SingleMemberShortArray(2) int x) {}
+    public void SingleMemberIntArrOneParam(@SingleMemberIntArray(3) int x) {}
+    public void SingleMemberLongArrOneParam(@SingleMemberLongArray(4L) int x) {}
+    public void SingleMemberCharArrOneParam(@SingleMemberCharArray('5') int x) {}
+    public void SingleMemberFloatArrOneParam(@SingleMemberFloatArray(6.0f) int x) {}
+    public void SingleMemberDoubleArrOneParam(@SingleMemberDoubleArray(7.0) int x) {}
+    public void SingleMemberBooleanArrOneParam(@SingleMemberBooleanArray(true) int x) {}
+    public void SingleMemberStringArrOneParam(@SingleMemberStringArray("custom") int x) {}
+    public void SingleMemberClassArrOneParam(@SingleMemberClassArray(Map.class) int x) {}
+    public void SingleMemberEnumArrOneParam(@SingleMemberEnumArray(Stooge.MOE) int x) {}
+
+    // Single member array (two elements)
+    public void SingleMemberByteArrTwoParam(@SingleMemberByteArray({1, 2}) int x) {}
+    public void SingleMemberShortArrTwoParam(@SingleMemberShortArray({2, 3}) int x) {}
+    public void SingleMemberIntArrTwoParam(@SingleMemberIntArray({3, 4}) int x) {}
+    public void SingleMemberLongArrTwoParam(@SingleMemberLongArray({4L, 5L}) int x) {}
+    public void SingleMemberCharArrTwoParam(@SingleMemberCharArray({'5', '6'}) int x) {}
+    public void SingleMemberFloatArrTwoParam(@SingleMemberFloatArray({6.0f, 7.0f}) int x) {}
+    public void SingleMemberDoubleArrTwoParam(@SingleMemberDoubleArray({7.0, 8.0}) int x) {}
+    public void SingleMemberBooleanArrTwoParam(@SingleMemberBooleanArray({true, false}) int x){}
+    public void SingleMemberStringArrTwoParam(@SingleMemberStringArray({"custom", "paint"}) int x) {}
+    public void SingleMemberClassArrTwoParam(@SingleMemberClassArray({Map.class, Set.class}) int x) {}
+    public void SingleMemberEnumArrTwoParam(@SingleMemberEnumArray({Stooge.MOE, Stooge.CURLY}) int x) {}
+
+    // Single member array with default (override)
+    public void SingleMemberByteArrOvrdDefParam(@SingleMemberByteArrayDef(1) int x) {}
+    public void SingleMemberShortArrOvrdDefParam(@SingleMemberShortArrayDef(2) int x) {}
+    public void SingleMemberIntArrOvrdDefParam(@SingleMemberIntArrayDef(3) int x) {}
+    public void SingleMemberLongArrOvrdDefParam(@SingleMemberLongArrayDef(4L) int x) {}
+    public void SingleMemberCharArrOvrdDefParam(@SingleMemberCharArrayDef('5') int x) {}
+    public void SingleMemberFloatArrOvrdDefParam(@SingleMemberFloatArrayDef(6.0f) int x) {}
+    public void SingleMemberDoubleArrOvrdDefParam(@SingleMemberDoubleArrayDef(7.0) int x) {}
+    public void SingleMemberBooleanArrOvrdDefParam(@SingleMemberBooleanArrayDef(true) int x){}
+    public void SingleMemberStringArrOvrdDefParam(@SingleMemberStringArrayDef("custom") int x) {}
+    public void SingleMemberClassArrOvrdDefParam(@SingleMemberClassArrayDef(Map.class) int x) {}
+    public void SingleMemberEnumArrOvrdDefParam(@SingleMemberEnumArrayDef(Stooge.MOE) int x) {}
+
+    // Single member array with default - accept
+    public void SingleMemberByteArrAcceptDefParam(@SingleMemberByteArrayDef int x) {}
+    public void SingleMemberShortArrAcceptDefParam(@SingleMemberShortArrayDef int x) {}
+    public void SingleMemberIntArrAcceptDefParam(@SingleMemberIntArrayDef int x) {}
+    public void SingleMemberLongArrAcceptDefParam(@SingleMemberLongArrayDef int x) {}
+    public void SingleMemberCharArrAcceptDefParam(@SingleMemberCharArrayDef int x) {}
+    public void SingleMemberFloatArrAcceptDefParam(@SingleMemberFloatArrayDef int x) {}
+    public void SingleMemberDoubleArrAcceptDefParam(@SingleMemberDoubleArrayDef int x) {}
+    public void SingleMemberBooleanArrAcceptDefParam(@SingleMemberBooleanArrayDef int x){}
+    public void SingleMemberStringArrAcceptDefParam(@SingleMemberStringArrayDef int x) {}
+    public void SingleMemberClassArrAcceptDefParam(@SingleMemberClassArrayDef int x) {}
+    public void SingleMemberEnumArrAcceptDefParam(@SingleMemberEnumArrayDef int x) {}
+}
+
+// Helper types
+
+enum Stooge { LARRY, MOE, CURLY }
+
+@Target({}) @interface Point { int x(); int y(); }
+
+// ANNOTATION TYPES
+
+@Retention(RUNTIME) @interface ScalarTypes {
+    byte     b();
+    short    s();
+    int      i();
+    long     l();
+    char     c();
+    float    f();
+    double   d();
+    boolean  bool();
+    String   str();
+    Class    cls();
+    Stooge   e();
+    Point    a();
+}
+
+@Retention(RUNTIME) @interface ScalarTypesWithDefault {
+    byte     b()    default 11;
+    short    s()    default 12;
+    int      i()    default 13;
+    long     l()    default 14;
+    char     c()    default 'V';
+    float    f()    default 16.0f;
+    double   d()    default 17.0;
+    boolean  bool() default false;
+    String   str()  default "default";
+    Class    cls()  default Class.class;
+    Stooge   e()    default Stooge.LARRY;
+    Point    a()    default @Point(x = 11, y = 12);
+}
+
+@Retention(RUNTIME) @interface ArrayTypes {
+    byte[]     b();
+    short[]    s();
+    int[]      i();
+    long[]     l();
+    char[]     c();
+    float[]    f();
+    double[]   d();
+    boolean[]  bool();
+    String[]   str();
+    Class[]    cls();
+    Stooge[]   e();
+    Point[]    a();
+}
+
+@Retention(RUNTIME) @interface ArrayTypesWithDefault {
+    byte[]    b()    default { 11 };
+    short[]   s()    default { 12 };
+    int[]     i()    default { 13 };
+    long[]    l()    default { 14L };
+    char[]    c()    default { 'V' };
+    float[]   f()    default { 16.0f };
+    double[]  d()    default { 17.0 };
+    boolean[] bool() default { false };
+    String[]  str()  default { "default" };
+    Class[]   cls()  default { Class.class };
+    Stooge[]  e()    default { Stooge.LARRY };
+    Point[]   a()    default { @Point(x = 11, y = 12) };
+}
+
+@Retention(RUNTIME) @interface Marker { }
+
+@Retention(RUNTIME) @interface SingleMemberByte    { byte     value(); }
+@Retention(RUNTIME) @interface SingleMemberShort   { short    value(); }
+@Retention(RUNTIME) @interface SingleMemberInt     { int      value(); }
+@Retention(RUNTIME) @interface SingleMemberLong    { long     value(); }
+@Retention(RUNTIME) @interface SingleMemberChar    { char     value(); }
+@Retention(RUNTIME) @interface SingleMemberFloat   { float    value(); }
+@Retention(RUNTIME) @interface SingleMemberDouble  { double   value(); }
+@Retention(RUNTIME) @interface SingleMemberBoolean { boolean  value(); }
+@Retention(RUNTIME) @interface SingleMemberString  { String   value(); }
+@Retention(RUNTIME) @interface SingleMemberClass   { Class    value(); }
+@Retention(RUNTIME) @interface SingleMemberEnum    { Stooge   value(); }
+
+@Retention(RUNTIME) @interface SingleMemberByteWithDef    { byte     value() default 11; }
+@Retention(RUNTIME) @interface SingleMemberShortWithDef   { short    value() default 12; }
+@Retention(RUNTIME) @interface SingleMemberIntWithDef     { int      value() default 13; }
+@Retention(RUNTIME) @interface SingleMemberLongWithDef    { long     value() default 14; }
+@Retention(RUNTIME) @interface SingleMemberCharWithDef    { char     value() default 'V'; }
+@Retention(RUNTIME) @interface SingleMemberFloatWithDef   { float    value() default 16.0f; }
+@Retention(RUNTIME) @interface SingleMemberDoubleWithDef  { double   value() default 17.0; }
+@Retention(RUNTIME) @interface SingleMemberBooleanWithDef { boolean  value() default false; }
+@Retention(RUNTIME) @interface SingleMemberStringWithDef  { String   value() default "default"; }
+@Retention(RUNTIME) @interface SingleMemberClassWithDef   { Class    value() default Class.class; }
+@Retention(RUNTIME) @interface SingleMemberEnumWithDef    { Stooge   value() default Stooge.LARRY; }
+
+@Retention(RUNTIME) @interface SingleMemberByteArray    { byte[]     value(); }
+@Retention(RUNTIME) @interface SingleMemberShortArray   { short[]    value(); }
+@Retention(RUNTIME) @interface SingleMemberIntArray     { int[]      value(); }
+@Retention(RUNTIME) @interface SingleMemberLongArray    { long[]     value(); }
+@Retention(RUNTIME) @interface SingleMemberCharArray    { char[]     value(); }
+@Retention(RUNTIME) @interface SingleMemberFloatArray   { float[]    value(); }
+@Retention(RUNTIME) @interface SingleMemberDoubleArray  { double[]   value(); }
+@Retention(RUNTIME) @interface SingleMemberBooleanArray { boolean[]  value(); }
+@Retention(RUNTIME) @interface SingleMemberStringArray  { String[]   value(); }
+@Retention(RUNTIME) @interface SingleMemberClassArray   { Class[]    value(); }
+@Retention(RUNTIME) @interface SingleMemberEnumArray    { Stooge[]   value(); }
+
+@Retention(RUNTIME) @interface SingleMemberByteArrayDef    { byte[]     value() default { 11 }; }
+@Retention(RUNTIME) @interface SingleMemberShortArrayDef   { short[]    value() default { 12 }; }
+@Retention(RUNTIME) @interface SingleMemberIntArrayDef     { int[]      value() default { 13 }; }
+@Retention(RUNTIME) @interface SingleMemberLongArrayDef    { long[]     value() default { 14 }; }
+@Retention(RUNTIME) @interface SingleMemberCharArrayDef    { char[]     value() default { 'V' }; }
+@Retention(RUNTIME) @interface SingleMemberFloatArrayDef   { float[]    value() default { 16.0f };}
+@Retention(RUNTIME) @interface SingleMemberDoubleArrayDef  { double[]   value() default { 17.0 }; }
+@Retention(RUNTIME) @interface SingleMemberBooleanArrayDef { boolean[]  value() default { false };}
+@Retention(RUNTIME) @interface SingleMemberStringArrayDef  {
+    String[]  value() default {"default"};
+}
+@Retention(RUNTIME) @interface SingleMemberClassArrayDef {
+    Class[]   value() default {Class.class};
+}
+@Retention(RUNTIME) @interface SingleMemberEnumArrayDef {
+    Stooge[]   value() default {Stooge.LARRY};
+}
+
+// Annotation types for inheritance and declared-annotations tests
+@Inherited @Retention(RUNTIME) @interface Foo { }
+           @Retention(RUNTIME) @interface Bar { }
+
+
+    // ANNOTATED CLASSES
+
+    @ScalarTypes (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    @Point(x = 1, y = 2)
+    )
+    class scalarTypesClass { }
+
+    @ScalarTypesWithDefault ( )
+    class scalarTypesAcceptDefaultClass { }
+
+    @ScalarTypesWithDefault (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE
+    )
+    class scalarTypesOverrideDefaultClass { }
+
+    @ArrayTypes (
+        b =    { },
+        s =    { },
+        i =    { },
+        l =    { },
+        c =    { },
+        f =    { },
+        d =    { },
+        bool = { },
+        str =  { },
+        cls =  { },
+        e =    { },
+        a =    { }
+    )
+    class emptyArrayTypesClass { }
+
+    @ArrayTypes (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    @Point(x = 1, y = 2)
+    )
+    class singleElementArrayTypesClass { }
+
+    @ArrayTypes (
+        b =    { 1, 2 },
+        s =    { 2, 3 },
+        i =    { 3, 4 },
+        l =    { 4L, 5L },
+        c =    { '5', '6' },
+        f =    { 6.0f, 7.0f },
+        d =    { 7.0, 8.0 },
+        bool = { true, false },
+        str =  { "custom", "paint" },
+        cls =  { Map.class, Set.class },
+        e =    { Stooge.MOE, Stooge.CURLY },
+        a =    { @Point(x = 1, y = 2),  @Point(x = 3, y = 4) }
+    )
+    class twoElementArrayTypesClass { }
+
+    @ArrayTypesWithDefault (
+    )
+    class arrayTypesAcceptDefaultClass { }
+
+    @ArrayTypesWithDefault (
+        b =    1,
+        s =    2,
+        i =    3,
+        l =    4L,
+        c =    '5',
+        f =    6.0f,
+        d =    7.0,
+        bool = true,
+        str =  "custom",
+        cls =  Map.class,
+        e =    Stooge.MOE,
+        a =    { @Point(x = 1, y = 2) }
+    )
+    class arrayTypesOverrideDefaultClass { }
+
+    @Marker class markerClass { }
+
+    // Single-member (shorthand)
+    @SingleMemberByte(1)          class SingleMemberByteClass { }
+    @SingleMemberShort(2)         class SingleMemberShortClass { }
+    @SingleMemberInt(3)           class SingleMemberIntClass { }
+    @SingleMemberLong(4L)         class SingleMemberLongClass { }
+    @SingleMemberChar('5')        class SingleMemberCharClass { }
+    @SingleMemberFloat(6.0f)      class SingleMemberFloatClass { }
+    @SingleMemberDouble(7.0)      class SingleMemberDoubleClass { }
+    @SingleMemberBoolean(true)    class SingleMemberBooleanClass { }
+    @SingleMemberString("custom") class SingleMemberStringClass { }
+    @SingleMemberClass(Map.class) class SingleMemberClassClass { }
+    @SingleMemberEnum(Stooge.MOE)        class SingleMemberEnumClass { }
+
+    // Single-member with default (Override)
+    @SingleMemberByteWithDef(1)          class SingleMemberByteOvrdDefClass { }
+    @SingleMemberShortWithDef(2)         class SingleMemberShortOvrdDefClass { }
+    @SingleMemberIntWithDef(3)           class SingleMemberIntOvrdDefClass { }
+    @SingleMemberLongWithDef(4L)         class SingleMemberLongOvrdDefClass { }
+    @SingleMemberCharWithDef('5')        class SingleMemberCharOvrdDefClass { }
+    @SingleMemberFloatWithDef(6.0f)      class SingleMemberFloatOvrdDefClass { }
+    @SingleMemberDoubleWithDef(7.0)      class SingleMemberDoubleOvrdDefClass { }
+    @SingleMemberBooleanWithDef(true)    class SingleMemberBooleanOvrdDefClass { }
+    @SingleMemberStringWithDef("custom") class SingleMemberStringOvrdDefClass { }
+    @SingleMemberClassWithDef(Map.class) class SingleMemberClassOvrdDefClass { }
+    @SingleMemberEnumWithDef(Stooge.MOE)        class SingleMemberEnumOvrdDefClass { }
+
+    // Single-member with default (Accept)
+    @SingleMemberByteWithDef    class SingleMemberByteAcceptDefClass { }
+    @SingleMemberShortWithDef   class SingleMemberShortAcceptDefClass { }
+    @SingleMemberIntWithDef     class SingleMemberIntAcceptDefClass { }
+    @SingleMemberLongWithDef    class SingleMemberLongAcceptDefClass { }
+    @SingleMemberCharWithDef    class SingleMemberCharAcceptDefClass { }
+    @SingleMemberFloatWithDef   class SingleMemberFloatAcceptDefClass { }
+    @SingleMemberDoubleWithDef  class SingleMemberDoubleAcceptDefClass { }
+    @SingleMemberBooleanWithDef class SingleMemberBooleanAcceptDefClass { }
+    @SingleMemberStringWithDef  class SingleMemberStringAcceptDefClass { }
+    @SingleMemberClassWithDef   class SingleMemberClassAcceptDefClass { }
+    @SingleMemberEnumWithDef    class SingleMemberEnumAcceptDefClass { }
+
+    // Single member array (empty array)
+    @SingleMemberByteArray({})   class SingleMemberByteArrEmptyClass { }
+    @SingleMemberShortArray({})  class SingleMemberShortArrEmptyClass { }
+    @SingleMemberIntArray({})    class SingleMemberIntArrEmptyClass { }
+    @SingleMemberLongArray({})   class SingleMemberLongArrEmptyClass { }
+    @SingleMemberCharArray({})   class SingleMemberCharArrEmptyClass { }
+    @SingleMemberFloatArray({})  class SingleMemberFloatArrEmptyClass { }
+    @SingleMemberDoubleArray({}) class SingleMemberDoubleArrEmptyClass { }
+    @SingleMemberBooleanArray({})class SingleMemberBooleanArrEmptyClass { }
+    @SingleMemberStringArray({}) class SingleMemberStringArrEmptyClass { }
+    @SingleMemberClassArray({})  class SingleMemberClassArrEmptyClass { }
+    @SingleMemberEnumArray({})   class SingleMemberEnumArrEmptyClass { }
+
+    // Single member array (one-element shorthand)
+    @SingleMemberByteArray(1)          class SingleMemberByteArrOneClass { }
+    @SingleMemberShortArray(2)         class SingleMemberShortArrOneClass { }
+    @SingleMemberIntArray(3)           class SingleMemberIntArrOneClass { }
+    @SingleMemberLongArray(4L)         class SingleMemberLongArrOneClass { }
+    @SingleMemberCharArray('5')        class SingleMemberCharArrOneClass { }
+    @SingleMemberFloatArray(6.0f)      class SingleMemberFloatArrOneClass { }
+    @SingleMemberDoubleArray(7.0)      class SingleMemberDoubleArrOneClass { }
+    @SingleMemberBooleanArray(true)    class SingleMemberBooleanArrOneClass { }
+    @SingleMemberStringArray("custom") class SingleMemberStringArrOneClass { }
+    @SingleMemberClassArray(Map.class) class SingleMemberClassArrOneClass { }
+    @SingleMemberEnumArray(Stooge.MOE)        class SingleMemberEnumArrOneClass { }
+
+    // Single member array (two elements)
+    @SingleMemberByteArray({1, 2})         class SingleMemberByteArrTwoClass { }
+    @SingleMemberShortArray({2, 3})        class SingleMemberShortArrTwoClass { }
+    @SingleMemberIntArray({3, 4})          class SingleMemberIntArrTwoClass { }
+    @SingleMemberLongArray({4L, 5L})       class SingleMemberLongArrTwoClass { }
+    @SingleMemberCharArray({'5', '6'})     class SingleMemberCharArrTwoClass { }
+    @SingleMemberFloatArray({6.0f, 7.0f})  class SingleMemberFloatArrTwoClass { }
+    @SingleMemberDoubleArray({7.0, 8.0})   class SingleMemberDoubleArrTwoClass { }
+    @SingleMemberBooleanArray({true,false})         class SingleMemberBooleanArrTwoClass { }
+    @SingleMemberStringArray({"custom", "paint"})   class SingleMemberStringArrTwoClass { }
+    @SingleMemberClassArray({Map.class, Set.class}) class SingleMemberClassArrTwoClass { }
+    @SingleMemberEnumArray({Stooge.MOE, Stooge.CURLY})            class SingleMemberEnumArrTwoClass { }
+
+    // Single member array with default (override)
+    @SingleMemberByteArrayDef(1)        class SingleMemberByteArrOvrdDefClass { }
+    @SingleMemberShortArrayDef(2)       class SingleMemberShortArrOvrdDefClass { }
+    @SingleMemberIntArrayDef(3)         class SingleMemberIntArrOvrdDefClass { }
+    @SingleMemberLongArrayDef(4L)       class SingleMemberLongArrOvrdDefClass { }
+    @SingleMemberCharArrayDef('5')      class SingleMemberCharArrOvrdDefClass { }
+    @SingleMemberFloatArrayDef(6.0f)    class SingleMemberFloatArrOvrdDefClass { }
+    @SingleMemberDoubleArrayDef(7.0)    class SingleMemberDoubleArrOvrdDefClass { }
+    @SingleMemberBooleanArrayDef(true)  class SingleMemberBooleanArrOvrdDefClass { }
+    @SingleMemberStringArrayDef("custom") class SingleMemberStringArrOvrdDefClass { }
+    @SingleMemberClassArrayDef(Map.class) class SingleMemberClassArrOvrdDefClass { }
+    @SingleMemberEnumArrayDef(Stooge.MOE)        class SingleMemberEnumArrOvrdDefClass { }
+
+    // Single member array with default - accept
+    @SingleMemberByteArrayDef    class SingleMemberByteArrAcceptDefClass { }
+    @SingleMemberShortArrayDef   class SingleMemberShortArrAcceptDefClass { }
+    @SingleMemberIntArrayDef     class SingleMemberIntArrAcceptDefClass { }
+    @SingleMemberLongArrayDef    class SingleMemberLongArrAcceptDefClass { }
+    @SingleMemberCharArrayDef    class SingleMemberCharArrAcceptDefClass { }
+    @SingleMemberFloatArrayDef   class SingleMemberFloatArrAcceptDefClass { }
+    @SingleMemberDoubleArrayDef  class SingleMemberDoubleArrAcceptDefClass { }
+    @SingleMemberBooleanArrayDef class SingleMemberBooleanArrAcceptDefClass { }
+    @SingleMemberStringArrayDef  class SingleMemberStringArrAcceptDefClass { }
+    @SingleMemberClassArrayDef   class SingleMemberClassArrAcceptDefClass { }
+    @SingleMemberEnumArrayDef    class SingleMemberEnumArrAcceptDefClass { }
+
+    // Annotated classes for inheritance and declared-annotations tests
+    @Foo @Bar class Grandpa     { }
+    class Dad extends Grandpa   { }
+    @Bar class Son extends Dad  { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/loaderLeak/A.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+public
+@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
+@interface A {
+    B b();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/loaderLeak/B.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+public @interface B {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/loaderLeak/C.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+public @A(b=@B()) class C {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/loaderLeak/LoaderLeak.sh	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+# Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+
+if [ "${TESTSRC}" = "" ]
+then
+  echo "TESTSRC not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTSRC=${TESTSRC}"
+if [ "${TESTJAVA}" = "" ]
+then
+  echo "TESTJAVA not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTJAVA=${TESTJAVA}"
+if [ "${TESTCLASSES}" = "" ]
+then
+  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTCLASSES=${TESTCLASSES}"
+echo "CLASSPATH=${CLASSPATH}"
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  SunOS | Linux )
+    NULL=/dev/null
+    PS=":"
+    FS="/"
+    ;;
+  Windows* )
+    NULL=NUL
+    PS=";"
+    FS="\\"
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+mkdir -p classes
+cp ${TESTSRC}${FS}*.java .
+${TESTJAVA}${FS}bin${FS}javac -d classes A.java B.java C.java
+${TESTJAVA}${FS}bin${FS}javac Main.java
+${TESTJAVA}${FS}bin${FS}java Main
+result=$?
+if [ $result -eq 0 ]
+then
+  echo "Passed 1 of 2"
+else
+  echo "Failed 1 of 2"
+  exit $result
+fi
+${TESTJAVA}${FS}bin${FS}java Main foo
+result=$?
+if [ $result -eq 0 ]
+then
+  echo "Passed 2 of 2"
+else
+  echo "Failed 2 of 2"
+fi
+exit $result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/loaderLeak/Main.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 5040740
+ * @summary annotations cause memory leak
+ * @author gafter
+ *
+ * @run shell LoaderLeak.sh
+ */
+
+import java.net.*;
+import java.lang.ref.*;
+import java.util.*;
+import java.io.*;
+
+public class Main {
+    public static void main(String[] args) throws Exception {
+        for (int i=0; i<100; i++)
+            doTest(args.length != 0);
+    }
+
+    static void doTest(boolean readAnn) throws Exception {
+        // URL classes = new URL("file://" + System.getProperty("user.dir") + "/classes");
+        // URL[] path = { classes };
+        // URLClassLoader loader = new URLClassLoader(path);
+        ClassLoader loader = new SimpleClassLoader();
+        WeakReference<Class<?>> c = new WeakReference(loader.loadClass("C"));
+        if (c.get() == null) throw new AssertionError();
+        if (c.get().getClassLoader() != loader) throw new AssertionError();
+        if (readAnn) System.out.println(c.get().getAnnotations()[0]);
+        if (c.get() == null) throw new AssertionError();
+        System.gc();
+        System.gc();
+        if (c.get() == null) throw new AssertionError();
+        System.gc();
+        System.gc();
+        loader = null;
+        System.gc();
+        System.gc();
+        if (c.get() != null) throw new AssertionError();
+    }
+}
+
+class SimpleClassLoader extends ClassLoader {
+    private Hashtable classes = new Hashtable();
+
+    public SimpleClassLoader() {
+    }
+    private byte getClassImplFromDataBase(String className)[] {
+        byte result[];
+        try {
+            FileInputStream fi = new FileInputStream("classes/"+className+".class");
+            result = new byte[fi.available()];
+            fi.read(result);
+            return result;
+        } catch (Exception e) {
+
+            /*
+             * If we caught an exception, either the class wasnt found or it
+             * was unreadable by our process.
+             */
+            return null;
+        }
+    }
+    public Class loadClass(String className) throws ClassNotFoundException {
+        return (loadClass(className, true));
+    }
+    public synchronized Class loadClass(String className, boolean resolveIt)
+        throws ClassNotFoundException {
+        Class result;
+        byte  classData[];
+
+        /* Check our local cache of classes */
+        result = (Class)classes.get(className);
+        if (result != null) {
+            return result;
+        }
+
+        /* Check with the primordial class loader */
+        try {
+            result = super.findSystemClass(className);
+            return result;
+        } catch (ClassNotFoundException e) {
+        }
+
+        /* Try to load it from our repository */
+        classData = getClassImplFromDataBase(className);
+        if (classData == null) {
+            throw new ClassNotFoundException();
+        }
+
+        /* Define it (parse the class file) */
+        result = defineClass(classData, 0, classData.length);
+        if (result == null) {
+            throw new ClassFormatError();
+        }
+
+        if (resolveIt) {
+            resolveClass(result);
+        }
+
+        classes.put(className, result);
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/package-info.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4901290 5037531
+ * @summary Package annotations
+ * @author gafter
+ *
+ * @compile -source 1.5 package-info.java PackageMain.java
+ * @run main PackageMain
+ */
+
+@java.lang.annotation.Documented
+package foo.bar;
+
+class Baz {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/AddTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2006 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6362557
+ * @summary Some tests of add(BigDecimal, mc)
+ * @author Joseph D. Darcy
+ */
+
+import java.math.*;
+import static java.math.BigDecimal.*;
+import java.util.Set;
+import java.util.EnumSet;
+
+public class AddTests {
+
+    private static Set<RoundingMode> nonExactRoundingModes =
+        EnumSet.complementOf(EnumSet.of(RoundingMode.UNNECESSARY));
+
+    /**
+     * Test for extreme value of scale and rounding precision that
+     * could cause integer overflow in right-shift-into-sticky-bit
+     * computations.
+     */
+    private static int extremaTests() {
+        int failures = 0;
+
+        failures += addWithoutException(valueOf(1, -Integer.MAX_VALUE),
+                                        valueOf(2, Integer.MAX_VALUE), null);
+        failures += addWithoutException(valueOf(1, -Integer.MAX_VALUE),
+                                        valueOf(-2, Integer.MAX_VALUE), null);
+        return failures;
+    }
+
+    /**
+     * Print sum of b1 and b2; correct result will not throw an
+     * exception.
+     */
+    private static int addWithoutException(BigDecimal b1, BigDecimal b2, MathContext mc) {
+        if (mc == null)
+            mc = new MathContext(2, RoundingMode.DOWN);
+
+        try {
+            BigDecimal sum = b1.add(b2, mc);
+            printAddition(b1, b2, sum.toString());
+            return 0;
+        } catch(ArithmeticException ae) {
+            printAddition(b1, b2, "Exception!");
+            return 1;
+        }
+    }
+
+    /**
+     * Test combinations of operands that may meet the condensation
+     * criteria when rounded to different precisions.
+     */
+    private static int roundingGradationTests() {
+        int failures = 0;
+
+        failures += roundAway(new BigDecimal("1234e100"),
+                              new BigDecimal(   "1234e97"));
+
+        failures += roundAway(new BigDecimal("1234e100"),
+                              new BigDecimal(    "1234e96"));
+
+        failures += roundAway(new BigDecimal("1234e100"),
+                              new BigDecimal(     "1234e95"));
+
+        failures += roundAway(new BigDecimal("1234e100"),
+                              new BigDecimal(      "1234e94"));
+
+        failures += roundAway(new BigDecimal("1234e100"),
+                              new BigDecimal(       "1234e93"));
+
+        failures += roundAway(new BigDecimal("1234e100"),
+                              new BigDecimal(        "1234e92"));
+
+        failures += roundAway(new BigDecimal("1234e100"),
+                              new BigDecimal("1234e50"));
+
+
+        failures += roundAway(new BigDecimal("1000e100"),
+                              new BigDecimal(   "1234e97"));
+
+        failures += roundAway(new BigDecimal("1000e100"),
+                              new BigDecimal(    "1234e96"));
+
+        failures += roundAway(new BigDecimal("1000e100"),
+                              new BigDecimal(     "1234e95"));
+
+        failures += roundAway(new BigDecimal("1000e100"),
+                              new BigDecimal(      "1234e94"));
+
+        failures += roundAway(new BigDecimal("1000e100"),
+                              new BigDecimal(       "1234e93"));
+
+        failures += roundAway(new BigDecimal("1000e100"),
+                              new BigDecimal(        "1234e92"));
+
+        failures += roundAway(new BigDecimal("1000e100"),
+                              new BigDecimal("1234e50"));
+
+
+
+        failures += roundAway(new BigDecimal("1999e100"),
+                              new BigDecimal(   "1234e97"));
+
+        failures += roundAway(new BigDecimal("1999e100"),
+                              new BigDecimal(    "1234e96"));
+
+        failures += roundAway(new BigDecimal("1999e100"),
+                              new BigDecimal(     "1234e95"));
+
+        failures += roundAway(new BigDecimal("1999e100"),
+                              new BigDecimal(      "1234e94"));
+
+        failures += roundAway(new BigDecimal("1999e100"),
+                              new BigDecimal(       "1234e93"));
+
+        failures += roundAway(new BigDecimal("1999e100"),
+                              new BigDecimal(        "1234e92"));
+
+        failures += roundAway(new BigDecimal("1999e100"),
+                              new BigDecimal("1234e50"));
+
+
+
+        failures += roundAway(new BigDecimal("9999e100"),
+                              new BigDecimal(   "1234e97"));
+
+        failures += roundAway(new BigDecimal("9999e100"),
+                              new BigDecimal(    "1234e96"));
+
+        failures += roundAway(new BigDecimal("9999e100"),
+                              new BigDecimal(     "1234e95"));
+
+        failures += roundAway(new BigDecimal("9999e100"),
+                              new BigDecimal(      "1234e94"));
+
+        failures += roundAway(new BigDecimal("9999e100"),
+                              new BigDecimal(       "1234e93"));
+
+        failures += roundAway(new BigDecimal("9999e100"),
+                              new BigDecimal(        "1234e92"));
+
+        failures += roundAway(new BigDecimal("9999e100"),
+                              new BigDecimal("1234e50"));
+
+        return failures;
+    }
+
+    private static void printAddition(BigDecimal b1, BigDecimal b2, String s) {
+        System.out.println("" + b1+ "\t+\t" + b2 + "\t=\t" + s);
+    }
+
+    private static int roundAway(BigDecimal b1, BigDecimal b2) {
+        int failures = 0;
+
+        b1.precision();
+        b2.precision();
+
+        BigDecimal b1_negate = b1.negate();
+        BigDecimal b2_negate = b2.negate();
+
+        b1_negate.precision();
+        b2_negate.precision();
+
+        failures += roundAway1(b1,        b2);
+        failures += roundAway1(b1,        b2_negate);
+        failures += roundAway1(b1_negate, b2);
+        failures += roundAway1(b1_negate, b2_negate);
+
+        return failures;
+    }
+
+    private static int roundAway1(BigDecimal b1, BigDecimal b2) {
+        int failures = 0;
+        failures += roundAway0(b1, b2);
+        failures += roundAway0(b2, b1);
+        return failures;
+    }
+
+    /**
+     * Compare b1.add(b2, mc) with b1.add(b2).round(mc) for a variety
+     * of MathContexts.
+     */
+    private static int roundAway0(BigDecimal b1, BigDecimal b2) {
+        int failures = 0;
+        BigDecimal exactSum = b1.add(b2);
+
+        for(int precision = 1 ; precision < exactSum.precision()+2; precision++) {
+            for(RoundingMode rm : nonExactRoundingModes) {
+                MathContext mc = new MathContext(precision, rm);
+                BigDecimal roundedExactSum = exactSum.round(mc);
+
+                try {
+                    BigDecimal sum = b1.add(b2, mc);
+
+                    if (!roundedExactSum.equals(sum) ) {
+                        failures++;
+                        System.out.println("Exact sum " + exactSum +
+                                           "\trounded by " + mc +
+                                           "\texpected: " + roundedExactSum + " got: ");
+                        printAddition(b1, b2, sum.toString());
+                    }
+//                  else {
+//                      System.out.print(mc + "\t");
+//                      printAddition(b1, b2, sum.toString());
+//                  }
+
+                } catch (ArithmeticException ae) {
+                    printAddition(b1, b2, "Exception!");
+                    failures++;
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    /**
+     * Verify calling the precision method should not change the
+     * computed result.
+     */
+    private static int precisionConsistencyTest() {
+        int failures = 0;
+        MathContext mc = new MathContext(1,RoundingMode.DOWN);
+        BigDecimal a = BigDecimal.valueOf(1999, -1); //value is equivalent to 19990
+
+        BigDecimal sum1 = a.add(BigDecimal.ONE, mc);
+        a.precision();
+        BigDecimal sum2 = a.add(BigDecimal.ONE, mc);
+
+        if (!sum1.equals(sum2)) {
+            failures ++;
+            System.out.println("Unequal sums after calling precision!");
+            System.out.print("Before:\t");
+            printAddition(a, BigDecimal.ONE, sum1.toString());
+
+            System.out.print("After:\t");
+            printAddition(a, BigDecimal.ONE, sum2.toString());
+        }
+
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += extremaTests();
+        failures += roundingGradationTests();
+        failures += precisionConsistencyTest();
+
+        if (failures > 0) {
+            throw new RuntimeException("Incurred " + failures +
+                                       " failures while testing rounding add.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/CompareToTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2006 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6473768
+ * @summary Tests of BigDecimal.compareTo
+ * @author Joseph D. Darcy
+ */
+import java.math.*;
+import static java.math.BigDecimal.*;
+
+public class CompareToTests {
+    private static int compareToTests() {
+        int failures = 0;
+
+        final BigDecimal MINUS_ONE = BigDecimal.ONE.negate();
+
+        // First operand, second operand, expected compareTo result
+        BigDecimal [][] testCases = {
+            // Basics
+            {valueOf(0),        valueOf(0),     ZERO},
+            {valueOf(0),        valueOf(1),     MINUS_ONE},
+            {valueOf(1),        valueOf(2),     MINUS_ONE},
+            {valueOf(2),        valueOf(1),     ONE},
+            {valueOf(10),       valueOf(10),    ZERO},
+
+            // Significands would compare differently than scaled value
+            {valueOf(2,1),      valueOf(2),     MINUS_ONE},
+            {valueOf(2,-1),     valueOf(2),     ONE},
+            {valueOf(1,1),      valueOf(2),     MINUS_ONE},
+            {valueOf(1,-1),     valueOf(2),     ONE},
+            {valueOf(5,-1),     valueOf(2),     ONE},
+
+            // Boundary and near boundary values
+            {valueOf(Long.MAX_VALUE),   valueOf(Long.MAX_VALUE),        ZERO},
+            {valueOf(Long.MAX_VALUE-1), valueOf(Long.MAX_VALUE),        MINUS_ONE},
+            {valueOf(Long.MIN_VALUE),   valueOf(Long.MAX_VALUE),        MINUS_ONE},
+            {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE),        MINUS_ONE},
+            {valueOf(Long.MIN_VALUE),   valueOf(Long.MIN_VALUE),        ZERO},
+            {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE),        ONE},
+        };
+
+        for (BigDecimal[] testCase : testCases) {
+            BigDecimal a = testCase[0];
+            BigDecimal a_negate = a.negate();
+            BigDecimal b = testCase[1];
+            BigDecimal b_negate = b.negate();
+            int expected = testCase[2].intValue();
+
+            failures += compareToTest(a,        b,         expected);
+            failures += compareToTest(a_negate, b,        -1);
+            failures += compareToTest(a,        b_negate,  1);
+            failures += compareToTest(a_negate, b_negate, -expected);
+        }
+
+
+        return failures;
+    }
+
+    private static int compareToTest(BigDecimal a, BigDecimal b, int expected) {
+        int result = a.compareTo(b);
+        int failed = (result==expected) ? 0 : 1;
+        if (result == 1) {
+            System.err.println("(" + a + ").compareTo(" + b + ") => " + result +
+                               "\n\tExpected " + expected);
+        }
+        return result;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += compareToTests();
+
+        if (failures > 0) {
+            throw new RuntimeException("Incurred " + failures +
+                                       " failures while testing exact compareTo.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/Constructor.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4259453
+ * @summary Test string constructor of BigDecimal
+ */
+import java.math.BigDecimal;
+
+public class Constructor {
+    public static void main(String[] args) throws Exception {
+        boolean nfe = false;
+        try {
+            BigDecimal bd = new BigDecimal("1.2e");
+        } catch (NumberFormatException e) {
+            nfe = true;
+        }
+        if (!nfe)
+            throw new Exception("Didn't throw NumberFormatException");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/DivideTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,340 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4851776 4907265 6177836
+ * @summary Some tests for the divide methods.
+ * @author Joseph D. Darcy
+ * @compile -source 1.5 DivideTests.java
+ * @run main DivideTests
+ */
+
+import java.math.*;
+import static java.math.BigDecimal.*;
+
+public class DivideTests {
+
+    // Preliminary exact divide method; could be used for comparison
+    // purposes.
+    BigDecimal anotherDivide(BigDecimal dividend, BigDecimal divisor) {
+        /*
+         * Handle zero cases first.
+         */
+        if (divisor.signum() == 0) {   // x/0
+            if (dividend.signum() == 0)    // 0/0
+                throw new ArithmeticException("Division undefined");  // NaN
+            throw new ArithmeticException("Division by zero");
+        }
+        if (dividend.signum() == 0)        // 0/y
+            return BigDecimal.ZERO;
+        else {
+            /*
+             * Determine if there is a result with a terminating
+             * decimal expansion.  Putting aside overflow and
+             * underflow considerations, the existance of an exact
+             * result only depends on the ratio of the intVal's of the
+             * dividend (i.e. this) and and divisor since the scales
+             * of the argument just affect where the decimal point
+             * lies.
+             *
+             * For the ratio of (a = this.intVal) and (b =
+             * divisor.intVal) to have a finite decimal expansion,
+             * once a/b is put in lowest terms, b must be equal to
+             * (2^i)*(5^j) for some integer i,j >= 0.  Therefore, we
+             * first compute to see if b_prime =(b/gcd(a,b)) is equal
+             * to (2^i)*(5^j).
+             */
+            BigInteger TWO  = BigInteger.valueOf(2);
+            BigInteger FIVE = BigInteger.valueOf(5);
+            BigInteger TEN  = BigInteger.valueOf(10);
+
+            BigInteger divisorIntvalue  = divisor.scaleByPowerOfTen(divisor.scale()).toBigInteger().abs();
+            BigInteger dividendIntvalue = dividend.scaleByPowerOfTen(dividend.scale()).toBigInteger().abs();
+
+            BigInteger b_prime = divisorIntvalue.divide(dividendIntvalue.gcd(divisorIntvalue));
+
+            boolean goodDivisor = false;
+            int i=0, j=0;
+
+            badDivisor: {
+                while(! b_prime.equals(BigInteger.ONE) ) {
+                    int b_primeModTen = b_prime.mod(TEN).intValue() ;
+
+                    switch(b_primeModTen) {
+                    case 0:
+                        // b_prime divisible by 10=2*5, increment i and j
+                        i++;
+                        j++;
+                        b_prime = b_prime.divide(TEN);
+                        break;
+
+                    case 5:
+                        // b_prime divisible by 5, increment j
+                        j++;
+                        b_prime = b_prime.divide(FIVE);
+                        break;
+
+                    case 2:
+                    case 4:
+                    case 6:
+                    case 8:
+                        // b_prime divisible by 2, increment i
+                        i++;
+                        b_prime = b_prime.divide(TWO);
+                        break;
+
+                    default: // hit something we shouldn't have
+                        b_prime = BigInteger.ONE; // terminate loop
+                        break badDivisor;
+                    }
+                }
+
+                goodDivisor = true;
+            }
+
+            if( ! goodDivisor ) {
+                throw new ArithmeticException("Non terminating decimal expansion");
+            }
+            else {
+                // What is a rule for determining how many digits are
+                // needed?  Once that is determined, cons up a new
+                // MathContext object and pass it on to the divide(bd,
+                // mc) method; precision == ?, roundingMode is unnecessary.
+
+                // Are we sure this is the right scale to use?  Should
+                // also determine a precision-based method.
+                MathContext mc = new MathContext(dividend.precision() +
+                                                 (int)Math.ceil(
+                                                      10.0*divisor.precision()/3.0),
+                                                 RoundingMode.UNNECESSARY);
+                // Should do some more work here to rescale, etc.
+                return dividend.divide(divisor, mc);
+            }
+        }
+    }
+
+    public static int powersOf2and5() {
+        int failures = 0;
+
+        for(int i = 0; i < 6; i++) {
+            int powerOf2 = (int)StrictMath.pow(2.0, i);
+
+            for(int j = 0; j < 6; j++) {
+                int powerOf5 = (int)StrictMath.pow(5.0, j);
+                int product;
+
+                BigDecimal bd;
+
+                try {
+                    bd = BigDecimal.ONE.divide(new BigDecimal(product=powerOf2*powerOf5));
+                } catch (ArithmeticException e) {
+                    failures++;
+                    System.err.println((new BigDecimal(powerOf2)).toString() + " / " +
+                                       (new BigDecimal(powerOf5)).toString() + " threw an exception.");
+                    e.printStackTrace();
+                }
+
+                try {
+                    bd = new BigDecimal(powerOf2).divide(new BigDecimal(powerOf5));
+                } catch (ArithmeticException e) {
+                    failures++;
+                    System.err.println((new BigDecimal(powerOf2)).toString() + " / " +
+                                       (new BigDecimal(powerOf5)).toString() + " threw an exception.");
+                    e.printStackTrace();
+                }
+
+                try {
+                    bd = new BigDecimal(powerOf5).divide(new BigDecimal(powerOf2));
+                } catch (ArithmeticException e) {
+                    failures++;
+                    System.err.println((new BigDecimal(powerOf5)).toString() + " / " +
+                                       (new BigDecimal(powerOf2)).toString() + " threw an exception.");
+
+                    e.printStackTrace();
+                }
+
+            }
+        }
+        return failures;
+    }
+
+    public static int nonTerminating() {
+        int failures = 0;
+        int[] primes = {1, 3, 7, 13, 17};
+
+        // For each pair of prime products, verify the ratio of
+        // non-equal products has a non-terminating expansion.
+
+        for(int i = 0; i < primes.length; i++) {
+            for(int j = i+1; j < primes.length; j++) {
+
+                for(int m = 0; m < primes.length; m++) {
+                    for(int n = m+1; n < primes.length; n++) {
+                        int dividend = primes[i] * primes[j];
+                        int divisor  = primes[m] * primes[n];
+
+                        if ( ((dividend/divisor) * divisor) != dividend ) {
+                            try {
+                                BigDecimal quotient = (new BigDecimal(dividend).
+                                                       divide(new BigDecimal(divisor)));
+                                failures++;
+                                System.err.println("Exact quotient " + quotient.toString() +
+                                                   " returned for non-terminating fraction " +
+                                                   dividend + " / " + divisor + ".");
+                            }
+                            catch (ArithmeticException e) {
+                                ; // Correct result
+                            }
+                        }
+
+                    }
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    public static int properScaleTests(){
+        int failures = 0;
+
+        BigDecimal[][] testCases = {
+            {new BigDecimal("1"),       new BigDecimal("5"),            new BigDecimal("2e-1")},
+            {new BigDecimal("1"),       new BigDecimal("50e-1"),        new BigDecimal("2e-1")},
+            {new BigDecimal("10e-1"),   new BigDecimal("5"),            new BigDecimal("2e-1")},
+            {new BigDecimal("1"),       new BigDecimal("500e-2"),       new BigDecimal("2e-1")},
+            {new BigDecimal("100e-2"),  new BigDecimal("5"),            new BigDecimal("20e-2")},
+            {new BigDecimal("1"),       new BigDecimal("32"),           new BigDecimal("3125e-5")},
+            {new BigDecimal("1"),       new BigDecimal("64"),           new BigDecimal("15625e-6")},
+            {new BigDecimal("1.0000000"),       new BigDecimal("64"),   new BigDecimal("156250e-7")},
+        };
+
+
+        for(BigDecimal[] tc : testCases) {
+            BigDecimal quotient;
+            if (! (quotient = tc[0].divide(tc[1])).equals(tc[2]) ) {
+                failures++;
+                System.err.println("Unexpected quotient from " + tc[0] + " / " + tc[1] +
+                                   "; expected " + tc[2] + " got " + quotient);
+            }
+        }
+
+        return failures;
+    }
+
+    public static int trailingZeroTests() {
+        int failures = 0;
+
+        MathContext mc = new MathContext(3, RoundingMode.FLOOR);
+        BigDecimal[][] testCases = {
+            {new BigDecimal("19"),      new BigDecimal("100"),          new BigDecimal("0.19")},
+            {new BigDecimal("21"),      new BigDecimal("110"),          new BigDecimal("0.190")},
+        };
+
+        for(BigDecimal[] tc : testCases) {
+            BigDecimal quotient;
+            if (! (quotient = tc[0].divide(tc[1], mc)).equals(tc[2]) ) {
+                failures++;
+                System.err.println("Unexpected quotient from " + tc[0] + " / " + tc[1] +
+                                   "; expected " + tc[2] + " got " + quotient);
+            }
+        }
+
+        return failures;
+    }
+
+    public static int scaledRoundedDivideTests() {
+        int failures = 0;
+        // Tests of the traditional scaled divide under different
+        // rounding modes.
+
+        // Encode rounding mode and scale for the divide in a
+        // BigDecimal with the significand equal to the rounding mode
+        // and the scale equal to the number's scale.
+
+        // {dividend, dividisor, rounding, quotient}
+        BigDecimal a = new BigDecimal("31415");
+        BigDecimal a_minus = a.negate();
+        BigDecimal b = new BigDecimal("10000");
+
+        BigDecimal c = new BigDecimal("31425");
+        BigDecimal c_minus = c.negate();
+
+        BigDecimal[][] testCases = {
+            {a,         b,      BigDecimal.valueOf(ROUND_UP, 3),        new BigDecimal("3.142")},
+            {a_minus,   b,      BigDecimal.valueOf(ROUND_UP, 3),        new BigDecimal("-3.142")},
+
+            {a,         b,      BigDecimal.valueOf(ROUND_DOWN, 3),      new BigDecimal("3.141")},
+            {a_minus,   b,      BigDecimal.valueOf(ROUND_DOWN, 3),      new BigDecimal("-3.141")},
+
+            {a,         b,      BigDecimal.valueOf(ROUND_CEILING, 3),   new BigDecimal("3.142")},
+            {a_minus,   b,      BigDecimal.valueOf(ROUND_CEILING, 3),   new BigDecimal("-3.141")},
+
+            {a,         b,      BigDecimal.valueOf(ROUND_FLOOR, 3),     new BigDecimal("3.141")},
+            {a_minus,   b,      BigDecimal.valueOf(ROUND_FLOOR, 3),     new BigDecimal("-3.142")},
+
+            {a,         b,      BigDecimal.valueOf(ROUND_HALF_UP, 3),   new BigDecimal("3.142")},
+            {a_minus,   b,      BigDecimal.valueOf(ROUND_HALF_UP, 3),   new BigDecimal("-3.142")},
+
+            {a,         b,      BigDecimal.valueOf(ROUND_DOWN, 3),      new BigDecimal("3.141")},
+            {a_minus,   b,      BigDecimal.valueOf(ROUND_DOWN, 3),      new BigDecimal("-3.141")},
+
+            {a,         b,      BigDecimal.valueOf(ROUND_HALF_EVEN, 3), new BigDecimal("3.142")},
+            {a_minus,   b,      BigDecimal.valueOf(ROUND_HALF_EVEN, 3), new BigDecimal("-3.142")},
+
+            {c,         b,      BigDecimal.valueOf(ROUND_HALF_EVEN, 3), new BigDecimal("3.142")},
+            {c_minus,   b,      BigDecimal.valueOf(ROUND_HALF_EVEN, 3), new BigDecimal("-3.142")},
+        };
+
+        for(BigDecimal tc[] : testCases) {
+            int scale = tc[2].scale();
+            int rm = tc[2].unscaledValue().intValue();
+
+            BigDecimal quotient = tc[0].divide(tc[1], scale, rm);
+            if (!quotient.equals(tc[3])) {
+                failures++;
+                System.err.println("Unexpected quotient from " + tc[0] + " / " + tc[1] +
+                                   " scale " + scale + " rounding mode " + RoundingMode.valueOf(rm) +
+                                   "; expected " + tc[3] + " got " + quotient);
+            }
+        }
+
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += powersOf2and5();
+        failures += nonTerminating();
+        failures += properScaleTests();
+        failures += trailingZeroTests();
+        failures += scaledRoundedDivideTests();
+
+        if (failures > 0) {
+            throw new RuntimeException("Incurred " + failures +
+                                       " failures while testing exact divide.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/FloatDoubleValueTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6274390
+ * @summary Verify {float, double}Value methods work with condensed representation
+ */
+import java.math.*;
+
+public class FloatDoubleValueTests {
+    private static final long two2the24 = 1L<<23;
+    private static final long two2the53 = 1L<<52;
+
+    // Largest long that fits exactly in a float
+    private static final long maxFltLong = (long)(Integer.MAX_VALUE & ~(0xff));
+
+    // Largest long that fits exactly in a double
+    private static final long maxDblLong = Long.MAX_VALUE & ~(0x7ffL);
+
+    static void testDoubleValue0(long i, BigDecimal bd) {
+        if (bd.doubleValue() != i ||
+            bd.longValue()   != i)
+            throw new RuntimeException("Unexpected equality failure for " +
+                                       i + "\t" + bd);
+    }
+
+    static void testFloatValue0(long i, BigDecimal bd) {
+        if (bd.floatValue() != i ||
+            bd.longValue()   != i)
+            throw new RuntimeException("Unexpected equality failure for " +
+                                       i + "\t" + bd);
+    }
+
+    static void checkFloat(BigDecimal bd, float f) {
+        float fbd = bd.floatValue();
+        if (f != fbd ) {
+            String message = String.format("Bad conversion:"+
+                                           "got %g (%a)\texpected %g (%a)",
+                                           f, f, fbd, fbd);
+            throw new RuntimeException(message);
+        }
+    }
+
+    static void checkDouble(BigDecimal bd, double d) {
+        double dbd = bd.doubleValue();
+        if (d != dbd ) {
+            String message = String.format("Bad conversion:"+
+                                           "got %g (%a)\texpected %g (%a)",
+                                           d, d, dbd, dbd);
+            throw new RuntimeException(message);
+        }
+    }
+
+    // Test integral values that will convert exactly to both float
+    // and double.
+    static void testFloatDoubleValue() {
+        long longValues[] = {
+            0,
+            1,
+            2,
+
+            two2the24-1,
+            two2the24,
+            two2the24+1,
+
+            maxFltLong-1,
+            maxFltLong,
+            maxFltLong+1,
+        };
+
+        for(long i : longValues) {
+            BigDecimal bd1 = new BigDecimal(i);
+            BigDecimal bd2 = new BigDecimal(-i);
+
+            testDoubleValue0( i, bd1);
+            testDoubleValue0(-i, bd2);
+
+            testFloatValue0( i, bd1);
+            testFloatValue0(-i, bd2);
+        }
+
+    }
+
+    static void testDoubleValue() {
+        long longValues[] = {
+            Integer.MAX_VALUE-1,
+            Integer.MAX_VALUE,
+            (long)Integer.MAX_VALUE+1,
+
+            two2the53-1,
+            two2the53,
+            two2the53+1,
+
+            maxDblLong,
+        };
+
+        // Test integral values that will convert exactly to double
+        // but not float.
+        for(long i : longValues) {
+            BigDecimal bd1 = new BigDecimal(i);
+            BigDecimal bd2 = new BigDecimal(-i);
+
+            testDoubleValue0( i, bd1);
+            testDoubleValue0(-i, bd2);
+
+            checkFloat(bd1, (float)i);
+            checkFloat(bd2, -(float)i);
+        }
+
+        // Now check values that should not convert the same in double
+        for(long i = maxDblLong; i < Long.MAX_VALUE; i++) {
+            BigDecimal bd1 = new BigDecimal(i);
+            BigDecimal bd2 = new BigDecimal(-i);
+            checkDouble(bd1, (double)i);
+            checkDouble(bd2, -(double)i);
+
+            checkFloat(bd1, (float)i);
+            checkFloat(bd2, -(float)i);
+        }
+
+        checkDouble(new BigDecimal(Long.MIN_VALUE), (double)Long.MIN_VALUE);
+        checkDouble(new BigDecimal(Long.MAX_VALUE), (double)Long.MAX_VALUE);
+    }
+
+    static void testFloatValue() {
+        // Now check values that should not convert the same in float
+        for(long i = maxFltLong; i <= Integer.MAX_VALUE; i++) {
+            BigDecimal bd1 = new BigDecimal(i);
+            BigDecimal bd2 = new BigDecimal(-i);
+            checkFloat(bd1, (float)i);
+            checkFloat(bd2, -(float)i);
+
+            testDoubleValue0( i, bd1);
+            testDoubleValue0(-i, bd2);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        testFloatDoubleValue();
+        testDoubleValue();
+        testFloatValue();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/IntegralDivisionTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+/*
+ * @test
+ * @bug 4904082 4917089 6337226
+ * @summary Tests that integral division and related methods return the proper result and scale.
+ * @author Joseph D. Darcy
+ * @compile -source 1.5 IntegralDivisionTests.java
+ * @run main IntegralDivisionTests
+ */
+import java.math.*;
+public class IntegralDivisionTests {
+
+    static int dividetoIntegralValueTests() {
+        int failures = 0;
+
+        // Exact integer quotient should have the same results from
+        // the exact divide and dividetoIntegralValue
+
+
+        // Rounded results
+        BigDecimal [][] moreTestCases = {
+            {new BigDecimal("11003"),   new BigDecimal("10"),   new BigDecimal("1100")},
+            {new BigDecimal("11003"),   new BigDecimal("1e1"),  new BigDecimal("1100.0")},
+            {new BigDecimal("1e9"),     new BigDecimal("1"),    new BigDecimal("1e9")},
+            {new BigDecimal("1e9"),     new BigDecimal("1.00"), new BigDecimal("1e9")},
+            {new BigDecimal("1e9"),     new BigDecimal("0.1"),  new BigDecimal("1e10")},
+            {new BigDecimal("10e8"),    new BigDecimal("0.1"),  new BigDecimal("10e9")},
+            {new BigDecimal("400e1"),   new BigDecimal("5"),    new BigDecimal("80e1")},
+            {new BigDecimal("400e1"),   new BigDecimal("4.999999999"),  new BigDecimal("8e2")},
+            {new BigDecimal("40e2"),    new BigDecimal("5"),    new BigDecimal("8e2")},
+        };
+
+        for(BigDecimal [] testCase: moreTestCases) {
+            BigDecimal quotient;
+            if (! (quotient=testCase[0].divideToIntegralValue(testCase[1])).equals(testCase[2]) ){
+                failures++;
+                // BigDecimal exact = testCase[0].divide(testCase[1]);
+                System.err.println();
+                System.err.println("dividend  = " + testCase[0] + " scale = " + testCase[0].scale());
+                System.err.println("divisor   = " + testCase[1] + " scale = " + testCase[1].scale());
+                System.err.println("quotient  = " + quotient    + " scale = " + quotient.scale());
+                System.err.println("expected  = " + testCase[2] + " scale = " + testCase[2].scale());
+                // System.err.println("exact     = " + exact       + " scale = " + exact.scale());
+            }
+        }
+
+        return failures;
+    }
+
+    static int dividetoIntegralValueRoundedTests() {
+        int failures = 0;
+
+        BigDecimal dividend = new BigDecimal("11003");
+        BigDecimal divisor = new BigDecimal("10");
+        BigDecimal [] quotients = {     // Expected results with precision =
+            new BigDecimal("1100"),     // 0
+            null,                       // 1
+            new BigDecimal("11e2"),     // 2
+            new BigDecimal("110e1"),    // 3
+            new BigDecimal("1100"),     // 4
+        };
+        failures += divideContextTestPrecs(dividend, divisor, quotients);
+
+        dividend = new BigDecimal("11003");
+        divisor = new BigDecimal("1e1");
+        BigDecimal [] quotients2 = {    // Expected results with precision =
+            new BigDecimal("1100.0"),   // 0
+            null,                       // 1
+            new BigDecimal("11e2"),     // 2
+            new BigDecimal("110e1"),    // 3
+            new BigDecimal("1100"),     // 4
+            new BigDecimal("1100.0"),   // 5
+        };
+        failures += divideContextTestPrecs(dividend, divisor, quotients2);
+
+        dividend = new BigDecimal("1230000");
+        divisor = new BigDecimal("100");
+        BigDecimal [] quotients3 = {    // Expected results with precision =
+            new BigDecimal("12300"),    // 0
+            null,                       // 1
+            null,                       // 2
+            new BigDecimal("123e2"),    // 3
+            new BigDecimal("1230e1"),   // 4
+            new BigDecimal("12300"),    // 5
+        };
+        failures += divideContextTestPrecs(dividend, divisor, quotients3);
+
+        dividend = new BigDecimal("33");
+        divisor  = new BigDecimal("3");
+        BigDecimal [] quotients4 = {    // Expected results with precision =
+            new BigDecimal("11"),       // 0
+            null,                       // 1
+            new BigDecimal("11"),       // 2
+            new BigDecimal("11"),       // 3
+        };
+        failures += divideContextTestPrecs(dividend, divisor, quotients4);
+
+        dividend = new BigDecimal("34");
+        divisor  = new BigDecimal("3");
+        BigDecimal [] quotients5 = {    // Expected results with precision =
+            new BigDecimal("11"),       // 0
+            null,                       // 1
+            new BigDecimal("11"),       // 2
+            new BigDecimal("11"),       // 3
+        };
+        failures += divideContextTestPrecs(dividend, divisor, quotients5);
+
+        return failures;
+    }
+
+    static int divideContextTestPrecs(BigDecimal dividend,
+                                      BigDecimal divisor,
+                                      BigDecimal[] quotients)
+    {
+        int failures = 0;
+        for(int i = 0; i < quotients.length; i++) {
+            BigDecimal result = null;
+            BigDecimal quotient = quotients[i];
+
+            try {
+                result = dividend.divideToIntegralValue(divisor,
+                                                        new MathContext(i, RoundingMode.DOWN));
+            } catch (ArithmeticException e) {
+                if (quotient != null) {
+                    failures++;
+                    System.err.println();
+                    System.err.println("Unexpected exception:");
+                    System.err.println("dividend  = " + dividend     + " scale = " + dividend.scale());
+                    System.err.println("divisor   = " + divisor      + " scale = " + divisor.scale());
+                    System.err.println("expected  = " + quotient     + " scale = " + quotient.scale());
+                }
+            }
+
+            if (quotient != null) {
+                if (! result.equals(quotient)) {
+                    failures++;
+                    System.err.println();
+                    System.err.println("Unexpected result:");
+                    System.err.println("dividend  = " + dividend     + " scale = " + dividend.scale());
+                    System.err.println("divisor   = " + divisor      + " scale = " + divisor.scale());
+                    System.err.println("quotient  = " + result       + " scale = " + result.scale());
+                    System.err.println("expected  = " + quotient     + " scale = " + quotient.scale());
+                    System.err.println("precision = " + i);
+                }
+            } else {
+                if (result != null) {
+                    failures++;
+                    System.err.println();
+                    System.err.println("Unexpected unexceptional result:");
+                    System.err.println("dividend  = " + dividend     + " scale = " + dividend.scale());
+                    System.err.println("divisor   = " + divisor      + " scale = " + divisor.scale());
+                    System.err.println("quotient  = " + result       + " scale = " + result.scale());
+                    System.err.println("precision = " + i);
+                }
+            }
+
+        }
+        return failures;
+    }
+
+
+    static int divideContextTests(BigDecimal dividend,
+                                  BigDecimal divisor,
+                                  BigDecimal expected,
+                                  MathContext mc) {
+        int failures = 0;
+
+        failures += divideContextTest(dividend,              divisor,          expected,                mc);
+        failures += divideContextTest(dividend.negate(),     divisor.negate(), expected,                mc);
+
+        if (expected != null) {
+            failures += divideContextTest(dividend.negate(), divisor,          expected.negate(),       mc);
+            failures += divideContextTest(dividend,          divisor.negate(), expected.negate(),       mc);
+        }
+
+        return failures;
+    }
+
+
+    static int divideContextTest(BigDecimal dividend,
+                                 BigDecimal divisor,
+                                 BigDecimal expected,
+                                 MathContext mc)
+    {
+        int failures = 0;
+
+        BigDecimal result = null;
+
+        try {
+            result = dividend.divideToIntegralValue(divisor, mc);
+        } catch (ArithmeticException e) {
+            if (expected != null) {
+                failures++;
+                System.err.println();
+                System.err.println("Unexpected exception:");
+                System.err.println("dividend  = " + dividend     + " scale = " + dividend.scale());
+                System.err.println("divisor   = " + divisor      + " scale = " + divisor.scale());
+                System.err.println("expected  = " + expected     + " scale = " + expected.scale());
+                System.err.println("MathContext  = " + mc);
+            }
+        }
+
+        if (expected != null) {
+            if (! result.equals(expected)) {
+                failures++;
+                System.err.println();
+                System.err.println("Unexpected result:");
+                System.err.println("dividend  = " + dividend     + " scale = " + dividend.scale());
+                System.err.println("divisor   = " + divisor      + " scale = " + divisor.scale());
+                System.err.println("expected  = " + expected     + " scale = " + expected.scale());
+                System.err.println("result    = " + result       + " scale = " + result.scale());
+                System.err.println("MathContext  = " + mc);
+            }
+        } else {
+            if (result != null) {
+                failures++;
+                System.err.println();
+                System.err.println("Unexpected unexceptional result:");
+                System.err.println("dividend  = " + dividend     + " scale = " + dividend.scale());
+                System.err.println("divisor   = " + divisor      + " scale = " + divisor.scale());
+                System.err.println("quotient  = " + result       + " scale = " + result.scale());
+                System.err.println("MathConext = " + mc);
+                }
+        }
+
+        return failures;
+    }
+
+    static int dividetoIntegralValueScalingTests() {
+        int failures = 0;
+
+        BigDecimal dividend = new BigDecimal("123456789000");
+        BigDecimal divisor = BigDecimal.ONE;
+        BigDecimal expected = new BigDecimal("123456789e3");
+        MathContext mc = new MathContext(9,RoundingMode.DOWN);
+        failures += divideContextTests(dividend, divisor, expected, mc);
+
+
+        // 100/3 = 33 remainder 1
+        int [] precisions = {0, 2, 3, 4};
+        dividend = new BigDecimal(100);
+        divisor  = new BigDecimal(3);
+        expected = new BigDecimal(33);
+
+        for(RoundingMode rm: RoundingMode.values())
+            for(int precision: precisions) {
+                failures += divideContextTests(dividend, divisor, expected,
+                                               new MathContext(precision, rm));
+            }
+
+        // 123000/10 = 12300 remainder 0
+        dividend = new BigDecimal(123000);
+        divisor  = new BigDecimal(10);
+        int[] precisions1 = {0, 1, 2, 3, 4, 5};
+        BigDecimal[] expected1 = {
+            new BigDecimal("12300"),
+            null,
+            null,
+            new BigDecimal("123e2"),
+            new BigDecimal("1230e1"),
+            new BigDecimal("12300"),
+        };
+
+        for(RoundingMode rm: RoundingMode.values())
+            for(int i = 0; i < precisions1.length; i++) {
+                failures += divideContextTests(dividend, divisor,
+                                               expected1[i],
+                                               new MathContext(precisions1[i], rm));
+            }
+
+        // 123e3/10 = 123e2 remainder 0
+        dividend = new BigDecimal("123e3");
+        divisor  = new BigDecimal(10);
+        int[] precisions2 = {0, 1, 2, 3, 4, 5};
+        BigDecimal[] expected2 = {
+            new BigDecimal("123e2"),
+            null,
+            null,
+            new BigDecimal("123e2"),
+            new BigDecimal("123e2"),
+            new BigDecimal("123e2"),
+        };
+
+        for(RoundingMode rm: RoundingMode.values())
+            for(int i = 0; i < precisions2.length; i++) {
+                failures += divideContextTests(dividend, divisor,
+                                               expected2[i],
+                                               new MathContext(precisions2[i], rm));
+            }
+
+
+        // 123000/1e1 = 12300.0 remainder 0
+        dividend = new BigDecimal("123000");
+        divisor  = new BigDecimal("1e1");
+        int[] precisions3 = {0, 1, 2, 3, 4, 5, 6};
+        BigDecimal[] expected3 = {
+            new BigDecimal("12300.0"),
+            null,
+            null,
+            new BigDecimal("123e2"),
+            new BigDecimal("1230e1"),
+            new BigDecimal("12300"),
+            new BigDecimal("12300.0"),
+        };
+
+        for(RoundingMode rm: RoundingMode.values())
+            for(int i = 0; i < precisions3.length; i++) {
+                failures += divideContextTests(dividend, divisor,
+                                               expected3[i],
+                                               new MathContext(precisions3[i], rm));
+            }
+
+
+
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += dividetoIntegralValueTests();
+        failures += dividetoIntegralValueRoundedTests();
+        failures += dividetoIntegralValueScalingTests();
+
+        if (failures > 0) {
+            System.err.println("Encountered " + failures +
+                               " failures while testing integral division.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/NegateTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6325535
+ * @summary Test for the rounding behavior of negate(MathContext)
+ * @author Joseph D. Darcy
+ */
+
+import java.math.*;
+
+public class NegateTests {
+
+    static BigDecimal negateThenRound(BigDecimal bd, MathContext mc) {
+        return bd.negate().plus(mc);
+    }
+
+
+    static BigDecimal absThenRound(BigDecimal bd, MathContext mc) {
+        return bd.abs().plus(mc);
+    }
+
+
+    static int negateTest(BigDecimal[][] testCases,  MathContext mc) {
+        int failures = 0;
+
+        for (BigDecimal [] testCase : testCases) {
+
+            BigDecimal bd = testCase[0];
+            BigDecimal neg1 = bd.negate(mc);
+            BigDecimal neg2 = negateThenRound(bd, mc);
+            BigDecimal expected = testCase[1];
+
+            if (! neg1.equals(expected) ) {
+                failures++;
+                System.err.println("(" + bd + ").negate(" + mc + ") => " +
+                                   neg1 + " != expected " + expected);
+            }
+
+            if (! neg1.equals(neg2) ) {
+                failures++;
+                System.err.println("(" + bd + ").negate(" + mc + ")  => " +
+                                   neg1 + " != ntr " + neg2);
+            }
+
+            // Test abs consistency
+            BigDecimal abs = bd.abs(mc);
+            BigDecimal expectedAbs = absThenRound(bd,mc);
+            if (! abs.equals(expectedAbs) ) {
+                failures++;
+                System.err.println("(" + bd + ").abs(" + mc + ")  => " +
+                                   abs + " != atr " +  expectedAbs);
+            }
+
+        }
+
+        return failures;
+    }
+
+    static int negateTests() {
+        int failures = 0;
+        BigDecimal [][] testCasesCeiling = {
+            {new BigDecimal("1.3"),     new BigDecimal("-1")},
+            {new BigDecimal("-1.3"),    new BigDecimal("2")},
+        };
+
+        failures += negateTest(testCasesCeiling,
+                               new MathContext(1, RoundingMode.CEILING));
+
+        BigDecimal [][] testCasesFloor = {
+            {new BigDecimal("1.3"),     new BigDecimal("-2")},
+            {new BigDecimal("-1.3"),    new BigDecimal("1")},
+        };
+
+        failures += negateTest(testCasesFloor,
+                               new MathContext(1, RoundingMode.FLOOR));
+
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += negateTests();
+
+        if (failures > 0 )
+            throw new RuntimeException("Incurred " + failures + " failures" +
+                                       " testing the negate and/or abs.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/PowTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4916097
+ * @summary Some exponent over/undeflow tests for the pow method
+ * @author Joseph D. Darcy
+ * @compile -source 1.5 PowTests.java
+ * @run main PowTests
+ */
+
+import java.math.*;
+
+public class PowTests {
+    static int zeroAndOneTests() {
+        int failures = 0;
+
+        BigDecimal[][] testCases = {
+            {BigDecimal.valueOf(0, Integer.MAX_VALUE),  new BigDecimal(0),              BigDecimal.valueOf(1, 0)},
+            {BigDecimal.valueOf(0, Integer.MAX_VALUE),  new BigDecimal(1),              BigDecimal.valueOf(0, Integer.MAX_VALUE)},
+            {BigDecimal.valueOf(0, Integer.MAX_VALUE),  new BigDecimal(2),              BigDecimal.valueOf(0, Integer.MAX_VALUE)},
+            {BigDecimal.valueOf(0, Integer.MAX_VALUE),  new BigDecimal(999999999),      BigDecimal.valueOf(0, Integer.MAX_VALUE)},
+
+            {BigDecimal.valueOf(0, Integer.MIN_VALUE),  new BigDecimal(0),              BigDecimal.valueOf(1, 0)},
+            {BigDecimal.valueOf(0, Integer.MIN_VALUE),  new BigDecimal(1),              BigDecimal.valueOf(0, Integer.MIN_VALUE)},
+            {BigDecimal.valueOf(0, Integer.MIN_VALUE),  new BigDecimal(2),              BigDecimal.valueOf(0, Integer.MIN_VALUE)},
+            {BigDecimal.valueOf(0, Integer.MIN_VALUE),  new BigDecimal(999999999),      BigDecimal.valueOf(0, Integer.MIN_VALUE)},
+
+            {BigDecimal.valueOf(1, Integer.MAX_VALUE),  new BigDecimal(0),              BigDecimal.valueOf(1, 0)},
+            {BigDecimal.valueOf(1, Integer.MAX_VALUE),  new BigDecimal(1),              BigDecimal.valueOf(1, Integer.MAX_VALUE)},
+            {BigDecimal.valueOf(1, Integer.MAX_VALUE),  new BigDecimal(2),              null}, // overflow
+            {BigDecimal.valueOf(1, Integer.MAX_VALUE),  new BigDecimal(999999999),      null}, // overflow
+
+            {BigDecimal.valueOf(1, Integer.MIN_VALUE),  new BigDecimal(0),              BigDecimal.valueOf(1, 0)},
+            {BigDecimal.valueOf(1, Integer.MIN_VALUE),  new BigDecimal(1),              BigDecimal.valueOf(1, Integer.MIN_VALUE)},
+            {BigDecimal.valueOf(1, Integer.MIN_VALUE),  new BigDecimal(2),              null}, // underflow
+            {BigDecimal.valueOf(1, Integer.MIN_VALUE),  new BigDecimal(999999999),      null}, // underflow
+        };
+
+        for(BigDecimal[] testCase: testCases) {
+            int exponent = testCase[1].intValueExact();
+            BigDecimal result;
+
+            try{
+                result = testCase[0].pow(exponent);
+                if (!result.equals(testCase[2]) ) {
+                    failures++;
+                    System.err.println("Unexpected result while raising " +
+                                       testCase[0] +
+                                       " to the " + exponent + " power; expected " +
+                                       testCase[2] + ", got " + result + ".");
+                }
+            } catch (ArithmeticException e) {
+                if (testCase[2] != null) {
+                    failures++;
+                    System.err.println("Unexpected exception while raising " + testCase[0] +
+                                       " to the " + exponent + " power.");
+
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += zeroAndOneTests();
+
+        if (failures > 0) {
+            throw new RuntimeException("Incurred " + failures +
+                                       " failures while testing pow methods.");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/RoundingTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6334849
+ * @summary Tests of dropping digits near the scale threshold
+ * @author Joseph D. Darcy
+ */
+import java.math.*;
+public class RoundingTests {
+    private static int roundingTests() {
+        int failures = 0;
+        BigDecimal bd1 = BigDecimal.valueOf(11, Integer.MIN_VALUE);
+        BigDecimal bd2 = null;
+        MathContext mc = new MathContext(1);
+        try {
+                bd2 = bd1.round(mc); // should overflow here
+                failures++;
+                System.err.printf("Did not get expected overflow rounding %s to %d digits, got %s%n",
+                                   bd1, mc.getPrecision(), bd2);
+        } catch(ArithmeticException e) {
+            ; // expected
+        }
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += roundingTests();
+
+        if (failures > 0) {
+            System.err.println("Encountered " + failures +
+                               " failures while testing rounding.");
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/ScaleByPowerOfTenTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4899722
+ * @summary Basic tests of scaleByPowerOfTen
+ * @author Joseph D. Darcy
+ */
+
+import java.math.*;
+
+public class ScaleByPowerOfTenTests {
+
+    public static void main(String argv[]) {
+        for (int i = -10; i < 10; i++) {
+            BigDecimal bd = BigDecimal.ONE.scaleByPowerOfTen(i);
+            BigDecimal expected;
+
+            if (!bd.equals(expected = new BigDecimal(BigInteger.ONE, -i))) {
+                throw new RuntimeException("Unexpected result " +
+                                           bd.toString() +
+                                           "; expected " +
+                                           expected.toString());
+            }
+
+            bd = BigDecimal.ONE.negate().scaleByPowerOfTen(i);
+            if (!bd.equals(expected = new BigDecimal(BigInteger.ONE.negate(), -i))) {
+                throw new RuntimeException("Unexpected result " +
+                                           bd.toString() +
+                                           "; expected " +
+                                           expected.toString());
+            }
+
+
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/SerializationTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6177836
+ * @summary Verify BigDecimal objects with collapsed values are serialized properly.
+ * @author Joseph D. Darcy
+ */
+
+import java.math.*;
+import java.io.*;
+
+public class SerializationTests {
+
+    static void checkSerialForm(BigDecimal bd) throws Exception  {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(bos);
+        oos.writeObject(bd);
+        oos.flush();
+        oos.close();
+        ObjectInputStream ois = new
+            ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
+        BigDecimal tmp = (BigDecimal)ois.readObject();
+
+        if (!bd.equals(tmp) ||
+            bd.hashCode() != tmp.hashCode()) {
+            System.err.print("  original : " + bd);
+            System.err.println(" (hash: 0x" + Integer.toHexString(bd.hashCode()) + ")");
+            System.err.print("serialized : " + tmp);
+            System.err.println(" (hash: 0x" + Integer.toHexString(tmp.hashCode()) + ")");
+            throw new RuntimeException("Bad serial roundtrip");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        BigDecimal values[] = {
+            BigDecimal.ZERO,
+            BigDecimal.ONE,
+            BigDecimal.TEN,
+            new BigDecimal(0),
+            new BigDecimal(1),
+            new BigDecimal(10),
+            new BigDecimal(Integer.MAX_VALUE),
+            new BigDecimal(Long.MAX_VALUE-1),
+            new BigDecimal(BigInteger.valueOf(1), 1),
+            new BigDecimal(BigInteger.valueOf(100), 50),
+        };
+
+        for(BigDecimal value : values) {
+            checkSerialForm(value);
+            checkSerialForm(value.negate());
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/StringConstructor.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,163 @@
+/*
+ * Copyright 1999-2005 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4103117 4331084 4488017 4490929 6255285 6268365
+ * @summary Tests the BigDecimal string constructor.
+ */
+
+import java.math.*;
+import java.util.Random;
+
+public class StringConstructor {
+
+    private static int seed = new Random().nextInt();
+    private static Random rnd = new Random(seed);
+
+    public static void main(String[] args) throws Exception {
+        constructWithError("");
+        constructWithError("+");
+        constructWithError("-");
+        constructWithError("+e");
+        constructWithError("-e");
+        constructWithError("e+");
+        constructWithError("1.-0");
+        constructWithError(".-123");
+        constructWithError("-");
+        constructWithError("--1.1");
+        constructWithError("-+1.1");
+        constructWithError("+-1.1");
+        constructWithError("1-.1");
+        constructWithError("1+.1");
+        constructWithError("1.111+1");
+        constructWithError("1.111-1");
+        constructWithError("11.e+");
+        constructWithError("11.e-");
+        constructWithError("11.e+-");
+        constructWithError("11.e-+");
+        constructWithError("11.e-+1");
+        constructWithError("11.e+-1");
+
+        // Range checks
+        constructWithError("1e"+Integer.MIN_VALUE);
+        constructWithError("10e"+Integer.MIN_VALUE);
+        constructWithError("0.01e"+Integer.MIN_VALUE);
+        constructWithError("1e"+((long)Integer.MIN_VALUE-1));
+        constructWithError("1e"+((long)Integer.MAX_VALUE + 1));
+
+        leadingExponentZeroTest();
+        nonAsciiZeroTest();
+
+        // Roundtrip tests
+        for (int i=0; i<100; i++) {
+            int size = rnd.nextInt(100) + 1;
+            BigInteger bi = new BigInteger(size, rnd);
+            if (rnd.nextBoolean())
+                bi = bi.negate();
+            int decimalLength = bi.toString().length();
+            int scale = rnd.nextInt(decimalLength);
+            BigDecimal bd = new BigDecimal(bi, scale);
+            String bdString = bd.toString();
+            // System.err.println("bi" + bi.toString() + "\tscale " + scale);
+            // System.err.println("bd string: " + bdString);
+            BigDecimal bdDoppel = new BigDecimal(bdString);
+            if (!bd.equals(bdDoppel)) {
+                System.err.println("Random number seed = " + seed);
+                System.err.println("bd string: scale: " + bd.scale() +
+                                   "\t" + bdString);
+                System.err.println("bd doppel: scale: " + bdDoppel.scale() +
+                                   "\t" + bdDoppel.toString());
+                throw new RuntimeException("String constructor failure.");
+            }
+        }
+    }
+
+
+    /*
+     * Verify precision is set properly if the significand has
+     * non-ASCII leading zeros.
+     */
+    private static void nonAsciiZeroTest() {
+        String values[] = {
+            "00004e5",
+            "\u0660\u0660\u0660\u06604e5",
+        };
+
+        BigDecimal expected = new BigDecimal("4e5");
+
+        for(String s : values) {
+            BigDecimal tmp = new BigDecimal(s);
+            // System.err.println("Testing " + s);
+            if (! expected.equals(tmp) || tmp.precision() != 1) {
+                System.err.println("Bad conversion of " + s + "got " +
+                                   tmp + "precision = " + tmp.precision());
+                throw new RuntimeException("String constructor failure.");
+            }
+        }
+
+    }
+
+    private static void leadingExponentZeroTest() {
+        BigDecimal twelve = new BigDecimal("12");
+        BigDecimal onePointTwo = new BigDecimal("1.2");
+
+        String start = "1.2e0";
+        String end = "1";
+        String middle = "";
+
+        // Test with more excess zeros than the largest number of
+        // decimal digits needed to represent a long
+        int limit  = ((int)Math.log10(Long.MAX_VALUE)) + 6;
+        for(int i = 0; i < limit; i++, middle += "0") {
+            String t1 = start + middle;
+            String t2 = t1 + end;
+
+            // System.out.println(i + "\t" + t1 + "\t" + t2);
+            testString(t1, onePointTwo);
+            testString(t2, twelve);
+        }
+    }
+
+    private static void testString(String s, BigDecimal expected) {
+        testString0(s, expected);
+        testString0(switchZero(s), expected);
+    }
+
+    private static void testString0(String s, BigDecimal expected) {
+        if (!expected.equals(new BigDecimal(s)))
+            throw new RuntimeException(s + " is not equal to " + expected);
+    }
+
+    private static String switchZero(String s) {
+        return s.replace('0', '\u0660'); // Arabic-Indic zero
+    }
+
+    private static void constructWithError(String badString) {
+        try {
+            BigDecimal d = new BigDecimal(badString);
+            throw new RuntimeException(badString + " accepted");
+        } catch(NumberFormatException e) {
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/StrippingZerosTest.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4108852
+ * @summary A few tests of stripTrailingZeros
+ * @author Joseph D. Darcy
+ */
+
+import java.math.*;
+
+public class StrippingZerosTest {
+    public static void main(String argv[]) {
+        BigDecimal [][] testCases = {
+            {new BigDecimal("1.00000"),         new BigDecimal("1")},
+            {new BigDecimal("1.000"),           new BigDecimal("1")},
+            {new BigDecimal("1"),               new BigDecimal("1")},
+            {new BigDecimal("0.1234"),          new BigDecimal("0.1234")},
+            {new BigDecimal("0.12340"),         new BigDecimal("0.1234")},
+            {new BigDecimal("0.12340000000"),   new BigDecimal("0.1234")},
+            {new BigDecimal("1234.5678"),       new BigDecimal("1234.5678")},
+            {new BigDecimal("1234.56780"),      new BigDecimal("1234.5678")},
+            {new BigDecimal("1234.567800000"),  new BigDecimal("1234.5678")},
+            {new BigDecimal("0"),               new BigDecimal("0")},
+            {new BigDecimal("0e100"),           new BigDecimal("0e100")},
+            {new BigDecimal("0e-100"),          new BigDecimal("0e-100")},
+            {new BigDecimal("10"),              new BigDecimal("1e1")},
+            {new BigDecimal("20"),              new BigDecimal("2e1")},
+            {new BigDecimal("100"),             new BigDecimal("1e2")},
+            {new BigDecimal("1000000000"),      new BigDecimal("1e9")},
+            {new BigDecimal("100000000e1"),     new BigDecimal("1e9")},
+            {new BigDecimal("10000000e2"),      new BigDecimal("1e9")},
+            {new BigDecimal("1000000e3"),       new BigDecimal("1e9")},
+            {new BigDecimal("100000e4"),        new BigDecimal("1e9")},
+        };
+
+        for(int i = 0; i < testCases.length; i++) {
+
+            if (!(testCases[i][0]).stripTrailingZeros().equals(testCases[i][1])) {
+                throw new RuntimeException("For input " + testCases[i][0].toString() +
+                                           " did not received expected result " +
+                                           testCases[i][1].toString() + ",  got " +
+                                           testCases[i][0].stripTrailingZeros());
+            }
+
+            testCases[i][0] = testCases[i][0].negate();
+            testCases[i][1] = testCases[i][1].negate();
+
+            if (!(testCases[i][0]).stripTrailingZeros().equals(testCases[i][1])) {
+                throw new RuntimeException("For input " + testCases[i][0].toString() +
+                                           " did not received expected result " +
+                                           testCases[i][1].toString() + ",  got " +
+                                           testCases[i][0].stripTrailingZeros());
+            }
+
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/ToPlainStringTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2004 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4984872
+ * @summary Basic tests of toPlainString method
+ * @author Joseph D. Darcy
+ * @compile -source 1.5 ToPlainStringTests.java
+ * @run main ToPlainStringTests
+ */
+
+import java.math.*;
+
+public class ToPlainStringTests {
+    public static void main(String argv[]) {
+        String [][] testCases = {
+            {"0",                       "0"},
+            {"1",                       "1"},
+            {"10",                      "10"},
+            {"2e1",                     "20"},
+            {"3e2",                     "300"},
+            {"4e3",                     "4000"},
+            {"5e4",                     "50000"},
+            {"6e5",                     "600000"},
+            {"7e6",                     "7000000"},
+            {"8e7",                     "80000000"},
+            {"9e8",                     "900000000"},
+            {"1e9",                     "1000000000"},
+
+            {".0",                      "0.0"},
+            {".1",                      "0.1"},
+            {".10",                     "0.10"},
+            {"1e-1",                    "0.1"},
+            {"1e-1",                    "0.1"},
+            {"2e-2",                    "0.02"},
+            {"3e-3",                    "0.003"},
+            {"4e-4",                    "0.0004"},
+            {"5e-5",                    "0.00005"},
+            {"6e-6",                    "0.000006"},
+            {"7e-7",                    "0.0000007"},
+            {"8e-8",                    "0.00000008"},
+            {"9e-9",                    "0.000000009"},
+            {"9000e-12",                "0.000000009000"},
+        };
+
+        int errors = 0;
+        for(String[] testCase: testCases) {
+            BigDecimal bd = new BigDecimal(testCase[0]);
+            String s;
+
+            if (!(s=bd.toPlainString()).equals(testCase[1])) {
+                errors++;
+                System.err.println("Unexpected plain result ``" +
+                                   s + "'' from BigDecimal " +
+                                   bd);
+            }
+
+            if (!(s=("-"+bd.toPlainString())).equals("-"+testCase[1])) {
+                errors++;
+                System.err.println("Unexpected plain result ``" +
+                                   s + "'' from BigDecimal " +
+                                   bd);
+            }
+        }
+
+        if(errors > 0)
+            throw new RuntimeException(errors + " errors during run.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigDecimal/ZeroScalingTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,466 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4902952 4905407 4916149
+ * @summary Tests that the scale of zero is propagated properly and has the proper effect.
+ * @author Joseph D. Darcy
+ * @compile -source 1.5 ZeroScalingTests.java
+ * @run main ZeroScalingTests
+ */
+
+import java.math.*;
+import java.util.*;
+
+public class ZeroScalingTests {
+
+    static MathContext longEnough = new MathContext(50, RoundingMode.UNNECESSARY);
+
+    static BigDecimal[]  zeros = new BigDecimal[23];
+    static {
+        for(int i = 0; i < 21; i++) {
+            zeros[i] = new BigDecimal(BigInteger.ZERO, i-10);
+        }
+        zeros[21] = new BigDecimal(BigInteger.ZERO, Integer.MIN_VALUE);
+        zeros[22] = new BigDecimal(BigInteger.ZERO, Integer.MAX_VALUE);
+    }
+
+    static BigDecimal element = BigDecimal.valueOf(100, -2);
+
+    static MathContext contexts[] = {
+        new MathContext(0, RoundingMode.UNNECESSARY),
+        new MathContext(100, RoundingMode.UNNECESSARY),
+        new MathContext(5, RoundingMode.UNNECESSARY),
+        new MathContext(4, RoundingMode.UNNECESSARY),
+        new MathContext(3, RoundingMode.UNNECESSARY),
+        new MathContext(2, RoundingMode.UNNECESSARY),
+        new MathContext(1, RoundingMode.UNNECESSARY),
+    };
+
+
+    static int addTests() {
+        int failures = 0;
+
+        for(BigDecimal zero1: zeros) {
+            for(BigDecimal zero2: zeros) {
+                BigDecimal expected = new BigDecimal(BigInteger.ZERO,
+                                                     Math.max(zero1.scale(), zero2.scale()));
+                BigDecimal result;
+
+                if(! (result=zero1.add(zero2)).equals(expected) ) {
+                    failures++;
+                    System.err.println("For classic exact add, expected scale of " +
+                                       expected.scale() + "; got " +
+                                       result.scale() + ".");
+                }
+
+                if(! (result=zero1.add(zero2, MathContext.UNLIMITED)).equals(expected) ) {
+                    failures++;
+                    System.err.println("For UNLIMITED math context add," +
+                                       " expected scale of " +
+                                       expected.scale() + "; got " +
+                                       result.scale() + ".");
+                }
+
+                if(! (result=zero1.add(zero2, longEnough)).equals(expected) ) {
+                    failures++;
+                    System.err.println("For longEnough math context add," +
+                                       " expected scale of " +
+                                       expected.scale() + "; got " +
+                                       result.scale() + ".");
+                }
+
+            }
+        }
+
+        // Test effect of adding zero to a nonzero value.
+        for (MathContext mc: contexts) {
+            for (BigDecimal zero: zeros) {
+                if (Math.abs((long)zero.scale()) < 100 ) {
+
+                    int preferredScale = Math.max(zero.scale(), element.scale());
+                    if (mc.getPrecision() != 0) {
+                        if (preferredScale < -4 )
+                            preferredScale = -4;
+                        else if (preferredScale > -(5 - mc.getPrecision())) {
+                            preferredScale = -(5 - mc.getPrecision());
+                        }
+                    }
+
+
+                    /*
+                      System.err.println("\n    " + element + " +\t" + zero + " =\t" + result);
+
+                      System.err.println("scales" + element.scale() + " \t" + zero.scale() +
+                      "  \t " + result.scale() + "\t precison = " + mc.getPrecision());
+                      System.err.println("expected scale = " + preferredScale);
+                    */
+
+                    BigDecimal result = element.add(zero, mc);
+                    if (result.scale() != preferredScale ||
+                            result.compareTo(element) != 0) {
+                        failures++;
+                        System.err.println("Expected scale  " + preferredScale +
+                                           " result scale was " + result.scale() +
+                                           " ; value was " + result);
+                    }
+
+                    result = zero.add(element, mc);
+                    if (result.scale() != preferredScale ||
+                            result.compareTo(element) != 0) {
+                        failures++;
+                        System.err.println("Expected scale  " + preferredScale +
+                                           " result scale was " + result.scale() +
+                                           " ; value was " + result);
+                    }
+
+                    result = element.negate().add(zero, mc);
+                    if (result.scale() != preferredScale ||
+                            result.compareTo(element.negate()) != 0) {
+                        failures++;
+                        System.err.println("Expected scale  " + preferredScale +
+                                           " result scale was " + result.scale() +
+                                           " ; value was " + result);
+                    }
+
+                    result = zero.add(element.negate(), mc);
+                    if (result.scale() != preferredScale ||
+                            result.compareTo(element.negate()) != 0) {
+                        failures++;
+                        System.err.println("Expected scale  " + preferredScale +
+                                           " result scale was " + result.scale() +
+                                           " ; value was " + result);
+                    }
+
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    static int subtractTests() {
+        int failures = 0;
+
+        for(BigDecimal zero1: zeros) {
+            for(BigDecimal zero2: zeros) {
+                BigDecimal expected = new BigDecimal(BigInteger.ZERO,
+                                                     Math.max(zero1.scale(), zero2.scale()));
+                BigDecimal result;
+
+                if(! (result=zero1.subtract(zero2)).equals(expected) ) {
+                    failures++;
+                    System.err.println("For classic exact subtract, expected scale of " +
+                                       expected.scale() + "; got " +
+                                       result.scale() + ".");
+                }
+
+                if(! (result=zero1.subtract(zero2, MathContext.UNLIMITED)).equals(expected) ) {
+                    failures++;
+                    System.err.println("For UNLIMITED math context subtract," +
+                                       " expected scale of " +
+                                       expected.scale() + "; got " +
+                                       result.scale() + ".");
+                }
+
+                if(! (result=zero1.subtract(zero2, longEnough)).equals(expected) ) {
+                    failures++;
+                    System.err.println("For longEnough math context subtract," +
+                                       " expected scale of " +
+                                       expected.scale() + "; got " +
+                                       result.scale() + ".");
+                }
+
+            }
+        }
+
+
+        // Test effect of adding zero to a nonzero value.
+        for (MathContext mc: contexts) {
+            for (BigDecimal zero: zeros) {
+                if (Math.abs((long)zero.scale()) < 100 ) {
+
+                    int preferredScale = Math.max(zero.scale(), element.scale());
+                    if (mc.getPrecision() != 0) {
+                        if (preferredScale < -4 )
+                            preferredScale = -4;
+                        else if (preferredScale > -(5 - mc.getPrecision())) {
+                            preferredScale = -(5 - mc.getPrecision());
+                        }
+                    }
+
+
+                    /*
+                      System.err.println("\n    " + element + " +\t" + zero + " =\t" + result);
+
+                      System.err.println("scales" + element.scale() + " \t" + zero.scale() +
+                      "  \t " + result.scale() + "\t precison = " + mc.getPrecision());
+                      System.err.println("expected scale = " + preferredScale);
+                    */
+
+                    BigDecimal result = element.subtract(zero, mc);
+                    if (result.scale() != preferredScale ||
+                            result.compareTo(element) != 0) {
+                        failures++;
+                        System.err.println("Expected scale  " + preferredScale +
+                                           " result scale was " + result.scale() +
+                                           " ; value was " + result);
+                    }
+
+                    result = zero.subtract(element, mc);
+                    if (result.scale() != preferredScale ||
+                            result.compareTo(element.negate()) != 0) {
+                        failures++;
+                        System.err.println("Expected scale  " + preferredScale +
+                                           " result scale was " + result.scale() +
+                                           " ; value was " + result);
+                    }
+
+                    result = element.negate().subtract(zero, mc);
+                    if (result.scale() != preferredScale ||
+                            result.compareTo(element.negate()) != 0) {
+                        failures++;
+                        System.err.println("Expected scale  " + preferredScale +
+                                           " result scale was " + result.scale() +
+                                           " ; value was " + result);
+                    }
+
+                    result = zero.subtract(element.negate(), mc);
+                    if (result.scale() != preferredScale ||
+                            result.compareTo(element) != 0) {
+                        failures++;
+                        System.err.println("Expected scale  " + preferredScale +
+                                           " result scale was " + result.scale() +
+                                           " ; value was " + result);
+                    }
+
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    static int multiplyTests() {
+        int failures = 0;
+
+        BigDecimal ones[] = {
+            BigDecimal.valueOf(1, 0),
+            BigDecimal.valueOf(10, 1),
+            BigDecimal.valueOf(1000, 3),
+            BigDecimal.valueOf(100000000, 8),
+        };
+
+        List<BigDecimal> values = new LinkedList<BigDecimal>();
+        values.addAll(Arrays.asList(zeros));
+        values.addAll(Arrays.asList(ones));
+
+        for(BigDecimal zero1: zeros) {
+            for(BigDecimal value: values) {
+                BigDecimal expected = new BigDecimal(BigInteger.ZERO,
+                                                     (int)Math.min(Math.max((long)zero1.scale()+value.scale(),
+                                                                            Integer.MIN_VALUE ),
+                                                                   Integer.MAX_VALUE ) );
+                BigDecimal result;
+
+                if(! (result=zero1.multiply(value)).equals(expected) ) {
+                    failures++;
+                    System.err.println("For classic exact multiply, expected scale of " +
+                                       expected.scale() + "; got " +
+                                       result.scale() + ".");
+                }
+
+                if(! (result=zero1.multiply(value, MathContext.UNLIMITED)).equals(expected) ) {
+                    failures++;
+                    System.err.println("For UNLIMITED math context multiply," +
+                                       " expected scale of " +
+                                       expected.scale() + "; got " +
+                                       result.scale() + ".");
+                }
+
+                if(! (result=zero1.multiply(value, longEnough)).equals(expected) ) {
+                    failures++;
+                    System.err.println("For longEnough math context multiply," +
+                                       " expected scale of " +
+                                       expected.scale() + "; got " +
+                                       result.scale() + ".");
+                }
+
+            }
+        }
+
+        return failures;
+    }
+
+    static int divideTests() {
+        int failures = 0;
+
+        BigDecimal [] ones = {
+            BigDecimal.valueOf(1, 0),
+            BigDecimal.valueOf(10, -1),
+            BigDecimal.valueOf(100, -2),
+            BigDecimal.valueOf(1000, -3),
+            BigDecimal.valueOf(1000000, -5),
+        };
+
+        for(BigDecimal one: ones) {
+            for(BigDecimal zero: zeros) {
+                BigDecimal expected = new BigDecimal(BigInteger.ZERO,
+                                                     (int)Math.min(Math.max((long)zero.scale() - one.scale(),
+                                                                            Integer.MIN_VALUE ),
+                                                                   Integer.MAX_VALUE ) );
+                BigDecimal result;
+
+                if(! (result=zero.divide(one)).equals(expected) ) {
+                    failures++;
+                    System.err.println("For classic exact divide, expected scale of " +
+                                       expected.scale() + "; got " +
+                                       result.scale() + ".");
+                }
+
+                if(! (result=zero.divide(one, MathContext.UNLIMITED)).equals(expected) ) {
+                    failures++;
+                    System.err.println("For UNLIMITED math context divide," +
+                                       " expected scale of " +
+                                       expected.scale() + "; got " +
+                                       result.scale() + ".");
+                }
+
+                if(! (result=zero.divide(one, longEnough)).equals(expected) ) {
+                    failures++;
+                    System.err.println("For longEnough math context divide," +
+                                       " expected scale of " +
+                                       expected.scale() + "; got " +
+                                       result.scale() + ".");
+                }
+
+            }
+        }
+
+        return failures;
+    }
+
+    static int setScaleTests() {
+        int failures = 0;
+
+        int scales[] = {
+            Integer.MIN_VALUE,
+            Integer.MIN_VALUE+1,
+            -10000000,
+            -3,
+            -2,
+            -1,
+            0,
+            1,
+            2,
+            3,
+            10,
+            10000000,
+            Integer.MAX_VALUE-1,
+            Integer.MAX_VALUE
+        };
+
+        for(BigDecimal zero: zeros) {
+            for(int scale: scales) {
+                try {
+                    BigDecimal bd = zero.setScale(scale);
+                }
+                catch (ArithmeticException e) {
+                    failures++;
+                    System.err.println("Exception when trying to set a scale of " + scale +
+                                       " on " + zero);
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    static int toEngineeringStringTests() {
+        int failures = 0;
+
+        String [][] testCases  = {
+            {"0E+10",   "0.00E+12"},
+            {"0E+9",    "0E+9"},
+            {"0E+8",    "0.0E+9"},
+            {"0E+7",    "0.00E+9"},
+
+            {"0E-10",   "0.0E-9"},
+            {"0E-9",    "0E-9"},
+            {"0E-8",    "0.00E-6"},
+            {"0E-7",    "0.0E-6"},
+        };
+
+        for(String[] testCase: testCases) {
+            BigDecimal bd = new BigDecimal(testCase[0]);
+            String result = bd.toEngineeringString();
+
+            if (!result.equals(testCase[1]) ||
+                !bd.equals(new BigDecimal(result))) {
+                failures++;
+                System.err.println("From input ``" + testCase[0] + ",'' " +
+                                   " bad engineering string output ``" + result +
+                                   "''; expected ``" + testCase[1] + ".''");
+            }
+
+        }
+
+        return failures;
+    }
+
+    static int ulpTests() {
+        int failures = 0;
+
+        for(BigDecimal zero: zeros) {
+            BigDecimal result;
+            BigDecimal expected = BigDecimal.valueOf(1, zero.scale());
+
+            if (! (result=zero.ulp()).equals(expected) ) {
+                failures++;
+                System.err.println("Unexpected ulp value for zero value " +
+                                   zero + "; expected " + expected +
+                                   ", got " + result);
+            }
+        }
+
+        return failures;
+    }
+
+    public static void main(String argv[]) {
+        int failures = 0;
+
+        failures += addTests();
+        failures += subtractTests();
+        failures += multiplyTests();
+        failures += divideTests();
+        failures += setScaleTests();
+        failures += toEngineeringStringTests();
+        failures += ulpTests();
+
+        if (failures > 0 ) {
+            throw new RuntimeException("Incurred " + failures + " failures" +
+                                       " testing the preservation of zero scales.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigInteger/BigIntegerTest.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,792 @@
+/*
+ * Copyright 1998-2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4181191 4161971 4227146 4194389 4823171 4624738 4812225
+ * @summary tests methods in BigInteger
+ * @run main/timeout=400 BigIntegerTest
+ * @author madbot
+ */
+
+import java.util.Random;
+import java.math.BigInteger;
+import java.io.*;
+
+/**
+ * This is a simple test class created to ensure that the results
+ * generated by BigInteger adhere to certain identities. Passing
+ * this test is a strong assurance that the BigInteger operations
+ * are working correctly.
+ *
+ * Three arguments may be specified which give the number of
+ * decimal digits you desire in the three batches of test numbers.
+ *
+ * The tests are performed on arrays of random numbers which are
+ * generated by a Random class as well as special cases which
+ * throw in boundary numbers such as 0, 1, maximum sized, etc.
+ *
+ */
+public class BigIntegerTest {
+    static Random rnd = new Random();
+    static int size = 1000; // numbers per batch
+    static boolean failure = false;
+
+    // Some variables for sizing test numbers in bits
+    private static int order1 = 100;
+    private static int order2 = 60;
+    private static int order3 = 30;
+
+    public static void pow() {
+        int failCount1 = 0;
+
+        for (int i=0; i<size; i++) {
+            int power = rnd.nextInt(6) +2;
+            BigInteger x = fetchNumber(order1);
+            BigInteger y = x.pow(power);
+            BigInteger z = x;
+
+            for (int j=1; j<power; j++)
+                z = z.multiply(x);
+
+            if (!y.equals(z))
+                failCount1++;
+        }
+        report("pow", failCount1);
+    }
+
+    public static void arithmetic() {
+        int failCount = 0;
+
+        for (int i=0; i<size; i++) {
+            BigInteger x = fetchNumber(order1);
+            while(x.compareTo(BigInteger.ZERO) != 1)
+                x = fetchNumber(order1);
+            BigInteger y = fetchNumber(order1/2);
+            while(x.compareTo(y) == -1)
+                y = fetchNumber(order1/2);
+            if (y.equals(BigInteger.ZERO))
+                y = y.add(BigInteger.ONE);
+
+            BigInteger baz = x.divide(y);
+            baz = baz.multiply(y);
+            baz = baz.add(x.remainder(y));
+            baz = baz.subtract(x);
+            if (!baz.equals(BigInteger.ZERO))
+                failCount++;
+        }
+        report("Arithmetic I", failCount);
+
+        failCount = 0;
+        for (int i=0; i<100; i++) {
+            BigInteger x = fetchNumber(order1);
+            while(x.compareTo(BigInteger.ZERO) != 1)
+                x = fetchNumber(order1);
+            BigInteger y = fetchNumber(order1/2);
+            while(x.compareTo(y) == -1)
+                y = fetchNumber(order1/2);
+            if (y.equals(BigInteger.ZERO))
+                y = y.add(BigInteger.ONE);
+
+            BigInteger baz[] = x.divideAndRemainder(y);
+            baz[0] = baz[0].multiply(y);
+            baz[0] = baz[0].add(baz[1]);
+            baz[0] = baz[0].subtract(x);
+            if (!baz[0].equals(BigInteger.ZERO))
+                failCount++;
+        }
+        report("Arithmetic II", failCount);
+    }
+
+    public static void bitCount() {
+        int failCount = 0;
+
+        for (int i=0; i<size*10; i++) {
+            int x = rnd.nextInt();
+            BigInteger bigX = BigInteger.valueOf((long)x);
+            int bit = (x < 0 ? 0 : 1);
+            int tmp = x, bitCount = 0;
+            for (int j=0; j<32; j++) {
+                bitCount += ((tmp & 1) == bit ? 1 : 0);
+                tmp >>= 1;
+            }
+
+            if (bigX.bitCount() != bitCount) {
+                //System.err.println(x+": "+bitCount+", "+bigX.bitCount());
+                failCount++;
+            }
+        }
+        report("Bit Count", failCount);
+    }
+
+    public static void bitLength() {
+        int failCount = 0;
+
+        for (int i=0; i<size*10; i++) {
+            int x = rnd.nextInt();
+            BigInteger bigX = BigInteger.valueOf((long)x);
+            int signBit = (x < 0 ? 0x80000000 : 0);
+            int tmp = x, bitLength, j;
+            for (j=0; j<32 && (tmp & 0x80000000)==signBit; j++)
+                tmp <<= 1;
+            bitLength = 32 - j;
+
+            if (bigX.bitLength() != bitLength) {
+                //System.err.println(x+": "+bitLength+", "+bigX.bitLength());
+                failCount++;
+            }
+        }
+
+        report("BitLength", failCount);
+    }
+
+    public static void bitOps() {
+        int failCount1 = 0, failCount2 = 0, failCount3 = 0;
+
+        for (int i=0; i<size*5; i++) {
+            BigInteger x = fetchNumber(order1);
+            BigInteger y;
+
+            /* Test setBit and clearBit (and testBit) */
+            if (x.signum() < 0) {
+                y = BigInteger.valueOf(-1);
+                for (int j=0; j<x.bitLength(); j++)
+                    if (!x.testBit(j))
+                        y = y.clearBit(j);
+            } else {
+                y = BigInteger.ZERO;
+                for (int j=0; j<x.bitLength(); j++)
+                    if (x.testBit(j))
+                        y = y.setBit(j);
+            }
+            if (!x.equals(y))
+                failCount1++;
+
+            /* Test flipBit (and testBit) */
+            y = BigInteger.valueOf(x.signum()<0 ? -1 : 0);
+            for (int j=0; j<x.bitLength(); j++)
+                if (x.signum()<0  ^  x.testBit(j))
+                    y = y.flipBit(j);
+            if (!x.equals(y))
+                failCount2++;
+        }
+        report("clearBit/testBit", failCount1);
+        report("flipBit/testBit", failCount2);
+
+        for (int i=0; i<size*5; i++) {
+            BigInteger x = fetchNumber(order1);
+
+            /* Test getLowestSetBit() */
+            int k = x.getLowestSetBit();
+            if (x.signum() == 0) {
+                if (k != -1)
+                    failCount3++;
+            } else {
+                BigInteger z = x.and(x.negate());
+                int j;
+                for (j=0; j<z.bitLength() && !z.testBit(j); j++)
+                    ;
+                if (k != j)
+                    failCount3++;
+            }
+        }
+        report("getLowestSetBit", failCount3);
+    }
+
+    public static void bitwise() {
+
+        /* Test identity x^y == x|y &~ x&y */
+        int failCount = 0;
+        for (int i=0; i<size; i++) {
+            BigInteger x = fetchNumber(order1);
+            BigInteger y = fetchNumber(order1);
+            BigInteger z = x.xor(y);
+            BigInteger w = x.or(y).andNot(x.and(y));
+            if (!z.equals(w))
+                failCount++;
+        }
+        report("Logic (^ | & ~)", failCount);
+
+        /* Test identity x &~ y == ~(~x | y) */
+        failCount = 0;
+        for (int i=0; i<size; i++) {
+            BigInteger x = fetchNumber(order1);
+            BigInteger y = fetchNumber(order1);
+            BigInteger z = x.andNot(y);
+            BigInteger w = x.not().or(y).not();
+            if (!z.equals(w))
+                failCount++;
+        }
+        report("Logic (&~ | ~)", failCount);
+    }
+
+    public static void shift() {
+        int failCount1 = 0;
+        int failCount2 = 0;
+        int failCount3 = 0;
+
+        for (int i=0; i<100; i++) {
+            BigInteger x = fetchNumber(order1);
+            int n = Math.abs(rnd.nextInt()%200);
+
+            if (!x.shiftLeft(n).equals
+                (x.multiply(BigInteger.valueOf(2L).pow(n))))
+                failCount1++;
+
+            BigInteger y[] =x.divideAndRemainder(BigInteger.valueOf(2L).pow(n));
+            BigInteger z = (x.signum()<0 && y[1].signum()!=0
+                            ? y[0].subtract(BigInteger.ONE)
+                            : y[0]);
+
+            BigInteger b = x.shiftRight(n);
+
+            if (!b.equals(z)) {
+                System.err.println("Input is "+x.toString(2));
+                System.err.println("shift is "+n);
+
+                System.err.println("Divided "+z.toString(2));
+                System.err.println("Shifted is "+b.toString(2));
+                if (b.toString().equals(z.toString()))
+                    System.err.println("Houston, we have a problem.");
+                failCount2++;
+            }
+
+            if (!x.shiftLeft(n).shiftRight(n).equals(x))
+                failCount3++;
+        }
+        report("baz shiftLeft", failCount1);
+        report("baz shiftRight", failCount2);
+        report("baz shiftLeft/Right", failCount3);
+    }
+
+    public static void divideAndRemainder() {
+        int failCount1 = 0;
+
+        for (int i=0; i<size; i++) {
+            BigInteger x = fetchNumber(order1).abs();
+            while(x.compareTo(BigInteger.valueOf(3L)) != 1)
+                x = fetchNumber(order1).abs();
+            BigInteger z = x.divide(BigInteger.valueOf(2L));
+            BigInteger y[] = x.divideAndRemainder(x);
+            if (!y[0].equals(BigInteger.ONE)) {
+                failCount1++;
+                System.err.println("fail1 x :"+x);
+                System.err.println("      y :"+y);
+            }
+            else if (!y[1].equals(BigInteger.ZERO)) {
+                failCount1++;
+                System.err.println("fail2 x :"+x);
+                System.err.println("      y :"+y);
+            }
+
+            y = x.divideAndRemainder(z);
+            if (!y[0].equals(BigInteger.valueOf(2))) {
+                failCount1++;
+                System.err.println("fail3 x :"+x);
+                System.err.println("      y :"+y);
+            }
+        }
+        report("divideAndRemainder I", failCount1);
+    }
+
+    public static void stringConv() {
+        int failCount = 0;
+
+        for (int i=0; i<100; i++) {
+            byte xBytes[] = new byte[Math.abs(rnd.nextInt())%100+1];
+            rnd.nextBytes(xBytes);
+            BigInteger x = new BigInteger(xBytes);
+
+            for (int radix=2; radix < 37; radix++) {
+                String result = x.toString(radix);
+                BigInteger test = new BigInteger(result, radix);
+                if (!test.equals(x)) {
+                    failCount++;
+                    System.err.println("BigInteger toString: "+x);
+                    System.err.println("Test: "+test);
+                    System.err.println(radix);
+                }
+            }
+        }
+        report("String Conversion", failCount);
+    }
+
+    public static void byteArrayConv() {
+        int failCount = 0;
+
+        for (int i=0; i<size; i++) {
+            BigInteger x = fetchNumber(order1);
+            while (x.equals(BigInteger.ZERO))
+                x = fetchNumber(order1);
+            BigInteger y = new BigInteger(x.toByteArray());
+            if (!x.equals(y)) {
+                failCount++;
+                System.err.println("orig is "+x);
+                System.err.println("new is "+y);
+            }
+        }
+        report("Array Conversion", failCount);
+    }
+
+    public static void modInv() {
+        int failCount = 0, successCount = 0, nonInvCount = 0;
+
+        for (int i=0; i<size; i++) {
+            BigInteger x = fetchNumber(order1);
+            while(x.equals(BigInteger.ZERO))
+                x = fetchNumber(order1);
+            BigInteger m = fetchNumber(order1).abs();
+            while(m.compareTo(BigInteger.ONE) != 1)
+                m = fetchNumber(order1).abs();
+
+            try {
+                BigInteger inv = x.modInverse(m);
+                BigInteger prod = inv.multiply(x).remainder(m);
+
+                if (prod.signum() == -1)
+                    prod = prod.add(m);
+
+                if (prod.equals(BigInteger.ONE))
+                    successCount++;
+                else
+                    failCount++;
+            } catch(ArithmeticException e) {
+                nonInvCount++;
+            }
+        }
+        report("Modular Inverse", failCount);
+    }
+
+    public static void modExp() {
+        int failCount = 0;
+
+        for (int i=0; i<size/10; i++) {
+            BigInteger m = fetchNumber(order1).abs();
+            while(m.compareTo(BigInteger.ONE) != 1)
+                m = fetchNumber(order1).abs();
+            BigInteger base = fetchNumber(order2);
+            BigInteger exp = fetchNumber(8).abs();
+
+            BigInteger z = base.modPow(exp, m);
+            BigInteger w = base.pow(exp.intValue()).mod(m);
+            if (!z.equals(w)) {
+                System.err.println("z is "+z);
+                System.err.println("w is "+w);
+                System.err.println("mod is "+m);
+                System.err.println("base is "+base);
+                System.err.println("exp is "+exp);
+                failCount++;
+            }
+        }
+        report("Exponentiation I", failCount);
+    }
+
+    // This test is based on Fermat's theorem
+    // which is not ideal because base must not be multiple of modulus
+    // and modulus must be a prime or pseudoprime (Carmichael number)
+    public static void modExp2() {
+        int failCount = 0;
+
+        for (int i=0; i<10; i++) {
+            BigInteger m = new BigInteger(100, 5, rnd);
+            while(m.compareTo(BigInteger.ONE) != 1)
+                m = new BigInteger(100, 5, rnd);
+            BigInteger exp = m.subtract(BigInteger.ONE);
+            BigInteger base = fetchNumber(order1).abs();
+            while(base.compareTo(m) != -1)
+                base = fetchNumber(order1).abs();
+            while(base.equals(BigInteger.ZERO))
+                base = fetchNumber(order1).abs();
+
+            BigInteger one = base.modPow(exp, m);
+            if (!one.equals(BigInteger.ONE)) {
+                System.err.println("m is "+m);
+                System.err.println("base is "+base);
+                System.err.println("exp is "+exp);
+                failCount++;
+            }
+        }
+        report("Exponentiation II", failCount);
+    }
+
+    private static final int[] mersenne_powers = {
+        521, 607, 1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941, 11213, 19937,
+        21701, 23209, 44497, 86243, 110503, 132049, 216091, 756839, 859433,
+        1257787, 1398269, 2976221, 3021377, 6972593, 13466917 };
+
+    private static final long[] carmichaels = {
+      561,1105,1729,2465,2821,6601,8911,10585,15841,29341,41041,46657,52633,
+      62745,63973,75361,101101,115921,126217,162401,172081,188461,252601,
+      278545,294409,314821,334153,340561,399001,410041,449065,488881,512461,
+      225593397919L };
+
+    // Note: testing the larger ones takes too long.
+    private static final int NUM_MERSENNES_TO_TEST = 7;
+    // Note: this constant used for computed Carmichaels, not the array above
+    private static final int NUM_CARMICHAELS_TO_TEST = 5;
+
+    private static final String[] customer_primes = {
+        "120000000000000000000000000000000019",
+        "633825300114114700748351603131",
+        "1461501637330902918203684832716283019651637554291",
+        "779626057591079617852292862756047675913380626199",
+        "857591696176672809403750477631580323575362410491",
+        "910409242326391377348778281801166102059139832131",
+        "929857869954035706722619989283358182285540127919",
+        "961301750640481375785983980066592002055764391999",
+        "1267617700951005189537696547196156120148404630231",
+        "1326015641149969955786344600146607663033642528339" };
+
+    private static final BigInteger ZERO = BigInteger.ZERO;
+    private static final BigInteger ONE = BigInteger.ONE;
+    private static final BigInteger TWO = new BigInteger("2");
+    private static final BigInteger SIX = new BigInteger("6");
+    private static final BigInteger TWELVE = new BigInteger("12");
+    private static final BigInteger EIGHTEEN = new BigInteger("18");
+
+    public static void prime() {
+        BigInteger p1, p2, c1;
+        int failCount = 0;
+
+        // Test consistency
+        for(int i=0; i<10; i++) {
+            p1 = BigInteger.probablePrime(100, rnd);
+            if (!p1.isProbablePrime(100)) {
+                System.err.println("Consistency "+p1.toString(16));
+                failCount++;
+            }
+        }
+
+        // Test some known Mersenne primes (2^n)-1
+        // The array holds the exponents, not the numbers being tested
+        for (int i=0; i<NUM_MERSENNES_TO_TEST; i++) {
+            p1 = new BigInteger("2");
+            p1 = p1.pow(mersenne_powers[i]);
+            p1 = p1.subtract(BigInteger.ONE);
+            if (!p1.isProbablePrime(100)) {
+                System.err.println("Mersenne prime "+i+ " failed.");
+                failCount++;
+            }
+        }
+
+        // Test some primes reported by customers as failing in the past
+        for (int i=0; i<customer_primes.length; i++) {
+            p1 = new BigInteger(customer_primes[i]);
+            if (!p1.isProbablePrime(100)) {
+                System.err.println("Customer prime "+i+ " failed.");
+                failCount++;
+            }
+        }
+
+        // Test some known Carmichael numbers.
+        for (int i=0; i<carmichaels.length; i++) {
+            c1 = BigInteger.valueOf(carmichaels[i]);
+            if(c1.isProbablePrime(100)) {
+                System.err.println("Carmichael "+i+ " reported as prime.");
+                failCount++;
+            }
+        }
+
+        // Test some computed Carmichael numbers.
+        // Numbers of the form (6k+1)(12k+1)(18k+1) are Carmichael numbers if
+        // each of the factors is prime
+        int found = 0;
+        BigInteger f1 = new BigInteger(40, 100, rnd);
+        while (found < NUM_CARMICHAELS_TO_TEST) {
+            BigInteger k = null;
+            BigInteger f2, f3;
+            f1 = f1.nextProbablePrime();
+            BigInteger[] result = f1.subtract(ONE).divideAndRemainder(SIX);
+            if (result[1].equals(ZERO)) {
+                k = result[0];
+                f2 = k.multiply(TWELVE).add(ONE);
+                if (f2.isProbablePrime(100)) {
+                    f3 = k.multiply(EIGHTEEN).add(ONE);
+                    if (f3.isProbablePrime(100)) {
+                        c1 = f1.multiply(f2).multiply(f3);
+                        if (c1.isProbablePrime(100)) {
+                            System.err.println("Computed Carmichael "
+                                               +c1.toString(16));
+                            failCount++;
+                        }
+                        found++;
+                    }
+                }
+            }
+            f1 = f1.add(TWO);
+        }
+
+        // Test some composites that are products of 2 primes
+        for (int i=0; i<50; i++) {
+            p1 = BigInteger.probablePrime(100, rnd);
+            p2 = BigInteger.probablePrime(100, rnd);
+            c1 = p1.multiply(p2);
+            if (c1.isProbablePrime(100)) {
+                System.err.println("Composite failed "+c1.toString(16));
+                failCount++;
+            }
+        }
+
+        for (int i=0; i<4; i++) {
+            p1 = BigInteger.probablePrime(600, rnd);
+            p2 = BigInteger.probablePrime(600, rnd);
+            c1 = p1.multiply(p2);
+            if (c1.isProbablePrime(100)) {
+                System.err.println("Composite failed "+c1.toString(16));
+                failCount++;
+            }
+        }
+
+        report("Prime", failCount);
+    }
+
+    private static final long[] primesTo100 = {
+        2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97
+    };
+
+    private static final long[] aPrimeSequence = {
+        1999999003L, 1999999013L, 1999999049L, 1999999061L, 1999999081L,
+        1999999087L, 1999999093L, 1999999097L, 1999999117L, 1999999121L,
+        1999999151L, 1999999171L, 1999999207L, 1999999219L, 1999999271L,
+        1999999321L, 1999999373L, 1999999423L, 1999999439L, 1999999499L,
+        1999999553L, 1999999559L, 1999999571L, 1999999609L, 1999999613L,
+        1999999621L, 1999999643L, 1999999649L, 1999999657L, 1999999747L,
+        1999999763L, 1999999777L, 1999999811L, 1999999817L, 1999999829L,
+        1999999853L, 1999999861L, 1999999871L, 1999999873
+    };
+
+    public static void nextProbablePrime() throws Exception {
+        int failCount = 0;
+        BigInteger p1, p2, p3;
+        p1 = p2 = p3 = ZERO;
+
+        // First test nextProbablePrime on the low range starting at zero
+        for (int i=0; i<primesTo100.length; i++) {
+            p1 = p1.nextProbablePrime();
+            if (p1.longValue() != primesTo100[i]) {
+                System.err.println("low range primes failed");
+                System.err.println("p1 is "+p1);
+                System.err.println("expected "+primesTo100[i]);
+                failCount++;
+            }
+        }
+
+        // Test nextProbablePrime on a relatively small, known prime sequence
+        p1 = BigInteger.valueOf(aPrimeSequence[0]);
+        for (int i=1; i<aPrimeSequence.length; i++) {
+            p1 = p1.nextProbablePrime();
+            if (p1.longValue() != aPrimeSequence[i]) {
+                System.err.println("prime sequence failed");
+                failCount++;
+            }
+        }
+
+        // Next, pick some large primes, use nextProbablePrime to find the
+        // next one, and make sure there are no primes in between
+        for (int i=0; i<100; i+=10) {
+            p1 = BigInteger.probablePrime(50 + i, rnd);
+            p2 = p1.add(ONE);
+            p3 = p1.nextProbablePrime();
+            while(p2.compareTo(p3) < 0) {
+                if (p2.isProbablePrime(100)){
+                    System.err.println("nextProbablePrime failed");
+                    System.err.println("along range "+p1.toString(16));
+                    System.err.println("to "+p3.toString(16));
+                    failCount++;
+                    break;
+                }
+                p2 = p2.add(ONE);
+            }
+        }
+
+        report("nextProbablePrime", failCount);
+    }
+
+    public static void serialize() throws Exception {
+        int failCount = 0;
+
+        String bitPatterns[] = {
+             "ffffffff00000000ffffffff00000000ffffffff00000000",
+             "ffffffffffffffffffffffff000000000000000000000000",
+             "ffffffff0000000000000000000000000000000000000000",
+             "10000000ffffffffffffffffffffffffffffffffffffffff",
+             "100000000000000000000000000000000000000000000000",
+             "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+            "-ffffffff00000000ffffffff00000000ffffffff00000000",
+            "-ffffffffffffffffffffffff000000000000000000000000",
+            "-ffffffff0000000000000000000000000000000000000000",
+            "-10000000ffffffffffffffffffffffffffffffffffffffff",
+            "-100000000000000000000000000000000000000000000000",
+            "-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+        };
+
+        for(int i = 0; i < bitPatterns.length; i++) {
+            BigInteger b1 = new BigInteger(bitPatterns[i], 16);
+
+            File f = new File("serialtest");
+            FileOutputStream fos = new FileOutputStream(f);
+            ObjectOutputStream oos = new ObjectOutputStream(fos);
+            oos.writeObject(b1);
+            oos.flush();
+            oos.close();
+            FileInputStream fis = new FileInputStream(f);
+            ObjectInputStream ois = new ObjectInputStream(fis);
+            BigInteger b2 = (BigInteger)ois.readObject();
+
+            if (!b1.equals(b2) ||
+                !b1.equals(b1.or(b2))) {
+                failCount++;
+                System.err.println("Serialized failed for hex " +
+                                   b1.toString(16));
+            }
+            f.delete();
+        }
+
+        for(int i=0; i<10; i++) {
+            BigInteger b1 = fetchNumber(rnd.nextInt(100));
+            File f = new File("serialtest");
+            FileOutputStream fos = new FileOutputStream(f);
+            ObjectOutputStream oos = new ObjectOutputStream(fos);
+            oos.writeObject(b1);
+            oos.flush();
+            oos.close();
+            FileInputStream fis = new FileInputStream(f);
+            ObjectInputStream ois = new ObjectInputStream(fis);
+            BigInteger b2 = (BigInteger)ois.readObject();
+
+            if (!b1.equals(b2) ||
+                !b1.equals(b1.or(b2)))
+                failCount++;
+            f.delete();
+        }
+
+        report("Serialize", failCount);
+    }
+
+    /**
+     * Main to interpret arguments and run several tests.
+     *
+     * Up to three arguments may be given to specify the size of BigIntegers
+     * used for call parameters 1, 2, and 3. The size is interpreted as
+     * the maximum number of decimal digits that the parameters will have.
+     *
+     */
+    public static void main(String[] args) throws Exception {
+
+        if (args.length >0)
+            order1 = (int)((Integer.parseInt(args[0]))* 3.333);
+        if (args.length >1)
+            order2 = (int)((Integer.parseInt(args[1]))* 3.333);
+        if (args.length >2)
+            order3 = (int)((Integer.parseInt(args[2]))* 3.333);
+
+        prime();
+        nextProbablePrime();
+
+        arithmetic();
+        divideAndRemainder();
+        pow();
+
+        bitCount();
+        bitLength();
+        bitOps();
+        bitwise();
+
+        shift();
+
+        byteArrayConv();
+
+        modInv();
+        modExp();
+        modExp2();
+
+        stringConv();
+        serialize();
+
+        if (failure)
+            throw new RuntimeException("Failure in BigIntegerTest.");
+    }
+
+    /*
+     * Get a random or boundary-case number. This is designed to provide
+     * a lot of numbers that will find failure points, such as max sized
+     * numbers, empty BigIntegers, etc.
+     *
+     * If order is less than 2, order is changed to 2.
+     */
+    private static BigInteger fetchNumber(int order) {
+        boolean negative = rnd.nextBoolean();
+        int numType = rnd.nextInt(6);
+        BigInteger result = null;
+        if (order < 2) order = 2;
+
+        switch (numType) {
+            case 0: // Empty
+                result = BigInteger.ZERO;
+                break;
+
+            case 1: // One
+                result = BigInteger.ONE;
+                break;
+
+            case 2: // All bits set in number
+                int numBytes = (order+7)/8;
+                byte[] fullBits = new byte[numBytes];
+                for(int i=0; i<numBytes; i++)
+                    fullBits[i] = (byte)0xff;
+                int excessBits = 8*numBytes - order;
+                fullBits[0] &= (1 << (8-excessBits)) - 1;
+                result = new BigInteger(1, fullBits);
+                break;
+
+            case 3: // One bit in number
+                result = BigInteger.ONE.shiftLeft(rnd.nextInt(order));
+                break;
+
+            case 4: // Random bit density
+                int iterations = rnd.nextInt(order-1);
+                result = BigInteger.ONE.shiftLeft(rnd.nextInt(order));
+                for(int i=0; i<iterations; i++) {
+                    BigInteger temp = BigInteger.ONE.shiftLeft(
+                                                rnd.nextInt(order));
+                    result = result.or(temp);
+                }
+                break;
+
+            default: // random bits
+                result = new BigInteger(order, rnd);
+        }
+
+        if (negative)
+            result = result.negate();
+
+        return result;
+    }
+
+    static void report(String testName, int failCount) {
+        System.err.println(testName+": " +
+                           (failCount==0 ? "Passed":"Failed("+failCount+")"));
+        if (failCount > 0)
+            failure = true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigInteger/ModPow.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1998 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 4181191
+ * @summary test BigInteger modPow method
+ */
+import java.math.BigInteger;
+import java.util.Random;
+
+public class ModPow {
+    public static void main(String[] args) {
+        Random rnd = new Random(1234);
+
+        for (int i=0; i<2000; i++) {
+            BigInteger m = new BigInteger(800, rnd);
+            BigInteger base = new BigInteger(16, rnd);
+            if (rnd.nextInt() % 1 == 0)
+                base = base.negate();
+            BigInteger exp = new BigInteger(8, rnd);
+
+            BigInteger z = base.modPow(exp, m);
+            BigInteger w = base.pow(exp.intValue()).mod(m);
+            if (!z.equals(w)){
+                System.err.println(base +" ** " + exp + " mod "+ m);
+                System.err.println("modPow : " + z);
+                System.err.println("pow.mod: " + w);
+                throw new RuntimeException("BigInteger modPow failure.");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigInteger/ModPow65537.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4891312
+ * @summary verify that modPow() not broken by the special case for 65537
+ * @author Andreas Sterbenz
+ */
+
+import java.math.BigInteger;
+import java.util.*;
+
+import java.security.*;
+import java.security.spec.*;
+
+public class ModPow65537 {
+
+    public static void main(String[] args) throws Exception {
+        // SunRsaSign uses BigInteger internally
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "SunRsaSign");
+        kpg.initialize(new RSAKeyGenParameterSpec(512, BigInteger.valueOf(65537)));
+        KeyPair kp = kpg.generateKeyPair();
+        testSigning(kp);
+
+        kpg.initialize(new RSAKeyGenParameterSpec(512, BigInteger.valueOf(65539)));
+        kp = kpg.generateKeyPair();
+        testSigning(kp);
+
+        kpg.initialize(new RSAKeyGenParameterSpec(512, BigInteger.valueOf(3)));
+        kp = kpg.generateKeyPair();
+        testSigning(kp);
+
+        // basic known answer test
+        BigInteger base = new BigInteger("19058071224156864789844466979330892664777520457048234786139035643344145635582");
+        BigInteger mod  = new BigInteger("75554098474976067521257305210610421240510163914613117319380559667371251381587");
+        BigInteger exp1 = BigInteger.valueOf(65537);
+        BigInteger exp2 = BigInteger.valueOf(75537);
+        BigInteger exp3 = new BigInteger("13456870775607312149");
+
+        BigInteger res1 = new BigInteger("5770048609366563851320890693196148833634112303472168971638730461010114147506");
+        BigInteger res2 = new BigInteger("63446979364051087123350579021875958137036620431381329472348116892915461751531");
+        BigInteger res3 = new BigInteger("39016891919893878823999350081191675846357272199067075794096200770872982089502");
+
+        if (base.modPow(exp1, mod).equals(res1) == false) {
+            throw new Exception("Error using " + exp1);
+        }
+        if (base.modPow(exp2, mod).equals(res2) == false) {
+            throw new Exception("Error using " + exp2);
+        }
+        if (base.modPow(exp3, mod).equals(res3) == false) {
+            throw new Exception("Error using " + exp3);
+        }
+
+        System.out.println("Passed");
+    }
+
+    private static void testSigning(KeyPair kp) throws Exception {
+        System.out.println(kp.getPublic());
+        byte[] data = new byte[1024];
+        new Random().nextBytes(data);
+
+        Signature sig = Signature.getInstance("SHA1withRSA", "SunRsaSign");
+        sig.initSign(kp.getPrivate());
+        sig.update(data);
+        byte[] sigBytes = sig.sign();
+
+        sig.initVerify(kp.getPublic());
+        sig.update(data);
+        if (sig.verify(sigBytes) == false) {
+            throw new Exception("signature verification failed");
+        }
+        System.out.println("OK");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigInteger/ModPowPowersof2.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright 1998 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @bug 4098742
+   @summary Test biginteger modpow method
+   @author Michael McCloskey
+   @run main/othervm ModPowPowersof2
+*/
+
+import java.math.BigInteger;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * This class tests to see if using modPow on a power
+ * of two crashes the vm
+ *
+ */
+public class ModPowPowersof2 {
+
+      public static void main(String args[]) throws Exception {
+          // Construct a command that runs the test in other vm
+          String[] command = new String[4];
+          int n = 0;
+
+          command[n++] = System.getProperty("java.home") + File.separator +
+              "bin" + File.separator + "java";
+          if (System.getProperty("java.class.path") != null) {
+              command[n++] = "-classpath";
+              command[n++] = System.getProperty("java.class.path");
+          }
+
+          command[n++] = "ModPowPowersof2$ModTester";
+
+          // Exec another vm to run test in
+          Process p = null;
+          p = Runtime.getRuntime().exec(command);
+
+          // Read the result to determine if test failed
+          BufferedReader in = new BufferedReader(new InputStreamReader(
+                                             p.getInputStream()));
+          String s;
+          s = in.readLine();
+          if (s == null)
+              throw new RuntimeException("ModPow causes vm crash");
+
+     }
+
+    public static class ModTester {
+        public static void main(String [] args) {
+            BigInteger two = BigInteger.valueOf(2);
+            BigInteger four = BigInteger.valueOf(4);
+
+            two.modPow(two, BigInteger.valueOf(4));
+            two.modPow(two, BigInteger.valueOf(8));
+            two.modPow(four, BigInteger.valueOf(8));
+
+            System.out.println("success");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigInteger/OperatorNpeTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2006 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6365176
+ * @summary Get NullPointerExceptions when expected
+ * @author Joseph D. Darcy
+ */
+
+import java.math.*;
+import static java.math.BigInteger.*;
+
+public class OperatorNpeTests {
+
+    public static void main(String... argv) {
+        BigInteger[] specialValues = {ZERO, ONE, TEN};
+
+        for (BigInteger bd : specialValues) {
+            BigInteger result;
+            try {
+                result = bd.multiply(null);
+                throw new RuntimeException("Instead of NPE got " + result);
+            } catch (NullPointerException npe) {
+                ; // Expected
+            }
+
+            try {
+                result = bd.divide(null);
+                throw new RuntimeException("Instead of NPE got " + result);
+            } catch (NullPointerException npe) {
+                ; // Expected
+            }
+
+            try {
+                result = bd.add(null);
+                throw new RuntimeException("Instead of NPE got " + result);
+            } catch (NullPointerException npe) {
+                ; // Expected
+            }
+
+            try {
+                result = bd.subtract(null);
+                throw new RuntimeException("Instead of NPE got " + result);
+            } catch (NullPointerException npe) {
+                ; // Expected
+            }
+
+
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigInteger/ProbablePrime.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2002 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4654323
+ * @summary Tests functionality of isProbablePrime(Integer.MAX_VALUE)
+ */
+import java.math.*;
+
+public class ProbablePrime {
+    public static void main(String [] argv) {
+                BigInteger num = new BigInteger("4");
+                int certainties[] = {-1, 0, 1, 2, 100, Integer.MAX_VALUE-1,
+                                     Integer.MAX_VALUE};
+                boolean expectations[] = {true, true, false, false, false,
+                                          false, false};
+
+                for(int i = 0; i < certainties.length; i++) {
+                    boolean b;
+                    if((b=num.isProbablePrime(certainties[i])) !=
+                       expectations[i])
+                       throw new RuntimeException("Unexpected answer " + b +
+                                                  " for certainty " +
+                                                  certainties[i]);
+                }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigInteger/StringConstructor.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2001-2007 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4489146 5017980
+ * @summary tests String constructors of BigInteger
+ * @author Joseph D. Darcy
+ */
+import java.math.*;
+
+public class StringConstructor {
+
+
+    public static void main(String [] argv) {
+        // Good strings
+        constructWithoutError("0", 0L);
+        constructWithoutError("000000000000000000", 0L);
+        constructWithoutError("1", 1L);
+        constructWithoutError("-1", -1L);
+        constructWithoutError("+1", +1L);
+        constructWithoutError( "123456789123456789", 123456789123456789L);
+        constructWithoutError("+123456789123456789", 123456789123456789L);
+        constructWithoutError("-123456789123456789", -123456789123456789L);
+        constructWithoutError(Integer.toString(Integer.MIN_VALUE),
+                              (long)Integer.MIN_VALUE);
+        constructWithoutError(Integer.toString(Integer.MAX_VALUE),
+                              (long)Integer.MAX_VALUE);
+        constructWithoutError(Long.toString(Long.MIN_VALUE),
+                              Long.MIN_VALUE);
+        constructWithoutError(Long.toString(Long.MAX_VALUE),
+                              Long.MAX_VALUE);
+
+        // Bad strings
+        constructWithError("");
+        constructWithError("-");
+        constructWithError("+");
+        constructWithError("--");
+        constructWithError("++");
+        constructWithError("-000-0");
+        constructWithError("+000+0");
+        constructWithError("+000-0");
+        constructWithError("--1234567890");
+        constructWithError("++1234567890");
+        constructWithError("-0-12345678");
+        constructWithError("+0+12345678");
+        constructWithError("--12345678-12345678-12345678");
+        constructWithError("++12345678+12345678+12345678");
+        constructWithError("12345-");
+        constructWithError("12345+");
+    }
+
+    // this method adapted from ../BigDecimal/StringConstructor.java
+    private static void constructWithError(String badString) {
+        try {
+            BigInteger bi = new BigInteger(badString);
+            throw new RuntimeException(badString + " accepted");
+        } catch(NumberFormatException e) {
+        }
+    }
+
+    private static void constructWithoutError(String goodString, long value) {
+            BigInteger bi = new BigInteger(goodString);
+            if(bi.longValue() != value) {
+                System.err.printf("From ``%s'' expected %d, got %s.\n", goodString, value, bi);
+                throw new RuntimeException();
+            }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/BigInteger/UnicodeConstructor.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright 1998 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4040456
+ * @summary Test biginteger constructor with i18n string
+ */
+
+import java.math.*;
+
+/**
+ * This class tests to see if creating a biginteger with an
+ * unicode japanese zero and one succeeds
+ *
+ */
+public class UnicodeConstructor {
+
+      public static void main(String args[]) {
+
+         try {
+             // the code for japanese zero
+             BigInteger b1 = new BigInteger("\uff10");
+             System.err.println(b1.toString());
+
+             // Japanese 1010
+             BigInteger b2 = new BigInteger("\uff11\uff10\uff11\uff10");
+             System.err.println(b2.toString());
+          }
+          catch (ArrayIndexOutOfBoundsException e) {
+              throw new RuntimeException(
+                       "BigInteger is not accepting unicode initializers.");
+          }
+
+     }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/math/RoundingMode/RoundingModeTests.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2003 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4851776 4891522 4905335
+ * @summary Basic tests for the RoundingMode class.
+ * @author Joseph D. Darcy
+ * @compile -source 1.5 RoundingModeTests.java
+ * @run main RoundingModeTests
+ */
+
+import java.math.RoundingMode;
+import java.math.BigDecimal;
+
+public class RoundingModeTests {
+    public static void main(String [] argv) {
+
+        // For each member of the family, make sure
+        // rm == valueOf(rm.toString())
+
+        for(RoundingMode rm: RoundingMode.values()) {
+            if (rm != RoundingMode.valueOf(rm.toString())) {
+                throw new RuntimeException("Bad roundtrip conversion of " +
+                                           rm.toString());
+            }
+        }
+
+        // Test that mapping of old integers to new values is correct
+        if (RoundingMode.valueOf(BigDecimal.ROUND_CEILING) !=
+                RoundingMode.CEILING) {
+                throw new RuntimeException("Bad mapping for ROUND_CEILING");
+        }
+
+        if (RoundingMode.valueOf(BigDecimal.ROUND_DOWN) !=
+                RoundingMode.DOWN) {
+                throw new RuntimeException("Bad mapping for ROUND_DOWN");
+        }
+
+        if (RoundingMode.valueOf(BigDecimal.ROUND_FLOOR) !=
+                RoundingMode.FLOOR) {
+                throw new RuntimeException("Bad mapping for ROUND_FLOOR");
+        }
+
+        if (RoundingMode.valueOf(BigDecimal.ROUND_HALF_DOWN) !=
+                RoundingMode.HALF_DOWN) {
+                throw new RuntimeException("Bad mapping for ROUND_HALF_DOWN");
+        }
+
+        if (RoundingMode.valueOf(BigDecimal.ROUND_HALF_EVEN) !=
+                RoundingMode.HALF_EVEN) {
+                throw new RuntimeException("Bad mapping for ROUND_HALF_EVEN");
+        }
+
+        if (RoundingMode.valueOf(BigDecimal.ROUND_HALF_UP) !=
+                RoundingMode.HALF_UP) {
+                throw new RuntimeException("Bad mapping for ROUND_HALF_UP");
+        }
+
+        if (RoundingMode.valueOf(BigDecimal.ROUND_UNNECESSARY) !=
+                RoundingMode.UNNECESSARY) {
+                throw new RuntimeException("Bad mapping for ROUND_UNNECESARY");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/text/Bidi/BidiBug.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4827312
+ * @summary verify that argument validity check is not fooled by overflow
+ */
+public class BidiBug {
+  public static void main(String[] args) {
+    try {
+        byte buff[] = new byte[3000];
+        java.text.Bidi bidi = new java.text.Bidi(new char[20],10,buff,Integer.MAX_VALUE-3,4,1);
+    }
+    catch (IllegalArgumentException e) {
+        System.out.println(e);
+        return; // success
+    }
+    throw new RuntimeException("didn't throw error, though we didn't crash either");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/text/Bidi/BidiEmbeddingTest.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4396492 4396496 4778510
+ * @summary verify that the embedding values processed by the bidi code use negative values to
+ * indicate overrides, rather than using bit 7.  Also tests Bidi without loading awt classes to
+ * confirm that Bidi can be used without awt. Verify that embedding level 0 is properly mapped
+ * to the base embedding level.
+ */
+
+import java.awt.Color;
+import java.awt.Frame;
+import java.awt.font.TextAttribute;
+import java.text.AttributedString;
+import java.text.Bidi;
+
+public class BidiEmbeddingTest {
+    public static void main(String[] args) {
+        // to regress embedding test against old fix, call with an arg.  A window will pop
+        // up causing awt lib to be loaded so the vm won't die with the unsatisfied link error.
+        if (args.length > 0) {
+            Frame f = new Frame();
+            f.setSize(300, 300);
+            f.setBackground(Color.white);
+            f.show();
+        }
+
+        test1();
+        test2();
+    }
+
+    static void test1() {
+        String target = "BACK WARDS";
+        String str = "If this text is >" + target + "< the test passed.";
+        int start = str.indexOf(target);
+        int limit = start + target.length();
+
+        System.out.println("start: " + start + " limit: " + limit);
+
+        AttributedString astr = new AttributedString(str);
+        astr.addAttribute(TextAttribute.BIDI_EMBEDDING,
+                         new Integer(-1),
+                         start,
+                         limit);
+
+        Bidi bidi = new Bidi(astr.getIterator());
+
+        for (int i = 0; i < bidi.getRunCount(); ++i) {
+            System.out.println("run " + i +
+                               " from " + bidi.getRunStart(i) +
+                               " to " + bidi.getRunLimit(i) +
+                               " at level " + bidi.getRunLevel(i));
+        }
+
+        System.out.println(bidi);
+
+        byte[] embs = new byte[str.length() + 3];
+        for (int i = start + 1; i < limit + 1; ++i) {
+            embs[i] = -1;
+        }
+
+        Bidi bidi2 = new Bidi(str.toCharArray(), 0, embs, 1, str.length(), Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+        for (int i = 0; i < bidi2.getRunCount(); ++i) {
+            System.out.println("run " + i +
+                               " from " + bidi2.getRunStart(i) +
+                               " to " + bidi2.getRunLimit(i) +
+                               " at level " + bidi2.getRunLevel(i));
+        }
+
+        System.out.println(bidi2);
+
+        if (bidi.getRunCount() != 3 || bidi2.getRunCount() != 3) {
+            throw new Error("Bidi run count incorrect");
+        }
+    }
+
+    // make sure BIDI_EMBEDDING values of 0 are mapped to base run direction, instead of flagging an error.
+    static void test2() {
+        String target = "BACK WARDS";
+        String str = "If this text is >" + target + "< the test passed.";
+        int length = str.length();
+        int start = str.indexOf(target);
+        int limit = start + target.length();
+
+        System.out.println("start: " + start + " limit: " + limit);
+
+        AttributedString astr = new AttributedString(str);
+        astr.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_RTL);
+
+        astr.addAttribute(TextAttribute.BIDI_EMBEDDING,
+                         new Integer(-3),
+                         start,
+                         limit);
+
+        Bidi bidi = new Bidi(astr.getIterator());
+
+        for (int i = 0; i < bidi.getRunCount(); ++i) {
+            System.out.println("run " + i +
+                               " from " + bidi.getRunStart(i) +
+                               " to " + bidi.getRunLimit(i) +
+                               " at level " + bidi.getRunLevel(i));
+        }
+
+        System.out.println(bidi);
+
+        if (bidi.getRunCount() != 6) { // runs of spaces and angles at embedding bound,s and final period, each get level 1
+            throw new Error("Bidi embedding processing failed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/text/Bidi/BidiSurrogateTest.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4888843
+ * @summary verify that surrogate pairs representing codepoints with R or AL directionality
+ * and correctly recognized and reordered.
+ */
+
+import java.text.Bidi;
+
+public class BidiSurrogateTest {
+    private static final String RTLS = new String(Character.toChars(0x10800)); // surrogate code point with R directionality
+    private static final String LTRS = new String(Character.toChars(0x107ff)); // surrogate code point with L directionality
+    private static final String LRE = "\u202a";
+    private static final String RLE = "\u202b";
+    private static final String PDF = "\u202c";
+
+
+    public static void main(String[] args) {
+        new BidiSurrogateTest().test();
+    }
+
+    void test() {
+        test0();
+        test1();
+    }
+
+    void test0() {
+        // test unpaired surrogates - should have L directionality
+        testRequiresBidi("\ud800", false);           // unpaired lead surrogate
+        testRequiresBidi("\udc00", false);           // unpaired trail surrogate
+        testRequiresBidi("\udc00\ud800", false);     // out of order surrogates
+        testRequiresBidi("a\udc00b\ud800c", false);  // out of order surrogates split
+        testRequiresBidi(LTRS, false);               // supplementary with L
+        testRequiresBidi(RTLS, true);                // supplementary with R
+        testRequiresBidi("a" + RTLS + "b", true);    // R supplementary in LTR text
+        testRequiresBidi(LTRS + RTLS, true);         // R supplementary in LTR supplementary text
+        testRequiresBidi(LRE, false);                // LRE lone embedding
+        testRequiresBidi(RLE, true);                 // RLE lone embedding
+        testRequiresBidi(PDF, false);                // PDF lone pop embedding
+    }
+
+    void testRequiresBidi(String string, boolean requiresBidi) {
+        char[] text = string.toCharArray();
+        if (Bidi.requiresBidi(text, 0, text.length) != requiresBidi) {
+            throw new RuntimeException("testRequiresBidi failed with '" + string + "', " + requiresBidi);
+        }
+    }
+
+    void test1() {
+        // test that strings with surrogate runs process surrogate directionality ok
+        testBidi("This is a string with " + LTRS + " in it.", false);
+        testBidi("This is a string with \ud800 in it.", false);
+        testBidi("This is a string with \u0640 in it.", 22, 1);
+        testBidi(RTLS, true);
+        testBidi("This is a string with " + RTLS + RTLS + RTLS + " in it.", 22, 6);
+    }
+
+    void testBidi(String string, boolean directionIsRTL) {
+        Bidi bidi = new Bidi(string, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+        if (bidi.isMixed()) {
+            throw new RuntimeException("bidi is mixed");
+        }
+        if (bidi.isRightToLeft() != directionIsRTL) {
+            throw new RuntimeException("bidi is not " + (directionIsRTL ? "rtl" : "ltr"));
+        }
+    }
+
+    void testBidi(String string, int rtlstart, int rtllength) {
+        Bidi bidi = new Bidi(string, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+        for (int i = 0; i < bidi.getRunCount(); ++i) {
+            if ((bidi.getRunLevel(i) & 1) != 0) {
+                if (bidi.getRunStart(i) != rtlstart ||
+                    bidi.getRunLimit(i) != rtlstart + rtllength) {
+                    throw new RuntimeException("first rtl run didn't match " + rtlstart + ", " + rtllength);
+                }
+                break;
+            }
+        }
+    }
+}
--- a/jdk/test/java/text/Format/DateFormat/Bug4823811.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/text/Format/DateFormat/Bug4823811.java	Wed Jul 05 16:46:22 2017 +0200
@@ -25,6 +25,7 @@
  * @test
  * @bug 4823811
  * @summary Confirm that text which includes numbers with a trailing minus sign is parsed correctly.
+ * @run main/othervm -Duser.timezone=GMT+09:00 Bug4823811
  */
 
 import java.text.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/text/Format/DateFormat/Bug6683975.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6683975
+ * @summary Make sure that date is formatted correctlyin th locale.
+ */
+import java.text.*;
+import java.util.*;
+
+public class Bug6683975 {
+
+    private static boolean err = false;
+
+    private static Locale th = new Locale("th", "");
+    private static Locale th_TH = new Locale("th", "TH");
+    private static String expected_th[] = {
+        "\u0e27\u0e31\u0e19\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23\u0e17\u0e35\u0e48 30 \u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19 \u0e04.\u0e28. 2008, 8 \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 0 \u0e19\u0e32\u0e17\u0e35 00 \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35",  // 0: FULL
+        "30 \u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19 2008, 8 \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 0 \u0e19\u0e32\u0e17\u0e35",  // 1: LONG
+        "30 \u0e01.\u0e22. 2008, 8:00:00",  // 2: MEDIUM
+        "30/9/2008, 8:00 \u0e19.",  // 3: SHORT
+    };
+    private static String expected_th_TH[] = {
+        "\u0e27\u0e31\u0e19\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23\u0e17\u0e35\u0e48 30 \u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19 \u0e1e.\u0e28. 2551, 8 \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 0 \u0e19\u0e32\u0e17\u0e35 00 \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35",  // 0: FULL
+        "30 \u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19 2551, 8 \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 0 \u0e19\u0e32\u0e17\u0e35",  // 1: LONG
+        "30 \u0e01.\u0e22. 2551, 8:00:00",  // 2: MEDIUM
+        "30/9/2551, 8:00 \u0e19."  // 3: SHORT
+    };
+    private static String stylePattern[] =  {
+        "FULL", "LONG", "MEDIUM", "SHORT"
+    };
+
+    private static void test(int style) {
+        DateFormat df_th = DateFormat.getDateTimeInstance(style, style, th);
+        DateFormat df_th_TH = DateFormat.getDateTimeInstance(style, style, th_TH);
+
+        String str_th = ((SimpleDateFormat)df_th).toPattern();
+        String str_th_TH = ((SimpleDateFormat)df_th_TH).toPattern();
+        if (!str_th.equals(str_th_TH)) {
+            err = true;
+            System.err.println("Error: Pattern for th locale should be the same as pattern for th_TH locale. (" + stylePattern[style] + ")");
+            System.err.println("\tth: " + str_th);
+            System.err.println("\tth_TH: " + str_th_TH);
+        }
+
+        Date date = new Date(2008-1900, Calendar.SEPTEMBER, 30, 8, 0, 0);
+        str_th = df_th.format(date);
+        if (!expected_th[style].equals(str_th)) {
+            err = true;
+            System.err.println("Error: Formatted date in th locale is incorrect in " +  stylePattern[style] + " pattern.");
+            System.err.println("\tExpected: " + expected_th[style]);
+            System.err.println("\tGot: " + str_th);
+        }
+
+        str_th_TH = df_th_TH.format(date);
+        if (!expected_th_TH[style].equals(str_th_TH)) {
+            err = true;
+            System.err.println("Error: Formatted date in th_TH locale is incorrect in " +  stylePattern[style] + " pattern.");
+            System.err.println("\tExpected: " + expected_th_TH[style]);
+            System.err.println("\tGot: " + str_th_TH);
+        }
+    }
+
+    public static void main(String[] args) {
+        TimeZone timezone = TimeZone.getDefault();
+        Locale locale = Locale.getDefault();
+
+        TimeZone.setDefault(TimeZone.getTimeZone("US/Pacific"));
+        Locale.setDefault(Locale.US);
+
+        try {
+            test(DateFormat.FULL);
+            test(DateFormat.LONG);
+            test(DateFormat.MEDIUM);
+            test(DateFormat.SHORT);
+        }
+        catch (Exception e) {
+            err = true;
+            System.err.println("Unexpected exception was thrown: " + e);
+        }
+        finally {
+            TimeZone.setDefault(timezone);
+            Locale.setDefault(locale);
+
+            if (err) {
+                throw new RuntimeException("Failed.");
+            } else {
+                System.out.println("Passed.");
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Calendar/Bug6645263.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+/*
+ * @test
+ * @bug 6645263
+ * @summary Test field normalization in non-lenient from the partially normalized state
+ */
+
+import java.util.*;
+
+public class Bug6645263 {
+    public static void main(String[] args) {
+        Calendar cal = new GregorianCalendar(Locale.US);
+        cal.setLenient(false);
+        cal.set(Calendar.YEAR, 2007);
+        cal.set(Calendar.MONTH, Calendar.NOVEMBER);
+        cal.set(Calendar.WEEK_OF_MONTH, 4);
+        cal.set(Calendar.DAY_OF_WEEK, 1);
+        // Let cal calculate the time from the given fields
+        cal.getTime();
+
+        // Change DAY_OF_MONTH
+        cal.set(Calendar.DAY_OF_MONTH, 1);
+        // The following line shouldn't throw an IllegalArgumentException.
+        cal.getTime();
+   }
+}
--- a/jdk/test/java/util/Currency/ValidateISO4217.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Currency/ValidateISO4217.java	Wed Jul 05 16:46:22 2017 +0200
@@ -22,7 +22,7 @@
  */
 /*
  * @test
- * @bug 4691089 4819436 4942982 5104960 6544471
+ * @bug 4691089 4819436 4942982 5104960 6544471 6627549
  * @summary Validate ISO 4217 data for Currency class.
  */
 
@@ -86,6 +86,8 @@
         {"JE", "GBP", "826", "2"},      // Jersey
         {"GG", "GBP", "826", "2"},      // Guernsey
         {"IM", "GBP", "826", "2"},      // Isle of Man
+        {"BL", "EUR", "978", "2"},      // Saint Barthelemy
+        {"MF", "EUR", "978", "2"},      // Saint Martin
     };
 
     /* Codes that are obsolete, do not have related country */
--- a/jdk/test/java/util/Formatter/Basic-X.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/Basic-X.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1054,6 +1054,52 @@
         test("%4.1f", " 1.0", val);
         test("%4.2f", "0.99", val);
         test("%4.3f", "0.990", val);
+
+        // #6476425
+        val = new BigDecimal("0.00001");
+        test("%.0f", "0", val);
+        test("%.1f", "0.0", val);
+        test("%.2f", "0.00", val);
+        test("%.3f", "0.000", val);
+        test("%.4f", "0.0000", val);
+        test("%.5f", "0.00001", val);
+
+        val = new BigDecimal("1.00001");
+        test("%.0f", "1", val);
+        test("%.1f", "1.0", val);
+        test("%.2f", "1.00", val);
+        test("%.3f", "1.000", val);
+        test("%.4f", "1.0000", val);
+        test("%.5f", "1.00001", val);
+
+        val = new BigDecimal("1.23456");
+        test("%.0f", "1", val);
+        test("%.1f", "1.2", val);
+        test("%.2f", "1.23", val);
+        test("%.3f", "1.235", val);
+        test("%.4f", "1.2346", val);
+        test("%.5f", "1.23456", val);
+        test("%.6f", "1.234560", val);
+
+        val = new BigDecimal("9.99999");
+        test("%.0f", "10", val);
+        test("%.1f", "10.0", val);
+        test("%.2f", "10.00", val);
+        test("%.3f", "10.000", val);
+        test("%.4f", "10.0000", val);
+        test("%.5f", "9.99999", val);
+        test("%.6f", "9.999990", val);
+
+
+        val = new BigDecimal("1.99999");
+        test("%.0f", "2", val);
+        test("%.1f", "2.0", val);
+        test("%.2f", "2.00", val);
+        test("%.3f", "2.000", val);
+        test("%.4f", "2.0000", val);
+        test("%.5f", "1.99999", val);
+        test("%.6f", "1.999990", val);
+
 #end[BigDecimal]
 
 #if[float]
--- a/jdk/test/java/util/Formatter/Basic.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/Basic.java	Wed Jul 05 16:46:22 2017 +0200
@@ -25,7 +25,7 @@
  * @summary Unit test for formatter
  * @bug 4906370 4962433 4973103 4989961 5005818 5031150 4970931 4989491 5002937
  *      5005104 5007745 5061412 5055180 5066788 5088703 6317248 6318369 6320122
- *      6344623 6369500 6534606 6282094 6286592
+ *      6344623 6369500 6534606 6282094 6286592 6476425
  *
  * @run shell/timeout=240 Basic.sh
  */
--- a/jdk/test/java/util/Formatter/BasicBigDecimal.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicBigDecimal.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1055,6 +1055,52 @@
         test("%4.2f", "0.99", val);
         test("%4.3f", "0.990", val);
 
+        // #6476425
+        val = new BigDecimal("0.00001");
+        test("%.0f", "0", val);
+        test("%.1f", "0.0", val);
+        test("%.2f", "0.00", val);
+        test("%.3f", "0.000", val);
+        test("%.4f", "0.0000", val);
+        test("%.5f", "0.00001", val);
+
+        val = new BigDecimal("1.00001");
+        test("%.0f", "1", val);
+        test("%.1f", "1.0", val);
+        test("%.2f", "1.00", val);
+        test("%.3f", "1.000", val);
+        test("%.4f", "1.0000", val);
+        test("%.5f", "1.00001", val);
+
+        val = new BigDecimal("1.23456");
+        test("%.0f", "1", val);
+        test("%.1f", "1.2", val);
+        test("%.2f", "1.23", val);
+        test("%.3f", "1.235", val);
+        test("%.4f", "1.2346", val);
+        test("%.5f", "1.23456", val);
+        test("%.6f", "1.234560", val);
+
+        val = new BigDecimal("9.99999");
+        test("%.0f", "10", val);
+        test("%.1f", "10.0", val);
+        test("%.2f", "10.00", val);
+        test("%.3f", "10.000", val);
+        test("%.4f", "10.0000", val);
+        test("%.5f", "9.99999", val);
+        test("%.6f", "9.999990", val);
+
+
+        val = new BigDecimal("1.99999");
+        test("%.0f", "2", val);
+        test("%.1f", "2.0", val);
+        test("%.2f", "2.00", val);
+        test("%.3f", "2.000", val);
+        test("%.4f", "2.0000", val);
+        test("%.5f", "1.99999", val);
+        test("%.6f", "1.999990", val);
+
+
 
 
 
--- a/jdk/test/java/util/Formatter/BasicBigInteger.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicBigInteger.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicBoolean.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicBoolean.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicBooleanObject.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicBooleanObject.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicByte.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicByte.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicByteObject.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicByteObject.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicChar.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicChar.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicCharObject.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicCharObject.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicDateTime.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicDateTime.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicDouble.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicDouble.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1074,6 +1074,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %f - float, double, Double, BigDecimal
         //---------------------------------------------------------------------
--- a/jdk/test/java/util/Formatter/BasicDoubleObject.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicDoubleObject.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1074,6 +1074,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %f - float, double, Double, BigDecimal
         //---------------------------------------------------------------------
--- a/jdk/test/java/util/Formatter/BasicFloat.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicFloat.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1057,6 +1057,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %f - float
         //---------------------------------------------------------------------
--- a/jdk/test/java/util/Formatter/BasicFloatObject.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicFloatObject.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1090,6 +1090,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %g
         //
--- a/jdk/test/java/util/Formatter/BasicInt.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicIntObject.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicIntObject.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicLong.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicLong.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicLongObject.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicLongObject.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicShort.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicShort.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/BasicShortObject.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/BasicShortObject.java	Wed Jul 05 16:46:22 2017 +0200
@@ -1524,6 +1524,52 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         //---------------------------------------------------------------------
         // %t
         //
--- a/jdk/test/java/util/Formatter/genBasic.sh	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Formatter/genBasic.sh	Wed Jul 05 16:46:22 2017 +0200
@@ -23,14 +23,14 @@
 # have any questions.
 #
 
-SPP='sh ../../../../make/java/nio/spp.sh'
+javac -d . ../../../../make/tools/src/build/tools/spp/Spp.java
 
 gen() {
 #  if [ $3 = "true" ]
 #  then $SPP -K$1 -Dtype=$1 -DType=$2 -Kprim<Basic-X.java >Basic$2.java
 #  else $SPP -K$1 -Dtype=$1 -DType=$2 -K$3 <Basic-X.java >Basic$2.java
 #  fi
- $SPP -K$1 -Dtype=$1 -DType=$2 -K$3 -K$4 -K$5 -K$6 <Basic-X.java >Basic$2.java
+    java build.tools.spp.Spp -K$1 -Dtype=$1 -DType=$2 -K$3 -K$4 -K$5 -K$6 <Basic-X.java >Basic$2.java
 }
 
 gen boolean Boolean       prim  ""  ""   ""
@@ -54,3 +54,5 @@
 gen BigDecimal BigDecimal ""    fp  ""   ""
 
 gen Calendar DateTime     ""    ""  ""   datetime
+
+rm -rf build
--- a/jdk/test/java/util/Locale/LocaleTest.java	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Locale/LocaleTest.java	Wed Jul 05 16:46:22 2017 +0200
@@ -24,7 +24,7 @@
  * @test
  * @bug 4052404 4052440 4084688 4092475 4101316 4105828 4107014 4107953 4110613
  * 4118587 4118595 4122371 4126371 4126880 4135316 4135752 4139504 4139940 4143951
- * 4147315 4147317 4147552 4335196 4778440 5010672 6475525 6544471
+ * 4147315 4147317 4147552 4335196 4778440 5010672 6475525 6544471 6627549 6786276
  * @summary test Locales
  */
 /*
@@ -439,8 +439,8 @@
         String[] spotCheck2 = { "US", "CA", "GB", "FR", "DE", "IT", "JP", "KR", "CN", "TW", "TH" };
 
 
-        if (test.length != 245)
-            errln("Expected getISOCountries to return 245 countries; it returned " + test.length);
+        if (test.length != 246)
+            errln("Expected getISOCountries to return 246 countries; it returned " + test.length);
         else {
             for (int i = 0; i < spotCheck2.length; i++) {
                 int j;
--- a/jdk/test/java/util/Locale/data/deflocale.sol10	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/java/util/Locale/data/deflocale.sol10	Wed Jul 05 16:46:22 2017 +0200
@@ -1,7 +1,7 @@
                          Solaris 10 3/05 s10_74L2a SPARC
-           Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
-                        Use is subject to license terms.
-                            Assembled 22 January 2005
+
+                      (copyright from `uname -a` goes here)
+
 SunOS deltas4 5.10 Generic_118833-03 sun4u sparc SUNW,Sun-Blade-2500
 
 OS Locale:  C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/GetFormat.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test AudioFloatConverter getFormat method */
+
+import javax.sound.sampled.*;
+import com.sun.media.sound.*;
+
+public class GetFormat {
+
+    public static void main(String[] args) throws Exception {
+        AudioFormat frm = new AudioFormat(8000, 16, 1, true, false);
+        AudioFloatConverter conv = AudioFloatConverter.getConverter(frm);
+        if(!conv.getFormat().matches(frm))
+            throw new RuntimeException("Incorrect audio format returned.");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/ToFloatArray.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test AudioFloatConverter toFloatArray method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ToFloatArray {
+
+    public static void main(String[] args) throws Exception {
+        float[] testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+
+        // Check conversion using PCM_FLOAT
+        for (int big = 0; big < 2; big+=1)
+        for (int bits = 32; bits <= 64; bits+=32) {
+            AudioFormat frm = new AudioFormat(
+                    AudioFloatConverter.PCM_FLOAT,
+                    44100, bits, 1, bits/8,
+                    44100, big==1);
+            byte[] buff = new byte[testarray.length * frm.getFrameSize()];
+            float[] testarray2 = new float[testarray.length];
+            AudioFloatConverter conv = AudioFloatConverter.getConverter(frm);
+            conv.toByteArray(testarray, buff);
+            conv.toFloatArray(buff, testarray2);
+            for (int i = 0; i < testarray2.length; i++) {
+                if(Math.abs(testarray[i] - testarray2[i]) > 0.05)
+                    throw new RuntimeException("Conversion failed for " + frm  +" , arrays not equal enough!\n");
+            }
+        }
+
+        // Check conversion from float2byte and byte2float.
+        for (int big = 0; big < 2; big+=1)
+        for (int signed = 0; signed < 2; signed+=1)
+        for (int bits = 6; bits <= 40; bits+=2) {
+            AudioFormat frm = new AudioFormat(44100, bits, 1, signed==1, big==1);
+            byte[] buff = new byte[testarray.length * frm.getFrameSize()];
+            float[] testarray2 = new float[testarray.length];
+            AudioFloatConverter conv = AudioFloatConverter.getConverter(frm);
+            conv.toByteArray(testarray, buff);
+            conv.toFloatArray(buff, testarray2);
+            for (int i = 0; i < testarray2.length; i++) {
+                if(Math.abs(testarray[i] - testarray2[i]) > 0.05)
+                    throw new RuntimeException("Conversion failed for " + frm  +" , arrays not equal enough!\n");
+            }
+        }
+
+        // Check big/little
+        for (int big = 0; big < 2; big+=1)
+        for (int signed = 0; signed < 2; signed+=1)
+        for (int bits = 6; bits <= 40; bits+=2) {
+            AudioFormat frm = new AudioFormat(44100, bits, 1, signed==1, big==1);
+            byte[] buff = new byte[testarray.length * frm.getFrameSize()];
+            AudioFloatConverter conv = AudioFloatConverter.getConverter(frm);
+            conv.toByteArray(testarray, buff);
+            byte[] buff2 = new byte[testarray.length * frm.getFrameSize()];
+            int fs = frm.getFrameSize();
+            for (int i = 0; i < buff2.length; i+=fs) {
+                for (int j = 0; j < fs; j++) {
+                    buff2[i+(fs-j-1)] = buff[i+j];
+                }
+            }
+            float[] testarray2 = new float[testarray.length];
+            AudioFormat frm2 = new AudioFormat(44100, bits, 1, signed==1, big==0);
+            AudioFloatConverter.getConverter(frm2).toFloatArray(buff2, testarray2);
+            for (int i = 0; i < testarray2.length; i++) {
+                if(Math.abs(testarray[i] - testarray2[i]) > 0.05)
+                {
+                    throw new RuntimeException("Conversion failed for " + frm  +" to " + frm2 + " , arrays not equal enough!\n");
+                }
+            }
+        }
+
+        // Check signed/unsigned
+        for (int big = 0; big < 2; big+=1)
+        for (int signed = 0; signed < 2; signed+=1)
+        for (int bits = 6; bits <= 40; bits+=2) {
+            AudioFormat frm = new AudioFormat(44100, bits, 1, signed==1, big==1);
+            byte[] b = new byte[testarray.length * frm.getFrameSize()];
+            AudioFloatConverter conv = AudioFloatConverter.getConverter(frm);
+            conv.toByteArray(testarray, b);
+            int fs = frm.getFrameSize();
+            if(big==1)
+            {
+                for(int i=0; i < b.length; i+= fs )
+                    b[i] = (b[i] >= 0) ? (byte)(0x80 | b[i]) : (byte)(0x7F & b[i]);
+            }
+            else
+            {
+                for(int i=(0+fs-1); i < b.length; i+= fs )
+                    b[i] = (b[i] >= 0) ? (byte)(0x80 | b[i]) : (byte)(0x7F & b[i]);
+            }
+            float[] testarray2 = new float[testarray.length];
+            AudioFormat frm2 = new AudioFormat(44100, bits, 1, signed==0, big==1);
+            AudioFloatConverter.getConverter(frm2).toFloatArray(b, testarray2);
+            for (int i = 0; i < testarray2.length; i++) {
+                if(Math.abs(testarray[i] - testarray2[i]) > 0.05)
+                {
+                    throw new RuntimeException("Conversion failed for " + frm  +" to " + frm2 + " , arrays not equal enough!\n");
+                }
+            }
+        }
+
+        // Check if conversion 32->24, 24->16, 16->8 result in same float data
+        AudioFormat frm = new AudioFormat(44100, 40, 1, true, true);
+        byte[] b = new byte[testarray.length * frm.getFrameSize()];
+        AudioFloatConverter.getConverter(frm).toByteArray(testarray, b);
+        for (int bits = 6; bits <= 40; bits+=2) {
+            AudioFormat frm2 = new AudioFormat(44100, bits, 1, true, true);
+            byte[] b2 = new byte[testarray.length * frm2.getFrameSize()];
+            int fs1 = frm.getFrameSize();
+            int fs2 = frm2.getFrameSize();
+            int ii = 0;
+            for (int i = 0; i < b.length; i+=fs1)
+                for (int j = 0; j < fs2; j++)
+                    b2[ii++] = b[i+j];
+            float[] testarray2 = new float[testarray.length];
+            AudioFloatConverter.getConverter(frm2).toFloatArray(b2, testarray2);
+            for (int i = 0; i < testarray2.length; i++) {
+                if(Math.abs(testarray[i] - testarray2[i]) > 0.05)
+                {
+                    throw new RuntimeException("Conversion failed for " + frm  +" to " + frm2 + " , arrays not equal enough!\n");
+                }
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/Available.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test AudioFloatInputStream available method */
+
+import java.io.*;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Available {
+
+    static float[] test_float_array;
+    static byte[] test_byte_array;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static AudioFloatInputStream getStream1()
+    {
+        return AudioFloatInputStream.getInputStream(format, test_byte_array, 0, test_byte_array.length);
+    }
+
+    static AudioFloatInputStream getStream2()
+    {
+        AudioInputStream strm = new AudioInputStream(new ByteArrayInputStream(test_byte_array), format, 1024);
+        return AudioFloatInputStream.getInputStream(strm);
+    }
+
+    static void setUp() throws Exception {
+        test_float_array = new float[1024];
+        test_byte_array = new byte[1024*format.getFrameSize()];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            test_float_array[i] = (float)Math.sin(10*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            test_float_array[i] *= 0.3;
+        }
+        AudioFloatConverter.getConverter(format).toByteArray(test_float_array, test_byte_array);
+    }
+
+    public static void main(String[] args) throws Exception {
+        setUp();
+        for (int i = 0; i < 2; i++) {
+            AudioFloatInputStream stream = null;
+            if(i == 0) stream = getStream1();
+            if(i == 1) stream = getStream2();
+            float[] buff = new float[512];
+            if(stream.available() != 1024)
+                throw new RuntimeException("stream.available return incorrect value.");
+            stream.read(buff);
+            if(stream.available() != 512)
+                throw new RuntimeException("stream.available return incorrect value.");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/Close.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test AudioFloatInputStream close method */
+
+import java.io.*;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Close {
+
+    static float[] test_float_array;
+    static byte[] test_byte_array;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static AudioFloatInputStream getStream1()
+    {
+        return AudioFloatInputStream.getInputStream(format, test_byte_array, 0, test_byte_array.length);
+    }
+
+    static AudioFloatInputStream getStream2()
+    {
+        AudioInputStream strm = new AudioInputStream(new ByteArrayInputStream(test_byte_array), format, 1024);
+        return AudioFloatInputStream.getInputStream(strm);
+    }
+
+    static void setUp() throws Exception {
+        test_float_array = new float[1024];
+        test_byte_array = new byte[1024*format.getFrameSize()];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            test_float_array[i] = (float)Math.sin(10*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            test_float_array[i] *= 0.3;
+        }
+        AudioFloatConverter.getConverter(format).toByteArray(test_float_array, test_byte_array);
+    }
+
+    public static void main(String[] args) throws Exception {
+        setUp();
+        getStream1().close();
+        getStream2().close();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/GetFormat.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test AudioFloatInputStream getFormat method */
+
+import java.io.*;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetFormat {
+
+    static float[] test_float_array;
+    static byte[] test_byte_array;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static AudioFloatInputStream getStream1()
+    {
+        return AudioFloatInputStream.getInputStream(format, test_byte_array, 0, test_byte_array.length);
+    }
+
+    static AudioFloatInputStream getStream2()
+    {
+        AudioInputStream strm = new AudioInputStream(new ByteArrayInputStream(test_byte_array), format, 1024);
+        return AudioFloatInputStream.getInputStream(strm);
+    }
+
+    static void setUp() throws Exception {
+        test_float_array = new float[1024];
+        test_byte_array = new byte[1024*format.getFrameSize()];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            test_float_array[i] = (float)Math.sin(10*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            test_float_array[i] *= 0.3;
+        }
+        AudioFloatConverter.getConverter(format).toByteArray(test_float_array, test_byte_array);
+    }
+
+    public static void main(String[] args) throws Exception {
+        setUp();
+        if(!getStream1().getFormat().matches(format))
+            throw new RuntimeException("Incorrect audio format returned.");
+        if(!getStream2().getFormat().matches(format))
+            throw new RuntimeException("Incorrect audio format returned.");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/GetFrameLength.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test AudioFloatInputStream getFrameLength method */
+
+import java.io.*;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetFrameLength {
+
+    static float[] test_float_array;
+    static byte[] test_byte_array;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static AudioFloatInputStream getStream1()
+    {
+        return AudioFloatInputStream.getInputStream(format, test_byte_array, 0, test_byte_array.length);
+    }
+
+    static AudioFloatInputStream getStream2()
+    {
+        AudioInputStream strm = new AudioInputStream(new ByteArrayInputStream(test_byte_array), format, 1024);
+        return AudioFloatInputStream.getInputStream(strm);
+    }
+
+    static void setUp() throws Exception {
+        test_float_array = new float[1024];
+        test_byte_array = new byte[1024*format.getFrameSize()];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            test_float_array[i] = (float)Math.sin(10*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            test_float_array[i] *= 0.3;
+        }
+        AudioFloatConverter.getConverter(format).toByteArray(test_float_array, test_byte_array);
+    }
+
+    public static void main(String[] args) throws Exception {
+        setUp();
+        if(getStream1().getFrameLength() != 1024L)
+            throw new RuntimeException("Incorrect frame length returned.");
+        if(getStream2().getFrameLength() != 1024L)
+            throw new RuntimeException("Incorrect frame length returned.");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/MarkSupported.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test AudioFloatInputStream markSupported method */
+
+import java.io.*;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class MarkSupported {
+
+    static float[] test_float_array;
+    static byte[] test_byte_array;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static AudioFloatInputStream getStream1()
+    {
+        return AudioFloatInputStream.getInputStream(format, test_byte_array, 0, test_byte_array.length);
+    }
+
+    static AudioFloatInputStream getStream2()
+    {
+        AudioInputStream strm = new AudioInputStream(new ByteArrayInputStream(test_byte_array), format, 1024);
+        return AudioFloatInputStream.getInputStream(strm);
+    }
+
+    static void setUp() throws Exception {
+        test_float_array = new float[1024];
+        test_byte_array = new byte[1024*format.getFrameSize()];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            test_float_array[i] = (float)Math.sin(10*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            test_float_array[i] *= 0.3;
+        }
+        AudioFloatConverter.getConverter(format).toByteArray(test_float_array, test_byte_array);
+    }
+
+    public static void main(String[] args) throws Exception {
+        setUp();
+        if(!getStream1().markSupported())
+            throw new RuntimeException("Mark not supported.");
+        if(!getStream2().markSupported())
+            throw new RuntimeException("Mark not supported.");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/Read.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test AudioFloatInputStream read method */
+
+import java.io.*;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Read {
+
+    static float[] test_float_array;
+    static byte[] test_byte_array;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static AudioFloatInputStream getStream1()
+    {
+        return AudioFloatInputStream.getInputStream(format, test_byte_array, 0, test_byte_array.length);
+    }
+
+    static AudioFloatInputStream getStream2()
+    {
+        AudioInputStream strm = new AudioInputStream(new ByteArrayInputStream(test_byte_array), format, 1024);
+        return AudioFloatInputStream.getInputStream(strm);
+    }
+
+    static void setUp() throws Exception {
+        test_float_array = new float[1024];
+        test_byte_array = new byte[1024*format.getFrameSize()];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            test_float_array[i] = (float)Math.sin(10*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            test_float_array[i] *= 0.3;
+        }
+        AudioFloatConverter.getConverter(format).toByteArray(test_float_array, test_byte_array);
+    }
+
+    public static void main(String[] args) throws Exception {
+        setUp();
+
+        for (int i = 0; i < 2; i++) {
+            AudioFloatInputStream stream = null;
+            if(i == 0) stream = getStream1();
+            if(i == 1) stream = getStream2();
+            float v = 0;
+            stream.skip(512);
+            v = stream.read();
+            if(!(Math.abs(v - test_float_array[512]) < 0.0001))
+            {
+                throw new RuntimeException("Read returned unexpected value.");
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/ReadFloatArray.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test AudioFloatInputStream read(float[]) method */
+
+import java.io.*;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadFloatArray {
+
+    static float[] test_float_array;
+    static byte[] test_byte_array;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static AudioFloatInputStream getStream1()
+    {
+        return AudioFloatInputStream.getInputStream(format, test_byte_array, 0, test_byte_array.length);
+    }
+
+    static AudioFloatInputStream getStream2()
+    {
+        AudioInputStream strm = new AudioInputStream(new ByteArrayInputStream(test_byte_array), format, 1024);
+        return AudioFloatInputStream.getInputStream(strm);
+    }
+
+    static void setUp() throws Exception {
+        test_float_array = new float[1024];
+        test_byte_array = new byte[1024*format.getFrameSize()];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            test_float_array[i] = (float)Math.sin(10*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            test_float_array[i] *= 0.3;
+        }
+        AudioFloatConverter.getConverter(format).toByteArray(test_float_array, test_byte_array);
+    }
+
+    public static void main(String[] args) throws Exception {
+        setUp();
+
+        for (int i = 0; i < 2; i++) {
+            AudioFloatInputStream stream = null;
+            if(i == 0) stream = getStream1();
+            if(i == 1) stream = getStream2();
+            float[] buff = new float[1024];
+            stream.read(buff);
+            for (int j = 0; j < buff.length; j++)
+                if(!(Math.abs(buff[j] - test_float_array[j]) < 0.0001))
+                    throw new RuntimeException("Incorrect data in buffer.");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/ReadFloatArrayIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test AudioFloatInputStream read(float[], int, int) method */
+
+import java.io.*;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadFloatArrayIntInt {
+
+    static float[] test_float_array;
+    static byte[] test_byte_array;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static AudioFloatInputStream getStream1()
+    {
+        return AudioFloatInputStream.getInputStream(format, test_byte_array, 0, test_byte_array.length);
+    }
+
+    static AudioFloatInputStream getStream2()
+    {
+        AudioInputStream strm = new AudioInputStream(new ByteArrayInputStream(test_byte_array), format, 1024);
+        return AudioFloatInputStream.getInputStream(strm);
+    }
+
+    static void setUp() throws Exception {
+        test_float_array = new float[1024];
+        test_byte_array = new byte[1024*format.getFrameSize()];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            test_float_array[i] = (float)Math.sin(10*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            test_float_array[i] *= 0.3;
+        }
+        AudioFloatConverter.getConverter(format).toByteArray(test_float_array, test_byte_array);
+    }
+
+    public static void main(String[] args) throws Exception {
+        setUp();
+
+        for (int i = 0; i < 2; i++) {
+            AudioFloatInputStream stream = null;
+            if(i == 0) stream = getStream1();
+            if(i == 1) stream = getStream2();
+            float[] buff = new float[1024];
+            stream.read(buff,0,512);
+            stream.read(buff,512,512);
+            for (int j = 0; j < buff.length; j++)
+                if(!(Math.abs(buff[j] - test_float_array[j]) < 0.0001))
+                    throw new RuntimeException("Incorrect data in buffer.");
+
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/Reset.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test AudioFloatInputStream reset method */
+
+import java.io.*;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Reset {
+
+    static float[] test_float_array;
+    static byte[] test_byte_array;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static AudioFloatInputStream getStream1()
+    {
+        return AudioFloatInputStream.getInputStream(format, test_byte_array, 0, test_byte_array.length);
+    }
+
+    static AudioFloatInputStream getStream2()
+    {
+        AudioInputStream strm = new AudioInputStream(new ByteArrayInputStream(test_byte_array), format, 1024);
+        return AudioFloatInputStream.getInputStream(strm);
+    }
+
+    static void setUp() throws Exception {
+        test_float_array = new float[1024];
+        test_byte_array = new byte[1024*format.getFrameSize()];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            test_float_array[i] = (float)Math.sin(10*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            test_float_array[i] *= 0.3;
+        }
+        AudioFloatConverter.getConverter(format).toByteArray(test_float_array, test_byte_array);
+    }
+
+    public static void main(String[] args) throws Exception {
+        setUp();
+
+        for (int i = 0; i < 2; i++) {
+            AudioFloatInputStream stream = null;
+            if(i == 0) stream = getStream1();
+            if(i == 1) stream = getStream2();
+            float[] buff = new float[512];
+            float[] buff2 = new float[512];
+            stream.read(buff);
+            stream.mark(512);
+            stream.read(buff);
+            stream.reset();
+            stream.read(buff2);
+            for (int j = 0; j < buff2.length; j++)
+                if(!(Math.abs(buff[j] - buff2[j]) < 0.0001))
+                    throw new RuntimeException("Incorrect data in buffer.");
+
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatInputStream/Skip.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test AudioFloatInputStream skip method */
+
+import java.io.*;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Skip {
+
+    static float[] test_float_array;
+    static byte[] test_byte_array;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static AudioFloatInputStream getStream1()
+    {
+        return AudioFloatInputStream.getInputStream(format, test_byte_array, 0, test_byte_array.length);
+    }
+
+    static AudioFloatInputStream getStream2()
+    {
+        AudioInputStream strm = new AudioInputStream(new ByteArrayInputStream(test_byte_array), format, 1024);
+        return AudioFloatInputStream.getInputStream(strm);
+    }
+
+    static void setUp() throws Exception {
+        test_float_array = new float[1024];
+        test_byte_array = new byte[1024*format.getFrameSize()];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            test_float_array[i] = (float)Math.sin(10*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            test_float_array[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            test_float_array[i] *= 0.3;
+        }
+        AudioFloatConverter.getConverter(format).toByteArray(test_float_array, test_byte_array);
+    }
+
+    public static void main(String[] args) throws Exception {
+        setUp();
+
+        for (int i = 0; i < 2; i++) {
+            AudioFloatInputStream stream = null;
+            if(i == 0) stream = getStream1();
+            if(i == 1) stream = getStream2();
+            float[] buff = new float[512];
+            stream.skip(512);
+            stream.read(buff);
+            for (int j = 0; j < buff.length; j++)
+                if(!(Math.abs(buff[j] - test_float_array[j+512]) < 0.0001))
+                    throw new RuntimeException("Incorrect data in buffer.");
+
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/DLSSoundbankReader/TestGetSoundbankFile.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test DLSSoundbankReader getSoundbank(File) method */
+
+import java.io.File;
+
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+
+import com.sun.media.sound.DLSSoundbankReader;
+
+public class TestGetSoundbankFile {
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        File file = new File(System.getProperty("test.src", "."), "ding.dls");
+        Soundbank dls = new DLSSoundbankReader().getSoundbank(file);
+        assertTrue(dls.getInstruments().length == 1);
+        Patch patch = dls.getInstruments()[0].getPatch();
+        assertTrue(patch.getProgram() == 0);
+        assertTrue(patch.getBank() == 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/DLSSoundbankReader/TestGetSoundbankInputStream.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test DLSSoundbankReader getSoundbank(InputStream) method */
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+
+import com.sun.media.sound.DLSSoundbankReader;
+
+public class TestGetSoundbankInputStream {
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        File file = new File(System.getProperty("test.src", "."), "ding.dls");
+        FileInputStream fis = new FileInputStream(file);
+        BufferedInputStream bis = new BufferedInputStream(fis);
+        try
+        {
+            Soundbank dls = new DLSSoundbankReader().getSoundbank(bis);
+            assertTrue(dls.getInstruments().length == 1);
+            Patch patch = dls.getInstruments()[0].getPatch();
+            assertTrue(patch.getProgram() == 0);
+            assertTrue(patch.getBank() == 0);
+        }
+        finally
+        {
+            bis.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/DLSSoundbankReader/TestGetSoundbankInputStream2.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test DLSSoundbankReader getSoundbank(InputStream) method using
+     very bad InputStream which can only read 1 byte at time */
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+
+import com.sun.media.sound.DLSSoundbankReader;
+
+public class TestGetSoundbankInputStream2 {
+
+    private static class BadInputStream extends InputStream
+    {
+
+        InputStream is;
+
+        public BadInputStream(InputStream is)
+        {
+            this.is = is;
+        }
+
+        public int read() throws IOException {
+            return is.read();
+        }
+
+        public int read(byte[] b, int off, int len) throws IOException {
+            if(len > 1) len = 1;
+            return is.read(b, off, len);
+        }
+
+        public int read(byte[] b) throws IOException {
+            return read(b, 0, b.length);
+        }
+
+        public long skip(long n) throws IOException {
+            if(n > 1) n = 1;
+            return is.skip(n);
+        }
+
+        public int available() throws IOException {
+            int avail = is.available();
+            if(avail > 1) avail = 1;
+            return avail;
+        }
+
+        public void close() throws IOException {
+            is.close();
+        }
+
+        public synchronized void mark(int readlimit) {
+            is.mark(readlimit);
+        }
+
+        public boolean markSupported() {
+            return is.markSupported();
+        }
+
+        public synchronized void reset() throws IOException {
+            is.reset();
+        }
+
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        File file = new File(System.getProperty("test.src", "."), "ding.dls");
+        FileInputStream fis = new FileInputStream(file);
+        BufferedInputStream bis = new BufferedInputStream(fis);
+        try
+        {
+            InputStream badis = new BadInputStream(bis);
+            Soundbank dls = new DLSSoundbankReader().getSoundbank(badis);
+            assertTrue(dls.getInstruments().length == 1);
+            Patch patch = dls.getInstruments()[0].getPatch();
+            assertTrue(patch.getProgram() == 0);
+            assertTrue(patch.getBank() == 0);
+        }
+        finally
+        {
+            bis.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/DLSSoundbankReader/TestGetSoundbankUrl.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test DLSSoundbankReader getSoundbank(File) method */
+
+import java.io.File;
+import java.net.URL;
+
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+
+import com.sun.media.sound.DLSSoundbankReader;
+
+public class TestGetSoundbankUrl {
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        File file = new File(System.getProperty("test.src", "."), "ding.dls");
+        URL url = file.toURI().toURL();
+        Soundbank dls = new DLSSoundbankReader().getSoundbank(url);
+        assertTrue(dls.getInstruments().length == 1);
+        Patch patch = dls.getInstruments()[0].getPatch();
+        assertTrue(patch.getProgram() == 0);
+        assertTrue(patch.getBank() == 0);
+    }
+}
Binary file jdk/test/javax/sound/midi/Gervill/DLSSoundbankReader/ding.dls has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/EmergencySoundbank/TestCreateSoundbank.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test EmergencySoundbank createSoundbank() method */
+
+import java.io.File;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+
+import com.sun.media.sound.EmergencySoundbank;
+import com.sun.media.sound.ModelInstrument;
+import com.sun.media.sound.ModelPatch;
+
+public class TestCreateSoundbank {
+
+    public static void main(String[] args) throws Exception {
+
+        Soundbank soundbank = EmergencySoundbank.createSoundbank();
+        for (int i = 0; i < 128; i++) {
+            Patch patch = new ModelPatch(0, i, false);
+            ModelInstrument ins = (ModelInstrument)soundbank.getInstrument(patch);
+            if(ins == null)
+                throw new Exception("Instrument " + i + " is missing!");
+            if(ins.getPerformers().length == 0)
+                throw new Exception("Instrument " + i + " doesn't have any performers!");
+        }
+        Patch patch = new ModelPatch(0, 0, true);
+        ModelInstrument ins = (ModelInstrument)soundbank.getInstrument(patch);
+        if(ins == null)
+            throw new Exception("Drumkit instrument is missing!");
+        if(ins.getPerformers().length == 0)
+            throw new Exception("Drumkit instrument doesn't have any performers!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/GetInputStream.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer getInputStream method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetInputStream {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 2; i++) {
+                ModelByteBuffer buff;
+                if(i == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+
+                byte[] b = new byte[test_byte_array.length];
+                buff.getInputStream().read(b);
+                for (int j = 0; j < b.length; j++)
+                    if(b[i] != test_byte_array[i])
+                         throw new RuntimeException("Byte array compare fails!");
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/GetRoot.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer getRoot method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetRoot {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            ModelByteBuffer buff = new ModelByteBuffer(test_file);
+            ModelByteBuffer buff2 = buff.subbuffer(10, 10);
+            ModelByteBuffer buff3 = buff2.subbuffer(2, 2);
+            if(buff != buff3.getRoot())
+                throw new RuntimeException("ModelByteBuffer doesn't return correct root!");
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/Load.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer load method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Load {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            ModelByteBuffer buff = new ModelByteBuffer(test_file);
+
+            buff.load();
+            if(buff.array() == null)
+                throw new RuntimeException("buf is null!");
+            if(buff.array().length != test_byte_array.length)
+                throw new RuntimeException("buff.array().length length is incorrect!");
+            byte[] b = buff.array();
+            for (int i = 0; i < b.length; i++)
+                if(test_byte_array[i] != b[i])
+                    throw new RuntimeException("buff.array() incorrect!");
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/LoadAll.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer loadAll method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class LoadAll {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            ModelByteBuffer buff = new ModelByteBuffer(test_file);
+            List<ModelByteBuffer> col = new ArrayList<ModelByteBuffer>();
+            col.add(buff);
+            ModelByteBuffer.loadAll(col);
+            if(buff.array() == null)
+                throw new RuntimeException("buf is null!");
+            if(buff.array().length != test_byte_array.length)
+                throw new RuntimeException("buff.array().length length is incorrect!");
+            byte[] b = buff.array();
+            for (int i = 0; i < b.length; i++)
+                if(test_byte_array[i] != b[i])
+                    throw new RuntimeException("buff.array() incorrect!");
+
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/NewModelByteBufferByteArray.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer(byte[]) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelByteBufferByteArray {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            ModelByteBuffer buff = new ModelByteBuffer(test_byte_array);
+            if(buff.array() != test_byte_array)
+                throw new RuntimeException("buff.bytearray incorrect!");
+            if(buff.capacity() != test_byte_array.length)
+                throw new RuntimeException("buff.capacity() incorrect!");
+            if(buff.arrayOffset() != 0)
+                throw new RuntimeException("buff.arrayOffset not 0!");
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/NewModelByteBufferByteArrayIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer(byte[],int,int) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelByteBufferByteArrayIntInt {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            ModelByteBuffer buff = new ModelByteBuffer(test_byte_array,10,20);
+            if(buff.array() != test_byte_array)
+                throw new RuntimeException("buff.array() incorrect!");
+            if(buff.capacity() != 20)
+                throw new RuntimeException("buff.capacity() not 20!");
+            if(buff.arrayOffset() != 10)
+                throw new RuntimeException("buff.arrayOffset() not 10!");
+            if(buff.getFile() != null)
+                throw new RuntimeException("buff.getFile() not null!");
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/NewModelByteBufferFile.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer(File) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelByteBufferFile {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            ModelByteBuffer buff = new ModelByteBuffer(test_file);
+            if(buff.array() != null)
+                throw new RuntimeException("buff.array() not null!");
+            if(buff.capacity() != test_file.length())
+                throw new RuntimeException("buff.capacity() incorrect!");
+            if(buff.arrayOffset() != 0)
+                throw new RuntimeException("buff.arrayOffset() not 0!");
+            if(buff.getFile() != test_file)
+                throw new RuntimeException("buff.getFile() incorrect!");
+            if(buff.getFilePointer() != 0)
+                throw new RuntimeException("buff.getFilePointer() not 0!");
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/NewModelByteBufferFileLongLong.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer(File,long,long) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelByteBufferFileLongLong {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            ModelByteBuffer buff = new ModelByteBuffer(test_file,10,20);
+            if(buff.array() != null)
+                throw new RuntimeException("buff.array() not null!");
+            if(buff.capacity() != 20)
+                throw new RuntimeException("buff.capacity() not 20!");
+            if(buff.arrayOffset() != 0)
+                throw new RuntimeException("buff.arrayOffset() not 0!");
+            if(buff.getFile() != test_file)
+                throw new RuntimeException("buff.getFile incorrect!");
+            if(buff.getFilePointer() != 10)
+                throw new RuntimeException("buff.getFilePointer not 10!");
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/Available.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream available() method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Available {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {
+                    int ret = is.available();
+                    if(ret != capacity)
+                        throw new RuntimeException("is.available() return unexpected value!");
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/Close.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream close method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Close {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/MarkReset.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream mark and reset methods */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class MarkReset {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {
+                    is.mark(1000);
+                    int ret = is.available();
+                    int a = is.read();
+                    is.skip(75);
+                    is.reset();
+                    if(is.available() != ret)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret)+") !");
+                    int b = is.read();
+                    if(a != b)
+                        throw new RuntimeException(
+                                "is doesn't return same value after reset ("
+                                + a + "!="+b+") !");
+
+                    is.skip(15);
+                    ret = is.available();
+                    is.mark(1000);
+                    is.reset();
+                    if(is.available() != ret)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret)+") !");
+
+
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/MarkSupported.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream markSupported() method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class MarkSupported {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {
+                    if(!is.markSupported())
+                        throw new RuntimeException("InputStream doesn't support mark/reset!");
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/Read.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream read() method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Read {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {
+                    byte[] b = new byte[100];
+                    int ret = is.available();
+                    int n = is.read();
+                    if(n == -1)
+                        throw new RuntimeException("is.read shouldn't return -1!");
+                    if(is.available() != ret - 1)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret - 1)+") !");
+                    is.skip(5000);
+                    if(is.read() != -1)
+                        throw new RuntimeException(
+                                "is.read() doesn't return -1!");
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/ReadByte.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream read(byte[]) method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadByte {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {
+                    byte[] b = new byte[100];
+                    int ret = is.available();
+                    int n = is.read(b);
+                    if(n == -1)
+                        throw new RuntimeException("is.read shouldn't return -1!");
+                    if(is.available() != ret - n)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret - n)+") !");
+                    is.skip(5000);
+                    if(is.read(b) != -1)
+                        throw new RuntimeException(
+                                "is.read() doesn't return -1!");
+
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/ReadByteIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream read(byte[], int, int) method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadByteIntInt {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {
+                    byte[] b = new byte[100];
+                    int ret = is.available();
+                    int n = is.read(b, 7, 50);
+                    if(n == -1)
+                        throw new RuntimeException("is.read shouldn't return -1!");
+                    if(is.available() != ret - n)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret - n)+") !");
+                    is.skip(5000);
+                    if(is.read(b, 7, 50) != -1)
+                        throw new RuntimeException(
+                                "is.read() doesn't return -1!");
+
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/RandomFileInputStream/Skip.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream skip(long) method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Skip {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {
+                    int ret = is.available();
+                    long n = is.skip(75);
+                    if(n == -1)
+                        throw new RuntimeException("is.read shouldn't return -1!");
+                    if(is.available() != ret - n)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret - n)+") !");
+
+                    ret = is.available();
+                    n = is.skip(-100);
+                    if(n != 0)
+                        throw new RuntimeException("is.skip(-100) shouldn't skip values!");
+                    if(is.available() != ret - n)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret - n)+") !");
+
+                    ret = is.available();
+                    n = is.skip(5000);
+                    if(is.available() != ret - n)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret - n)+") !");
+                    if(is.available() != 0)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(0)+") !");                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/SubbufferLong.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer subbuffer(long) method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SubbufferLong {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 2; i++) {
+                ModelByteBuffer buff;
+                if(i == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+
+                ModelByteBuffer buff2 = buff.subbuffer(10);
+                if(buff2.getFilePointer() != buff.getFilePointer())
+                    throw new RuntimeException("buff2.getFilePointer() incorreect!");
+                if(buff2.arrayOffset() != 10)
+                    throw new RuntimeException("buff2.arrayOffset() not 10!");
+                if(buff2.capacity() != buff.capacity()-10)
+                    throw new RuntimeException("buff2.capacity() not correct!");
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/SubbufferLongLong.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer subbuffer(long,long) method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SubbufferLongLong {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 2; i++) {
+                ModelByteBuffer buff;
+                if(i == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+
+                ModelByteBuffer buff2 = buff.subbuffer(10,21);
+                if(buff2.getFilePointer() != buff.getFilePointer())
+                    throw new RuntimeException("buff2.getFilePointer() incorrect!");
+                if(buff2.arrayOffset() != 10)
+                    throw new RuntimeException("buff2.arrayOffset() not 10!");
+                if(buff2.capacity() != 11)
+                    throw new RuntimeException("buff2.capacity() not 11!");
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/SubbufferLongLongBoolean.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer subbuffer(long,long,boolean) method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SubbufferLongLongBoolean {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 2; i++) {
+                ModelByteBuffer buff;
+                if(i == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+
+                ModelByteBuffer buff2 = buff.subbuffer(10,21,true);
+                if(buff2.getRoot() != buff2);
+                if(buff2.capacity() != 11);
+                if(i == 0)
+                {
+                    if(buff2.getFilePointer() != buff.getFilePointer()+10)
+                        throw new RuntimeException("buff2.getFilePointer() incorrect!");
+                }
+                else
+                {
+                    if(buff2.arrayOffset() != 10)
+                        throw new RuntimeException("buff2.arrayOffset() not 10!");
+                }
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/Unload.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer unload method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Unload {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            ModelByteBuffer buff = new ModelByteBuffer(test_file);
+            buff.load();
+            buff.unload();
+            if(buff.array() != null)
+                throw new RuntimeException("buff.array() not null!");
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBuffer/WriteTo.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer writeTo method */
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class WriteTo {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }
+
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }
+
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+
+            for (int i = 0; i < 2; i++) {
+                ModelByteBuffer buff;
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                if(i == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                buff.writeTo(baos);
+                byte[] b = baos.toByteArray();
+                for (int j = 0; j < b.length; j++)
+                    if(b[i] != test_byte_array[i])
+                        throw new RuntimeException("baos.toByteArray() incorrect!");
+            }
+        }
+        finally
+        {
+            tearDown();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetAttenuation.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable getAttenuation method */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetAttenuation {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static byte[] test_byte_array_8ext;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false);
+    static ModelByteBuffer buffer;
+    static ModelByteBuffer buffer_wave;
+    static ModelByteBuffer buffer8;
+    static ModelByteBuffer buffer16_8;
+    static ModelByteBuffer buffer24;
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        buffer = new ModelByteBuffer(test_byte_array);
+
+        byte[] test_byte_array2 = new byte[testarray.length*3];
+        buffer24 = new ModelByteBuffer(test_byte_array2);
+        test_byte_array_8ext = new byte[testarray.length];
+        byte[] test_byte_array_8_16 = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format24).toByteArray(testarray, test_byte_array2);
+        int ix = 0;
+        int x = 0;
+        for (int i = 0; i < test_byte_array_8ext.length; i++) {
+            test_byte_array_8ext[i] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+        }
+        buffer16_8 = new ModelByteBuffer(test_byte_array_8_16);
+        buffer8 = new ModelByteBuffer(test_byte_array_8ext);
+
+        AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), format, testarray.length);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos);
+        buffer_wave = new ModelByteBuffer(baos.toByteArray());
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        setUp();
+
+        ModelByteBufferWavetable wavetable = new ModelByteBufferWavetable(buffer,format);
+        wavetable.setAttenuation(10f);
+        if(wavetable.getAttenuation() != 10f)
+            throw new RuntimeException("wavetable.getAttenuation() not 10!");
+        wavetable.setAttenuation(20f);
+        if(wavetable.getAttenuation() != 20f)
+            throw new RuntimeException("wavetable.getAttenuation() not 20!");
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetChannels.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable getChannels method */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetChannels {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static byte[] test_byte_array_8ext;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false);
+    static ModelByteBuffer buffer;
+    static ModelByteBuffer buffer_wave;
+    static ModelByteBuffer buffer8;
+    static ModelByteBuffer buffer16_8;
+    static ModelByteBuffer buffer24;
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        buffer = new ModelByteBuffer(test_byte_array);
+
+        byte[] test_byte_array2 = new byte[testarray.length*3];
+        buffer24 = new ModelByteBuffer(test_byte_array2);
+        test_byte_array_8ext = new byte[testarray.length];
+        byte[] test_byte_array_8_16 = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format24).toByteArray(testarray, test_byte_array2);
+        int ix = 0;
+        int x = 0;
+        for (int i = 0; i < test_byte_array_8ext.length; i++) {
+            test_byte_array_8ext[i] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+        }
+        buffer16_8 = new ModelByteBuffer(test_byte_array_8_16);
+        buffer8 = new ModelByteBuffer(test_byte_array_8ext);
+
+        AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), format, testarray.length);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos);
+        buffer_wave = new ModelByteBuffer(baos.toByteArray());
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        setUp();
+
+        AudioFormat format1 = new AudioFormat(44100, 16, 1, true, false);
+        AudioFormat format2 = new AudioFormat(44100, 16, 2, true, false);
+        ModelByteBufferWavetable wavetable = new ModelByteBufferWavetable(buffer,format1,10f);
+        if(wavetable.getChannels() != 1)
+            throw new RuntimeException("wavetable.getChannels() not 1!");
+        wavetable = new ModelByteBufferWavetable(buffer,format2,10f);
+        if(wavetable.getChannels() != 2)
+            throw new RuntimeException("wavetable.getChannels() not 2!");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetLoopLength.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable getLoopLength method */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetLoopLength {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static byte[] test_byte_array_8ext;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false);
+    static ModelByteBuffer buffer;
+    static ModelByteBuffer buffer_wave;
+    static ModelByteBuffer buffer8;
+    static ModelByteBuffer buffer16_8;
+    static ModelByteBuffer buffer24;
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        buffer = new ModelByteBuffer(test_byte_array);
+
+        byte[] test_byte_array2 = new byte[testarray.length*3];
+        buffer24 = new ModelByteBuffer(test_byte_array2);
+        test_byte_array_8ext = new byte[testarray.length];
+        byte[] test_byte_array_8_16 = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format24).toByteArray(testarray, test_byte_array2);
+        int ix = 0;
+        int x = 0;
+        for (int i = 0; i < test_byte_array_8ext.length; i++) {
+            test_byte_array_8ext[i] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+        }
+        buffer16_8 = new ModelByteBuffer(test_byte_array_8_16);
+        buffer8 = new ModelByteBuffer(test_byte_array_8ext);
+
+        AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), format, testarray.length);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos);
+        buffer_wave = new ModelByteBuffer(baos.toByteArray());
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        setUp();
+
+        ModelByteBufferWavetable wavetable = new ModelByteBufferWavetable(buffer,format);
+        wavetable.setLoopLength(10f);
+        if(wavetable.getLoopLength() != 10f)
+            throw new RuntimeException("wavetable.getLoopLength() not 10!");
+        wavetable.setLoopLength(20f);
+        if(wavetable.getLoopLength() != 20f)
+            throw new RuntimeException("wavetable.getLoopLength() not 20!");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetLoopStart.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable getLoopStart method */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetLoopStart {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static byte[] test_byte_array_8ext;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false);
+    static ModelByteBuffer buffer;
+    static ModelByteBuffer buffer_wave;
+    static ModelByteBuffer buffer8;
+    static ModelByteBuffer buffer16_8;
+    static ModelByteBuffer buffer24;
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        buffer = new ModelByteBuffer(test_byte_array);
+
+        byte[] test_byte_array2 = new byte[testarray.length*3];
+        buffer24 = new ModelByteBuffer(test_byte_array2);
+        test_byte_array_8ext = new byte[testarray.length];
+        byte[] test_byte_array_8_16 = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format24).toByteArray(testarray, test_byte_array2);
+        int ix = 0;
+        int x = 0;
+        for (int i = 0; i < test_byte_array_8ext.length; i++) {
+            test_byte_array_8ext[i] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+        }
+        buffer16_8 = new ModelByteBuffer(test_byte_array_8_16);
+        buffer8 = new ModelByteBuffer(test_byte_array_8ext);
+
+        AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), format, testarray.length);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos);
+        buffer_wave = new ModelByteBuffer(baos.toByteArray());
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        setUp();
+
+        ModelByteBufferWavetable wavetable = new ModelByteBufferWavetable(buffer,format);
+        wavetable.setLoopStart(10f);
+        if(wavetable.getLoopStart() != 10f)
+            throw new RuntimeException("wavetable.getLoopStart() not 10!");
+        wavetable.setLoopStart(20f);
+        if(wavetable.getLoopStart() != 20f)
+            throw new RuntimeException("wavetable.getLoopStart() not 20!");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/GetPitchCorrection.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable getPitchCorrect method */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetPitchCorrection {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static byte[] test_byte_array_8ext;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false);
+    static ModelByteBuffer buffer;
+    static ModelByteBuffer buffer_wave;
+    static ModelByteBuffer buffer8;
+    static ModelByteBuffer buffer16_8;
+    static ModelByteBuffer buffer24;
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        buffer = new ModelByteBuffer(test_byte_array);
+
+        byte[] test_byte_array2 = new byte[testarray.length*3];
+        buffer24 = new ModelByteBuffer(test_byte_array2);
+        test_byte_array_8ext = new byte[testarray.length];
+        byte[] test_byte_array_8_16 = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format24).toByteArray(testarray, test_byte_array2);
+        int ix = 0;
+        int x = 0;
+        for (int i = 0; i < test_byte_array_8ext.length; i++) {
+            test_byte_array_8ext[i] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+        }
+        buffer16_8 = new ModelByteBuffer(test_byte_array_8_16);
+        buffer8 = new ModelByteBuffer(test_byte_array_8ext);
+
+        AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), format, testarray.length);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos);
+        buffer_wave = new ModelByteBuffer(baos.toByteArray());
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        setUp();
+
+        ModelByteBufferWavetable wavetable = new ModelByteBufferWavetable(buffer,format);
+        wavetable.setPitchcorrection(10f);
+        if(wavetable.getPitchcorrection() != 10f)
+            throw new RuntimeException("wavetable.getPitchcorrection() not 10!");
+        wavetable.setPitchcorrection(20f);
+        if(wavetable.getPitchcorrection() != 20f)
+            throw new RuntimeException("wavetable.getPitchcorrection() not 20!");
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/NewModelByteBufferWavetableModelByteBuffer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable(ModelByteBuffer)  method */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelByteBufferWavetableModelByteBuffer {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static byte[] test_byte_array_8ext;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false);
+    static ModelByteBuffer buffer;
+    static ModelByteBuffer buffer_wave;
+    static ModelByteBuffer buffer8;
+    static ModelByteBuffer buffer16_8;
+    static ModelByteBuffer buffer24;
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        buffer = new ModelByteBuffer(test_byte_array);
+
+        byte[] test_byte_array2 = new byte[testarray.length*3];
+        buffer24 = new ModelByteBuffer(test_byte_array2);
+        test_byte_array_8ext = new byte[testarray.length];
+        byte[] test_byte_array_8_16 = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format24).toByteArray(testarray, test_byte_array2);
+        int ix = 0;
+        int x = 0;
+        for (int i = 0; i < test_byte_array_8ext.length; i++) {
+            test_byte_array_8ext[i] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+        }
+        buffer16_8 = new ModelByteBuffer(test_byte_array_8_16);
+        buffer8 = new ModelByteBuffer(test_byte_array_8ext);
+
+        AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), format, testarray.length);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos);
+        buffer_wave = new ModelByteBuffer(baos.toByteArray());
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        setUp();
+
+        ModelByteBufferWavetable wavetable = new ModelByteBufferWavetable(buffer_wave);
+        if(wavetable.getBuffer() != buffer_wave)
+            throw new RuntimeException("wavetable.getBuffer() incorrect!");
+        if(!wavetable.getFormat().matches(format))
+            throw new RuntimeException("wavetable.getFormat() incorrect!");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/NewModelByteBufferWavetableModelByteBufferAudioFormat.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable(ModelByteBuffer, AudioFormat)  method */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelByteBufferWavetableModelByteBufferAudioFormat {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static byte[] test_byte_array_8ext;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false);
+    static ModelByteBuffer buffer;
+    static ModelByteBuffer buffer_wave;
+    static ModelByteBuffer buffer8;
+    static ModelByteBuffer buffer16_8;
+    static ModelByteBuffer buffer24;
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        buffer = new ModelByteBuffer(test_byte_array);
+
+        byte[] test_byte_array2 = new byte[testarray.length*3];
+        buffer24 = new ModelByteBuffer(test_byte_array2);
+        test_byte_array_8ext = new byte[testarray.length];
+        byte[] test_byte_array_8_16 = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format24).toByteArray(testarray, test_byte_array2);
+        int ix = 0;
+        int x = 0;
+        for (int i = 0; i < test_byte_array_8ext.length; i++) {
+            test_byte_array_8ext[i] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+        }
+        buffer16_8 = new ModelByteBuffer(test_byte_array_8_16);
+        buffer8 = new ModelByteBuffer(test_byte_array_8ext);
+
+        AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), format, testarray.length);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos);
+        buffer_wave = new ModelByteBuffer(baos.toByteArray());
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        setUp();
+
+        ModelByteBufferWavetable wavetable = new ModelByteBufferWavetable(buffer,format);
+        if(wavetable.getBuffer() != buffer)
+            throw new RuntimeException("wavetable.getBuffer() incorrect!");
+        if(wavetable.getFormat() != format)
+            throw new RuntimeException("wavetable.getFormat() incorrect!");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/NewModelByteBufferWavetableModelByteBufferAudioFormatFloat.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable(ModelByteBuffer, AudioFormat)  method */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelByteBufferWavetableModelByteBufferAudioFormatFloat {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static byte[] test_byte_array_8ext;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false);
+    static ModelByteBuffer buffer;
+    static ModelByteBuffer buffer_wave;
+    static ModelByteBuffer buffer8;
+    static ModelByteBuffer buffer16_8;
+    static ModelByteBuffer buffer24;
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        buffer = new ModelByteBuffer(test_byte_array);
+
+        byte[] test_byte_array2 = new byte[testarray.length*3];
+        buffer24 = new ModelByteBuffer(test_byte_array2);
+        test_byte_array_8ext = new byte[testarray.length];
+        byte[] test_byte_array_8_16 = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format24).toByteArray(testarray, test_byte_array2);
+        int ix = 0;
+        int x = 0;
+        for (int i = 0; i < test_byte_array_8ext.length; i++) {
+            test_byte_array_8ext[i] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+        }
+        buffer16_8 = new ModelByteBuffer(test_byte_array_8_16);
+        buffer8 = new ModelByteBuffer(test_byte_array_8ext);
+
+        AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), format, testarray.length);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos);
+        buffer_wave = new ModelByteBuffer(baos.toByteArray());
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        setUp();
+
+        ModelByteBufferWavetable wavetable = new ModelByteBufferWavetable(buffer,format);
+        if(wavetable.getBuffer() != buffer)
+            throw new RuntimeException("wavetable.getBuffer() incorrect!");
+        if(!wavetable.getFormat().matches(format))
+            throw new RuntimeException("wavetable.getFormat() incorrect!");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/NewModelByteBufferWavetableModelByteBufferFloat.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable(ModelByteBuffer, AudioFormat, float)  method */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelByteBufferWavetableModelByteBufferFloat {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static byte[] test_byte_array_8ext;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false);
+    static ModelByteBuffer buffer;
+    static ModelByteBuffer buffer_wave;
+    static ModelByteBuffer buffer8;
+    static ModelByteBuffer buffer16_8;
+    static ModelByteBuffer buffer24;
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        buffer = new ModelByteBuffer(test_byte_array);
+
+        byte[] test_byte_array2 = new byte[testarray.length*3];
+        buffer24 = new ModelByteBuffer(test_byte_array2);
+        test_byte_array_8ext = new byte[testarray.length];
+        byte[] test_byte_array_8_16 = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format24).toByteArray(testarray, test_byte_array2);
+        int ix = 0;
+        int x = 0;
+        for (int i = 0; i < test_byte_array_8ext.length; i++) {
+            test_byte_array_8ext[i] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+        }
+        buffer16_8 = new ModelByteBuffer(test_byte_array_8_16);
+        buffer8 = new ModelByteBuffer(test_byte_array_8ext);
+
+        AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), format, testarray.length);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos);
+        buffer_wave = new ModelByteBuffer(baos.toByteArray());
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        setUp();
+
+        ModelByteBufferWavetable wavetable = new ModelByteBufferWavetable(buffer,format,10f);
+        if(wavetable.getBuffer() != buffer)
+            throw new RuntimeException("wavetable.getBuffer() incorrect!");
+        if(!wavetable.getFormat().matches(format))
+            throw new RuntimeException("wavetable.getFormat() incorrect!");
+        if(wavetable.getPitchcorrection() != 10f)
+            throw new RuntimeException("wavetable.getPitchcorrection() not 10!");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/Open.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable open method */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Open {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static byte[] test_byte_array_8ext;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false);
+    static ModelByteBuffer buffer;
+    static ModelByteBuffer buffer_wave;
+    static ModelByteBuffer buffer8;
+    static ModelByteBuffer buffer16_8;
+    static ModelByteBuffer buffer24;
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        buffer = new ModelByteBuffer(test_byte_array);
+
+        byte[] test_byte_array2 = new byte[testarray.length*3];
+        buffer24 = new ModelByteBuffer(test_byte_array2);
+        test_byte_array_8ext = new byte[testarray.length];
+        byte[] test_byte_array_8_16 = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format24).toByteArray(testarray, test_byte_array2);
+        int ix = 0;
+        int x = 0;
+        for (int i = 0; i < test_byte_array_8ext.length; i++) {
+            test_byte_array_8ext[i] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+        }
+        buffer16_8 = new ModelByteBuffer(test_byte_array_8_16);
+        buffer8 = new ModelByteBuffer(test_byte_array_8ext);
+
+        AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), format, testarray.length);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos);
+        buffer_wave = new ModelByteBuffer(baos.toByteArray());
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        setUp();
+
+        ModelByteBufferWavetable wavetable = new ModelByteBufferWavetable(buffer,format);
+        if(wavetable.open(44100) != null)
+            throw new RuntimeException("wavetable.open(44100) doesn't return null!");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/Set8BitExtensionBuffer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable set8BitExtensionBuffer method */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Set8BitExtensionBuffer {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static byte[] test_byte_array_8ext;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false);
+    static ModelByteBuffer buffer;
+    static ModelByteBuffer buffer_wave;
+    static ModelByteBuffer buffer8;
+    static ModelByteBuffer buffer16_8;
+    static ModelByteBuffer buffer24;
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        buffer = new ModelByteBuffer(test_byte_array);
+
+        byte[] test_byte_array2 = new byte[testarray.length*3];
+        buffer24 = new ModelByteBuffer(test_byte_array2);
+        test_byte_array_8ext = new byte[testarray.length];
+        byte[] test_byte_array_8_16 = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format24).toByteArray(testarray, test_byte_array2);
+        int ix = 0;
+        int x = 0;
+        for (int i = 0; i < test_byte_array_8ext.length; i++) {
+            test_byte_array_8ext[i] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+        }
+        buffer16_8 = new ModelByteBuffer(test_byte_array_8_16);
+        buffer8 = new ModelByteBuffer(test_byte_array_8ext);
+
+        AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), format, testarray.length);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos);
+        buffer_wave = new ModelByteBuffer(baos.toByteArray());
+    }
+
+    static float compare(float[] a, float[] b)
+    {
+        float ac_error = 0;
+        int counter = 0;
+        for (int i = 0; i < a.length; i++) {
+            ac_error += Math.abs(a[i] - b[i]);
+            counter++;
+        }
+        return ac_error / ((float)counter);
+
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        setUp();
+
+        ModelByteBufferWavetable wavetable = new ModelByteBufferWavetable(buffer16_8,format,10f);
+        float[] f1 = new float[testarray.length];
+        float[] f2 = new float[testarray.length];
+        wavetable.openStream().read(f1);
+        wavetable.set8BitExtensionBuffer(buffer8);
+        if(wavetable.get8BitExtensionBuffer() != buffer8)
+            throw new RuntimeException("wavetable.get8BitExtensionBuffer() incorrect!");
+        wavetable.openStream().read(f2);
+        // f2 should have more accurity than f1,
+        //    about 256 times more, or 8 bits
+        float spec1 = compare(f1, testarray);
+        float spec2 = compare(f2, testarray);
+        if((spec1/spec2) <= 200)
+            throw new RuntimeException("(spec1/spec2) <= 200!");
+
+
+    }
+
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/SetLoopType.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable SetLoopType method */
+
+import java.io.ByteArrayOutputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetLoopType {
+
+    static float[] testarray;
+    static byte[] test_byte_array;
+    static byte[] test_byte_array_8ext;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false);
+    static ModelByteBuffer buffer;
+    static ModelByteBuffer buffer_wave;
+    static ModelByteBuffer buffer8;
+    static ModelByteBuffer buffer16_8;
+    static ModelByteBuffer buffer24;
+
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        buffer = new ModelByteBuffer(test_byte_array);
+
+        byte[] test_byte_array2 = new byte[testarray.length*3];
+        buffer24 = new ModelByteBuffer(test_byte_array2);
+        test_byte_array_8ext = new byte[testarray.length];
+        byte[] test_byte_array_8_16 = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format24).toByteArray(testarray, test_byte_array2);
+        int ix = 0;
+        int x = 0;
+        for (int i = 0; i < test_byte_array_8ext.length; i++) {
+            test_byte_array_8ext[i] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+            test_byte_array_8_16[x++] = test_byte_array2[ix++];
+        }
+        buffer16_8 = new ModelByteBuffer(test_byte_array_8_16);
+        buffer8 = new ModelByteBuffer(test_byte_array_8ext);
+
+        AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), format, testarray.length);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos);
+        buffer_wave = new ModelByteBuffer(baos.toByteArray());
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        setUp();
+
+        ModelByteBufferWavetable wavetable = new ModelByteBufferWavetable(buffer,format);
+        wavetable.setLoopType(1);
+        if(wavetable.getLoopType() != 1)
+            throw new RuntimeException("wavetable.getLoopType() not 1!");
+        wavetable.setLoopType(2);
+        if(wavetable.getLoopType() != 2)
+            throw new RuntimeException("wavetable.getLoopType() not 2!");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelDestination/NewModelDestination.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelDestination constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelDestination {
+
+    public static void main(String[] args) throws Exception {
+        ModelDestination dest = new ModelDestination();
+        if(dest.getIdentifier() != ModelDestination.DESTINATION_NONE)
+            throw new RuntimeException("dest.getIdentifier() is not equals ModelDestination.DESTINATION_NONE!");
+        if(!(dest.getTransform() instanceof ModelStandardTransform))
+            throw new RuntimeException("dest.getTransform() is not instancoef ModelStandardTransform!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelDestination/NewModelDestinationModelIdentifier.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelDestination(ModelIdentifier) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelDestinationModelIdentifier {
+
+    public static void main(String[] args) throws Exception {
+        ModelDestination dest = new ModelDestination(ModelDestination.DESTINATION_EG1_ATTACK);
+        if(dest.getIdentifier() != ModelDestination.DESTINATION_EG1_ATTACK)
+            throw new RuntimeException("dest.getIdentifier() is not equals ModelDestination.DESTINATION_EG1_ATTACK!");
+        if(!(dest.getTransform() instanceof ModelStandardTransform))
+            throw new RuntimeException("dest.getTransform() is not instancoef ModelStandardTransform!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelDestination/SetIdentifier.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable setIdentifier(ModelIdentifier) method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetIdentifier {
+
+    public static void main(String[] args) throws Exception {
+        ModelDestination dest = new ModelDestination();
+        dest.setIdentifier(ModelDestination.DESTINATION_EG1_ATTACK);
+        if(dest.getIdentifier() != ModelDestination.DESTINATION_EG1_ATTACK)
+            throw new RuntimeException("dest.getIdentifier() is not equals ModelDestination.DESTINATION_EG1_ATTACK!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelDestination/SetTransform.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBufferWavetable setTransform(ModelTransform) method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetTransform{
+
+    public static void main(String[] args) throws Exception {
+        ModelDestination dest = new ModelDestination();
+        ModelStandardTransform newtransform = new ModelStandardTransform();
+        dest.setTransform(newtransform);
+        if(dest.getTransform() != newtransform)
+            throw new RuntimeException("dest.getTransform() is incorrect!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelIdentifier/EqualsObject.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelIdentifier equals method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class EqualsObject {
+
+    public static void main(String[] args) throws Exception {
+        ModelIdentifier id = new ModelIdentifier("test","a",1);
+        ModelIdentifier id2 = new ModelIdentifier("test","a",1);
+        ModelIdentifier id3 = new ModelIdentifier("test","a",2);
+        ModelIdentifier id4 = new ModelIdentifier("test","b",1);
+        ModelIdentifier id5 = new ModelIdentifier("hello","a",1);
+        if(!id.equals(id2))
+            throw new RuntimeException("Compare failed!");
+        if(id.equals(id3))
+            throw new RuntimeException("Compare failed!");
+        if(id.equals(id4))
+            throw new RuntimeException("Compare failed!");
+        if(id.equals(id5))
+            throw new RuntimeException("Compare failed!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelIdentifier/NewModelIdentifierString.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelIdentifier(String) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelIdentifierString {
+
+    public static void main(String[] args) throws Exception {
+        ModelIdentifier id = new ModelIdentifier("test");
+        if(!id.getObject().equals("test"))
+            throw new RuntimeException("id.getObject() doesn't return \"test\"!");
+        if(id.getVariable() != null)
+            throw new RuntimeException("id.getVariable() doesn't return null!");
+        if(id.getInstance() != 0)
+            throw new RuntimeException("id.getInstance() doesn't return 0!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelIdentifier/NewModelIdentifierStringInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelIdentifier(String, integer) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelIdentifierStringInt {
+
+    public static void main(String[] args) throws Exception {
+        ModelIdentifier id = new ModelIdentifier("test",1);
+        if(!id.getObject().equals("test"))
+            throw new RuntimeException("id.getObject() doesn't return \"test\"!");
+        if(id.getVariable() != null)
+            throw new RuntimeException("id.getVariable() doesn't return null!");
+        if(id.getInstance() != 1)
+            throw new RuntimeException("id.getInstance() doesn't return 1!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelIdentifier/NewModelIdentifierStringString.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelIdentifier(String,String) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelIdentifierStringString {
+
+    public static void main(String[] args) throws Exception {
+        ModelIdentifier id = new ModelIdentifier("test","a");
+        if(!id.getObject().equals("test"))
+            throw new RuntimeException("id.getObject() doesn't return \"test\"!");
+        if(!id.getVariable().equals("a"))
+            throw new RuntimeException("id.getVariable() doesn't return \"a\"!");
+        if(id.getInstance() != 0)
+            throw new RuntimeException("id.getInstance() doesn't return 0!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelIdentifier/NewModelIdentifierStringStringInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelIdentifier(String,String,int) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelIdentifierStringStringInt {
+
+    public static void main(String[] args) throws Exception {
+        ModelIdentifier id = new ModelIdentifier("test","a",1);;
+        if(!id.getObject().equals("test"))
+            throw new RuntimeException("id.getObject() doesn't return \"test\"!");
+        if(!id.getVariable().equals("a"))
+            throw new RuntimeException("id.getVariable() doesn't return \"a\"!");
+        if(id.getInstance() != 1)
+            throw new RuntimeException("id.getInstance() doesn't return 1!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelIdentifier/SetInstance.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelIdentifier setInstance method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetInstance {
+
+    public static void main(String[] args) throws Exception {
+        ModelIdentifier id = new ModelIdentifier("test","a",1);
+        id.setInstance(2);
+        if(id.getInstance() != 2)
+            throw new RuntimeException("id.getInstance() doesn't return 2!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelIdentifier/SetObject.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelIdentifier setObject method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetObject {
+
+    public static void main(String[] args) throws Exception {
+        ModelIdentifier id = new ModelIdentifier("test","a",1);
+        id.setObject("hello");
+        if(!id.getObject().equals("hello"))
+            throw new RuntimeException("id.getObject() does't return \"hello\"!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelIdentifier/SetVariable.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelIdentifier setVariable method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetVariable {
+
+    public static void main(String[] args) throws Exception {
+        ModelIdentifier id = new ModelIdentifier("test","a",1);
+        id.setVariable("b");
+        if(!id.getVariable().equals("b"))
+            throw new RuntimeException("id.getVariable() does't return \"b\"!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelPerformer/GetOscillators.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelPerformer getOscillators method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetOscillators {
+
+    public static void main(String[] args) throws Exception {
+        ModelPerformer performer = new ModelPerformer();
+        if(performer.getOscillators() == null)
+            throw new RuntimeException("performer.getOscillators() returned null!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetConnectionBlocks.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelPerformer setConnectionBlocks method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetConnectionBlocks {
+
+    public static void main(String[] args) throws Exception {
+        ModelPerformer performer = new ModelPerformer();
+        List<ModelConnectionBlock> newlist = new ArrayList<ModelConnectionBlock>();
+        performer.setConnectionBlocks(newlist);
+        if(performer.getConnectionBlocks() != newlist)
+            throw new RuntimeException("performer.getConnectionBlocks() returned incorrect data!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetDefaultConnectionsEnabled.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelPerformer setDefaultConnectionsEnabled method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetDefaultConnectionsEnabled {
+
+    public static void main(String[] args) throws Exception {
+        ModelPerformer performer = new ModelPerformer();
+        performer.setDefaultConnectionsEnabled(true);
+        if(performer.isDefaultConnectionsEnabled() != true)
+            throw new RuntimeException("performer.isAddDefaultConnectionsEnabled() didn't return true!");
+        performer.setDefaultConnectionsEnabled(false);
+        if(performer.isDefaultConnectionsEnabled() != false)
+            throw new RuntimeException("performer.isAddDefaultConnectionsEnabled() didn't return false!");
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetExclusiveClass.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelPerformer setExclusiveClass method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetExclusiveClass {
+
+    public static void main(String[] args) throws Exception {
+        ModelPerformer performer = new ModelPerformer();
+        performer.setExclusiveClass(10);
+        if(performer.getExclusiveClass() != 10)
+            throw new RuntimeException("performer.getExclusiveClass() didn't return 10!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetKeyFrom.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelPerformer setKeyFrom method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetKeyFrom {
+
+    public static void main(String[] args) throws Exception {
+        ModelPerformer performer = new ModelPerformer();
+        performer.setKeyFrom(10);
+        if(performer.getKeyFrom() != 10)
+            throw new RuntimeException("performer.getKeyFrom() didn't return 10!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetKeyTo.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelPerformer setKeyTo method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetKeyTo {
+
+    public static void main(String[] args) throws Exception {
+        ModelPerformer performer = new ModelPerformer();
+        performer.setKeyTo(10);
+        if(performer.getKeyTo() != 10)
+            throw new RuntimeException("performer.getKeyTo() didn't return 10!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetName.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelPerformer setName method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetName {
+
+    public static void main(String[] args) throws Exception {
+        ModelPerformer performer = new ModelPerformer();
+        performer.setName("hello");
+        if(!performer.getName().equals("hello"))
+            throw new RuntimeException("performer.getName() didn't return \"hello\"!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetSelfNonExclusive.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelPerformer setSelfNonExclusive method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetSelfNonExclusive {
+
+    public static void main(String[] args) throws Exception {
+        ModelPerformer performer = new ModelPerformer();
+        performer.setSelfNonExclusive(true);
+        if(performer.isSelfNonExclusive() != true)
+            throw new RuntimeException("performer.isSelfNonExclusive() didn't return true!");
+        performer.setSelfNonExclusive(false);
+        if(performer.isSelfNonExclusive() != false)
+            throw new RuntimeException("performer.isSelfNonExclusive() didn't return false!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetVelFrom.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelPerformer setVelFrom method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetVelFrom {
+
+    public static void main(String[] args) throws Exception {
+        ModelPerformer performer = new ModelPerformer();
+        performer.setVelFrom(10);
+        if(performer.getVelFrom() != 10)
+            throw new RuntimeException("performer.getVelFrom() didn't return 10!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelPerformer/SetVelTo.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelPerformer setVelTo method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetVelTo {
+
+    public static void main(String[] args) throws Exception {
+        ModelPerformer performer = new ModelPerformer();
+        performer.setVelTo(10);
+        if(performer.getVelTo() != 10)
+            throw new RuntimeException("performer.getVelTo() didn't return 10!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelSource/NewModelSource.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelSource() constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelSource {
+
+    public static void main(String[] args) throws Exception {
+        ModelSource src = new ModelSource();
+        if(src.getIdentifier() != ModelSource.SOURCE_NONE)
+            throw new RuntimeException("src.getIdentifier() doesn't return ModelSource.SOURCE_NONE!");
+        if(!(src.getTransform() instanceof ModelStandardTransform))
+            throw new RuntimeException("src.getTransform() doesn't return object which is instance of ModelStandardTransform!");
+
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifier.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelSource(ModelIdentifier) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelSourceModelIdentifier {
+
+    public static void main(String[] args) throws Exception {
+        ModelSource src = new ModelSource(ModelSource.SOURCE_NOTEON_KEYNUMBER);
+        if(src.getIdentifier() != ModelSource.SOURCE_NOTEON_KEYNUMBER)
+            throw new RuntimeException("src.getIdentifier() doesn't return ModelSource.SOURCE_NOTEON_KEYNUMBER!");
+        if(!(src.getTransform() instanceof ModelStandardTransform))
+            throw new RuntimeException("src.getTransform() doesn't return object which is instance of ModelStandardTransform!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifierBoolean.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelSource(ModelIdentifier,boolean) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelSourceModelIdentifierBoolean {
+
+    public static void main(String[] args) throws Exception {
+        ModelSource src = new ModelSource(ModelSource.SOURCE_NOTEON_KEYNUMBER,ModelStandardTransform.DIRECTION_MAX2MIN);
+        if(src.getIdentifier() != ModelSource.SOURCE_NOTEON_KEYNUMBER)
+            throw new RuntimeException("src.getIdentifier() doesn't return ModelSource.SOURCE_NOTEON_KEYNUMBER!");
+        if(!(src.getTransform() instanceof ModelStandardTransform))
+            throw new RuntimeException("src.getTransform() doesn't return object which is instance of ModelStandardTransform!");
+        ModelStandardTransform trans = (ModelStandardTransform)src.getTransform();
+        if(trans.getDirection() != ModelStandardTransform.DIRECTION_MAX2MIN)
+            throw new RuntimeException("trans.getDirection() doesn't return ModelStandardTransform.DIRECTION_MAX2MIN!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifierBooleanBoolean.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelSource(ModelIdentifier,boolean,boolean) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelSourceModelIdentifierBooleanBoolean {
+
+    public static void main(String[] args) throws Exception {
+        ModelSource src = new ModelSource(ModelSource.SOURCE_NOTEON_KEYNUMBER,ModelStandardTransform.DIRECTION_MAX2MIN,ModelStandardTransform.POLARITY_BIPOLAR);
+        if(src.getIdentifier() != ModelSource.SOURCE_NOTEON_KEYNUMBER)
+            throw new RuntimeException("src.getIdentifier() doesn't return ModelSource.SOURCE_NOTEON_KEYNUMBER!");
+        if(!(src.getTransform() instanceof ModelStandardTransform))
+            throw new RuntimeException("src.getTransform() doesn't return object which is instance of ModelStandardTransform!");
+        ModelStandardTransform trans = (ModelStandardTransform)src.getTransform();
+        if(trans.getDirection() != ModelStandardTransform.DIRECTION_MAX2MIN)
+            throw new RuntimeException("trans.getDirection() doesn't return ModelStandardTransform.DIRECTION_MAX2MIN!");
+        if(trans.getPolarity() != ModelStandardTransform.POLARITY_BIPOLAR)
+            throw new RuntimeException("trans.getPolarity() doesn't return ModelStandardTransform.POLARITY_BIPOLAR!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifierBooleanBooleanInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelSource(ModelIdentifier,boolean,boolean,int) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelSourceModelIdentifierBooleanBooleanInt {
+
+    public static void main(String[] args) throws Exception {
+        ModelSource src = new ModelSource(ModelSource.SOURCE_NOTEON_KEYNUMBER,
+                ModelStandardTransform.DIRECTION_MAX2MIN,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_CONCAVE);
+        if(src.getIdentifier() != ModelSource.SOURCE_NOTEON_KEYNUMBER)
+            throw new RuntimeException("src.getIdentifier() doesn't return ModelSource.SOURCE_NOTEON_KEYNUMBER!");
+        if(!(src.getTransform() instanceof ModelStandardTransform))
+            throw new RuntimeException("src.getTransform() doesn't return object which is instance of ModelStandardTransform!");
+        ModelStandardTransform trans = (ModelStandardTransform)src.getTransform();
+        if(trans.getDirection() != ModelStandardTransform.DIRECTION_MAX2MIN)
+            throw new RuntimeException("trans.getDirection() doesn't return ModelStandardTransform.DIRECTION_MAX2MIN!");
+        if(trans.getPolarity() != ModelStandardTransform.POLARITY_BIPOLAR)
+            throw new RuntimeException("trans.getPolarity() doesn't return ModelStandardTransform.POLARITY_BIPOLAR!");
+        if(trans.getTransform() != ModelStandardTransform.TRANSFORM_CONCAVE)
+            throw new RuntimeException("trans.getTransform() doesn't return ModelStandardTransform.TRANSFORM_CONCAVE!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelSource/NewModelSourceModelIdentifierModelTransform.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelSource(ModelIdentifier,ModelTransform) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelSourceModelIdentifierModelTransform {
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform trans = new ModelStandardTransform();
+        ModelSource src = new ModelSource(ModelSource.SOURCE_NOTEON_KEYNUMBER, trans);
+        if(src.getIdentifier() != ModelSource.SOURCE_NOTEON_KEYNUMBER)
+            throw new RuntimeException("src.getIdentifier() doesn't return ModelSource.SOURCE_NOTEON_KEYNUMBER!");
+        if(src.getTransform() != trans)
+            throw new RuntimeException("src.getTransform() doesn't return trans!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelSource/SetIdentifier.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelSource setIdentifier method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetIdentifier {
+
+    public static void main(String[] args) throws Exception {
+        ModelSource src = new ModelSource();
+        src.setIdentifier(ModelSource.SOURCE_NOTEON_KEYNUMBER);
+        if(src.getIdentifier() != ModelSource.SOURCE_NOTEON_KEYNUMBER)
+            throw new RuntimeException("src.getIdentifier() doesn't return ModelSource.SOURCE_NOTEON_KEYNUMBER!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelSource/SetTransform.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelSource setTransform method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetTransform {
+
+    public static void main(String[] args) throws Exception {
+        ModelSource src = new ModelSource();
+        ModelStandardTransform trans = new ModelStandardTransform();
+        src.setTransform(trans);
+        if(src.getTransform() != trans)
+            throw new RuntimeException("src.getTransform() doesn't return trans!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/NewModelStandardTransform.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelStandardTransform constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelStandardTransform {
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform transform = new ModelStandardTransform();
+        if(transform.getDirection() != ModelStandardTransform.DIRECTION_MIN2MAX)
+            throw new RuntimeException("transform.getDirection() doesn't return ModelStandardTransform.DIRECTION_MIN2MAX!");
+        if(transform.getPolarity() != ModelStandardTransform.POLARITY_UNIPOLAR)
+            throw new RuntimeException("transform.getPolarity() doesn't return ModelStandardTransform.POLARITY_UNIPOLAR!");
+        if(transform.getTransform() != ModelStandardTransform.TRANSFORM_LINEAR)
+            throw new RuntimeException("transform.getTransform() doesn't return ModelStandardTransform.TRANSFORM_LINEAR!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/NewModelStandardTransformBoolean.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelStandardTransform(boolean) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelStandardTransformBoolean {
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform transform = new ModelStandardTransform(ModelStandardTransform.DIRECTION_MAX2MIN);
+        if(transform.getDirection() != ModelStandardTransform.DIRECTION_MAX2MIN)
+            throw new RuntimeException("transform.getDirection() doesn't return ModelStandardTransform.DIRECTION_MAX2MIN!");
+        if(transform.getPolarity() != ModelStandardTransform.POLARITY_UNIPOLAR)
+            throw new RuntimeException("transform.getPolarity() doesn't return ModelStandardTransform.POLARITY_UNIPOLAR!");
+        if(transform.getTransform() != ModelStandardTransform.TRANSFORM_LINEAR)
+            throw new RuntimeException("transform.getTransform() doesn't return ModelStandardTransform.TRANSFORM_LINEAR!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/NewModelStandardTransformBooleanBoolean.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelStandardTransform(boolean,boolean) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelStandardTransformBooleanBoolean {
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform transform = new ModelStandardTransform(
+                ModelStandardTransform.DIRECTION_MAX2MIN,
+                ModelStandardTransform.POLARITY_BIPOLAR);
+        if(transform.getDirection() != ModelStandardTransform.DIRECTION_MAX2MIN)
+            throw new RuntimeException("transform.getDirection() doesn't return ModelStandardTransform.DIRECTION_MAX2MIN!");
+        if(transform.getPolarity() != ModelStandardTransform.POLARITY_BIPOLAR)
+            throw new RuntimeException("transform.getPolarity() doesn't return ModelStandardTransform.POLARITY_BIPOLAR!");
+        if(transform.getTransform() != ModelStandardTransform.TRANSFORM_LINEAR)
+            throw new RuntimeException("transform.getTransform() doesn't return ModelStandardTransform.TRANSFORM_LINEAR!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/NewModelStandardTransformBooleanBooleanInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelStandardTransform(boolean,boolean,int) constructor */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewModelStandardTransformBooleanBooleanInt {
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform transform = new ModelStandardTransform(
+                ModelStandardTransform.DIRECTION_MAX2MIN,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_CONVEX);
+        if(transform.getDirection() != ModelStandardTransform.DIRECTION_MAX2MIN)
+            throw new RuntimeException("transform.getDirection() doesn't return ModelStandardTransform.DIRECTION_MAX2MIN!");
+        if(transform.getPolarity() != ModelStandardTransform.POLARITY_BIPOLAR)
+            throw new RuntimeException("transform.getPolarity() doesn't return ModelStandardTransform.POLARITY_BIPOLAR!");
+        if(transform.getTransform() != ModelStandardTransform.TRANSFORM_CONVEX)
+            throw new RuntimeException("transform.getTransform() doesn't return ModelStandardTransform.TRANSFORM_CONVEX!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/SetDirection.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelStandardTransform setDirection method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetDirection {
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform transform = new ModelStandardTransform();
+        transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+        if(transform.getDirection() != ModelStandardTransform.DIRECTION_MAX2MIN)
+            throw new RuntimeException("transform.getDirection() doesn't return ModelStandardTransform.DIRECTION_MAX2MIN!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/SetPolarity.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelStandardTransform setPolarity method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetPolarity {
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform transform = new ModelStandardTransform();
+        transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+        if(transform.getPolarity() != ModelStandardTransform.POLARITY_BIPOLAR)
+            throw new RuntimeException("transform.getPolarity() doesn't return ModelStandardTransform.POLARITY_BIPOLAR!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/SetTransform.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelStandardTransform setTransform method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetTransform {
+
+
+    private static boolean checkLinearity(ModelStandardTransform transform)
+    {
+        double lastx = 0;
+        for (int p = 0; p < 2; p++)
+        for (int d = 0; d < 2; d++)
+        for (double i = 0; i < 1.0; i+=0.001) {
+            if(p == 0)
+                transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+            else
+                transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+            if(d == 0)
+                transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+            else
+                transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+            double x = transform.transform(i);
+            if(i == 0)
+                lastx = x;
+            else
+            {
+                if(lastx - x > 0.2) return false;
+                lastx = x;
+            }
+        }
+        return true;
+    }
+
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform transform = new ModelStandardTransform();
+        transform.setTransform(ModelStandardTransform.TRANSFORM_CONVEX);
+        if(transform.getTransform() != ModelStandardTransform.TRANSFORM_CONVEX)
+            throw new RuntimeException("transform.getTransform() doesn't return ModelStandardTransform.TRANSFORM_CONVEX!");
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/TransformAbsolute.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelStandardTransform transform method */
+
+import com.sun.media.sound.ModelStandardTransform;
+
+public class TransformAbsolute {
+
+    private static boolean checkLinearity(ModelStandardTransform transform)
+    {
+        double lastx = 0;
+        for (int p = 0; p < 2; p++)
+        for (int d = 0; d < 2; d++)
+        for (double i = 0; i < 1.0; i+=0.001) {
+            if(p == 0)
+                transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+            else
+                transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+            if(d == 0)
+                transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+            else
+                transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+            double x = transform.transform(i);
+            if(i == 0)
+                lastx = x;
+            else
+            {
+                if(lastx - x > 0.2) return false;
+                lastx = x;
+            }
+        }
+        return true;
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+
+    }
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform transform = new ModelStandardTransform();
+        transform.setTransform(ModelStandardTransform.TRANSFORM_ABSOLUTE);
+        assertTrue(Math.abs(transform.transform(0.2f) - 0.2f) < 0.0001f);
+        assertTrue(Math.abs(transform.transform(-0.8f) - 0.8f) < 0.0001f);
+        assertTrue(checkLinearity(transform));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/TransformConcave.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelStandardTransform transform method */
+
+import com.sun.media.sound.ModelStandardTransform;
+
+public class TransformConcave {
+
+    private static boolean checkLinearity(ModelStandardTransform transform)
+    {
+        double lastx = 0;
+        for (int p = 0; p < 2; p++)
+        for (int d = 0; d < 2; d++)
+        for (double i = 0; i < 1.0; i+=0.001) {
+            if(p == 0)
+                transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+            else
+                transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+            if(d == 0)
+                transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+            else
+                transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+            double x = transform.transform(i);
+            if(i == 0)
+                lastx = x;
+            else
+            {
+                if(lastx - x > 0.2) return false;
+                lastx = x;
+            }
+        }
+        return true;
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform transform = new ModelStandardTransform();
+        transform.setTransform(ModelStandardTransform.TRANSFORM_CONCAVE);
+        assertTrue(checkLinearity(transform));
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+        transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+        assertTrue(Math.abs(transform.transform(0.0f) - 0.0f) < 0.0001f);
+        assertTrue(transform.transform(0.5f) < 0.5f);
+        assertTrue(Math.abs(transform.transform(1.0f) - 1.0f) < 0.0001f);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+        transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+        assertTrue(Math.abs(transform.transform(1.0f) - 0.0f) < 0.0001f);
+        assertTrue(transform.transform(0.5f) < 0.5f);
+        assertTrue(Math.abs(transform.transform(0.0f) - 1.0f) < 0.0001f);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+        transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+        assertTrue(Math.abs(transform.transform(0.0f) + 1.0f) < 0.0001f);
+        assertTrue(transform.transform(0.25f) > -0.5f);
+        assertTrue(Math.abs(transform.transform(0.5f) - 0.0f) < 0.0001f);
+        assertTrue(transform.transform(0.75f) < 0.5f);
+        assertTrue(Math.abs(transform.transform(1.0f) - 1.0f) < 0.0001f);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+        transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+        assertTrue(Math.abs(transform.transform(1.0f) + 1.0f) < 0.0001f);
+        assertTrue(transform.transform(0.75f) > -0.5f);
+        assertTrue(Math.abs(transform.transform(0.50f) - 0.0f) < 0.0001f);
+        assertTrue(transform.transform(0.25f) < 0.5f);
+        assertTrue(Math.abs(transform.transform(0.0f) - 1.0f) < 0.0001f);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/TransformConvex.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelStandardTransform transform method */
+
+import com.sun.media.sound.ModelStandardTransform;
+
+public class TransformConvex {
+
+    private static boolean checkLinearity(ModelStandardTransform transform)
+    {
+        double lastx = 0;
+        for (int p = 0; p < 2; p++)
+        for (int d = 0; d < 2; d++)
+        for (double i = 0; i < 1.0; i+=0.001) {
+            if(p == 0)
+                transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+            else
+                transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+            if(d == 0)
+                transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+            else
+                transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+            double x = transform.transform(i);
+            if(i == 0)
+                lastx = x;
+            else
+            {
+                if(lastx - x > 0.2) return false;
+                lastx = x;
+            }
+        }
+        return true;
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform transform = new ModelStandardTransform();
+        transform.setTransform(ModelStandardTransform.TRANSFORM_CONVEX);
+        assertTrue(checkLinearity(transform));
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+        transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+        assertTrue(Math.abs(transform.transform(0.0f) - 0.0f) < 0.0001f);
+        assertTrue(transform.transform(0.5f) > 0.5f);
+        assertTrue(Math.abs(transform.transform(1.0f) - 1.0f) < 0.0001f);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+        transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+        assertTrue(Math.abs(transform.transform(1.0f) - 0.0f) < 0.0001f);
+        assertTrue(transform.transform(0.5f) > 0.5f);
+        assertTrue(Math.abs(transform.transform(0.0f) - 1.0f) < 0.0001f);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+        transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+        assertTrue(Math.abs(transform.transform(0.0f) + 1.0f) < 0.0001f);
+        assertTrue(transform.transform(0.25f) < -0.5f);
+        assertTrue(Math.abs(transform.transform(0.5f) - 0.0f) < 0.0001f);
+        assertTrue(transform.transform(0.75f) > 0.5f);
+        assertTrue(Math.abs(transform.transform(1.0f) - 1.0f) < 0.0001f);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+        transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+        assertTrue(Math.abs(transform.transform(1.0f) + 1.0f) < 0.0001f);
+        assertTrue(transform.transform(0.75f) < -0.5f);
+        assertTrue(Math.abs(transform.transform(0.50f) - 0.0f) < 0.0001f);
+        assertTrue(transform.transform(0.25f) > 0.5f);
+        assertTrue(Math.abs(transform.transform(0.0f) - 1.0f) < 0.0001f);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/TransformLinear.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelStandardTransform transform method */
+
+import com.sun.media.sound.ModelStandardTransform;
+
+public class TransformLinear {
+
+    private static boolean checkLinearity(ModelStandardTransform transform)
+    {
+        double lastx = 0;
+        for (int p = 0; p < 2; p++)
+        for (int d = 0; d < 2; d++)
+        for (double i = 0; i < 1.0; i+=0.001) {
+            if(p == 0)
+                transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+            else
+                transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+            if(d == 0)
+                transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+            else
+                transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+            double x = transform.transform(i);
+            if(i == 0)
+                lastx = x;
+            else
+            {
+                if(lastx - x > 0.2) return false;
+                lastx = x;
+            }
+        }
+        return true;
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform transform = new ModelStandardTransform();
+        transform.setTransform(ModelStandardTransform.TRANSFORM_LINEAR);
+        assertTrue(checkLinearity(transform));
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+        transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+        assertTrue(Math.abs(transform.transform(0.2f) - 0.2f) < 0.0001f);
+        assertTrue(Math.abs(transform.transform(0.8f) - 0.8f) < 0.0001f);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+        transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+        assertTrue(Math.abs(transform.transform(0.2f) - 0.8f) < 0.0001f);
+        assertTrue(Math.abs(transform.transform(0.8f) - 0.2f) < 0.0001f);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+        transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+        assertTrue(Math.abs(transform.transform(0.2f) - (-0.6f)) < 0.0001f);
+        assertTrue(Math.abs(transform.transform(0.8f) - (0.6f)) < 0.0001f);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+        transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+        assertTrue(Math.abs(transform.transform(0.2f) - (0.6f)) < 0.0001f);
+        assertTrue(Math.abs(transform.transform(0.8f) - (-0.6f)) < 0.0001f);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/ModelStandardTransform/TransformSwitch.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelStandardTransform transform method */
+
+import com.sun.media.sound.ModelStandardTransform;
+
+public class TransformSwitch {
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        ModelStandardTransform transform = new ModelStandardTransform();
+        transform.setTransform(ModelStandardTransform.TRANSFORM_SWITCH);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+        transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+        assertTrue(Math.abs(transform.transform(0.2f) - 0.0f) < 0.0001f);
+        assertTrue(Math.abs(transform.transform(0.8f) - 1.0f) < 0.0001f);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+        transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+        assertTrue(Math.abs(transform.transform(0.2f) - 1.0f) < 0.0001f);
+        assertTrue(Math.abs(transform.transform(0.8f) - 0.0f) < 0.0001f);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+        transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+        assertTrue(Math.abs(transform.transform(0.2f) + 1.0f) < 0.0001f);
+        assertTrue(Math.abs(transform.transform(0.8f) - 1.0f) < 0.0001f);
+
+        transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+        transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+        assertTrue(Math.abs(transform.transform(0.2f) - 1.0f) < 0.0001f);
+        assertTrue(Math.abs(transform.transform(0.8f) + 1.0f) < 0.0001f);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/Available.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader available method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Available {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.writeByte(10);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            RIFFReader readchunk = reader.nextChunk();
+            int avail = readchunk.available();
+            readchunk.readByte();
+            assertEquals(avail - 1,readchunk.available());
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/Close.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader close method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Close {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            reader.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/GetFilePointer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader getFilePointer method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetFilePointer {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.writeByte(10);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            RIFFReader readchunk = reader.nextChunk();
+            long p = readchunk.getFilePointer();
+            readchunk.readByte();
+            assertEquals(p+1,readchunk.getFilePointer());
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/GetSize.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader getSize method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetSize {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.writeByte(10);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            RIFFReader readchunk = reader.nextChunk();
+            assertEquals(readchunk.getSize(), (long)readchunk.available());
+            readchunk.readByte();
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/HasNextChunk.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader hasNextChunk method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class HasNextChunk {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean a) throws Exception
+    {
+        if(!a)
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.writeByte(10);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            assertTrue(reader.hasNextChunk());
+            RIFFReader readchunk = reader.nextChunk();
+            readchunk.readByte();
+            readchunk.close();
+            assertTrue(!reader.hasNextChunk());
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/Read.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader read method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Read {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.write((byte)33);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            assertEquals(reader.getFormat(), "RIFF");
+            assertEquals(reader.getType(), "TEST");
+            RIFFReader readchunk = reader.nextChunk();
+            assertEquals(readchunk.getFormat(), "TSCH");
+            assertEquals(readchunk.read(), 33);
+            fis.close();
+            reader = null;
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadByte.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader read(byte) method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadByte {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.writeByte((byte)33);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            assertEquals(reader.getFormat(), "RIFF");
+            assertEquals(reader.getType(), "TEST");
+            RIFFReader readchunk = reader.nextChunk();
+            assertEquals(readchunk.getFormat(), "TSCH");
+            assertEquals((int)reader.readByte(), 33);
+            fis.close();
+            reader = null;
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadByteArrayIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader read(byte[], int, int) method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadByteArrayIntInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.write(new byte[] {1,2,3});
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            assertEquals(reader.getFormat(), "RIFF");
+            assertEquals(reader.getType(), "TEST");
+            RIFFReader readchunk = reader.nextChunk();
+            assertEquals(readchunk.getFormat(), "TSCH");
+            assertEquals(readchunk.read(), 1);
+            assertEquals(readchunk.read(), 2);
+            assertEquals(readchunk.read(), 3);
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader readInt method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.writeInt(133);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            assertEquals(reader.getFormat(), "RIFF");
+            assertEquals(reader.getType(), "TEST");
+            RIFFReader readchunk = reader.nextChunk();
+            assertEquals(readchunk.getFormat(), "TSCH");
+            assertEquals(reader.readInt(), 133);
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadLong.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader readLong method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadLong {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.writeLong(133L);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            assertEquals(reader.getFormat(), "RIFF");
+            assertEquals(reader.getType(), "TEST");
+            RIFFReader readchunk = reader.nextChunk();
+            assertEquals(readchunk.getFormat(), "TSCH");
+            assertEquals(reader.readLong(), 133L);
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadShort.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader readShort method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadShort {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.writeShort((short)133);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            assertEquals(reader.getFormat(), "RIFF");
+            assertEquals(reader.getType(), "TEST");
+            RIFFReader readchunk = reader.nextChunk();
+            assertEquals(readchunk.getFormat(), "TSCH");
+            assertEquals(reader.readShort(), (short)133);
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadString.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader readString method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadString {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.writeString("HELLO",5);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            assertEquals(reader.getFormat(), "RIFF");
+            assertEquals(reader.getType(), "TEST");
+            RIFFReader readchunk = reader.nextChunk();
+            assertEquals(readchunk.getFormat(), "TSCH");
+            assertEquals(reader.readString(5), "HELLO");
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadUnsignedByte.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader readUnsignedByte method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadUnsignedByte {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.writeUnsignedByte(77);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            assertEquals(reader.getFormat(), "RIFF");
+            assertEquals(reader.getType(), "TEST");
+            RIFFReader readchunk = reader.nextChunk();
+            assertEquals(readchunk.getFormat(), "TSCH");
+            assertEquals(reader.readUnsignedByte(), 77);
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadUnsignedInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader readUnsignedInt method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadUnsignedInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.writeUnsignedInt(55377);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            assertEquals(reader.getFormat(), "RIFF");
+            assertEquals(reader.getType(), "TEST");
+            RIFFReader readchunk = reader.nextChunk();
+            assertEquals(readchunk.getFormat(), "TSCH");
+            assertEquals(reader.readUnsignedInt(), 55377L);
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/ReadUnsignedShort.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader readUnsignedShort method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadUnsignedShort {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.writeUnsignedShort(377);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            assertEquals(reader.getFormat(), "RIFF");
+            assertEquals(reader.getType(), "TEST");
+            RIFFReader readchunk = reader.nextChunk();
+            assertEquals(readchunk.getFormat(), "TSCH");
+            assertEquals(reader.readUnsignedShort(), 377);
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/Skip.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffReader skip method */
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Skip {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            writer = new RIFFWriter(tempfile, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.write((byte)33);
+            chunk.write((byte)44);
+            writer.close();
+            writer = null;
+            FileInputStream fis = new FileInputStream(tempfile);
+            reader = new RIFFReader(fis);
+            RIFFReader readchunk = reader.nextChunk();
+            reader.skip(1);
+            assertEquals(readchunk.read(), 44);
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/RiffReaderWriter/WriteOutputStream.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test RiffWriter(OutputStream) constructor */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class WriteOutputStream {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        RIFFWriter writer = null;
+        RIFFReader reader = null;
+        File tempfile = File.createTempFile("test",".riff");
+        try
+        {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            writer = new RIFFWriter(baos, "TEST");
+            RIFFWriter chunk = writer.writeChunk("TSCH");
+            chunk.write((byte)33);
+            writer.close();
+            writer = null;
+            ByteArrayInputStream fis = new ByteArrayInputStream(baos.toByteArray());
+            reader = new RIFFReader(fis);
+            assertEquals(reader.getFormat(), "RIFF");
+            assertEquals(reader.getType(), "TEST");
+            RIFFReader readchunk = reader.nextChunk();
+            assertEquals(readchunk.getFormat(), "TSCH");
+            assertEquals(readchunk.read(), 33);
+            fis.close();
+            reader = null;
+
+
+        }
+        finally
+        {
+            if(writer != null)
+                writer.close();
+            if(reader != null)
+                reader.close();
+
+            if(tempfile.exists())
+                if(!tempfile.delete())
+                    tempfile.deleteOnExit();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SF2SoundbankReader/TestGetSoundbankFile.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test SF2SoundbankReader getSoundbank(File) method */
+
+import java.io.File;
+
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+
+import com.sun.media.sound.SF2SoundbankReader;
+
+public class TestGetSoundbankFile {
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        File file = new File(System.getProperty("test.src", "."), "ding.sf2");
+        Soundbank sf2 = new SF2SoundbankReader().getSoundbank(file);
+        assertTrue(sf2.getInstruments().length == 1);
+        Patch patch = sf2.getInstruments()[0].getPatch();
+        assertTrue(patch.getProgram() == 0);
+        assertTrue(patch.getBank() == 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SF2SoundbankReader/TestGetSoundbankInputStream.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test SF2SoundbankReader getSoundbank(InputStream) method */
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+
+import com.sun.media.sound.SF2SoundbankReader;
+
+public class TestGetSoundbankInputStream {
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        File file = new File(System.getProperty("test.src", "."), "ding.sf2");
+        FileInputStream fis = new FileInputStream(file);
+        BufferedInputStream bis = new BufferedInputStream(fis);
+        try
+        {
+            Soundbank sf2 = new SF2SoundbankReader().getSoundbank(bis);
+            assertTrue(sf2.getInstruments().length == 1);
+            Patch patch = sf2.getInstruments()[0].getPatch();
+            assertTrue(patch.getProgram() == 0);
+            assertTrue(patch.getBank() == 0);
+        }
+        finally
+        {
+            bis.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SF2SoundbankReader/TestGetSoundbankInputStream2.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test SF2SoundbankReader getSoundbank(InputStream) method using
+     very bad InputStream which can only read 1 byte at time */
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+
+import com.sun.media.sound.SF2SoundbankReader;
+
+public class TestGetSoundbankInputStream2 {
+
+    private static class BadInputStream extends InputStream
+    {
+
+        InputStream is;
+
+        public BadInputStream(InputStream is)
+        {
+            this.is = is;
+        }
+
+        public int read() throws IOException {
+            return is.read();
+        }
+
+        public int read(byte[] b, int off, int len) throws IOException {
+            if(len > 1) len = 1;
+            return is.read(b, off, len);
+        }
+
+        public int read(byte[] b) throws IOException {
+            return read(b, 0, b.length);
+        }
+
+        public long skip(long n) throws IOException {
+            if(n > 1) n = 1;
+            return is.skip(n);
+        }
+
+        public int available() throws IOException {
+            int avail = is.available();
+            if(avail > 1) avail = 1;
+            return avail;
+        }
+
+        public void close() throws IOException {
+            is.close();
+        }
+
+        public synchronized void mark(int readlimit) {
+            is.mark(readlimit);
+        }
+
+        public boolean markSupported() {
+            return is.markSupported();
+        }
+
+        public synchronized void reset() throws IOException {
+            is.reset();
+        }
+
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        File file = new File(System.getProperty("test.src", "."), "ding.sf2");
+        FileInputStream fis = new FileInputStream(file);
+        BufferedInputStream bis = new BufferedInputStream(fis);
+        try
+        {
+            InputStream badis = new BadInputStream(bis);
+            Soundbank sf2 = new SF2SoundbankReader().getSoundbank(badis);
+            assertTrue(sf2.getInstruments().length == 1);
+            Patch patch = sf2.getInstruments()[0].getPatch();
+            assertTrue(patch.getProgram() == 0);
+            assertTrue(patch.getBank() == 0);
+        }
+        finally
+        {
+            bis.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SF2SoundbankReader/TestGetSoundbankUrl.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test SF2SoundbankReader getSoundbank(File) method */
+
+import java.io.File;
+import java.net.URL;
+
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+
+import com.sun.media.sound.SF2SoundbankReader;
+
+public class TestGetSoundbankUrl {
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        File file = new File(System.getProperty("test.src", "."), "ding.sf2");
+        URL url = file.toURI().toURL();
+        Soundbank sf2 = new SF2SoundbankReader().getSoundbank(url);
+        assertTrue(sf2.getInstruments().length == 1);
+        Patch patch = sf2.getInstruments()[0].getPatch();
+        assertTrue(patch.getProgram() == 0);
+        assertTrue(patch.getBank() == 0);
+    }
+}
Binary file jdk/test/javax/sound/midi/Gervill/SF2SoundbankReader/ding.sf2 has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelInstrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument add(ModelInstrument) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddModelInstrument {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        SimpleInstrument subins = new SimpleInstrument();
+        subins.add(performers[0]);
+        instrument.add(subins);
+        instrument.add(performers[1]);
+        ModelPerformer[] performers2 = instrument.getPerformers();
+        for (int i = 0; i < performers2.length; i++) {
+            assertEquals(performers[i].getConnectionBlocks(), performers2[i].getConnectionBlocks());
+            assertEquals(performers[i].getExclusiveClass(), performers2[i].getExclusiveClass());
+            assertEquals(performers[i].getKeyFrom(), performers2[i].getKeyFrom());
+            assertEquals(performers[i].getKeyTo(), performers2[i].getKeyTo());
+            assertEquals(performers[i].getVelFrom(), performers2[i].getVelFrom());
+            assertEquals(performers[i].getVelTo(), performers2[i].getVelTo());
+            assertEquals(performers[i].getOscillators(), performers2[i].getOscillators());
+            assertEquals(performers[i].isSelfNonExclusive(), performers2[i].isSelfNonExclusive());
+            assertEquals(performers[i].isDefaultConnectionsEnabled(), performers2[i].isDefaultConnectionsEnabled());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelInstrumentIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument add(ModelInstrument,int,int) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddModelInstrumentIntInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        SimpleInstrument subins = new SimpleInstrument();
+        subins.add(performers[0]);
+        instrument.add(subins, 18, 40);
+        ModelPerformer[] performers2 = instrument.getPerformers();
+        for (int i = 0; i < performers2.length; i++) {
+            assertEquals(performers[i].getConnectionBlocks(), performers2[i].getConnectionBlocks());
+            assertEquals(performers[i].getExclusiveClass(), performers2[i].getExclusiveClass());
+            if(performers[i].getKeyFrom() < 18)
+                assertEquals(18, performers2[i].getKeyFrom());
+            else
+                assertEquals(performers[i].getKeyFrom(), performers2[i].getKeyFrom());
+            if(performers[i].getKeyTo() > 40)
+                assertEquals(40, performers2[i].getKeyTo());
+            else
+                assertEquals(performers[i].getKeyTo(), performers2[i].getKeyTo());
+            assertEquals(performers[i].getVelFrom(), performers2[i].getVelFrom());
+            assertEquals(performers[i].getVelTo(), performers2[i].getVelTo());
+            assertEquals(performers[i].getOscillators(), performers2[i].getOscillators());
+            assertEquals(performers[i].isSelfNonExclusive(), performers2[i].isSelfNonExclusive());
+            assertEquals(performers[i].isDefaultConnectionsEnabled(), performers2[i].isDefaultConnectionsEnabled());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelInstrumentIntIntIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument add(ModelInstrument,int,int,int,int) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddModelInstrumentIntIntIntInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        SimpleInstrument subins = new SimpleInstrument();
+        subins.add(performers[0]);
+        instrument.add(subins,18,40,20,75);
+        ModelPerformer[] performers2 = instrument.getPerformers();
+        for (int i = 0; i < performers2.length; i++) {
+            assertEquals(performers[i].getConnectionBlocks(), performers2[i].getConnectionBlocks());
+            assertEquals(performers[i].getExclusiveClass(), performers2[i].getExclusiveClass());
+            if(performers[i].getKeyFrom() < 18)
+                assertEquals(18, performers2[i].getKeyFrom());
+            else
+                assertEquals(performers[i].getKeyFrom(), performers2[i].getKeyFrom());
+            if(performers[i].getKeyTo() > 40)
+                assertEquals(40, performers2[i].getKeyTo());
+            else
+                assertEquals(performers[i].getKeyTo(), performers2[i].getKeyTo());
+            if(performers[i].getVelFrom() < 20)
+                assertEquals(20, performers2[i].getVelFrom());
+            else
+                assertEquals(performers[i].getVelFrom(), performers2[i].getVelFrom());
+            if(performers[i].getVelTo() > 75)
+                assertEquals(75, performers2[i].getVelTo());
+            else
+                assertEquals(performers[i].getVelTo(), performers2[i].getVelTo());
+            assertEquals(performers[i].getOscillators(), performers2[i].getOscillators());
+            assertEquals(performers[i].isSelfNonExclusive(), performers2[i].isSelfNonExclusive());
+            assertEquals(performers[i].isDefaultConnectionsEnabled(), performers2[i].isDefaultConnectionsEnabled());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelInstrumentIntIntIntIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument add(ModelInstrument,int,int,int,int,int) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddModelInstrumentIntIntIntIntInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        SimpleInstrument subins = new SimpleInstrument();
+        subins.add(performers[0]);
+        instrument.add(subins,18,40,20,75,12);
+        ModelPerformer[] performers2 = instrument.getPerformers();
+        for (int i = 0; i < performers2.length; i++) {
+            assertEquals(performers[i].getConnectionBlocks(), performers2[i].getConnectionBlocks());
+            assertEquals(12, performers2[i].getExclusiveClass());
+            if(performers[i].getKeyFrom() < 18)
+                assertEquals(18, performers2[i].getKeyFrom());
+            else
+                assertEquals(performers[i].getKeyFrom(), performers2[i].getKeyFrom());
+            if(performers[i].getKeyTo() > 40)
+                assertEquals(40, performers2[i].getKeyTo());
+            else
+                assertEquals(performers[i].getKeyTo(), performers2[i].getKeyTo());
+            if(performers[i].getVelFrom() < 20)
+                assertEquals(20, performers2[i].getVelFrom());
+            else
+                assertEquals(performers[i].getVelFrom(), performers2[i].getVelFrom());
+            if(performers[i].getVelTo() > 75)
+                assertEquals(75, performers2[i].getVelTo());
+            else
+                assertEquals(performers[i].getVelTo(), performers2[i].getVelTo());
+            assertEquals(performers[i].getOscillators(), performers2[i].getOscillators());
+            assertEquals(performers[i].isSelfNonExclusive(), performers2[i].isSelfNonExclusive());
+            assertEquals(performers[i].isDefaultConnectionsEnabled(), performers2[i].isDefaultConnectionsEnabled());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument add(ModelPerformer) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddModelPerformer {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        instrument.add(performers[0]);
+        ModelPerformer[] performers2 = instrument.getPerformers();
+        for (int i = 0; i < performers2.length; i++) {
+            assertEquals(performers[i].getConnectionBlocks(), performers2[i].getConnectionBlocks());
+            assertEquals(performers[i].getExclusiveClass(), performers2[i].getExclusiveClass());
+            assertEquals(performers[i].getKeyFrom(), performers2[i].getKeyFrom());
+            assertEquals(performers[i].getKeyTo(), performers2[i].getKeyTo());
+            assertEquals(performers[i].getVelFrom(), performers2[i].getVelFrom());
+            assertEquals(performers[i].getVelTo(), performers2[i].getVelTo());
+            assertEquals(performers[i].getOscillators(), performers2[i].getOscillators());
+            assertEquals(performers[i].isSelfNonExclusive(), performers2[i].isSelfNonExclusive());
+            assertEquals(performers[i].isDefaultConnectionsEnabled(), performers2[i].isDefaultConnectionsEnabled());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerArray.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument add(ModelPerformer[]) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddModelPerformerArray {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        instrument.add(performers);
+        ModelPerformer[] performers2 = instrument.getPerformers();
+        for (int i = 0; i < performers2.length; i++) {
+            assertEquals(performers[i].getConnectionBlocks(), performers2[i].getConnectionBlocks());
+            assertEquals(performers[i].getExclusiveClass(), performers2[i].getExclusiveClass());
+            assertEquals(performers[i].getKeyFrom(), performers2[i].getKeyFrom());
+            assertEquals(performers[i].getKeyTo(), performers2[i].getKeyTo());
+            assertEquals(performers[i].getVelFrom(), performers2[i].getVelFrom());
+            assertEquals(performers[i].getVelTo(), performers2[i].getVelTo());
+            assertEquals(performers[i].getOscillators(), performers2[i].getOscillators());
+            assertEquals(performers[i].isSelfNonExclusive(), performers2[i].isSelfNonExclusive());
+            assertEquals(performers[i].isDefaultConnectionsEnabled(), performers2[i].isDefaultConnectionsEnabled());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerArrayIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument add(ModelPerformer[],int,int) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddModelPerformerArrayIntInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        instrument.add(performers,18,40);
+        ModelPerformer[] performers2 = instrument.getPerformers();
+        for (int i = 0; i < performers2.length; i++) {
+            assertEquals(performers[i].getConnectionBlocks(), performers2[i].getConnectionBlocks());
+            assertEquals(performers[i].getExclusiveClass(), performers2[i].getExclusiveClass());
+            if(performers[i].getKeyFrom() < 18)
+                assertEquals(18, performers2[i].getKeyFrom());
+            else
+                assertEquals(performers[i].getKeyFrom(), performers2[i].getKeyFrom());
+            if(performers[i].getKeyTo() > 40)
+                assertEquals(40, performers2[i].getKeyTo());
+            else
+                assertEquals(performers[i].getKeyTo(), performers2[i].getKeyTo());
+            assertEquals(performers[i].getVelFrom(), performers2[i].getVelFrom());
+            assertEquals(performers[i].getVelTo(), performers2[i].getVelTo());
+            assertEquals(performers[i].getOscillators(), performers2[i].getOscillators());
+            assertEquals(performers[i].isSelfNonExclusive(), performers2[i].isSelfNonExclusive());
+            assertEquals(performers[i].isDefaultConnectionsEnabled(), performers2[i].isDefaultConnectionsEnabled());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerArrayIntIntIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument add(ModelPerformer[],int,int,int,int) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddModelPerformerArrayIntIntIntInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        instrument.add(performers,18,40,20,75);
+        ModelPerformer[] performers2 = instrument.getPerformers();
+        for (int i = 0; i < performers2.length; i++) {
+            assertEquals(performers[i].getConnectionBlocks(), performers2[i].getConnectionBlocks());
+            assertEquals(performers[i].getExclusiveClass(), performers2[i].getExclusiveClass());
+            if(performers[i].getKeyFrom() < 18)
+                assertEquals(18, performers2[i].getKeyFrom());
+            else
+                assertEquals(performers[i].getKeyFrom(), performers2[i].getKeyFrom());
+            if(performers[i].getKeyTo() > 40)
+                assertEquals(40, performers2[i].getKeyTo());
+            else
+                assertEquals(performers[i].getKeyTo(), performers2[i].getKeyTo());
+            if(performers[i].getVelFrom() < 20)
+                assertEquals(20, performers2[i].getVelFrom());
+            else
+                assertEquals(performers[i].getVelFrom(), performers2[i].getVelFrom());
+            if(performers[i].getVelTo() > 75)
+                assertEquals(75, performers2[i].getVelTo());
+            else
+                assertEquals(performers[i].getVelTo(), performers2[i].getVelTo());
+            assertEquals(performers[i].getOscillators(), performers2[i].getOscillators());
+            assertEquals(performers[i].isSelfNonExclusive(), performers2[i].isSelfNonExclusive());
+            assertEquals(performers[i].isDefaultConnectionsEnabled(), performers2[i].isDefaultConnectionsEnabled());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerArrayIntIntIntIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument add(ModelPerformer[],int,int,int,int,int) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddModelPerformerArrayIntIntIntIntInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        instrument.add(performers,18,40,20,75,12);
+        ModelPerformer[] performers2 = instrument.getPerformers();
+        for (int i = 0; i < performers2.length; i++) {
+            assertEquals(performers[i].getConnectionBlocks(), performers2[i].getConnectionBlocks());
+            assertEquals(12, performers2[i].getExclusiveClass());
+            if(performers[i].getKeyFrom() < 18)
+                assertEquals(18, performers2[i].getKeyFrom());
+            else
+                assertEquals(performers[i].getKeyFrom(), performers2[i].getKeyFrom());
+            if(performers[i].getKeyTo() > 40)
+                assertEquals(40, performers2[i].getKeyTo());
+            else
+                assertEquals(performers[i].getKeyTo(), performers2[i].getKeyTo());
+            if(performers[i].getVelFrom() < 20)
+                assertEquals(20, performers2[i].getVelFrom());
+            else
+                assertEquals(performers[i].getVelFrom(), performers2[i].getVelFrom());
+            if(performers[i].getVelTo() > 75)
+                assertEquals(75, performers2[i].getVelTo());
+            else
+                assertEquals(performers[i].getVelTo(), performers2[i].getVelTo());
+            assertEquals(performers[i].getOscillators(), performers2[i].getOscillators());
+            assertEquals(performers[i].isSelfNonExclusive(), performers2[i].isSelfNonExclusive());
+            assertEquals(performers[i].isDefaultConnectionsEnabled(), performers2[i].isDefaultConnectionsEnabled());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument add(ModelPerformer,int,int) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddModelPerformerIntInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        instrument.add(performers[0],18,40);
+        ModelPerformer[] performers2 = instrument.getPerformers();
+        for (int i = 0; i < performers2.length; i++) {
+            assertEquals(performers[i].getConnectionBlocks(), performers2[i].getConnectionBlocks());
+            assertEquals(performers[i].getExclusiveClass(), performers2[i].getExclusiveClass());
+            if(performers[i].getKeyFrom() < 18)
+                assertEquals(18, performers2[i].getKeyFrom());
+            else
+                assertEquals(performers[i].getKeyFrom(), performers2[i].getKeyFrom());
+            if(performers[i].getKeyTo() > 40)
+                assertEquals(40, performers2[i].getKeyTo());
+            else
+                assertEquals(performers[i].getKeyTo(), performers2[i].getKeyTo());
+            assertEquals(performers[i].getVelFrom(), performers2[i].getVelFrom());
+            assertEquals(performers[i].getVelTo(), performers2[i].getVelTo());
+            assertEquals(performers[i].getOscillators(), performers2[i].getOscillators());
+            assertEquals(performers[i].isSelfNonExclusive(), performers2[i].isSelfNonExclusive());
+            assertEquals(performers[i].isDefaultConnectionsEnabled(), performers2[i].isDefaultConnectionsEnabled());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerIntIntIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument add(ModelPerformer,int,int,int,int) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddModelPerformerIntIntIntInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        instrument.add(performers[0],18,40,20,75);
+        ModelPerformer[] performers2 = instrument.getPerformers();
+        for (int i = 0; i < performers2.length; i++) {
+            assertEquals(performers[i].getConnectionBlocks(), performers2[i].getConnectionBlocks());
+            assertEquals(performers[i].getExclusiveClass(), performers2[i].getExclusiveClass());
+            if(performers[i].getKeyFrom() < 18)
+                assertEquals(18, performers2[i].getKeyFrom());
+            else
+                assertEquals(performers[i].getKeyFrom(), performers2[i].getKeyFrom());
+            if(performers[i].getKeyTo() > 40)
+                assertEquals(40, performers2[i].getKeyTo());
+            else
+                assertEquals(performers[i].getKeyTo(), performers2[i].getKeyTo());
+            if(performers[i].getVelFrom() < 20)
+                assertEquals(20, performers2[i].getVelFrom());
+            else
+                assertEquals(performers[i].getVelFrom(), performers2[i].getVelFrom());
+            if(performers[i].getVelTo() > 75)
+                assertEquals(75, performers2[i].getVelTo());
+            else
+                assertEquals(performers[i].getVelTo(), performers2[i].getVelTo());
+            assertEquals(performers[i].getOscillators(), performers2[i].getOscillators());
+            assertEquals(performers[i].isSelfNonExclusive(), performers2[i].isSelfNonExclusive());
+            assertEquals(performers[i].isDefaultConnectionsEnabled(), performers2[i].isDefaultConnectionsEnabled());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/AddModelPerformerIntIntIntIntInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument add(ModelPerformer,int,int,int,int,int) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddModelPerformerIntIntIntIntInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        instrument.add(performers[0],18,40,20,75,12);
+        ModelPerformer[] performers2 = instrument.getPerformers();
+        for (int i = 0; i < performers2.length; i++) {
+            assertEquals(performers[i].getConnectionBlocks(), performers2[i].getConnectionBlocks());
+            assertEquals(12, performers2[i].getExclusiveClass());
+            if(performers[i].getKeyFrom() < 18)
+                assertEquals(18, performers2[i].getKeyFrom());
+            else
+                assertEquals(performers[i].getKeyFrom(), performers2[i].getKeyFrom());
+            if(performers[i].getKeyTo() > 40)
+                assertEquals(40, performers2[i].getKeyTo());
+            else
+                assertEquals(performers[i].getKeyTo(), performers2[i].getKeyTo());
+            if(performers[i].getVelFrom() < 20)
+                assertEquals(20, performers2[i].getVelFrom());
+            else
+                assertEquals(performers[i].getVelFrom(), performers2[i].getVelFrom());
+            if(performers[i].getVelTo() > 75)
+                assertEquals(75, performers2[i].getVelTo());
+            else
+                assertEquals(performers[i].getVelTo(), performers2[i].getVelTo());
+            assertEquals(performers[i].getOscillators(), performers2[i].getOscillators());
+            assertEquals(performers[i].isSelfNonExclusive(), performers2[i].isSelfNonExclusive());
+            assertEquals(performers[i].isDefaultConnectionsEnabled(), performers2[i].isDefaultConnectionsEnabled());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/Clear.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument clear method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Clear {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        instrument.add(performers[0]);
+        instrument.clear();
+        assertEquals(instrument.getPerformers().length, 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/SetName.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument setName(String) method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetName {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        instrument.setName("hello");
+        assertEquals(instrument.getName(), "hello");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleInstrument/SetPatch.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleInstrument setPatch(Patch) method */
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetPatch {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        SimpleInstrument instrument = new SimpleInstrument();
+
+        ModelPerformer[] performers = new ModelPerformer[2];
+
+        performers[0] = new ModelPerformer();
+        performers[0].setExclusiveClass(1);
+        performers[0].setKeyFrom(36);
+        performers[0].setKeyTo(48);
+        performers[0].setVelFrom(16);
+        performers[0].setVelTo(80);
+        performers[0].setSelfNonExclusive(true);
+        performers[0].setDefaultConnectionsEnabled(false);
+        performers[0].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[0].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        performers[1] = new ModelPerformer();
+        performers[1].setExclusiveClass(0);
+        performers[1].setKeyFrom(12);
+        performers[1].setKeyTo(24);
+        performers[1].setVelFrom(20);
+        performers[1].setVelTo(90);
+        performers[1].setSelfNonExclusive(false);
+        performers[0].setDefaultConnectionsEnabled(true);
+        performers[1].getConnectionBlocks().add(new ModelConnectionBlock());
+        performers[1].getOscillators().add(new ModelByteBufferWavetable(new ModelByteBuffer(new byte[] {1,2,3})));
+
+        Patch patch = new Patch(0,36);
+        instrument.setPatch(patch);
+        assertEquals(instrument.getPatch().getProgram(), patch.getProgram());
+        assertEquals(instrument.getPatch().getBank(), patch.getBank());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/AddInstrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleSoundbank addInstrument method */
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddInstrument {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SimpleSoundbank soundbank = new SimpleSoundbank();
+        SimpleInstrument ins = new SimpleInstrument();
+        ins.setPatch(new Patch(3,7));
+        soundbank.addInstrument(ins);
+        assertEquals(soundbank.getInstruments().length, 1);
+        assertEquals(soundbank.getInstruments()[0], ins);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/AddResource.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleSoundbank addResource method */
+
+import javax.sound.midi.SoundbankResource;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AddResource {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SimpleSoundbank soundbank = new SimpleSoundbank();
+        SoundbankResource res = new SoundbankResource(soundbank, "test", null) {
+            public Object getData() {
+                return null;
+            }};
+        soundbank.addResource(res);
+        assertEquals(soundbank.getResources().length, 1);
+        assertEquals(soundbank.getResources()[0], res);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/GetInstrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleSoundbank getInstrument method */
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetInstrument {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SimpleSoundbank soundbank = new SimpleSoundbank();
+        SimpleInstrument ins = new SimpleInstrument();
+        ins.setPatch(new Patch(3,7));
+        soundbank.addInstrument(ins);
+        assertEquals(soundbank.getInstrument(new Patch(3,7)), ins);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/RemoveInstrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleSoundbank removeInstrument method */
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class RemoveInstrument {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean a) throws Exception
+    {
+        if(!a)
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SimpleSoundbank soundbank = new SimpleSoundbank();
+        SimpleInstrument ins = new SimpleInstrument();
+        ins.setPatch(new Patch(3,7));
+        soundbank.addInstrument(ins);
+        soundbank.removeInstrument(ins);
+        assertEquals(soundbank.getInstruments().length, 0);
+        assertTrue(soundbank.getInstrument(new Patch(3,7)) == null);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/SetDescription.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleSoundbank setDescription method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetDescription {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SimpleSoundbank soundbank = new SimpleSoundbank();
+        soundbank.setDescription("hello");
+        assertEquals(soundbank.getDescription(), "hello");
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/SetName.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleSoundbank setName method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetName {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SimpleSoundbank soundbank = new SimpleSoundbank();
+        soundbank.setName("hello");
+        assertEquals(soundbank.getName(), "hello");
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/SetVendor.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleSoundbank setVendor method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetVendor {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SimpleSoundbank soundbank = new SimpleSoundbank();
+        soundbank.setVendor("hello");
+        assertEquals(soundbank.getVendor(), "hello");
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SimpleSoundbank/SetVersion.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SimpleSoundbank setVersion method */
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SetVersion {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SimpleSoundbank soundbank = new SimpleSoundbank();
+        soundbank.setVersion("hello");
+        assertEquals(soundbank.getVersion(), "hello");
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftAudioBuffer/Array.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftAudioBuffer array method */
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Array {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioFormat frm = new AudioFormat(8000, 8, 1, true, false);
+        SoftAudioBuffer buff = new SoftAudioBuffer(377, frm);
+        float[] ar = buff.array();
+        assertEquals(ar.length, 377);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftAudioBuffer/Clear.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftAudioBuffer clear method */
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Clear {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioFormat frm = new AudioFormat(8000, 8, 1, true, false);
+        SoftAudioBuffer buff = new SoftAudioBuffer(377, frm);
+        buff.array();
+        assertTrue(!buff.isSilent());
+        buff.clear();
+        assertTrue(buff.isSilent());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftAudioBuffer/Get.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftAudioBuffer get method */
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Get {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioFormat frm = new AudioFormat(8000, 16, 1, true, false);
+        SoftAudioBuffer buff = new SoftAudioBuffer(100, frm);
+        float[] ar = buff.array();
+        for (int i = 0; i < ar.length; i++) {
+            if(i % 2 == 0)
+                ar[i] = 1;
+            if(i % 2 == 0)
+                ar[i] = -0.5f;
+        }
+
+        byte[] bbuff = new byte[ar.length*frm.getFrameSize()];
+        buff.get(bbuff, 0);
+        float[] ar2 = new float[ar.length];
+        AudioFloatConverter.getConverter(frm).toFloatArray(bbuff, ar2);
+
+        for (int i = 0; i < ar2.length; i++)
+            if(Math.abs(ar[i] - ar2[i]) > 0.001)
+                throw new Exception("conversion failure!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftAudioBuffer/NewSoftAudioBuffer.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftAudioBuffer constructor */
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewSoftAudioBuffer {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioFormat frm = new AudioFormat(8000, 8, 1, true, false);
+        SoftAudioBuffer buff = new SoftAudioBuffer(377, frm);
+        assertEquals(buff.getSize(), 377);
+        assertEquals(buff.getFormat(), frm);
+        assertTrue(buff.isSilent());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftAudioSynthesizer/DummySourceDataLine.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.util.ArrayList;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Control;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.AudioFormat.Encoding;
+import javax.sound.sampled.Control.Type;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+/**
+ * This is a SourceDataLine simulator used for testing SoftSynthesizer
+ * without using real SourceDataLine / Audio Device.
+ *
+ * @author Karl Helgason
+ */
+
+public class DummySourceDataLine implements SourceDataLine {
+
+    private int bufferSize = -1;
+
+    private AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false);
+
+    private DataLine.Info sourceLineInfo;
+
+    private boolean active = false;
+
+    private long framepos = 0;
+
+    private boolean opened = false;
+
+    private int framesize = 0;
+
+    public DummySourceDataLine()
+    {
+        ArrayList<AudioFormat> formats = new ArrayList<AudioFormat>();
+        for (int channels = 1; channels <= 2; channels++) {
+            formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+            for (int bits = 16; bits < 32; bits += 8) {
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+            }
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, true));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, true));
+        }
+        AudioFormat[] formats_array = formats.toArray(new AudioFormat[formats
+                .size()]);
+        sourceLineInfo = new DataLine.Info(SourceDataLine.class,
+                formats_array, AudioSystem.NOT_SPECIFIED,
+                AudioSystem.NOT_SPECIFIED);
+
+    }
+
+    public void open() throws LineUnavailableException {
+        open(format);
+    }
+
+    public void open(AudioFormat format) throws LineUnavailableException {
+        if (bufferSize == -1)
+            bufferSize = ((int) (format.getFrameRate() / 2))
+                    * format.getFrameSize();
+        open(format, bufferSize);
+    }
+
+    public void open(AudioFormat format, int bufferSize)
+            throws LineUnavailableException {
+        this.format = format;
+        this.bufferSize = bufferSize;
+        this.framesize = format.getFrameSize();
+        opened = true;
+    }
+
+    public boolean isOpen() {
+        return opened;
+    }
+
+    public int write(byte[] b, int off, int len) {
+        if (!isOpen())
+            return 0;
+        if (len % framesize != 0)
+            throw new IllegalArgumentException(
+                    "Number of bytes does not represent an integral number of sample frames.");
+
+
+        int flen = len / framesize;
+        framepos += flen;
+
+        long time =  (long) (flen * (1000.0 / (double) getFormat()
+                .getSampleRate()));
+        try {
+            Thread.sleep(time);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+            return 0;
+        }
+
+        return len;
+    }
+
+    public int available() {
+        return 0;
+    }
+
+    public void drain() {
+    }
+
+    public void flush() {
+    }
+
+    public int getBufferSize() {
+        return bufferSize;
+    }
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public int getFramePosition() {
+        return (int) getLongFramePosition();
+    }
+
+    public float getLevel() {
+        return AudioSystem.NOT_SPECIFIED;
+    }
+
+    public long getLongFramePosition() {
+        return framepos;
+    }
+
+    public long getMicrosecondPosition() {
+        return (long) (getLongFramePosition() * (1000000.0 / (double) getFormat()
+                .getSampleRate()));
+    }
+
+    public boolean isActive() {
+        return active;
+    }
+
+    public boolean isRunning() {
+        return active;
+    }
+
+    public void start() {
+        active = true;
+    }
+
+    public void stop() {
+        active = false;
+    }
+
+    public void close() {
+        stop();
+    }
+
+    public Control getControl(Type control) {
+        throw new IllegalArgumentException("Unsupported control type : "
+                + control);
+    }
+
+    public Control[] getControls() {
+        return new Control[0];
+    }
+
+    public javax.sound.sampled.Line.Info getLineInfo() {
+        return sourceLineInfo;
+    }
+
+    public boolean isControlSupported(Type control) {
+        return false;
+    }
+
+    public void addLineListener(LineListener listener) {
+    }
+
+    public void removeLineListener(LineListener listener) {
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftAudioSynthesizer/GetFormat.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftAudioSynthesizer getFormat method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetFormat {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        AudioFormat defformat = synth.getFormat();
+        assertTrue(defformat != null);
+        synth.openStream(null, null);
+        assertTrue(synth.getFormat().toString().equals(defformat.toString()));
+        synth.close();
+        AudioFormat custformat = new AudioFormat(8000, 16, 1, true, false);
+        synth.openStream(custformat, null);
+        assertTrue(synth.getFormat().toString().equals(custformat.toString()));
+        synth.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftAudioSynthesizer/GetPropertyInfo.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftAudioSynthesizer getPropertyInfo method */
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetPropertyInfo {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        AudioSynthesizerPropertyInfo[] info = synth.getPropertyInfo(null);
+        assertTrue(info != null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftAudioSynthesizer/Open.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftAudioSynthesizer open method */
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Open {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        SourceDataLine line = new DummySourceDataLine(); //AudioSystem.getSourceDataLine(new AudioFormat(44100, 16, 2, true, false));
+        synth.open(line, null);
+        synth.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftAudioSynthesizer/OpenStream.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftAudioSynthesizer openStream method */
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class OpenStream {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        assertTrue(synth.isOpen());
+        synth.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/AllNotesOff.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel allNotesOff method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AllNotesOff {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        channel.noteOn(60, 64);
+        soft.read(1);
+        VoiceStatus[] v = soft.synth.getVoiceStatus();
+        assertEquals(v[0].note, 60);
+        assertEquals(v[0].active, true);
+        channel.allNotesOff();
+        soft.read(1);
+        v = soft.synth.getVoiceStatus();
+        assertEquals(v[0].active, false);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/AllSoundOff.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel allSoundOff method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class AllSoundOff {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        channel.noteOn(60, 64);
+        soft.read(1);
+        VoiceStatus[] v = soft.synth.getVoiceStatus();
+        assertEquals(v[0].note, 60);
+        assertEquals(v[0].active, true);
+        channel.allSoundOff();
+        soft.read(1);
+        v = soft.synth.getVoiceStatus();
+        assertEquals(v[0].active, false);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/ChannelPressure.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel channelPressure method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ChannelPressure {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        channel.setChannelPressure(10);
+        assertEquals(channel.getChannelPressure(), 10);
+        channel.setChannelPressure(90);
+        assertEquals(channel.getChannelPressure(), 90);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/Controller.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel controller method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Controller {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        for (int i = 0; i < 128; i++) {
+            if(i == 0 || i == 32) continue;
+            channel.controlChange(i, 10);
+            assertEquals(channel.getController(i), 10);
+            channel.controlChange(i, 100);
+            assertEquals(channel.getController(i), 100);
+        }
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/LocalControl.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel localControl method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class LocalControl {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        // Local control not supported
+        // because this is a software synthesizer
+        // localControl() should always return false
+        assertEquals(channel.localControl(true), false);
+        assertEquals(channel.localControl(false), false);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/Mono.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel mono method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Mono {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        channel.setMono(true);
+        assertEquals(channel.getMono(), true);
+        channel.setMono(false);
+        assertEquals(channel.getMono(), false);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/Mute.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel mute method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Mute {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        channel.setMute(true);
+        assertEquals(channel.getMute(), true);
+        channel.setMute(false);
+        assertEquals(channel.getMute(), false);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/NoteOff.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel noteOff method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NoteOff {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        channel.noteOn(60, 64);
+        soft.read(1);
+        VoiceStatus[] v = soft.synth.getVoiceStatus();
+        assertEquals(v[0].note, 60);
+        assertEquals(v[0].active, true);
+        channel.noteOff(60);
+        soft.read(1);
+        v = soft.synth.getVoiceStatus();;
+        assertEquals(v[0].active, false);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/NoteOff2.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel noteOff method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NoteOff2 {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        channel.noteOn(60, 64);
+        soft.read(1);
+        VoiceStatus[] v = soft.synth.getVoiceStatus();
+        assertEquals(v[0].note, 60);
+        assertEquals(v[0].active, true);
+        channel.noteOff(60);
+        soft.read(1);
+        v = soft.synth.getVoiceStatus();;
+        assertEquals(v[0].active, false);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/NoteOn.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel noteOn method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NoteOn {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        channel.noteOn(60, 64);
+        soft.read(1);
+        VoiceStatus[] v = soft.synth.getVoiceStatus();
+        assertEquals(v[0].note, 60);
+        assertEquals(v[0].active, true);
+        channel.noteOn(60, 0);
+        soft.read(1);
+        v = soft.synth.getVoiceStatus();
+        assertEquals(v[0].active, false);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/Omni.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel omni method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Omni {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        channel.setOmni(true);
+        // Poly or Omni not supported by GM2
+        // getOmni() should always return false
+        assertEquals(channel.getOmni(), false);
+        channel.setOmni(false);
+        assertEquals(channel.getOmni(), false);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/PitchBend.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel pitchBend method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class PitchBend {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        channel.setPitchBend(10);
+        assertEquals(channel.getPitchBend(), 10);
+        channel.setPitchBend(9000);
+        assertEquals(channel.getPitchBend(), 9000);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/PolyPressure.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel polyPressure method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class PolyPressure {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        for (int i = 0; i < 128; i++) {
+            channel.setPolyPressure(i, 10);
+            assertEquals(channel.getPolyPressure(i),10);
+            channel.setPolyPressure(i, 100);
+            assertEquals(channel.getPolyPressure(i),100);
+        }
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/ProgramChange.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel programChange method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ProgramChange {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        channel.programChange(36);
+        assertEquals(channel.getProgram(), 36);
+        channel.programChange(48);
+        assertEquals(channel.getProgram(), 48);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/ResetAllControllers.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel resetAllControllers method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ResetAllControllers {
+
+    public static boolean[] dontResetControls = new boolean[128];
+    static {
+        for (int i = 0; i < dontResetControls.length; i++)
+            dontResetControls[i] = false;
+
+        dontResetControls[0] = true;   // Bank Select (MSB)
+        dontResetControls[32] = true;  // Bank Select (LSB)
+        dontResetControls[7] = true;   // Channel Volume (MSB)
+        dontResetControls[8] = true;   // Balance (MSB)
+        dontResetControls[10] = true;  // Pan (MSB)
+        dontResetControls[11] = true;  // Expression (MSB)
+        dontResetControls[91] = true;  // Effects 1 Depth (default: Reverb Send)
+        dontResetControls[92] = true;  // Effects 2 Depth (default: Tremolo Depth)
+        dontResetControls[93] = true;  // Effects 3 Depth (default: Chorus Send)
+        dontResetControls[94] = true;  // Effects 4 Depth (default: Celeste [Detune] Depth)
+        dontResetControls[95] = true;  // Effects 5 Depth (default: Phaser Depth)
+        dontResetControls[70] = true;  // Sound Controller 1 (default: Sound Variation)
+        dontResetControls[71] = true;  // Sound Controller 2 (default: Timbre / Harmonic Quality)
+        dontResetControls[72] = true;  // Sound Controller 3 (default: Release Time)
+        dontResetControls[73] = true;  // Sound Controller 4 (default: Attack Time)
+        dontResetControls[74] = true;  // Sound Controller 5 (default: Brightness)
+        dontResetControls[75] = true;  // Sound Controller 6 (GM2 default: Decay Time)
+        dontResetControls[76] = true;  // Sound Controller 7 (GM2 default: Vibrato Rate)
+        dontResetControls[77] = true;  // Sound Controller 8 (GM2 default: Vibrato Depth)
+        dontResetControls[78] = true;  // Sound Controller 9 (GM2 default: Vibrato Delay)
+        dontResetControls[79] = true;  // Sound Controller 10 (GM2 default: Undefined)
+        dontResetControls[120] = true; // All Sound Off
+        dontResetControls[121] = true; // Reset All Controllers
+        dontResetControls[122] = true; // Local Control On/Off
+        dontResetControls[123] = true; // All Notes Off
+        dontResetControls[124] = true; // Omni Mode Off
+        dontResetControls[125] = true; // Omni Mode On
+        dontResetControls[126] = true; // Poly Mode Off
+        dontResetControls[127] = true; // Poly Mode On
+
+        dontResetControls[6] = true;   // Data Entry (MSB)
+        dontResetControls[38] = true;  // Data Entry (LSB)
+        dontResetControls[96] = true;  // Data Increment
+        dontResetControls[97] = true;  // Data Decrement
+        dontResetControls[98] = true;  // Non-Registered Parameter Number (LSB)
+        dontResetControls[99] = true;  // Non-Registered Parameter Number(MSB)
+        dontResetControls[100] = true; // RPN = Null
+        dontResetControls[101] = true; // RPN = Null
+    }
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        // First let all controls contain non-default values
+        for (int i = 0; i < 128; i++)
+            channel.setPolyPressure(i, 10);
+        channel.setChannelPressure(10);
+        channel.setPitchBend(2192);
+        for (int i = 0; i < 120; i++)
+            channel.controlChange(i, 1);
+        channel.resetAllControllers();
+
+        // Now check if resetAllControllers did what it was suppose to do
+
+        for (int i = 0; i < 128; i++)
+            assertEquals(channel.getPolyPressure(i), 0);
+        assertEquals(channel.getChannelPressure(), 0);
+        assertEquals(channel.getPitchBend(),8192);
+        for (int i = 0; i < 120; i++)
+            if(!dontResetControls[i])
+                assertEquals(channel.getController(i), 0);
+        assertEquals(channel.getController(71), 64); // Filter Resonance
+        assertEquals(channel.getController(72), 64); // Release Time
+        assertEquals(channel.getController(73), 64); // Attack Time
+        assertEquals(channel.getController(74), 64); // Brightness
+        assertEquals(channel.getController(75), 64); // Decay Time
+        assertEquals(channel.getController(76), 64); // Vibrato Rate
+        assertEquals(channel.getController(77), 64); // Vibrato Depth
+        assertEquals(channel.getController(78), 64); // Vibrato Delay
+        assertEquals(channel.getController(8), 64); // Balance
+        assertEquals(channel.getController(11), 127); // Expression
+        assertEquals(channel.getController(98), 127); // NRPN Null
+        assertEquals(channel.getController(99), 127); // NRPN Null
+        assertEquals(channel.getController(100), 127); // RPN = Null
+        assertEquals(channel.getController(101), 127); // RPN = Null
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/SoftTestUtils.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.io.IOException;
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SoftTestUtils {
+
+    public AudioSynthesizer synth = new SoftSynthesizer();
+    public AudioInputStream stream;
+    public byte[] tmpbuffer = new byte[1024];
+
+    public static SF2Soundbank createTestSoundBank()
+    {
+        SF2Soundbank sf2 = new SF2Soundbank();
+        AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+        float[] data = new float[44100+1000];
+        float fr = 440/format.getSampleRate();
+        for (int i = 0; i < data.length; i++)
+            data[i] = (float)Math.sin(i*fr*2*Math.PI);
+        byte[] bdata = new byte[data.length*format.getFrameSize()];
+        AudioFloatConverter.getConverter(format).toByteArray(data, bdata);
+        SF2Sample sample = new SF2Sample(sf2);
+        sample.setName("Test Sample");
+        sample.setData(bdata);
+        sample.setStartLoop(500);
+        sample.setEndLoop(data.length - 500);
+        sample.setSampleRate((long) format.getSampleRate());
+        sample.setOriginalPitch(69);
+        sf2.addResource(sample);
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Test Layer");
+        sf2.addResource(layer);
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+        SF2Instrument ins = new SF2Instrument(sf2);
+        ins.setName("Test Instrument");
+        sf2.addInstrument(ins);
+        SF2InstrumentRegion insregion = new SF2InstrumentRegion();
+        insregion.setLayer(layer);
+        ins.getRegions().add(insregion);
+
+        return sf2;
+    }
+
+    public SoftTestUtils() throws Exception {
+        stream = synth.openStream(null, null);
+        synth.unloadAllInstruments(synth.getDefaultSoundbank());
+        synth.loadAllInstruments(createTestSoundBank());
+    }
+
+    public void close() throws Exception {
+        stream.close();
+        stream = null;
+        synth.close();
+        synth = null;
+    }
+
+    public void read(double seconds) throws IOException
+    {
+        int bufflen =
+           stream.getFormat().getFrameSize() *
+           (int)(stream.getFormat().getFrameRate() * seconds);
+        while(bufflen != 0)
+        {
+            if(bufflen > 1024)
+                bufflen -= stream.read(tmpbuffer,0,1024);
+            else
+                bufflen -= stream.read(tmpbuffer,0, bufflen);
+        }
+    }
+
+    public VoiceStatus findVoice(int channel, int note) {
+        VoiceStatus[] v = synth.getVoiceStatus();
+        for (int k = 0; k < v.length; k++)
+            if(v[k].active)
+                if(v[k].channel == channel)
+                    if(v[k].note == note)
+                        return v[k];
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftChannel/Solo.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftChannel solo method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Solo {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+
+        channel.setSolo(true);
+        assertEquals(channel.getSolo(), true);
+        channel.setSolo(false);
+        assertEquals(channel.getSolo(), false);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftCubicResampler/Interpolate.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftCubicResampler interpolate method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Interpolate {
+
+    private static float getResamplerTestValue(double i)
+    {
+        return (float)Math.sin(i / 10.0);
+    }
+
+    private static void perfectInterpolation(float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+
+         float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+        if (pitchstep == 0f) {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = getResamplerTestValue(ix);
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = getResamplerTestValue(ix);
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+
+    private static float testResampler(SoftAbstractResampler resampler, float p_pitch, float p_pitch2)
+    {
+        float[] testbuffer = new float[4096];
+        float[] testbuffer2 = new float[1024];
+        float[] testbuffer3 = new float[1024];
+        for (int i = 0; i < testbuffer.length; i++)
+            testbuffer[i] = getResamplerTestValue(i);
+        int pads = resampler.getPadding();
+        float pitchstep = (p_pitch2 - p_pitch)/1024f;
+        int[] out_offset2 = {0};
+        int[] out_offset3 = {0};
+        resampler.interpolate(testbuffer, new float[] {pads}, testbuffer.length - pads, new float[] {p_pitch}, pitchstep, testbuffer2, out_offset2, testbuffer2.length);
+        perfectInterpolation(new float[] {pads}, testbuffer.length - pads, new float[] {p_pitch}, pitchstep, testbuffer3, out_offset3, testbuffer3.length);
+        int out_off = out_offset2[0];
+        if(out_offset3[0] < out_off)
+            out_off = out_offset3[0];
+        float ac_error = 0;
+        int counter = 0;
+        for (int i = pads; i < out_off; i++) {
+            ac_error += Math.abs(testbuffer2[i] - testbuffer3[i]);
+            counter++;
+        }
+        return ac_error / ((float)counter);
+    }
+
+    private static void fail(String error) throws Exception
+    {
+        throw new RuntimeException(error);
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftCubicResampler resampler = new SoftCubicResampler();
+        float max = testResampler(resampler, 0.3f, 0.3f);
+        if(max > 0.005)
+            fail("Interpolation failed, error="+max);
+        max = testResampler(resampler, 0.3f, 0.01f);
+        if(max > 0.005)
+            fail("Interpolation failed, error="+max);
+        max = testResampler(resampler, 1.0f, 0.00f);
+        if(max > 0.005)
+            fail("Interpolation failed, error="+max);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftLanczosResampler/Interpolate.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftLanczosResampler interpolate method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Interpolate {
+
+    private static float getResamplerTestValue(double i)
+    {
+        return (float)Math.sin(i / 10.0);
+    }
+
+    private static void perfectInterpolation(float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+
+         float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+        if (pitchstep == 0f) {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = getResamplerTestValue(ix);
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = getResamplerTestValue(ix);
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+
+    private static float testResampler(SoftAbstractResampler resampler, float p_pitch, float p_pitch2)
+    {
+        float[] testbuffer = new float[4096];
+        float[] testbuffer2 = new float[1024];
+        float[] testbuffer3 = new float[1024];
+        for (int i = 0; i < testbuffer.length; i++)
+            testbuffer[i] = getResamplerTestValue(i);
+        int pads = resampler.getPadding();
+        float pitchstep = (p_pitch2 - p_pitch)/1024f;
+        int[] out_offset2 = {0};
+        int[] out_offset3 = {0};
+        resampler.interpolate(testbuffer, new float[] {pads}, testbuffer.length - pads, new float[] {p_pitch}, pitchstep, testbuffer2, out_offset2, testbuffer2.length);
+        perfectInterpolation(new float[] {pads}, testbuffer.length - pads, new float[] {p_pitch}, pitchstep, testbuffer3, out_offset3, testbuffer3.length);
+        int out_off = out_offset2[0];
+        if(out_offset3[0] < out_off)
+            out_off = out_offset3[0];
+        float ac_error = 0;
+        int counter = 0;
+        for (int i = pads; i < out_off; i++) {
+            ac_error += Math.abs(testbuffer2[i] - testbuffer3[i]);
+            counter++;
+        }
+        return ac_error / ((float)counter);
+    }
+
+    private static void fail(String error) throws Exception
+    {
+        throw new RuntimeException(error);
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftLanczosResampler resampler = new SoftLanczosResampler();
+        float max = testResampler(resampler, 0.3f, 0.3f);
+        if(max > 0.01)
+            fail("Interpolation failed, error="+max);
+        max = testResampler(resampler, 0.3f, 0.01f);
+        if(max > 0.01)
+            fail("Interpolation failed, error="+max);
+        max = testResampler(resampler, 1.0f, 0.00f);
+        if(max > 0.01)
+            fail("Interpolation failed, error="+max);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_mix.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftLimiter processAudio method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ProcessAudio_replace_mix {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+
+        SoftAudioBuffer in1 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer in2 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer out1 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer out2 = new SoftAudioBuffer(250, synth.getFormat());
+
+        float[] testdata1 = new float[in1.getSize()];
+        float[] testdata2 = new float[in2.getSize()];
+        float[] n1a = in1.array();
+        float[] n2a = in2.array();
+        float[] out1a = out1.array();
+        float[] out2a = out2.array();
+        for (int i = 0; i < n1a.length; i++) {
+            testdata1[i] = (float)Math.sin(i*0.3)*0.9f;
+            testdata2[i] = (float)Math.sin(i*0.4)*0.9f;
+            n1a[i] = testdata1[i];
+            n2a[i] = testdata2[i];
+            out1a[i] = 1;
+            out2a[i] = 1;
+        }
+
+        SoftLimiter limiter = new SoftLimiter();
+        limiter.init(44100, 147);
+        limiter.setMixMode(true);
+        limiter.setInput(0, in1);
+        limiter.setInput(1, in2);
+        limiter.setOutput(0, out1);
+        limiter.setOutput(1, out2);
+        limiter.processControlLogic();
+        limiter.processAudio();
+        limiter.processControlLogic();
+        limiter.processAudio();
+        // Limiter should delay audio by one buffer,
+        // and there should almost no different in output v.s. input
+        for (int i = 0; i < n1a.length; i++) {
+            if(Math.abs(out1a[i] - testdata1[i] - 1) > 0.00001)
+                throw new Exception("input != output");
+            if(Math.abs(out2a[i] - testdata2[i] - 1) > 0.00001)
+                throw new Exception("input != output");
+        }
+
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_mix_mono.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftLimiter processAudio method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ProcessAudio_replace_mix_mono {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(new AudioFormat(44100, 16, 1, true, false), null);
+
+        SoftAudioBuffer in1 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer out1 = new SoftAudioBuffer(250, synth.getFormat());
+
+        float[] testdata1 = new float[in1.getSize()];
+        float[] n1a = in1.array();
+        float[] out1a = out1.array();
+        for (int i = 0; i < n1a.length; i++) {
+            testdata1[i] = (float)Math.sin(i*0.3)*0.9f;
+            n1a[i] = testdata1[i];
+            out1a[i] = 1;
+        }
+
+        SoftLimiter limiter = new SoftLimiter();
+        limiter.init(44100, 147);
+        limiter.setMixMode(true);
+        limiter.setInput(0, in1);
+        limiter.setOutput(0, out1);
+        limiter.processControlLogic();
+        limiter.processAudio();
+        limiter.processControlLogic();
+        limiter.processAudio();
+        // Limiter should delay audio by one buffer,
+        // and there should almost no different in output v.s. input
+        for (int i = 0; i < n1a.length; i++) {
+            if(Math.abs(out1a[i] - testdata1[i] - 1) > 0.00001)
+                throw new Exception("input != output");
+        }
+
+        synth.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_mix_mono_overdrive.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftLimiter processAudio method */
+
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ProcessAudio_replace_mix_mono_overdrive {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(new AudioFormat(44100, 16, 1, true, false), null);
+
+        SoftAudioBuffer in1 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer out1 = new SoftAudioBuffer(250, synth.getFormat());
+
+        float[] testdata1 = new float[in1.getSize()];
+        float[] n1a = in1.array();
+        float[] out1a = out1.array();
+        for (int i = 0; i < n1a.length; i++) {
+            testdata1[i] = (float)Math.sin(i*0.3)*2.5f;
+            n1a[i] = testdata1[i];
+            out1a[i] = 1;
+        }
+
+        SoftLimiter limiter = new SoftLimiter();
+        limiter.init(44100, 147);
+        limiter.setMixMode(true);
+        limiter.setInput(0, in1);
+        limiter.setOutput(0, out1);
+        limiter.processControlLogic();
+        limiter.processAudio();
+        limiter.processControlLogic();
+        limiter.processAudio();
+        // Limiter should delay audio by one buffer,
+        // and there should almost no different in output v.s. input
+        for (int i = 0; i < n1a.length; i++) {
+            if(Math.abs(out1a[i]-1) > 1.0)
+                throw new Exception("abs(output)>1");
+        }
+
+        synth.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_mix_overdrive.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftLimiter processAudio method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ProcessAudio_replace_mix_overdrive {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+
+        SoftAudioBuffer in1 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer in2 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer out1 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer out2 = new SoftAudioBuffer(250, synth.getFormat());
+
+        float[] testdata1 = new float[in1.getSize()];
+        float[] testdata2 = new float[in2.getSize()];
+        float[] n1a = in1.array();
+        float[] n2a = in2.array();
+        float[] out1a = out1.array();
+        float[] out2a = out2.array();
+        for (int i = 0; i < n1a.length; i++) {
+            testdata1[i] = (float)Math.sin(i*0.3)*2.5f;
+            testdata2[i] = (float)Math.sin(i*0.4)*2.5f;
+            n1a[i] = testdata1[i];
+            n2a[i] = testdata2[i];
+            out1a[i] = 1;
+            out2a[i] = 1;
+        }
+
+        SoftLimiter limiter = new SoftLimiter();
+        limiter.init(44100, 147);
+        limiter.setMixMode(true);
+        limiter.setInput(0, in1);
+        limiter.setInput(1, in2);
+        limiter.setOutput(0, out1);
+        limiter.setOutput(1, out2);
+        limiter.processControlLogic();
+        limiter.processAudio();
+        limiter.processControlLogic();
+        limiter.processAudio();
+        // Limiter should delay audio by one buffer,
+        // and there should almost no different in output v.s. input
+        for (int i = 0; i < n1a.length; i++) {
+            if(Math.abs(out1a[i]-1) > 1.0)
+                throw new Exception("abs(output)>1");
+            if(Math.abs(out2a[i]-1) > 1.0)
+                throw new Exception("abs(output)>1");
+        }
+
+        synth.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_normal.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftLimiter processAudio method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ProcessAudio_replace_normal {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+
+        SoftAudioBuffer in1 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer in2 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer out1 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer out2 = new SoftAudioBuffer(250, synth.getFormat());
+
+        float[] testdata1 = new float[in1.getSize()];
+        float[] testdata2 = new float[in2.getSize()];
+        float[] n1a = in1.array();
+        float[] n2a = in2.array();
+        float[] out1a = out1.array();
+        float[] out2a = out2.array();
+        for (int i = 0; i < n1a.length; i++) {
+            testdata1[i] = (float)Math.sin(i*0.3)*0.9f;
+            testdata2[i] = (float)Math.sin(i*0.4)*0.9f;
+            n1a[i] = testdata1[i];
+            n2a[i] = testdata2[i];
+            out1a[i] = 1;
+            out2a[i] = 1;
+        }
+
+        SoftLimiter limiter = new SoftLimiter();
+        limiter.init(44100, 147);
+        limiter.setMixMode(false);
+        limiter.setInput(0, in1);
+        limiter.setInput(1, in2);
+        limiter.setOutput(0, out1);
+        limiter.setOutput(1, out2);
+        limiter.processControlLogic();
+        limiter.processAudio();
+        limiter.processControlLogic();
+        limiter.processAudio();
+        // Limiter should delay audio by one buffer,
+        // and there should almost no different in output v.s. input
+        for (int i = 0; i < n1a.length; i++) {
+            if(Math.abs(out1a[i] - testdata1[i]) > 0.00001)
+                throw new Exception("input != output");
+            if(Math.abs(out2a[i] - testdata2[i]) > 0.00001)
+                throw new Exception("input != output");
+        }
+
+        synth.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_normal_mono.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftLimiter processAudio method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ProcessAudio_replace_normal_mono {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(new AudioFormat(44100, 16, 1, true, false), null);
+
+        SoftAudioBuffer in1 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer out1 = new SoftAudioBuffer(250, synth.getFormat());
+
+        float[] testdata1 = new float[in1.getSize()];
+        float[] n1a = in1.array();
+        float[] out1a = out1.array();
+        for (int i = 0; i < n1a.length; i++) {
+            testdata1[i] = (float)Math.sin(i*0.3)*0.9f;
+            n1a[i] = testdata1[i];
+            out1a[i] = 1;
+        }
+
+        SoftLimiter limiter = new SoftLimiter();
+        limiter.init(44100, 147);
+        limiter.setMixMode(false);
+        limiter.setInput(0, in1);
+        limiter.setOutput(0, out1);
+        limiter.processControlLogic();
+        limiter.processAudio();
+        limiter.processControlLogic();
+        limiter.processAudio();
+        // Limiter should delay audio by one buffer,
+        // and there should almost no different in output v.s. input
+        for (int i = 0; i < n1a.length; i++) {
+            if(Math.abs(out1a[i] - testdata1[i]) > 0.00001)
+                throw new Exception("input != output");
+        }
+
+        synth.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_overdrive.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftLimiter processAudio method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ProcessAudio_replace_overdrive {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+
+        SoftAudioBuffer in1 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer in2 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer out1 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer out2 = new SoftAudioBuffer(250, synth.getFormat());
+
+        float[] testdata1 = new float[in1.getSize()];
+        float[] testdata2 = new float[in2.getSize()];
+        float[] n1a = in1.array();
+        float[] n2a = in2.array();
+        float[] out1a = out1.array();
+        float[] out2a = out2.array();
+        for (int i = 0; i < n1a.length; i++) {
+            testdata1[i] = (float)Math.sin(i*0.3)*2.5f;
+            testdata2[i] = (float)Math.sin(i*0.4)*2.5f;
+            n1a[i] = testdata1[i];
+            n2a[i] = testdata2[i];
+            out1a[i] = 1;
+            out2a[i] = 1;
+        }
+
+        SoftLimiter limiter = new SoftLimiter();
+        limiter.init(44100, 147);
+        limiter.setMixMode(false);
+        limiter.setInput(0, in1);
+        limiter.setInput(1, in2);
+        limiter.setOutput(0, out1);
+        limiter.setOutput(1, out2);
+        limiter.processControlLogic();
+        limiter.processAudio();
+        limiter.processControlLogic();
+        limiter.processAudio();
+        // Limiter should delay audio by one buffer,
+        // and there should almost no different in output v.s. input
+        for (int i = 0; i < n1a.length; i++) {
+            if(Math.abs(out1a[i]) > 1.0)
+                throw new Exception("abs(output)>1");
+            if(Math.abs(out2a[i]) > 1.0)
+                throw new Exception("abs(output)>1");
+        }
+
+        synth.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftLimiter/ProcessAudio_replace_overdrive_mono.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftLimiter processAudio method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ProcessAudio_replace_overdrive_mono {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(new AudioFormat(44100, 16, 1, true, false), null);
+
+        SoftAudioBuffer in1 = new SoftAudioBuffer(250, synth.getFormat());
+        SoftAudioBuffer out1 = new SoftAudioBuffer(250, synth.getFormat());
+
+        float[] testdata1 = new float[in1.getSize()];
+        float[] n1a = in1.array();
+        float[] out1a = out1.array();
+        for (int i = 0; i < n1a.length; i++) {
+            testdata1[i] = (float)Math.sin(i*0.3)*2.5f;
+            n1a[i] = testdata1[i];
+            out1a[i] = 1;
+        }
+
+        SoftLimiter limiter = new SoftLimiter();
+        limiter.init(44100, 147);
+        limiter.setMixMode(false);
+        limiter.setInput(0, in1);
+        limiter.setOutput(0, out1);
+        limiter.processControlLogic();
+        limiter.processAudio();
+        limiter.processControlLogic();
+        limiter.processAudio();
+        // Limiter should delay audio by one buffer,
+        // and there should almost no different in output v.s. input
+        for (int i = 0; i < n1a.length; i++) {
+            if(Math.abs(out1a[i]) > 1.0)
+                throw new Exception("abs(output)>1");
+        }
+
+        synth.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftLinearResampler/Interpolate.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftLinearResampler interpolate method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Interpolate {
+
+    private static float getResamplerTestValue(double i)
+    {
+        return (float)Math.sin(i / 10.0);
+    }
+
+    private static void perfectInterpolation(float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+        if (pitchstep == 0f) {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = getResamplerTestValue(ix);
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = getResamplerTestValue(ix);
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+
+    private static float testResampler(SoftAbstractResampler resampler, float p_pitch, float p_pitch2)
+    {
+        float[] testbuffer = new float[4096];
+        float[] testbuffer2 = new float[1024];
+        float[] testbuffer3 = new float[1024];
+        for (int i = 0; i < testbuffer.length; i++)
+            testbuffer[i] = getResamplerTestValue(i);
+        int pads = resampler.getPadding();
+        float pitchstep = (p_pitch2 - p_pitch)/1024f;
+        int[] out_offset2 = {0};
+        int[] out_offset3 = {0};
+        resampler.interpolate(testbuffer, new float[] {pads}, testbuffer.length - pads, new float[] {p_pitch}, pitchstep, testbuffer2, out_offset2, testbuffer2.length);
+        perfectInterpolation(new float[] {pads}, testbuffer.length - pads, new float[] {p_pitch}, pitchstep, testbuffer3, out_offset3, testbuffer3.length);
+        int out_off = out_offset2[0];
+        if(out_offset3[0] < out_off)
+            out_off = out_offset3[0];
+        float ac_error = 0;
+        int counter = 0;
+        for (int i = pads; i < out_off; i++) {
+            ac_error += Math.abs(testbuffer2[i] - testbuffer3[i]);
+            counter++;
+        }
+        return ac_error / ((float)counter);
+    }
+
+    private static void fail(String error) throws Exception
+    {
+        throw new RuntimeException(error);
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftLinearResampler resampler = new SoftLinearResampler();
+        float max = testResampler(resampler, 0.3f, 0.3f);
+        if(max > 0.001)
+            fail("Interpolation failed, error="+max);
+        max = testResampler(resampler, 0.3f, 0.01f);
+        if(max > 0.001)
+            fail("Interpolation failed, error="+max);
+        max = testResampler(resampler, 1.0f, 0.00f);
+        if(max > 0.001)
+            fail("Interpolation failed, error="+max);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftLinearResampler2/Interpolate.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftLinearResampler2 interpolate method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Interpolate {
+
+    private static float getResamplerTestValue(double i)
+    {
+        return (float)Math.sin(i / 10.0);
+    }
+
+    private static void perfectInterpolation(float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+        if (pitchstep == 0f) {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = getResamplerTestValue(ix);
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = getResamplerTestValue(ix);
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+
+    private static float testResampler(SoftAbstractResampler resampler, float p_pitch, float p_pitch2)
+    {
+        float[] testbuffer = new float[4096];
+        float[] testbuffer2 = new float[1024];
+        float[] testbuffer3 = new float[1024];
+        for (int i = 0; i < testbuffer.length; i++)
+            testbuffer[i] = getResamplerTestValue(i);
+        int pads = resampler.getPadding();
+        float pitchstep = (p_pitch2 - p_pitch)/1024f;
+        int[] out_offset2 = {0};
+        int[] out_offset3 = {0};
+        resampler.interpolate(testbuffer, new float[] {pads}, testbuffer.length - pads, new float[] {p_pitch}, pitchstep, testbuffer2, out_offset2, testbuffer2.length);
+        perfectInterpolation(new float[] {pads}, testbuffer.length - pads, new float[] {p_pitch}, pitchstep, testbuffer3, out_offset3, testbuffer3.length);
+        int out_off = out_offset2[0];
+        if(out_offset3[0] < out_off)
+            out_off = out_offset3[0];
+        float ac_error = 0;
+        int counter = 0;
+        for (int i = pads; i < out_off; i++) {
+            ac_error += Math.abs(testbuffer2[i] - testbuffer3[i]);
+            counter++;
+        }
+        return ac_error / ((float)counter);
+    }
+
+    private static void fail(String error) throws Exception
+    {
+        throw new RuntimeException(error);
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftLinearResampler2 resampler = new SoftLinearResampler2();
+        float max = testResampler(resampler, 0.3f, 0.3f);
+        if(max > 0.2)
+            fail("Interpolation failed, error="+max);
+        max = testResampler(resampler, 0.3f, 0.01f);
+        if(max > 0.2)
+            fail("Interpolation failed, error="+max);
+        max = testResampler(resampler, 1.0f, 0.00f);
+        if(max > 0.2)
+            fail("Interpolation failed, error="+max);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftPointResampler/Interpolate.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftPointResampler interpolate method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Interpolate {
+
+    private static float getResamplerTestValue(double i)
+    {
+        return (float)Math.sin(i / 10.0);
+    }
+
+    private static void perfectInterpolation(float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+        if (pitchstep == 0f) {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = getResamplerTestValue(ix);
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = getResamplerTestValue(ix);
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+
+    private static float testResampler(SoftAbstractResampler resampler, float p_pitch, float p_pitch2)
+    {
+        float[] testbuffer = new float[4096];
+        float[] testbuffer2 = new float[1024];
+        float[] testbuffer3 = new float[1024];
+        for (int i = 0; i < testbuffer.length; i++)
+            testbuffer[i] = getResamplerTestValue(i);
+        int pads = resampler.getPadding();
+        float pitchstep = (p_pitch2 - p_pitch)/1024f;
+        int[] out_offset2 = {0};
+        int[] out_offset3 = {0};
+        resampler.interpolate(testbuffer, new float[] {pads}, testbuffer.length - pads, new float[] {p_pitch}, pitchstep, testbuffer2, out_offset2, testbuffer2.length);
+        perfectInterpolation(new float[] {pads}, testbuffer.length - pads, new float[] {p_pitch}, pitchstep, testbuffer3, out_offset3, testbuffer3.length);
+        int out_off = out_offset2[0];
+        if(out_offset3[0] < out_off)
+            out_off = out_offset3[0];
+        float ac_error = 0;
+        int counter = 0;
+        for (int i = pads; i < out_off; i++) {
+            ac_error += Math.abs(testbuffer2[i] - testbuffer3[i]);
+            counter++;
+        }
+        return ac_error / ((float)counter);
+    }
+
+    private static void fail(String error) throws Exception
+    {
+        throw new RuntimeException(error);
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftPointResampler resampler = new SoftPointResampler();
+        float max = testResampler(resampler, 0.3f, 0.3f);
+        if(max > 0.2)
+            fail("Interpolation failed, error="+max);
+        max = testResampler(resampler, 0.3f, 0.01f);
+        if(max > 0.2)
+            fail("Interpolation failed, error="+max);
+        max = testResampler(resampler, 1.0f, 0.00f);
+        if(max > 0.2)
+            fail("Interpolation failed, error="+max);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftProvider/GetDevice.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftProvider getDevice method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetDevice {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+
+    private static class FakeInfo extends Info {
+        public FakeInfo() {
+            super("a", "b", "c", "d");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftProvider provider = new SoftProvider();
+        Info[] infos = provider.getDeviceInfo();
+        assertTrue(infos.length > 0);
+        for (int i = 0; i < infos.length; i++) {
+            assertTrue(infos[i] != null);
+            MidiDevice d = provider.getDevice(infos[i]);
+            assertTrue(d instanceof SoftSynthesizer);
+        }
+        assertTrue(provider.getDevice(new FakeInfo()) == null);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Close.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver close method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Close {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        assertEquals(soft.synth.getReceivers().size(), 1);
+        receiver.close();
+        assertEquals(soft.synth.getReceivers().size(), 0);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_ActiveSense.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_ActiveSense {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void sendActiveSens(Receiver r) throws Exception
+    {
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.ACTIVE_SENSING);
+        r.send(smsg, -1);
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        sendActiveSens(receiver);
+
+        // 1. Check if notes are keept active
+        //    if send active sens every 200-300 msec
+
+        sendActiveSens(receiver);
+        channel.noteOn(60, 64);
+        assertTrue(soft.findVoice(0,60) != null);
+        for (int i = 0; i < 10; i++) {
+            soft.read(0.2); // read 200 msec
+            sendActiveSens(receiver);
+            assertTrue(soft.findVoice(0,60) != null);
+        }
+        // 2. Now we stop send active sense message
+        //    and the note should be killed off
+        soft.read(2);
+        assertTrue(soft.findVoice(0,60) == null);
+
+
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_AllNotesOff.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_AllNotesOff {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        channel.noteOn(60, 64);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) != null);
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.CONTROL_CHANGE,0, 123,0);
+        receiver.send(smsg, -1);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) == null);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_AllSoundOff.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_AllSoundOff {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        channel.noteOn(60, 64);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) != null);
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.CONTROL_CHANGE,0, 120,0);
+        receiver.send(smsg, -1);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) == null);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_ChannelPressure.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_ChannelPressure {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.CHANNEL_PRESSURE,0, 10,0);
+        receiver.send(smsg, -1);
+        assertEquals(channel.getChannelPressure(), 10);
+        smsg.setMessage(ShortMessage.CHANNEL_PRESSURE,0, 90,0);
+        receiver.send(smsg, -1);
+        assertEquals(channel.getChannelPressure(), 90);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_Controller.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_Controller {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        ShortMessage smsg = new ShortMessage();
+        for (int i = 0; i < 128; i++) {
+            if(i == 0 || i == 32) continue;
+            smsg.setMessage(ShortMessage.CONTROL_CHANGE,0, i,10);
+            receiver.send(smsg, -1);
+            assertEquals(channel.getController(i), 10);
+            smsg.setMessage(ShortMessage.CONTROL_CHANGE,0, i,100);
+            receiver.send(smsg, -1);
+            assertEquals(channel.getController(i), 100);
+        }
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_Mono.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_Mono {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.CONTROL_CHANGE,0, 126,100);
+        receiver.send(smsg, -1);
+        assertEquals(channel.getMono(), false);
+        smsg.setMessage(ShortMessage.CONTROL_CHANGE,0, 126,1);
+        receiver.send(smsg, -1);
+        assertEquals(channel.getMono(), true);
+        smsg.setMessage(ShortMessage.CONTROL_CHANGE,0, 127,0);
+        receiver.send(smsg, -1);
+        assertEquals(channel.getMono(), false);
+
+        // Check if send mono triggers AllNotesOff
+        channel.noteOn(60, 64);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) != null);
+        smsg.setMessage(ShortMessage.CONTROL_CHANGE,0, 127,0);
+        receiver.send(smsg, -1);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) == null);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOff.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_NoteOff {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.NOTE_ON,0, 60, 64);
+        receiver.send(smsg, -1);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) != null);
+        smsg.setMessage(ShortMessage.NOTE_OFF,0, 60, 0);
+        receiver.send(smsg, -1);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) == null);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOn.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_NoteOn {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.NOTE_ON,0, 60, 64);
+        receiver.send(smsg, -1);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) != null);
+        smsg.setMessage(ShortMessage.NOTE_ON,0, 60, 0);
+        receiver.send(smsg, -1);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) == null);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOn_AllChannels.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_NoteOn_AllChannels {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        for (int i = 0; i < 15; i++) {
+            if(i == 9) i++;
+            ShortMessage smsg = new ShortMessage();
+            smsg.setMessage(ShortMessage.NOTE_ON,i, 60, 64);
+            receiver.send(smsg, -1);
+            soft.read(1);
+            VoiceStatus voice = soft.findVoice(i,60);
+            assertTrue(voice != null);
+            smsg.setMessage(ShortMessage.NOTE_ON,i, 60, 0);
+            receiver.send(smsg, -1);
+            soft.read(1);
+            voice = soft.findVoice(i,60);
+            assertTrue(voice == null);
+            soft.read(1);
+        }
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOn_Delayed.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_NoteOn_Delayed {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.NOTE_ON,0, 60, 64);
+        receiver.send(smsg, 2000000); // Delay sending note for 2 sec
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) == null);
+        soft.read(2);
+        assertTrue(soft.findVoice(0,60) != null);
+        smsg.setMessage(ShortMessage.NOTE_ON,0, 60, 0);
+        receiver.send(smsg, -1);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) == null);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_NoteOn_Multiple.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_NoteOn_Multiple {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.NOTE_ON,0, 60, 64);
+        receiver.send(smsg, -1);
+        smsg.setMessage(ShortMessage.NOTE_ON,0, 61, 64);
+        receiver.send(smsg, -1);
+        smsg.setMessage(ShortMessage.NOTE_ON,0, 62, 64);
+        receiver.send(smsg, -1);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) != null);
+        assertTrue(soft.findVoice(0,61) != null);
+        assertTrue(soft.findVoice(0,62) != null);
+
+        smsg.setMessage(ShortMessage.NOTE_ON,0, 60, 0);
+        receiver.send(smsg, -1);
+        smsg.setMessage(ShortMessage.NOTE_ON,0, 61, 0);
+        receiver.send(smsg, -1);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) == null);
+        assertTrue(soft.findVoice(0,61) == null);
+        assertTrue(soft.findVoice(0,62) != null);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_Omni.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_Omni {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.CONTROL_CHANGE,0, 125,0);
+        receiver.send(smsg, -1);
+        // Poly or Omni not supported by GM2
+        // getOmni() should always return false
+        assertEquals(channel.getOmni(), false);
+        smsg.setMessage(ShortMessage.CONTROL_CHANGE,0, 124,0);
+        receiver.send(smsg, -1);
+        assertEquals(channel.getOmni(), false);
+
+        // Check if send omni triggers AllNotesOff
+        channel.noteOn(60, 64);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) != null);
+        smsg.setMessage(ShortMessage.CONTROL_CHANGE,0, 124,0);
+        receiver.send(smsg, -1);
+        soft.read(1);
+        assertTrue(soft.findVoice(0,60) == null);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_PitchBend.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_PitchBend {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.PITCH_BEND,0, 10,0);
+        receiver.send(smsg, -1);
+        assertEquals(channel.getPitchBend(), 10);
+        smsg.setMessage(ShortMessage.PITCH_BEND,0, 9000%128,9000/128);
+        receiver.send(smsg, -1);
+        assertEquals(channel.getPitchBend(), 9000);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_PolyPressure.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_PolyPressure {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        ShortMessage smsg = new ShortMessage();
+        for (int i = 0; i < 128; i++) {
+            smsg.setMessage(ShortMessage.POLY_PRESSURE,0, i, 10);
+            receiver.send(smsg, -1);
+            assertEquals(channel.getPolyPressure(i),10);
+            smsg.setMessage(ShortMessage.POLY_PRESSURE,0, i, 100);
+            receiver.send(smsg, -1);
+            assertEquals(channel.getPolyPressure(i),100);
+        }
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_ProgramChange.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_ProgramChange {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.PROGRAM_CHANGE,0, 36,0);
+        receiver.send(smsg, -1);
+        assertEquals(channel.getProgram(), 36);
+        smsg.setMessage(ShortMessage.PROGRAM_CHANGE,0, 48,0);
+        receiver.send(smsg, -1);
+        assertEquals(channel.getProgram(), 48);
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/Send_ResetAllControllers.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftReceiver send method */
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Send_ResetAllControllers {
+
+    public static boolean[] dontResetControls = new boolean[128];
+    static {
+        for (int i = 0; i < dontResetControls.length; i++)
+            dontResetControls[i] = false;
+
+        dontResetControls[0] = true;   // Bank Select (MSB)
+        dontResetControls[32] = true;  // Bank Select (LSB)
+        dontResetControls[7] = true;   // Channel Volume (MSB)
+        dontResetControls[8] = true;   // Balance (MSB)
+        dontResetControls[10] = true;  // Pan (MSB)
+        dontResetControls[11] = true;  // Expression (MSB)
+        dontResetControls[91] = true;  // Effects 1 Depth (default: Reverb Send)
+        dontResetControls[92] = true;  // Effects 2 Depth (default: Tremolo Depth)
+        dontResetControls[93] = true;  // Effects 3 Depth (default: Chorus Send)
+        dontResetControls[94] = true;  // Effects 4 Depth (default: Celeste [Detune] Depth)
+        dontResetControls[95] = true;  // Effects 5 Depth (default: Phaser Depth)
+        dontResetControls[70] = true;  // Sound Controller 1 (default: Sound Variation)
+        dontResetControls[71] = true;  // Sound Controller 2 (default: Timbre / Harmonic Quality)
+        dontResetControls[72] = true;  // Sound Controller 3 (default: Release Time)
+        dontResetControls[73] = true;  // Sound Controller 4 (default: Attack Time)
+        dontResetControls[74] = true;  // Sound Controller 5 (default: Brightness)
+        dontResetControls[75] = true;  // Sound Controller 6 (GM2 default: Decay Time)
+        dontResetControls[76] = true;  // Sound Controller 7 (GM2 default: Vibrato Rate)
+        dontResetControls[77] = true;  // Sound Controller 8 (GM2 default: Vibrato Depth)
+        dontResetControls[78] = true;  // Sound Controller 9 (GM2 default: Vibrato Delay)
+        dontResetControls[79] = true;  // Sound Controller 10 (GM2 default: Undefined)
+        dontResetControls[120] = true; // All Sound Off
+        dontResetControls[121] = true; // Reset All Controllers
+        dontResetControls[122] = true; // Local Control On/Off
+        dontResetControls[123] = true; // All Notes Off
+        dontResetControls[124] = true; // Omni Mode Off
+        dontResetControls[125] = true; // Omni Mode On
+        dontResetControls[126] = true; // Poly Mode Off
+        dontResetControls[127] = true; // Poly Mode On
+
+        dontResetControls[6] = true;   // Data Entry (MSB)
+        dontResetControls[38] = true;  // Data Entry (LSB)
+        dontResetControls[96] = true;  // Data Increment
+        dontResetControls[97] = true;  // Data Decrement
+        dontResetControls[98] = true;  // Non-Registered Parameter Number (LSB)
+        dontResetControls[99] = true;  // Non-Registered Parameter Number(MSB)
+        dontResetControls[100] = true; // RPN = Null
+        dontResetControls[101] = true; // RPN = Null
+    }
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTestUtils soft = new SoftTestUtils();
+        MidiChannel channel = soft.synth.getChannels()[0];
+        Receiver receiver = soft.synth.getReceiver();
+
+        // First let all controls contain non-default values
+        for (int i = 0; i < 128; i++)
+            channel.setPolyPressure(i, 10);
+        channel.setChannelPressure(10);
+        channel.setPitchBend(2192);
+        for (int i = 0; i < 120; i++)
+            channel.controlChange(i, 1);
+
+        ShortMessage smsg = new ShortMessage();
+        smsg.setMessage(ShortMessage.CONTROL_CHANGE,0, 121,0);
+        receiver.send(smsg, -1);
+
+        // Now check if resetAllControllers did what it was suppose to do
+
+        for (int i = 0; i < 128; i++)
+            assertEquals(channel.getPolyPressure(i), 0);
+        assertEquals(channel.getChannelPressure(), 0);
+        assertEquals(channel.getPitchBend(),8192);
+        for (int i = 0; i < 120; i++)
+            if(!dontResetControls[i])
+                assertEquals(channel.getController(i), 0);
+        assertEquals(channel.getController(71), 64); // Filter Resonance
+        assertEquals(channel.getController(72), 64); // Release Time
+        assertEquals(channel.getController(73), 64); // Attack Time
+        assertEquals(channel.getController(74), 64); // Brightness
+        assertEquals(channel.getController(75), 64); // Decay Time
+        assertEquals(channel.getController(76), 64); // Vibrato Rate
+        assertEquals(channel.getController(77), 64); // Vibrato Depth
+        assertEquals(channel.getController(78), 64); // Vibrato Delay
+        assertEquals(channel.getController(8), 64); // Balance
+        assertEquals(channel.getController(11), 127); // Expression
+        assertEquals(channel.getController(98), 127); // NRPN Null
+        assertEquals(channel.getController(99), 127); // NRPN Null
+        assertEquals(channel.getController(100), 127); // RPN = Null
+        assertEquals(channel.getController(101), 127); // RPN = Null
+
+        soft.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftReceiver/SoftTestUtils.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.io.IOException;
+
+import javax.sound.midi.*;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class SoftTestUtils {
+
+    public AudioSynthesizer synth = new SoftSynthesizer();
+    public AudioInputStream stream;
+    public byte[] tmpbuffer = new byte[1024];
+
+    public static SF2Soundbank createTestSoundBank()
+    {
+        SF2Soundbank sf2 = new SF2Soundbank();
+        AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+        float[] data = new float[44100+1000];
+        float fr = 440/format.getSampleRate();
+        for (int i = 0; i < data.length; i++)
+            data[i] = (float)Math.sin(i*fr*2*Math.PI);
+        byte[] bdata = new byte[data.length*format.getFrameSize()];
+        AudioFloatConverter.getConverter(format).toByteArray(data, bdata);
+        SF2Sample sample = new SF2Sample(sf2);
+        sample.setName("Test Sample");
+        sample.setData(bdata);
+        sample.setStartLoop(500);
+        sample.setEndLoop(data.length - 500);
+        sample.setSampleRate((long) format.getSampleRate());
+        sample.setOriginalPitch(69);
+        sf2.addResource(sample);
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Test Layer");
+        sf2.addResource(layer);
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+        SF2Instrument ins = new SF2Instrument(sf2);
+        ins.setName("Test Instrument");
+        sf2.addInstrument(ins);
+        SF2InstrumentRegion insregion = new SF2InstrumentRegion();
+        insregion.setLayer(layer);
+        ins.getRegions().add(insregion);
+
+        return sf2;
+    }
+
+    public SoftTestUtils() throws Exception {
+        stream = synth.openStream(null, null);
+        synth.unloadAllInstruments(synth.getDefaultSoundbank());
+        synth.loadAllInstruments(createTestSoundBank());
+    }
+
+    public void close() throws Exception {
+        stream.close();
+        stream = null;
+        synth.close();
+        synth = null;
+    }
+
+    public void read(double seconds) throws IOException
+    {
+        int bufflen =
+           stream.getFormat().getFrameSize() *
+           (int)(stream.getFormat().getFrameRate() * seconds);
+        while(bufflen != 0)
+        {
+            if(bufflen > 1024)
+                bufflen -= stream.read(tmpbuffer,0,1024);
+            else
+                bufflen -= stream.read(tmpbuffer,0, bufflen);
+        }
+    }
+
+    public VoiceStatus findVoice(int channel, int note) {
+        VoiceStatus[] v = synth.getVoiceStatus();
+        for (int k = 0; k < v.length; k++)
+            if(v[k].active)
+                if(v[k].channel == channel)
+                    if(v[k].note == note)
+                        return v[k];
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSincResampler/Interpolate.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSincResampler interpolate method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Interpolate {
+
+    private static float getResamplerTestValue(double i)
+    {
+        return (float)Math.sin(i / 10.0);
+    }
+
+    private static void perfectInterpolation(float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+
+         float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+        if (pitchstep == 0f) {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = getResamplerTestValue(ix);
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = getResamplerTestValue(ix);
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+
+    private static float testResampler(SoftAbstractResampler resampler, float p_pitch, float p_pitch2)
+    {
+        float[] testbuffer = new float[4096];
+        float[] testbuffer2 = new float[1024];
+        float[] testbuffer3 = new float[1024];
+        for (int i = 0; i < testbuffer.length; i++)
+            testbuffer[i] = getResamplerTestValue(i);
+        int pads = resampler.getPadding();
+        float pitchstep = (p_pitch2 - p_pitch)/1024f;
+        int[] out_offset2 = {0};
+        int[] out_offset3 = {0};
+        resampler.interpolate(testbuffer, new float[] {pads}, testbuffer.length - pads, new float[] {p_pitch}, pitchstep, testbuffer2, out_offset2, testbuffer2.length);
+        perfectInterpolation(new float[] {pads}, testbuffer.length - pads, new float[] {p_pitch}, pitchstep, testbuffer3, out_offset3, testbuffer3.length);
+        int out_off = out_offset2[0];
+        if(out_offset3[0] < out_off)
+            out_off = out_offset3[0];
+        float ac_error = 0;
+        int counter = 0;
+        for (int i = pads; i < out_off; i++) {
+            ac_error += Math.abs(testbuffer2[i] - testbuffer3[i]);
+            counter++;
+        }
+        return ac_error / ((float)counter);
+    }
+
+    private static void fail(String error) throws Exception
+    {
+        throw new RuntimeException(error);
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftSincResampler resampler = new SoftSincResampler();
+        float max = testResampler(resampler, 0.3f, 0.3f);
+        if(max > 0.0001)
+            fail("Interpolation failed, error="+max);
+        max = testResampler(resampler, 0.3f, 0.01f);
+        if(max > 0.0001)
+            fail("Interpolation failed, error="+max);
+        max = testResampler(resampler, 1.0f, 0.00f);
+        if(max > 0.0001)
+            fail("Interpolation failed, error="+max);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/Close.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer close method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class Close {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        synth.close();
+        assertTrue(!synth.isOpen());
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/DummySourceDataLine.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.util.ArrayList;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Control;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.AudioFormat.Encoding;
+import javax.sound.sampled.Control.Type;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+/**
+ * This is a SourceDataLine simulator used for testing SoftSynthesizer
+ * without using real SourceDataLine / Audio Device.
+ *
+ * @author Karl Helgason
+ */
+
+public class DummySourceDataLine implements SourceDataLine {
+
+    private int bufferSize = -1;
+
+    private AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false);
+
+    private DataLine.Info sourceLineInfo;
+
+    private boolean active = false;
+
+    private long framepos = 0;
+
+    private boolean opened = false;
+
+    private int framesize = 0;
+
+    public DummySourceDataLine()
+    {
+        ArrayList<AudioFormat> formats = new ArrayList<AudioFormat>();
+        for (int channels = 1; channels <= 2; channels++) {
+            formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+            for (int bits = 16; bits < 32; bits += 8) {
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+            }
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, true));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, true));
+        }
+        AudioFormat[] formats_array = formats.toArray(new AudioFormat[formats
+                .size()]);
+        sourceLineInfo = new DataLine.Info(SourceDataLine.class,
+                formats_array, AudioSystem.NOT_SPECIFIED,
+                AudioSystem.NOT_SPECIFIED);
+
+    }
+
+    public void open() throws LineUnavailableException {
+        open(format);
+    }
+
+    public void open(AudioFormat format) throws LineUnavailableException {
+        if (bufferSize == -1)
+            bufferSize = ((int) (format.getFrameRate() / 2))
+                    * format.getFrameSize();
+        open(format, bufferSize);
+    }
+
+    public void open(AudioFormat format, int bufferSize)
+            throws LineUnavailableException {
+        this.format = format;
+        this.bufferSize = bufferSize;
+        this.framesize = format.getFrameSize();
+        opened = true;
+    }
+
+    public boolean isOpen() {
+        return opened;
+    }
+
+    public int write(byte[] b, int off, int len) {
+        if (!isOpen())
+            return 0;
+        if (len % framesize != 0)
+            throw new IllegalArgumentException(
+                    "Number of bytes does not represent an integral number of sample frames.");
+
+
+        int flen = len / framesize;
+        framepos += flen;
+
+        long time =  (long) (flen * (1000.0 / (double) getFormat()
+                .getSampleRate()));
+        try {
+            Thread.sleep(time);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+            return 0;
+        }
+
+        return len;
+    }
+
+    public int available() {
+        return 0;
+    }
+
+    public void drain() {
+    }
+
+    public void flush() {
+    }
+
+    public int getBufferSize() {
+        return bufferSize;
+    }
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public int getFramePosition() {
+        return (int) getLongFramePosition();
+    }
+
+    public float getLevel() {
+        return AudioSystem.NOT_SPECIFIED;
+    }
+
+    public long getLongFramePosition() {
+        return framepos;
+    }
+
+    public long getMicrosecondPosition() {
+        return (long) (getLongFramePosition() * (1000000.0 / (double) getFormat()
+                .getSampleRate()));
+    }
+
+    public boolean isActive() {
+        return active;
+    }
+
+    public boolean isRunning() {
+        return active;
+    }
+
+    public void start() {
+        active = true;
+    }
+
+    public void stop() {
+        active = false;
+    }
+
+    public void close() {
+        stop();
+    }
+
+    public Control getControl(Type control) {
+        throw new IllegalArgumentException("Unsupported control type : "
+                + control);
+    }
+
+    public Control[] getControls() {
+        return new Control[0];
+    }
+
+    public javax.sound.sampled.Line.Info getLineInfo() {
+        return sourceLineInfo;
+    }
+
+    public boolean isControlSupported(Type control) {
+        return false;
+    }
+
+    public void addLineListener(LineListener listener) {
+    }
+
+    public void removeLineListener(LineListener listener) {
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetAvailableInstruments.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getAvailableInstruments method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetAvailableInstruments {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        Soundbank defsbk = synth.getDefaultSoundbank();
+        if(defsbk != null)
+        {
+            assertTrue(defsbk.getInstruments().length == synth.getAvailableInstruments().length);
+        }
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetChannels.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getChannels method */
+
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetChannels {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        assertTrue(synth.getChannels() != null);
+        assertTrue(synth.getChannels().length == 16);
+        MidiChannel[] channels = synth.getChannels();
+        for (int i = 0; i < channels.length; i++) {
+            assertTrue(channels[i] != null);
+        }
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetDefaultSoundbank.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getDefaultSoundbank method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetDefaultSoundbank {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        assertTrue(synth.getDefaultSoundbank() != null);
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetDeviceInfo.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getDeviceInfo method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetDeviceInfo {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        assertTrue(synth.getDeviceInfo() != null);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetLatency.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getLatency method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetLatency {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.open(new DummySourceDataLine(), null);
+        assertTrue(synth.getLatency() != -1);
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetLoadedInstruments.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getLoadedInstruments method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetLoadedInstruments {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        Soundbank defsbk = synth.getDefaultSoundbank();
+        if(defsbk != null)
+        {
+            synth.unloadAllInstruments(defsbk);
+            synth.loadAllInstruments(defsbk);
+            assertTrue(synth.getLoadedInstruments().length != 0);
+        }
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetMaxPolyphony.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getMaxPolyphony method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetMaxPolyphony {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        assertTrue(synth.getMaxPolyphony() != -1);
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetMaxReceivers.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getMaxReceivers method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetMaxReceivers {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        assertTrue(synth.getMaxReceivers() == -1);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetMaxTransmitters.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getMaxTransmitters method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetMaxTransmitters {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        assertTrue(synth.getMaxTransmitters() == 0);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetMicrosecondPosition.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getMicrosecondPosition method */
+
+import java.io.IOException;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetMicrosecondPosition {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        AudioInputStream stream = synth.openStream(null, null);
+        assertTrue(synth.getMicrosecondPosition() == 0);
+        AudioFormat format = stream.getFormat();
+        byte[] buff = new byte[((int)format.getFrameRate())*format.getFrameSize()];;
+        stream.read(buff);
+        assertTrue(Math.abs(synth.getMicrosecondPosition()-1000000) < 10000);
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetReceiver.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getReceiver method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Receiver;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetReceiver {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.open(new DummySourceDataLine(), null);
+        Receiver recv = synth.getReceiver();
+        assertTrue(recv != null);
+        Receiver recv2 = synth.getReceiver();
+        assertTrue(recv2 != null);
+        assertTrue(recv2 != recv);
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetReceiver2.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getReceiver method */
+
+import javax.sound.midi.Receiver;
+import javax.sound.midi.ShortMessage;
+
+import com.sun.media.sound.AudioSynthesizer;
+import com.sun.media.sound.SoftSynthesizer;
+
+public class GetReceiver2 {
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        Receiver recv = synth.getReceiver();
+        assertTrue(recv != null);
+        ShortMessage sm = new ShortMessage();
+        sm.setMessage(ShortMessage.NOTE_OFF, 0, 64, 64);
+        synth.open(new DummySourceDataLine(), null);
+        recv.send(sm, -1);
+        synth.close();
+        try
+        {
+            recv.send(sm, -1);
+            throw new RuntimeException("Exception not thrown!");
+        }
+        catch(Exception e)
+        {
+            // Just checking if exception is thrown
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetReceivers.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getReceivers method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Receiver;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetReceivers {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.open(new DummySourceDataLine(), null);
+        assertTrue(synth.getReceivers().size() == 0);
+        Receiver recv = synth.getReceiver();
+        assertTrue(synth.getReceivers().size() == 1);
+        recv.close();
+        assertTrue(synth.getReceivers().size() == 0);
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetTransmitter.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getTransmitter method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetTransmitter {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.open(new DummySourceDataLine(), null);
+        try
+        {
+            synth.getTransmitter();
+            throw new Exception("MidiUnavailableException not thrown!");
+        } catch (MidiUnavailableException e) {
+        }
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetTransmitters.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getTransmitters method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetTransmitters {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.open(new DummySourceDataLine(), null);
+        assertTrue(synth.getTransmitters().size() == 0);
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/GetVoiceStatus.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer getVoiceStatus method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.VoiceStatus;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class GetVoiceStatus {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        VoiceStatus[] v = synth.getVoiceStatus();
+        assertTrue(v != null);
+        assertTrue(synth.getChannels().length != synth.getMaxPolyphony());
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/ImplicitOpenClose.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer implicit open/close using getReceiver. */
+
+import java.lang.reflect.Field;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Synthesizer;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class ImplicitOpenClose {
+
+    public static void main(String[] args) throws Exception {
+        Field f = SoftSynthesizer.class.getDeclaredField("testline");
+        f.setAccessible(true);
+        f.set(null, new DummySourceDataLine());
+
+        Synthesizer synth = new SoftSynthesizer();
+
+        ReferenceCountingDevice rcd = (ReferenceCountingDevice)synth;
+
+        // Test single open/close cycle
+
+        Receiver recv = rcd.getReceiverReferenceCounting();
+        if(!synth.isOpen())
+            throw new Exception("Synthesizer not open!");
+        recv.close();
+        if(synth.isOpen())
+            throw new Exception("Synthesizer not closed!");
+
+        // Test using 2 receiver cycle
+
+        Receiver recv1 = rcd.getReceiverReferenceCounting();
+        if(!synth.isOpen())
+            throw new Exception("Synthesizer not open!");
+        Receiver recv2 = rcd.getReceiverReferenceCounting();
+        if(!synth.isOpen())
+            throw new Exception("Synthesizer not open!");
+
+        recv2.close();
+        if(!synth.isOpen())
+            throw new Exception("Synthesizer was closed!");
+        recv1.close();
+        if(synth.isOpen())
+            throw new Exception("Synthesizer not closed!");
+
+        // Test for explicit,implicit conflict
+
+        synth.open();
+        Receiver recv3 = rcd.getReceiverReferenceCounting();
+        if(!synth.isOpen())
+            throw new Exception("Synthesizer not open!");
+        recv3.close();
+        if(!synth.isOpen())
+            throw new Exception("Synthesizer was closed!");
+        synth.close();
+        if(synth.isOpen())
+            throw new Exception("Synthesizer not closed!");
+
+        // Test for implicit,explicit conflict
+
+        recv3 = rcd.getReceiverReferenceCounting();
+        synth.open();
+        if(!synth.isOpen())
+            throw new Exception("Synthesizer not open!");
+        recv3.close();
+        if(!synth.isOpen())
+            throw new Exception("Synthesizer was closed!");
+        synth.close();
+        if(synth.isOpen())
+            throw new Exception("Synthesizer not closed!");
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/IsOpen.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer isOpen method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class IsOpen {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        assertTrue(synth.isOpen());
+        synth.close();
+        assertTrue(!synth.isOpen());
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/IsSoundbankSupported.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer isSoundbankSupported method */
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class IsSoundbankSupported {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        SimpleSoundbank sbk = new SimpleSoundbank();
+        SimpleInstrument ins = new SimpleInstrument();
+        sbk.addInstrument(ins);
+        assertTrue(synth.isSoundbankSupported(sbk));
+        Soundbank dummysbk = new Soundbank()
+        {
+            public String getName() {
+                return null;
+            }
+            public String getVersion() {
+                return null;
+            }
+            public String getVendor() {
+                return null;
+            }
+            public String getDescription() {
+                return null;
+            }
+            public SoundbankResource[] getResources() {
+                return null;
+            }
+            public Instrument[] getInstruments() {
+                Instrument ins = new Instrument(null, null, null, null)
+                {
+                    public Object getData() {
+                        return null;
+                    }
+                };
+                return new Instrument[] {ins};
+            }
+            public Instrument getInstrument(Patch patch) {
+                return null;
+            }
+        };
+        assertTrue(!synth.isSoundbankSupported(dummysbk));
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadAllInstruments.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer loadAllInstruments method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class LoadAllInstruments {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        Soundbank defsbk = synth.getDefaultSoundbank();
+        if(defsbk != null)
+        {
+            assertTrue(synth.getLoadedInstruments().length == 0);
+            synth.unloadAllInstruments(defsbk);
+            SimpleSoundbank sbk = new SimpleSoundbank();
+            SimpleInstrument ins = new SimpleInstrument();
+            ins.setPatch(new Patch(0,1));
+            sbk.addInstrument(ins);
+            SimpleInstrument ins2 = new SimpleInstrument();
+            ins2.setPatch(new Patch(0,2));
+            sbk.addInstrument(ins2);
+            synth.loadAllInstruments(sbk);
+            assertTrue(synth.getLoadedInstruments().length == 2);
+        }
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer loadAllInstrument method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class LoadInstrument {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        Soundbank defsbk = synth.getDefaultSoundbank();
+        if(defsbk != null)
+        {
+            assertTrue(synth.getLoadedInstruments().length == 0);
+            synth.unloadAllInstruments(defsbk);
+            SimpleSoundbank sbk = new SimpleSoundbank();
+            SimpleInstrument ins = new SimpleInstrument();
+            ins.setPatch(new Patch(0,1));
+            sbk.addInstrument(ins);
+            SimpleInstrument ins2 = new SimpleInstrument();
+            ins2.setPatch(new Patch(0,2));
+            sbk.addInstrument(ins2);
+            synth.loadInstrument(ins2);
+            assertTrue(synth.getLoadedInstruments().length == 1);
+        }
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstruments.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer loadAllInstruments method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class LoadInstruments {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        Soundbank defsbk = synth.getDefaultSoundbank();
+        if(defsbk != null)
+        {
+            assertTrue(synth.getLoadedInstruments().length == 0);
+            synth.unloadAllInstruments(defsbk);
+            SimpleSoundbank sbk = new SimpleSoundbank();
+            SimpleInstrument ins = new SimpleInstrument();
+            ins.setPatch(new Patch(0,1));
+            sbk.addInstrument(ins);
+            SimpleInstrument ins2 = new SimpleInstrument();
+            ins2.setPatch(new Patch(0,2));
+            sbk.addInstrument(ins2);
+            synth.loadInstruments(sbk, new Patch[] {ins2.getPatch()});
+            assertTrue(synth.getLoadedInstruments().length == 1);
+        }
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/Open.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer open method */
+
+import java.lang.reflect.Field;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class Open {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        Field f = SoftSynthesizer.class.getDeclaredField("testline");
+        f.setAccessible(true);
+        f.set(null, new DummySourceDataLine());
+
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.open();
+        assertTrue(synth.isOpen());
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/OpenStream.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer openStream method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class OpenStream {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        assertTrue(synth.isOpen());
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/RemapInstrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer remapInstrument method */
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class RemapInstrument {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        Soundbank defsbk = synth.getDefaultSoundbank();
+        if(defsbk != null)
+        {
+            Instrument ins0 = defsbk.getInstrument(new Patch(0,0));
+            Instrument ins10 = defsbk.getInstrument(new Patch(0,10));
+            assertTrue(synth.remapInstrument(ins0, ins10));
+            Instrument[] loaded = synth.getLoadedInstruments();
+            for (int i = 0; i < loaded.length; i++) {
+                if(loaded[i].getPatch().getBank() == 0)
+                if(loaded[i].getPatch().getProgram() == 10)
+                {
+                    assertEquals(loaded[i].getName(), ins0.getName());
+                    break;
+                }
+            }
+
+        }
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/TestRender1.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test SoftSynthesizer simple note rendering in many settings */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.sound.sampled.*;
+import javax.sound.midi.*;
+
+import com.sun.media.sound.*;
+
+public class TestRender1 {
+
+    public static double send(Sequence seq, Receiver recv) {
+        float divtype = seq.getDivisionType();
+        assert (seq.getDivisionType() == Sequence.PPQ);
+        Track[] tracks = seq.getTracks();
+        int[] trackspos = new int[tracks.length];
+        int mpq = 60000000 / 100;
+        int seqres = seq.getResolution();
+        long lasttick = 0;
+        long curtime = 0;
+        while (true) {
+            MidiEvent selevent = null;
+            int seltrack = -1;
+            for (int i = 0; i < tracks.length; i++) {
+                int trackpos = trackspos[i];
+                Track track = tracks[i];
+                if (trackpos < track.size()) {
+                    MidiEvent event = track.get(trackpos);
+                    if (selevent == null
+                            || event.getTick() < selevent.getTick()) {
+                        selevent = event;
+                        seltrack = i;
+                    }
+                }
+            }
+            if (seltrack == -1)
+                break;
+            trackspos[seltrack]++;
+            long tick = selevent.getTick();
+            if (divtype == Sequence.PPQ)
+                curtime += ((tick - lasttick) * mpq) / seqres;
+            else
+                curtime = (long) ((tick * 1000000.0 * divtype) / seqres);
+            lasttick = tick;
+            MidiMessage msg = selevent.getMessage();
+            if (msg instanceof MetaMessage) {
+                if (divtype == Sequence.PPQ)
+                    if (((MetaMessage) msg).getType() == 0x51) {
+                        byte[] data = ((MetaMessage) msg).getData();
+                        mpq = ((data[0] & 0xff) << 16)
+                                | ((data[1] & 0xff) << 8) | (data[2] & 0xff);
+                    }
+            } else {
+                if (recv != null)
+                    recv.send(msg, curtime);
+            }
+        }
+
+        return curtime / 1000000.0;
+    }
+
+    public static void test(AudioFormat format, Map<String, Object> info)
+            throws Exception {
+        OutputStream nullout = new OutputStream() {
+            public void write(int b) throws IOException {
+            }
+
+            public void write(byte[] b, int off, int len) throws IOException {
+            }
+
+            public void write(byte[] b) throws IOException {
+            }
+        };
+        render(nullout, format, info);
+    }
+
+    public static void render(OutputStream os, AudioFormat format,
+            Map<String, Object> info) throws Exception {
+        AudioSynthesizer synth = (AudioSynthesizer) new SoftSynthesizer();
+        AudioInputStream stream = synth.openStream(format, info);
+        Receiver recv = synth.getReceiver();
+        Soundbank defsbk = synth.getDefaultSoundbank();
+        if (defsbk != null)
+            synth.unloadAllInstruments(defsbk);
+        synth.loadAllInstruments(soundbank);
+
+        double totalTime = 5;
+        send(sequence, recv);
+
+        long len = (long) (stream.getFormat().getFrameRate() * (totalTime + 4));
+        stream = new AudioInputStream(stream, stream.getFormat(), len);
+
+        long t = System.currentTimeMillis();
+        AudioSystem.write(stream, AudioFileFormat.Type.WAVE, os);
+        t = System.currentTimeMillis() - t;
+        stream.close();
+    }
+
+
+    static Soundbank soundbank;
+
+    static Sequence sequence;
+
+    public static InputStream getInputStream(String filename) throws IOException
+    {
+        File file = new File(System.getProperty("test.src", "."), filename);
+        FileInputStream fis = new FileInputStream(file);
+        return new BufferedInputStream(fis);
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        InputStream sb = getInputStream("ding.sf2");
+        soundbank = MidiSystem.getSoundbank(sb);
+        sb.close();
+
+        InputStream si = getInputStream("expresso.mid");
+        sequence = MidiSystem.getSequence(si);
+        si.close();
+
+        AudioFormat format;
+        Map<String, Object> info = new HashMap<String, Object>();
+        {
+            format = new AudioFormat(22050, 16, 2, true, false);
+            test(format, info);
+            format = new AudioFormat(44100, 16, 2, true, false);
+            test(format, info);
+        }
+        {
+            format = new AudioFormat(44100, 8, 2, true, false);
+            test(format, info);
+            format = new AudioFormat(44100, 16, 2, true, false);
+            test(format, info);
+            format = new AudioFormat(44100, 24, 2, true, false);
+            test(format, info);
+        }
+        {
+            format = new AudioFormat(44100, 16, 1, true, false);
+            test(format, info);
+            format = new AudioFormat(44100, 16, 2, true, false);
+            test(format, info);
+        }
+        {
+            format = new AudioFormat(44100, 16, 2, true, false);
+
+            info.clear();
+            info.put("control rate", 100f);
+            test(format, info);
+            info.clear();
+            info.put("control rate", 147f);
+            test(format, info);
+
+        }
+        {
+            format = new AudioFormat(44100, 16, 2, true, false);
+
+            info.clear();
+            info.put("interpolation", "point");
+            test(format, info);
+            info.clear();
+            info.put("interpolation", "linear");
+            test(format, info);
+            info.clear();
+            info.put("interpolation", "cubic");
+            test(format, info);
+        }
+        {
+            format = new AudioFormat(44100, 16, 2, true, false);
+            info.clear();
+            info.put("max polyphony", 4);
+            test(format, info);
+            info.clear();
+            info.put("max polyphony", 16);
+            test(format, info);
+            info.clear();
+
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadAllInstruments.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer unloadAllInstruments method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class UnloadAllInstruments {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        Soundbank defsbk = synth.getDefaultSoundbank();
+        if(defsbk != null)
+        {
+            assertTrue(synth.getLoadedInstruments().length == 0);
+            synth.unloadAllInstruments(defsbk);
+            assertTrue(synth.getAvailableInstruments().length == 0);
+            synth.loadAllInstruments(defsbk);
+            assertTrue(synth.getLoadedInstruments().length != 0);
+            synth.unloadAllInstruments(defsbk);
+            assertTrue(synth.getLoadedInstruments().length == 0);
+        }
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstrument.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer unloadInstrument method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class UnloadInstrument {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        Soundbank defsbk = synth.getDefaultSoundbank();
+        if(defsbk != null)
+        {
+            assertTrue(synth.getLoadedInstruments().length == 0);
+            synth.unloadAllInstruments(defsbk);
+            SimpleSoundbank sbk = new SimpleSoundbank();
+            SimpleInstrument ins = new SimpleInstrument();
+            ins.setPatch(new Patch(0,1));
+            sbk.addInstrument(ins);
+            SimpleInstrument ins2 = new SimpleInstrument();
+            ins2.setPatch(new Patch(0,2));
+            sbk.addInstrument(ins2);
+            synth.loadInstrument(ins2);
+            assertTrue(synth.getLoadedInstruments().length == 1);
+            synth.unloadInstrument(ins2);
+            assertTrue(synth.getLoadedInstruments().length == 0);
+        }
+        synth.close();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstruments.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftSynthesizer unloadInstruments method */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.sampled.*;
+import javax.sound.midi.MidiDevice.Info;
+
+import com.sun.media.sound.*;
+
+public class UnloadInstruments {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        AudioSynthesizer synth = new SoftSynthesizer();
+        synth.openStream(null, null);
+        Soundbank defsbk = synth.getDefaultSoundbank();
+        if(defsbk != null)
+        {
+            assertTrue(synth.getLoadedInstruments().length == 0);
+            synth.unloadAllInstruments(defsbk);
+            SimpleSoundbank sbk = new SimpleSoundbank();
+            SimpleInstrument ins = new SimpleInstrument();
+            ins.setPatch(new Patch(0,1));
+            sbk.addInstrument(ins);
+            SimpleInstrument ins2 = new SimpleInstrument();
+            ins2.setPatch(new Patch(0,2));
+            sbk.addInstrument(ins2);
+            synth.loadInstrument(ins2);
+            assertTrue(synth.getLoadedInstruments().length == 1);
+            synth.unloadInstruments(sbk, new Patch[] {ins2.getPatch()});
+            assertTrue(synth.getLoadedInstruments().length == 0);
+        }
+        synth.close();
+
+    }
+}
Binary file jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/ding.sf2 has changed
Binary file jdk/test/javax/sound/midi/Gervill/SoftSynthesizer/expresso.mid has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/GetName.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning getName method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetName {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTuning tuning = new SoftTuning();
+        tuning.setName("custom");
+        assertEquals(tuning.getName(), "custom");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/GetTuning.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning getTuning method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetTuning {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTuning tuning = new SoftTuning();
+        double[] tunings = tuning.getTuning();
+        for (int i = 0; i < tunings.length; i++) {
+            assertTrue(Math.abs(tunings[i]-i*100) < 0.00001);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/GetTuningInt.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning getTuning(int) method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class GetTuningInt {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTuning tuning = new SoftTuning();
+        assertTrue(Math.abs(tuning.getTuning(36)-3600) < 0.00001);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/Load1.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning load method */
+
+import java.io.UnsupportedEncodingException;
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Load1 {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        // http://www.midi.org/about-midi/tuning.shtml
+        // 0x01 BULK TUNING DUMP
+        SoftTuning tuning = new SoftTuning();
+        byte[] name;
+        name = "Testing123      ".getBytes("ascii");
+
+        int[] msg = new int[24+3*128];
+        int[] head = {0xf0,0x7e,0x7f,0x08,0x01,0x00};
+        int ox = 0;
+        for (int i = 0; i < head.length; i++)
+            msg[ox++] = head[i];
+        for (int i = 0; i < name.length; i++)
+            msg[ox++] = name[i];
+        for (int i = 0; i < 128; i++) {
+            msg[ox++] = i;
+            msg[ox++] = 64;
+            msg[ox++] = 0;
+        }
+
+        // Calc checksum
+        int x = msg[1] & 0xFF; // 7E
+        x = x ^ (msg[2] & 0xFF); // <device ID>
+        x = x ^ (msg[4] & 0xFF); // nn
+        x = x ^ (msg[5] & 0xFF); // tt
+        for (int i = 22; i < msg.length - 2; i++)
+            x = x ^ (msg[i] & 0xFF);
+        msg[ox++] = (x & 127);
+
+        msg[ox++] = 0xf7;
+        byte[] bmsg = new byte[msg.length];
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+
+        tuning.load(bmsg);
+        assertEquals(tuning.getName(), "Testing123      ");
+        double[] tunings = tuning.getTuning();
+        for (int i = 0; i < tunings.length; i++)
+            assertTrue(Math.abs(tunings[i]-(i*100 + 50)) < 0.00001);
+
+        // Check if tuning fails if checksum is wrong
+        /*
+        msg[msg.length - 2] += 10;
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        tuning = new SoftTuning();
+        tuning.load(bmsg);
+        assertTrue(!tuning.getName().equals("Testing123      "));
+        */
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/Load2.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning load method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Load2 {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        // http://www.midi.org/about-midi/tuning.shtml
+        // 0x02 SINGLE NOTE TUNING CHANGE (REAL-TIME)
+        SoftTuning tuning = new SoftTuning();
+        int[] msg = {0xf0,0x7f,0x7f,0x08,0x02,0x10,0x02,
+                36,36,64,0,
+                40,70,0,0,
+                0xf7};
+        byte[] bmsg = new byte[msg.length];
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        tuning.load(bmsg);
+        double[] tunings = tuning.getTuning();
+        for (int i = 0; i < tunings.length; i++) {
+            if(i == 36)
+                assertTrue(Math.abs(tunings[i]-3650)< 0.00001);
+            else if(i == 40)
+                assertTrue(Math.abs(tunings[i]-7000) < 0.00001);
+            else
+                assertTrue(Math.abs(tunings[i]-i*100) < 0.00001);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/Load4.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning load method */
+
+import java.io.UnsupportedEncodingException;
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Load4 {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        // http://www.midi.org/about-midi/tuning_extens.shtml
+        // 0x04 KEY-BASED TUNING DUMP
+        SoftTuning tuning = new SoftTuning();
+        byte[] name;
+        name = "Testing123      ".getBytes("ascii");
+
+        int[] msg = new int[25+3*128];
+        int[] head = {0xf0,0x7e,0x7f,0x08,0x04,0x00,0x00};
+        int ox = 0;
+        for (int i = 0; i < head.length; i++)
+            msg[ox++] = head[i];
+        for (int i = 0; i < name.length; i++)
+            msg[ox++] = name[i];
+        for (int i = 0; i < 128; i++) {
+            msg[ox++] = i;
+            msg[ox++] = 64;
+            msg[ox++] = 0;
+        }
+
+        // Calc checksum
+        int x = msg[1] & 0xFF;
+        for (int i = 2; i < msg.length - 2; i++)
+            x = x ^ (msg[i] & 0xFF);
+        msg[ox++] = (x & 127);
+
+        msg[ox++] = 0xf7;
+        byte[] bmsg = new byte[msg.length];
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+
+        tuning.load(bmsg);
+        assertEquals(tuning.getName(), "Testing123      ");
+        double[] tunings = tuning.getTuning();
+        for (int i = 0; i < tunings.length; i++)
+            assertTrue(Math.abs(tunings[i]-(i*100 + 50)) < 0.00001);
+
+        // Check if tuning fails if checksum is wrong
+        msg[msg.length - 2] += 10;
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        tuning = new SoftTuning();
+        tuning.load(bmsg);
+        assertTrue(!tuning.getName().equals("Testing123      "));
+
+        // Check if tuning fails if checksum is wrong
+        msg[msg.length - 2] += 10;
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        tuning = new SoftTuning();
+        tuning.load(bmsg);
+        assertTrue(!tuning.getName().equals("Testing123      "));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/Load5.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning load method */
+
+import java.io.UnsupportedEncodingException;
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Load5 {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        // http://www.midi.org/about-midi/tuning_extens.shtml
+        // 0x05 SCALE/OCTAVE TUNING DUMP, 1 byte format
+        SoftTuning tuning = new SoftTuning();
+
+        byte[] name;
+        name = "Testing123      ".getBytes("ascii");
+        int[] msg = {0xf0,0x7e,0x7f,0x08,0x05,0,0,
+                name[0],name[1],name[2],name[3],name[4],name[5],name[6],
+                name[7],name[8],name[9],name[10],name[11],name[12],name[13],
+                name[14],name[15],
+                5,10,15,20,25,30,35,40,45,50,51,52,0,
+                0xf7};
+        // Calc checksum
+        int x = msg[1] & 0xFF;
+        for (int i = 2; i < msg.length - 2; i++)
+            x = x ^ (msg[i] & 0xFF);
+        msg[msg.length-2] = (x & 127);
+
+        int[] oct = {5,10,15,20,25,30,35,40,45,50,51,52};
+        byte[] bmsg = new byte[msg.length];
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        tuning.load(bmsg);
+        double[] tunings = tuning.getTuning();
+        for (int i = 0; i < tunings.length; i++)
+            assertTrue(Math.abs(tunings[i]-(i*100 + (oct[i%12]-64))) < 0.00001);
+
+        // Check if tuning fails if checksum is wrong
+        msg[msg.length - 2] += 10;
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        tuning = new SoftTuning();
+        tuning.load(bmsg);
+        assertTrue(!tuning.getName().equals("Testing123      "));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/Load6.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning load method */
+
+import java.io.UnsupportedEncodingException;
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Load6 {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        // http://www.midi.org/about-midi/tuning_extens.shtml
+        // 0x06 SCALE/OCTAVE TUNING DUMP, 2 byte format
+        SoftTuning tuning = new SoftTuning();
+
+        byte[] name;
+        name = "Testing123      ".getBytes("ascii");
+        int[] msg = {0xf0,0x7e,0x7f,0x08,0x06,0,0,
+                name[0],name[1],name[2],name[3],name[4],name[5],name[6],
+                name[7],name[8],name[9],name[10],name[11],name[12],name[13],
+                name[14],name[15],
+                5,10,15,20,25,30,35,40,45,50,51,52,
+                5,10,15,20,25,30,35,40,45,50,51,52,
+                0,0xf7};
+        // Calc checksum
+        int x = msg[1] & 0xFF;
+        for (int i = 2; i < msg.length - 2; i++)
+            x = x ^ (msg[i] & 0xFF);
+        msg[msg.length-2] = (x & 127);
+
+        int[] oct = {5,10,15,20,25,30,35,40,45,50,51,52,5,10,15,20,25,30,35,40,45,50,51,52};
+        byte[] bmsg = new byte[msg.length];
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        tuning.load(bmsg);
+        double[] tunings = tuning.getTuning();
+        for (int i = 0; i < tunings.length; i++)
+        {
+            double c = (oct[(i%12)*2]*128 + oct[(i%12)*2+1] -8192)*(100.0/8192.0);
+            assertTrue(Math.abs(tunings[i]-(i*100 + (c))) < 0.00001);
+        }
+
+        // Check if tuning fails if checksum is wrong
+        msg[msg.length - 2] += 10;
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        tuning = new SoftTuning();
+        tuning.load(bmsg);
+        assertTrue(!tuning.getName().equals("Testing123      "));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/Load7.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning load method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Load7 {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        // http://www.midi.org/about-midi/tuning_extens.shtml
+        // 0x07 SINGLE NOTE TUNING CHANGE (NON REAL-TIME) (BANK)
+        SoftTuning tuning = new SoftTuning();
+        int[] msg = {0xf0,0x7f,0x7f,0x08,0x07,0x00,0x00,0x02,
+                36,36,64,0,
+                40,70,0,0,
+                0xf7};
+        byte[] bmsg = new byte[msg.length];
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        tuning.load(bmsg);
+        double[] tunings = tuning.getTuning();
+        for (int i = 0; i < tunings.length; i++) {
+            if(i == 36)
+                assertTrue(Math.abs(tunings[i]-3650)< 0.00001);
+            else if(i == 40)
+                assertTrue(Math.abs(tunings[i]-7000) < 0.00001);
+            else
+                assertTrue(Math.abs(tunings[i]-i*100) < 0.00001);
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/Load8.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning load method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Load8 {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        // http://www.midi.org/about-midi/tuning-scale.shtml
+        // 0x08 scale/octave tuning 1-byte form (Non Real-Time/REAL-TIME)
+        SoftTuning tuning = new SoftTuning();
+        int[] msg = {0xf0,0x7f,0x7f,0x08,0x08,0x03,0x7f,0x7f,
+                5,10,15,20,25,30,35,40,45,50,51,52,
+                0xf7};
+        int[] oct = {5,10,15,20,25,30,35,40,45,50,51,52};
+        byte[] bmsg = new byte[msg.length];
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        tuning.load(bmsg);
+        double[] tunings = tuning.getTuning();
+        for (int i = 0; i < tunings.length; i++)
+            assertTrue(Math.abs(tunings[i]-(i*100 + (oct[i%12]-64))) < 0.00001);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/Load9.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning load method */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Load9 {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        // http://www.midi.org/about-midi/tuning-scale.shtml
+        // 0x09 scale/octave tuning 2-byte form (Non Real-Time/REAL-TIME)
+        SoftTuning tuning = new SoftTuning();
+        int[] msg = {0xf0,0x7f,0x7f,0x08,0x09,0x03,0x7f,0x7f,
+                5,10,15,20,25,30,35,40,45,50,51,52,
+                5,10,15,20,25,30,35,40,45,50,51,52,
+                0xf7};
+        int[] oct = {5,10,15,20,25,30,35,40,45,50,51,52,5,10,15,20,25,30,35,40,45,50,51,52};
+        byte[] bmsg = new byte[msg.length];
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        tuning.load(bmsg);
+        double[] tunings = tuning.getTuning();
+        for (int i = 0; i < tunings.length; i++)
+        {
+            double c = (oct[(i%12)*2]*128 + oct[(i%12)*2+1] -8192)*(100.0/8192.0);
+            assertTrue(Math.abs(tunings[i]-(i*100 + (c))) < 0.00001);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/NewSoftTuning.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning constructor */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewSoftTuning {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTuning tuning = new SoftTuning();
+        double[] tunings = tuning.getTuning();
+        for (int i = 0; i < tunings.length; i++) {
+            assertTrue(Math.abs(tunings[i]-i*100) < 0.00001);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/NewSoftTuningByteArray.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning constructor */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewSoftTuningByteArray {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        // RealTime: Scale/Octave tuning in 1-byte format
+        int[] msg = {0xf0,0x7f,0x7f,0x08,0x08,0x03,0x7f,0x7f,
+                5,10,15,20,25,30,35,40,45,50,51,52,
+                0xf7};
+        int[] oct = {5,10,15,20,25,30,35,40,45,50,51,52};
+        byte[] bmsg = new byte[msg.length];
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        SoftTuning tuning = new SoftTuning(bmsg);
+        double[] tunings = tuning.getTuning();
+        for (int i = 0; i < tunings.length; i++)
+            assertTrue(Math.abs(tunings[i]-(i*100 + (oct[i%12]-64))) < 0.00001);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/NewSoftTuningPatch.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning constructor */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewSoftTuningPatch {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SoftTuning tuning = new SoftTuning(new Patch(8,32));
+        assertEquals(tuning.getPatch().getProgram(), 32);
+        assertEquals(tuning.getPatch().getBank(), 8);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/SoftTuning/NewSoftTuningPatchByteArray.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2007 Sun Microsystems, 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftTuning constructor */
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class NewSoftTuningPatchByteArray {
+
+    private static void assertEquals(Object a, Object b) throws Exception
+    {
+        if(!a.equals(b))
+            throw new RuntimeException("assertEquals fails!");
+    }
+
+    private static void assertTrue(boolean value) throws Exception
+    {
+        if(!value)
+            throw new RuntimeException("assertTrue fails!");
+    }
+
+    public static void main(String[] args) throws Exception {
+        // RealTime: Scale/Octave tuning in 1-byte format
+        int[] msg = {0xf0,0x7f,0x7f,0x08,0x08,0x03,0x7f,0x7f,
+                5,10,15,20,25,30,35,40,45,50,51,52,
+                0xf7};
+        int[] oct = {5,10,15,20,25,30,35,40,45,50,51,52};
+        byte[] bmsg = new byte[msg.length];
+        for (int i = 0; i < bmsg.length; i++)
+            bmsg[i] = (byte)msg[i];
+        SoftTuning tuning = new SoftTuning(new Patch(8,32),bmsg);
+        double[] tunings = tuning.getTuning();
+        for (int i = 0; i < tunings.length; i++)
+            assertTrue(Math.abs(tunings[i]-(i*100 + (oct[i%12]-64))) < 0.00001);
+        assertEquals(tuning.getPatch().getProgram(), 32);
+        assertEquals(tuning.getPatch().getBank(), 8);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JColorChooser/Test4222508.html	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,9 @@
+<html>
+<body>
+Use the check box above the color chooser to disable it.
+You could not choose a color using by the disable color chooser.
+
+<applet width="600" height="400" code="Test4222508.class">
+</applet>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JColorChooser/Test4222508.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4222508
+ * @summary Tests the color chooser disabling
+ * @author Sergey Malenkov
+ * @run applet/manual=yesno Test4222508.html
+ */
+
+import java.awt.BorderLayout;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import javax.swing.JApplet;
+import javax.swing.JCheckBox;
+import javax.swing.JColorChooser;
+
+public final class Test4222508 extends JApplet implements ItemListener {
+
+    private JCheckBox checkbox;
+    private JColorChooser chooser;
+
+    @Override
+    public void init() {
+        this.chooser = new JColorChooser();
+        this.checkbox = new JCheckBox("Enable the color chooser below", true);
+        this.checkbox.addItemListener(this);
+        add(BorderLayout.NORTH, this.checkbox);
+        add(BorderLayout.CENTER, this.chooser);
+    }
+
+    public void itemStateChanged(ItemEvent event) {
+        this.chooser.setEnabled(this.checkbox.isSelected());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFileChooser/6698013/bug6698013.html	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,8 @@
+<html>
+<body>
+<applet  code="bug6698013.class" width=200 height=200></applet>
+1. Go into 'subdir' folder via double click
+2. Return to parent directory
+3. Go into 'subdir' folder: select 'subdir' folder and press the 'Open' button
+</body>
+</html> 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFileChooser/6698013/bug6698013.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,174 @@
+/* @test %W% %E%
+   @bug 6698013
+   @summary JFileChooser can no longer navigate non-local file systems.
+   @author Pavel Porvatov
+   @run applet/manual=done bug6698013.html
+*/
+
+import javax.swing.*;
+import javax.swing.filechooser.FileSystemView;
+import java.io.File;
+
+public class bug6698013 extends JApplet {
+
+    final static VirtualFile root = new VirtualFile("testdir", true);
+
+    final static VirtualFile rootFile = new VirtualFile("testdir/test.txt", false);
+
+    final static VirtualFile subdir = new VirtualFile("testdir/subdir", true);
+
+    final static VirtualFile subdirFile = new VirtualFile("testdir/subdir/subtest.txt", false);
+
+    public static void main(String[] args) {
+        JFileChooser chooser = new JFileChooser(new VirtualFileSystemView());
+        chooser.setCurrentDirectory(root);
+        chooser.showSaveDialog(null);
+    }
+
+    public void init() {
+        JFileChooser chooser = new JFileChooser(new VirtualFileSystemView());
+        chooser.setCurrentDirectory(root);
+        chooser.showSaveDialog(null);
+    }
+}
+
+class VirtualFileSystemView extends FileSystemView {
+
+    public boolean isRoot(File dir) {
+        return bug6698013.root.equals(dir);
+    }
+
+    public File createNewFolder(File dir) {
+        return null;
+    }
+
+    public File[] getRoots() {
+        return new File[]{bug6698013.root};
+    }
+
+    public boolean isDrive(File dir) {
+        return false;
+    }
+
+    public boolean isFloppyDrive(File dir) {
+        return false;
+    }
+
+    public File getParentDirectory(File dir) {
+        if (dir == null) {
+            return null;
+        }
+
+        return new VirtualFile(dir.getPath(), true).getParentFile();
+    }
+
+    public File[] getFiles(File dir, boolean hide_hidden) {
+        if (dir.equals(bug6698013.root)) {
+            return new File[]{bug6698013.rootFile, bug6698013.subdir};
+        }
+
+        if (dir.equals(bug6698013.subdir)) {
+            return new File[]{bug6698013.subdirFile};
+        }
+
+        return null;
+    }
+
+    public File getHomeDirectory() {
+        return bug6698013.root;
+    }
+
+    public File getDefaultDirectory() {
+        return getHomeDirectory();
+    }
+
+    public String getSystemDisplayName(File file) {
+        return file.getName();
+    }
+
+    public Boolean isTraversable(File file) {
+        return Boolean.valueOf(file.isDirectory());
+    }
+}
+
+/**
+ * A Virtual File. Contains a path and a directory flag that
+ * represents the location of a virtual file to be contained in the
+ * Virtual FileSystemView.
+ */
+class VirtualFile extends File {
+
+    private static final long serialVersionUID = 0L;
+
+    private String path;
+
+    private boolean directory;
+
+    public VirtualFile(String path, boolean directory) {
+        super(path);
+        this.path = path;
+        this.directory = directory;
+    }
+
+    public File getParentFile() {
+        int index = path.lastIndexOf('/');
+
+        if (index == -1) {
+            return null;
+        }
+
+        return new VirtualFile(path.substring(0, index), true);
+    }
+
+    public File getCanonicalFile() {
+        return this;
+    }
+
+    public String getParent() {
+        File parent_file = getParentFile();
+
+        return parent_file == null ? null : parent_file.getPath();
+    }
+
+    public String getName() {
+        int index = path.lastIndexOf('/');
+
+        return index == -1 ? path : path.substring(index + 1);
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public String getAbsolutePath() {
+        return path;
+    }
+
+    public String getCanonicalPath() {
+        return path;
+    }
+
+    public String toString() {
+        return path;
+    }
+
+    public boolean equals(Object obj) {
+        return obj instanceof VirtualFile && path.equals(obj.toString());
+    }
+
+    public int hashCode() {
+        return path.hashCode();
+    }
+
+    public boolean canWrite() {
+        return true;
+    }
+
+    public boolean isDirectory() {
+        return directory;
+    }
+
+    public boolean exists() {
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JSlider/6794836/bug6794836.java	Wed Jul 05 16:46:22 2017 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 6794836
+ * @summary BasicSliderUI throws NullPointerExc when JSlider maximum is Integer.MAX_VALUE
+ * @author Pavel Porvatov
+ * @run main bug6794836
+ */
+
+import javax.swing.*;
+import javax.swing.plaf.basic.BasicSliderUI;
+import java.lang.reflect.Method;
+import java.util.Hashtable;
+
+public class bug6794836 {
+    public static void main(String[] args) throws Exception {
+        new bug6794836().run();
+    }
+
+    public void run() throws Exception {
+        JSlider slider = new JSlider(0, Integer.MAX_VALUE);
+
+        slider.setPaintLabels(true);
+
+        JLabel minLabel = new JLabel("Min");
+        JLabel maxLabel = new JLabel("Max");
+
+        Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer, JLabel>();
+
+        labelTable.put(Integer.MIN_VALUE, minLabel);
+        labelTable.put(Integer.MAX_VALUE, maxLabel);
+
+        slider.setLabelTable(labelTable);
+
+        BasicSliderUI ui = (BasicSliderUI) slider.getUI();
+
+        if (invokeMethod("getHighestValueLabel", ui) != maxLabel) {
+            fail("invalid getHighestValueLabel result");
+        }
+
+        if (invokeMethod("getLowestValueLabel", ui) != minLabel) {
+            fail("invalid getLowestValueLabel result");
+        }
+
+        System.out.println("The bug6794836 test passed");
+    }
+
+    private static Object invokeMethod(String name, BasicSliderUI ui) throws Exception {
+        Method method = BasicSliderUI.class.getDeclaredMethod(name, null);
+
+        method.setAccessible(true);
+
+        return method.invoke(ui, null);
+    }
+
+    private static void fail(String s) {
+        throw new RuntimeException("Test failed: " + s);
+    }
+}
--- a/jdk/test/sun/text/resources/LocaleData	Thu Jan 29 13:21:02 2009 -0800
+++ b/jdk/test/sun/text/resources/LocaleData	Wed Jul 05 16:46:22 2017 +0200
@@ -5518,3 +5518,11 @@
 FormatData/sv/AmPmMarkers/0=fm
 FormatData/sv/AmPmMarkers/1=em
 
+# JE, GG, IM (6544471)
+LocaleNames//JE=Jersey
+LocaleNames//GG=Guernsey
+LocaleNames//IM=Isle Of Man
+
+# BL, MF (6627549)
+LocaleNames//BL=Saint Barth\u00e9lemy
+LocaleNames//MF=Saint Martin