changeset 17364:d7c0497507a3

Merge
author amurillo
date Sat, 30 Jul 2016 00:11:02 +0000
parents 52b9765c780e dd56fbbb2527
children 02651d14d282
files src/java.base/linux/classes/sun/nio/fs/GioFileTypeDetector.java src/java.base/linux/classes/sun/nio/fs/MagicFileTypeDetector.java src/java.base/linux/native/libnio/fs/GioFileTypeDetector.c src/java.base/linux/native/libnio/fs/MagicFileTypeDetector.c src/java.desktop/macosx/classes/sun/lwawt/macosx/AccessibilityEventMonitor.java src/jdk.jlink/share/classes/jdk/tools/jlink/internal/AbstractModuleEntry.java src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ArchiveEntryModuleEntry.java src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ByteArrayModuleEntry.java src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModuleEntryFactory.java src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModulePoolImpl.java src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PathModuleEntry.java src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/LinkModule.java src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ModuleEntry.java src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ModulePool.java test/java/util/SplittableRandom/SplittableRandomTest.java test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java
diffstat 206 files changed, 7249 insertions(+), 4772 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Jul 29 10:18:47 2016 +0200
+++ b/.hgtags	Sat Jul 30 00:11:02 2016 +0000
@@ -371,3 +371,4 @@
 6fda66a5bdf2da8994032b9da2078a4137f4d954 jdk-9+126
 7a97b89ba83077ca62e4aa5a05437adc8f315343 jdk-9+127
 9446c534f0222b4eecfd9d9e25ab37c4fd4400a5 jdk-9+128
+47699aa2e69ec2702542dc73eb01de3bfb61aea0 jdk-9+129
--- a/make/data/tzdata/VERSION	Fri Jul 29 10:18:47 2016 +0200
+++ b/make/data/tzdata/VERSION	Sat Jul 30 00:11:02 2016 +0000
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2016d
+tzdata2016f
--- a/make/data/tzdata/africa	Fri Jul 29 10:18:47 2016 +0200
+++ b/make/data/tzdata/africa	Sat Jul 30 00:11:02 2016 +0000
@@ -366,6 +366,12 @@
 # decision to abandon DST permanently.  See Ahram Online 2015-04-24.
 # http://english.ahram.org.eg/NewsContent/1/64/128509/Egypt/Politics-/Sisi-cancels-daylight-saving-time-in-Egypt.aspx
 
+# From Steffen Thorsen (2016-04-29):
+# Egypt will have DST from July 7 until the end of October....
+# http://english.ahram.org.eg/NewsContentP/1/204655/Egypt/Daylight-savings-time-returning-to-Egypt-on--July.aspx
+# From Mina Samuel (2016-07-04):
+# Egyptian government took the decision to cancel the DST,
+
 Rule	Egypt	2008	only	-	Aug	lastThu	24:00	0	-
 Rule	Egypt	2009	only	-	Aug	20	24:00	0	-
 Rule	Egypt	2010	only	-	Aug	10	24:00	0	-
@@ -881,11 +887,11 @@
 Rule	Morocco	2010	only	-	May	 2	 0:00	1:00	S
 Rule	Morocco	2010	only	-	Aug	 8	 0:00	0	-
 Rule	Morocco	2011	only	-	Apr	 3	 0:00	1:00	S
-Rule	Morocco	2011	only	-	Jul	31	 0	0	-
+Rule	Morocco	2011	only	-	Jul	31	 0:00	0	-
 Rule	Morocco	2012	2013	-	Apr	lastSun	 2:00	1:00	S
-Rule	Morocco	2012	only	-	Sep	30	 3:00	0	-
 Rule	Morocco	2012	only	-	Jul	20	 3:00	0	-
 Rule	Morocco	2012	only	-	Aug	20	 2:00	1:00	S
+Rule	Morocco	2012	only	-	Sep	30	 3:00	0	-
 Rule	Morocco	2013	only	-	Jul	 7	 3:00	0	-
 Rule	Morocco	2013	only	-	Aug	10	 2:00	1:00	S
 Rule	Morocco	2013	max	-	Oct	lastSun	 3:00	0	-
--- a/make/data/tzdata/antarctica	Fri Jul 29 10:18:47 2016 +0200
+++ b/make/data/tzdata/antarctica	Sat Jul 30 00:11:02 2016 +0000
@@ -36,7 +36,7 @@
 #
 # Except for the French entries,
 # I made up all time zone abbreviations mentioned here; corrections welcome!
-# FORMAT is 'zzz' and GMTOFF is 0 for locations while uninhabited.
+# FORMAT is '-00' and GMTOFF is 0 for locations while uninhabited.
 
 # Argentina - year-round bases
 # Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
@@ -90,22 +90,22 @@
 # http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/Casey	0	-	zzz	1969
+Zone Antarctica/Casey	0	-	-00	1969
 			8:00	-	AWST	2009 Oct 18  2:00
 						# Australian Western Std Time
 			11:00	-	CAST	2010 Mar  5  2:00  # Casey Time
 			8:00	-	AWST	2011 Oct 28  2:00
 			11:00	-	CAST	2012 Feb 21 17:00u
 			8:00	-	AWST
-Zone Antarctica/Davis	0	-	zzz	1957 Jan 13
+Zone Antarctica/Davis	0	-	-00	1957 Jan 13
 			7:00	-	DAVT	1964 Nov    # Davis Time
-			0	-	zzz	1969 Feb
+			0	-	-00	1969 Feb
 			7:00	-	DAVT	2009 Oct 18  2:00
 			5:00	-	DAVT	2010 Mar 10 20:00u
 			7:00	-	DAVT	2011 Oct 28  2:00
 			5:00	-	DAVT	2012 Feb 21 20:00u
 			7:00	-	DAVT
-Zone Antarctica/Mawson	0	-	zzz	1954 Feb 13
+Zone Antarctica/Mawson	0	-	-00	1954 Feb 13
 			6:00	-	MAWT	2009 Oct 18  2:00 # Mawson Time
 			5:00	-	MAWT
 # References:
@@ -160,7 +160,7 @@
 #	fishing stations operated variously 1819/1931
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Indian/Kerguelen	0	-	zzz	1950 # Port-aux-Français
+Zone Indian/Kerguelen	0	-	-00	1950 # Port-aux-Français
 			5:00	-	TFT	# ISO code TF Time
 #
 # year-round base in the main continent
@@ -171,9 +171,9 @@
 # It was destroyed by fire on 1952-01-14.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/DumontDUrville 0 -	zzz	1947
+Zone Antarctica/DumontDUrville 0 -	-00	1947
 			10:00	-	PMT	1952 Jan 14 # Port-Martin Time
-			0	-	zzz	1956 Nov
+			0	-	-00	1956 Nov
 			10:00	-	DDUT	# Dumont-d'Urville Time
 
 # France & Italy - year-round base
@@ -199,7 +199,7 @@
 # was established on 1957-01-29.  Since Syowa station is still the main
 # station of Japan, it's appropriate for the principal location.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/Syowa	0	-	zzz	1957 Jan 29
+Zone Antarctica/Syowa	0	-	-00	1957 Jan 29
 			3:00	-	SYOT	# Syowa Time
 # See:
 # NIPR Antarctic Research Activities (1999-08-17)
@@ -249,7 +249,7 @@
 # Remove the following line when uncommenting the above '#Rule' lines.
 Rule	Troll	2004	max	-	Oct	lastSun	1:00u	0:00	UTC
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/Troll	0	-	zzz	2005 Feb 12
+Zone Antarctica/Troll	0	-	-00	2005 Feb 12
 			0:00	Troll	%s
 
 # Poland - year-round base
@@ -290,7 +290,7 @@
 # happened to be during their visit.  So we still don't really know what time
 # it is at Vostok.  But we'll guess UTC+6.
 #
-Zone Antarctica/Vostok	0	-	zzz	1957 Dec 16
+Zone Antarctica/Vostok	0	-	-00	1957 Dec 16
 			6:00	-	VOST	# Vostok time
 
 # S Africa - year-round bases
@@ -323,7 +323,7 @@
 # <http://webexhibits.org/daylightsaving/g.html> says Rothera is -03 all year.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/Rothera	0	-	zzz	1976 Dec  1
+Zone Antarctica/Rothera	0	-	-00	1976 Dec  1
 			-3:00	-	ROTT	# Rothera time
 
 # Uruguay - year round base
--- a/make/data/tzdata/asia	Fri Jul 29 10:18:47 2016 +0200
+++ b/make/data/tzdata/asia	Sat Jul 30 00:11:02 2016 +0000
@@ -169,7 +169,7 @@
 			3:00	-	BAKT	1957 Mar    # Baku Time
 			4:00 RussiaAsia BAK%sT	1991 Mar 31  2:00s
 			3:00	1:00	BAKST	1991 Aug 30 # independence
-			3:00 RussiaAsia	AZ%sT	1992 Sep lastSat 23:00
+			3:00 RussiaAsia	AZ%sT	1992 Sep lastSun  2:00s
 			4:00	-	AZT	1996     # Azerbaijan Time
 			4:00	EUAsia	AZ%sT	1997
 			4:00	Azer	AZ%sT
--- a/make/data/tzdata/australasia	Fri Jul 29 10:18:47 2016 +0200
+++ b/make/data/tzdata/australasia	Sat Jul 30 00:11:02 2016 +0000
@@ -266,11 +266,11 @@
 # will produce a binary file with an [A]EST-type as the first 32-bit type;
 # this is required for correct handling of times before 1916 by
 # pre-2013 versions of localtime.
-Zone Antarctica/Macquarie 0	-	zzz	1899 Nov
+Zone Antarctica/Macquarie 0	-	-00	1899 Nov
 			10:00	-	AEST	1916 Oct  1  2:00
 			10:00	1:00	AEDT	1917 Feb
 			10:00	Aus	AE%sT	1919 Apr  1  0:00s
-			0	-	zzz	1948 Mar 25
+			0	-	-00	1948 Mar 25
 			10:00	Aus	AE%sT	1967
 			10:00	AT	AE%sT	2010 Apr  4  3:00
 			11:00	-	MIST	# Macquarie I Standard Time
--- a/make/data/tzdata/europe	Fri Jul 29 10:18:47 2016 +0200
+++ b/make/data/tzdata/europe	Sat Jul 30 00:11:02 2016 +0000
@@ -778,6 +778,14 @@
 			1:00	EU	CE%sT
 
 # Belarus
+#
+# From Stepan Golosunov (2016-07-02):
+# http://www.lawbelarus.com/repub/sub30/texf9611.htm
+# (Act of the Cabinet of Ministers of the Republic of Belarus from
+# 1992-03-25 No. 157) ... says clocks were to be moved forward at 2:00
+# on last Sunday of March and backward at 3:00 on last Sunday of September
+# (the same as previous USSR and contemporary Russian regulations).
+#
 # From Yauhen Kharuzhy (2011-09-16):
 # By latest Belarus government act Europe/Minsk timezone was changed to
 # GMT+3 without DST (was GMT+2 with DST).
@@ -801,9 +809,6 @@
 			1:00	C-Eur	CE%sT	1944 Jul  3
 			3:00	Russia	MSK/MSD	1990
 			3:00	-	MSK	1991 Mar 31  2:00s
-			2:00	1:00	EEST	1991 Sep 29  2:00s
-			2:00	-	EET	1992 Mar 29  0:00s
-			2:00	1:00	EEST	1992 Sep 27  0:00s
 			2:00	Russia	EE%sT	2011 Mar 27  2:00s
 			3:00	-	FET	2014 Oct 26  1:00s
 			3:00	-	MSK
@@ -2746,14 +2751,22 @@
 # Asia/Novosibirsk covers:
 # 54	RU-NVS	Novosibirsk Oblast
 
+# From Stepan Golosunov (2016-05-30):
+# http://asozd2.duma.gov.ru/main.nsf/(Spravka)?OpenAgent&RN=1085784-6
+# moves Novosibirsk oblast from UTC+6 to UTC+7.
+# From Stepan Golosunov (2016-07-04):
+# The law was signed yesterday and published today on
+# http://publication.pravo.gov.ru/Document/View/0001201607040064
+
 Zone Asia/Novosibirsk	 5:31:40 -	LMT	1919 Dec 14  6:00
-			 6:00	-	NOVT	1930 Jun 21 # Novosibirsk Time
-			 7:00	Russia	NOV%sT	1991 Mar 31  2:00s
-			 6:00	Russia	NOV%sT	1992 Jan 19  2:00s
-			 7:00	Russia	NOV%sT	1993 May 23 # say Shanks & P.
-			 6:00	Russia	NOV%sT	2011 Mar 27  2:00s
-			 7:00	-	NOVT	2014 Oct 26  2:00s
-			 6:00	-	NOVT
+			 6:00	-	+06	1930 Jun 21
+			 7:00	Russia	+07/+08	1991 Mar 31  2:00s
+			 6:00	Russia	+06/+07	1992 Jan 19  2:00s
+			 7:00	Russia	+07/+08	1993 May 23 # say Shanks & P.
+			 6:00	Russia	+06/+07	2011 Mar 27  2:00s
+			 7:00	-	+07	2014 Oct 26  2:00s
+			 6:00	-	+06	2016 Jul 24  2:00s
+			 7:00	-	+07
 
 # From Paul Eggert (2016-03-18):
 # Asia/Tomsk covers:
@@ -2794,6 +2807,9 @@
 # approved by the Federation Council on 2016-04-20, signed by the President and
 # published as a law around 2016-04-26.
 
+# From Matt Johnson (2016-04-26):
+# http://publication.pravo.gov.ru/Document/View/0001201604260048
+
 Zone	Asia/Tomsk	 5:39:51 -	LMT	1919 Dec 22
 			 6:00	-	+06	1930 Jun 21
 			 7:00	Russia	+07/+08	1991 Mar 31  2:00s
@@ -2833,14 +2849,12 @@
 # realigning itself with KRAT.
 
 Zone Asia/Novokuznetsk	 5:48:48 -	LMT	1924 May  1
-			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
-			 7:00	Russia	KRA%sT	1991 Mar 31  2:00s
-			 6:00	Russia	KRA%sT	1992 Jan 19  2:00s
-			 7:00	Russia	KRA%sT	2010 Mar 28  2:00s
-			 6:00	Russia	NOV%sT	2011 Mar 27  2:00s # Novosibirsk
-			 7:00	-	NOVT	2014 Oct 26  2:00s
-			 7:00	-	KRAT	# Krasnoyarsk Time
-
+			 6:00	-	+06	1930 Jun 21
+			 7:00	Russia	+07/+08	1991 Mar 31  2:00s
+			 6:00	Russia	+06/+07	1992 Jan 19  2:00s
+			 7:00	Russia	+07/+08	2010 Mar 28  2:00s
+			 6:00	Russia	+06/+07	2011 Mar 27  2:00s
+			 7:00	-	+07
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
 # Asia/Krasnoyarsk covers...
--- a/make/data/tzdata/northamerica	Fri Jul 29 10:18:47 2016 +0200
+++ b/make/data/tzdata/northamerica	Sat Jul 30 00:11:02 2016 +0000
@@ -2214,39 +2214,39 @@
 Rule	NT_YK	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 # aka Panniqtuuq
-Zone America/Pangnirtung 0	-	zzz	1921 # trading post est.
+Zone America/Pangnirtung 0	-	-00	1921 # trading post est.
 			-4:00	NT_YK	A%sT	1995 Apr Sun>=1  2:00
 			-5:00	Canada	E%sT	1999 Oct 31  2:00
 			-6:00	Canada	C%sT	2000 Oct 29  2:00
 			-5:00	Canada	E%sT
 # formerly Frobisher Bay
-Zone America/Iqaluit	0	-	zzz	1942 Aug # Frobisher Bay est.
+Zone America/Iqaluit	0	-	-00	1942 Aug # Frobisher Bay est.
 			-5:00	NT_YK	E%sT	1999 Oct 31  2:00
 			-6:00	Canada	C%sT	2000 Oct 29  2:00
 			-5:00	Canada	E%sT
 # aka Qausuittuq
-Zone America/Resolute	0	-	zzz	1947 Aug 31 # Resolute founded
+Zone America/Resolute	0	-	-00	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	2007 Mar 11  3:00
 			-6:00	Canada	C%sT
 # aka Kangiqiniq
-Zone America/Rankin_Inlet 0	-	zzz	1957 # Rankin Inlet founded
+Zone America/Rankin_Inlet 0	-	-00	1957 # Rankin Inlet 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
 # aka Iqaluktuuttiaq
-Zone America/Cambridge_Bay 0	-	zzz	1920 # trading post est.?
+Zone America/Cambridge_Bay 0	-	-00	1920 # trading post est.?
 			-7:00	NT_YK	M%sT	1999 Oct 31  2:00
 			-6:00	Canada	C%sT	2000 Oct 29  2:00
 			-5:00	-	EST	2000 Nov  5  0:00
 			-6:00	-	CST	2001 Apr  1  3:00
 			-7:00	Canada	M%sT
-Zone America/Yellowknife 0	-	zzz	1935 # Yellowknife founded?
+Zone America/Yellowknife 0	-	-00	1935 # Yellowknife founded?
 			-7:00	NT_YK	M%sT	1980
 			-7:00	Canada	M%sT
-Zone America/Inuvik	0	-	zzz	1953 # Inuvik founded
+Zone America/Inuvik	0	-	-00	1953 # Inuvik founded
 			-8:00	NT_YK	P%sT	1979 Apr lastSun  2:00
 			-7:00	NT_YK	M%sT	1980
 			-7:00	Canada	M%sT
--- a/make/data/tzdata/southamerica	Fri Jul 29 10:18:47 2016 +0200
+++ b/make/data/tzdata/southamerica	Sat Jul 30 00:11:02 2016 +0000
@@ -1332,7 +1332,7 @@
 # Palmer used to be supplied from Argentina.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/Palmer	0	-	zzz	1965
+Zone Antarctica/Palmer	0	-	-00	1965
 			-4:00	Arg	AR%sT	1969 Oct  5
 			-3:00	Arg	AR%sT	1982 May
 			-4:00	Chile	CL%sT
@@ -1782,16 +1782,16 @@
 # https://actualidad.rt.com/actualidad/204758-venezuela-modificar-huso-horario-sequia-elnino
 #
 # From Paul Eggert (2016-04-15):
-# Clocks advance 30 minutes on 2016-05-01 at 02:30. See:
-# Barboza AD. Huso horario en Venezuela volverá a 4 horas menos con
-# respecto al "Greenwich". Panorama 2016-04-15 12:20 -0430.
-# http://www.panorama.com.ve/ciudad/Huso-horario-en-Venezuela-volvera-a-4-horas-menos-con-respecto-al-Greenwich-20160415-0032.html
-#
+# Clocks advance 30 minutes on 2016-05-01 at 02:30....
 # "'Venezuela's new time-zone: hours without light, hours without water,
-# hours of presidential broadcasts, hours of lines," quipped comedian
-# Jean Mary Curro ...". See: Cawthorne A, Kai D. Venezuela scraps
+# hours of presidential broadcasts, hours of lines,' quipped comedian
+# Jean Mary Curró ...". See: Cawthorne A, Kai D. Venezuela scraps
 # half-hour time difference set by Chavez. Reuters 2016-04-15 14:50 -0400
 # http://www.reuters.com/article/us-venezuela-timezone-idUSKCN0XC2BE
+#
+# From Matt Johnson (2016-04-20):
+# ... published in the official Gazette [2016-04-18], here:
+# http://historico.tsj.gob.ve/gaceta_ext/abril/1842016/E-1842016-4551.pdf
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	America/Caracas	-4:27:44 -	LMT	1890
--- a/make/lib/Awt2dLibraries.gmk	Fri Jul 29 10:18:47 2016 +0200
+++ b/make/lib/Awt2dLibraries.gmk	Sat Jul 30 00:11:02 2016 +0000
@@ -915,7 +915,7 @@
     LIBSPLASHSCREEN_LDFLAGS := -delayload:user32.dll
     LIBSPLASHSCREEN_LIBS += kernel32.lib user32.lib gdi32.lib delayimp.lib $(WIN_JAVA_LIB) jvm.lib
   else
-    LIBSPLASHSCREEN_LIBS += $(X_LIBS) -lX11 -lXext $(LIBM) -lpthread
+    LIBSPLASHSCREEN_LIBS += $(X_LIBS) -lX11 -lXext $(LIBM) -lpthread -ldl
   endif
 
   $(eval $(call SetupNativeCompilation,BUILD_LIBSPLASHSCREEN, \
--- a/make/mapfiles/libawt_xawt/mapfile-vers	Fri Jul 29 10:18:47 2016 +0200
+++ b/make/mapfiles/libawt_xawt/mapfile-vers	Sat Jul 30 00:11:02 2016 +0000
@@ -164,6 +164,7 @@
         Java_sun_awt_X11_XRobotPeer_mouseReleaseImpl;
         Java_sun_awt_X11_XRobotPeer_mouseWheelImpl;
         Java_sun_awt_X11_XRobotPeer_setup;
+        Java_sun_awt_X11_XRobotPeer_loadNativeLibraries;
         Java_sun_awt_X11_XToolkit_getNumberOfButtonsImpl;
         Java_java_awt_Component_initIDs;
         Java_java_awt_Container_initIDs;
--- a/make/mapfiles/libnio/mapfile-linux	Fri Jul 29 10:18:47 2016 +0200
+++ b/make/mapfiles/libnio/mapfile-linux	Sat Jul 30 00:11:02 2016 +0000
@@ -136,10 +136,6 @@
 		Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0;
 		Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs;
 		Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect;
-		Java_sun_nio_fs_GioFileTypeDetector_initializeGio;
-		Java_sun_nio_fs_GioFileTypeDetector_probeGio;
-		Java_sun_nio_fs_MagicFileTypeDetector_initialize0;
-		Java_sun_nio_fs_MagicFileTypeDetector_probe0;
 		Java_sun_nio_fs_LinuxWatchService_eventSize;
 		Java_sun_nio_fs_LinuxWatchService_eventOffsets;
 		Java_sun_nio_fs_LinuxWatchService_inotifyInit;
--- a/src/java.base/linux/classes/sun/nio/fs/GioFileTypeDetector.java	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.nio.fs;
-
-import java.nio.file.Path;
-import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * File type detector that uses the GNOME I/O library to guess the
- * MIME type of a file.
- */
-
-public class GioFileTypeDetector
-    extends AbstractFileTypeDetector
-{
-    // true if GIO is available
-    private final boolean gioAvailable;
-
-    public GioFileTypeDetector() {
-        gioAvailable = initializeGio();
-    }
-
-    @Override
-    public String implProbeContentType(Path obj) throws IOException {
-        if (!gioAvailable)
-            return null;
-        if (!(obj instanceof UnixPath))
-            return null;
-
-        UnixPath path = (UnixPath)obj;
-        NativeBuffer buffer = NativeBuffers.asNativeBuffer(path.getByteArrayForSysCalls());
-        try {
-            // GIO may access file so need permission check
-            path.checkRead();
-            byte[] type = probeGio(buffer.address());
-            return (type == null) ? null : Util.toString(type);
-        } finally {
-            buffer.release();
-        }
-
-    }
-
-    // GIO
-    private static native boolean initializeGio();
-    //
-    // The probeGIO() method is synchronized to avert potential problems
-    // such as crashes due to a suspected lack of thread safety in GIO.
-    //
-    private static synchronized native byte[] probeGio(long pathAddress);
-
-    static {
-        AccessController.doPrivileged(new PrivilegedAction<>() {
-            public Void run() {
-                System.loadLibrary("nio");
-                return null;
-        }});
-    }
-}
--- a/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -106,9 +106,7 @@
         Path userMimeTypes = Paths.get(userHome, ".mime.types");
         Path etcMimeTypes = Paths.get("/etc/mime.types");
 
-        return chain(new GioFileTypeDetector(),
-                     new MimeTypesFileTypeDetector(userMimeTypes),
-                     new MimeTypesFileTypeDetector(etcMimeTypes),
-                     new MagicFileTypeDetector());
+        return chain(new MimeTypesFileTypeDetector(userMimeTypes),
+                     new MimeTypesFileTypeDetector(etcMimeTypes));
     }
 }
--- a/src/java.base/linux/classes/sun/nio/fs/MagicFileTypeDetector.java	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.nio.fs;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * File type detector that uses the libmagic to guess the MIME type of a file.
- */
-
-class MagicFileTypeDetector extends AbstractFileTypeDetector {
-
-    private static final String UNKNOWN_MIME_TYPE = "application/octet-stream";
-
-    // true if libmagic is available and successfully loaded
-    private final boolean libmagicAvailable;
-
-    public MagicFileTypeDetector() {
-        libmagicAvailable = initialize0();
-    }
-
-    @Override
-    protected String implProbeContentType(Path obj) throws IOException {
-        if (!libmagicAvailable || !(obj instanceof UnixPath))
-            return null;
-
-        UnixPath path = (UnixPath) obj;
-        path.checkRead();
-
-        NativeBuffer buffer = NativeBuffers.asNativeBuffer(path.getByteArrayForSysCalls());
-        try {
-            byte[] type = probe0(buffer.address());
-            String mimeType = (type == null) ? null : new String(type);
-            return UNKNOWN_MIME_TYPE.equals(mimeType) ? null : mimeType;
-        } finally {
-            buffer.release();
-        }
-    }
-
-    private static native boolean initialize0();
-
-    private static native byte[] probe0(long pathAddress);
-
-    static {
-        AccessController.doPrivileged(new PrivilegedAction<>() {
-            @Override
-            public Void run() {
-                System.loadLibrary("nio");
-                return null;
-            }
-        });
-    }
-}
--- a/src/java.base/linux/native/libnio/fs/GioFileTypeDetector.c	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jvm.h"
-#include "jlong.h"
-
-#include <stdlib.h>
-#include <dlfcn.h>
-
-#ifdef __solaris__
-#include <strings.h>
-#endif
-
-#if defined(__linux__)
-#include <string.h>
-#endif
-
-/*
- * For reference see for example the GFileInfo section at
- * https://developer.gnome.org/gio/unstable/.
- */
-
-/* Definitions for GIO */
-
-#define G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "standard::content-type"
-
-typedef void* gpointer;
-typedef struct _GFile GFile;
-typedef struct _GFileInfo GFileInfo;
-typedef struct _GCancellable GCancellable;
-typedef struct _GError GError;
-
-typedef enum {
-  G_FILE_QUERY_INFO_NONE = 0
-} GFileQueryInfoFlags;
-
-typedef void (*g_type_init_func)(void);
-typedef void (*g_object_unref_func)(gpointer object);
-typedef GFile* (*g_file_new_for_path_func)(const char* path);
-typedef GFileInfo* (*g_file_query_info_func)(GFile *file,
-    const char *attributes, GFileQueryInfoFlags flags,
-    GCancellable *cancellable, GError **error);
-typedef char* (*g_file_info_get_content_type_func)(GFileInfo *info);
-
-static g_type_init_func g_type_init;
-static g_object_unref_func g_object_unref;
-static g_file_new_for_path_func g_file_new_for_path;
-static g_file_query_info_func g_file_query_info;
-static g_file_info_get_content_type_func g_file_info_get_content_type;
-
-
-#include "sun_nio_fs_GioFileTypeDetector.h"
-
-
-JNIEXPORT jboolean JNICALL
-Java_sun_nio_fs_GioFileTypeDetector_initializeGio
-    (JNIEnv* env, jclass this)
-{
-    void* gio_handle;
-
-    gio_handle = dlopen("libgio-2.0.so", RTLD_LAZY);
-    if (gio_handle == NULL) {
-        gio_handle = dlopen("libgio-2.0.so.0", RTLD_LAZY);
-        if (gio_handle == NULL) {
-            return JNI_FALSE;
-        }
-    }
-
-    g_type_init = (g_type_init_func)dlsym(gio_handle, "g_type_init");
-
-    g_object_unref = (g_object_unref_func)dlsym(gio_handle, "g_object_unref");
-
-    g_file_new_for_path =
-        (g_file_new_for_path_func)dlsym(gio_handle, "g_file_new_for_path");
-
-    g_file_query_info =
-        (g_file_query_info_func)dlsym(gio_handle, "g_file_query_info");
-
-    g_file_info_get_content_type = (g_file_info_get_content_type_func)
-        dlsym(gio_handle, "g_file_info_get_content_type");
-
-    if (g_object_unref == NULL ||
-        g_file_new_for_path == NULL ||
-        g_file_query_info == NULL ||
-        g_file_info_get_content_type == NULL)
-    {
-        dlclose(gio_handle);
-        return JNI_FALSE;
-    }
-
-    if (g_type_init != NULL) {
-        (*g_type_init)();
-    }
-
-    return JNI_TRUE;
-}
-
-JNIEXPORT jbyteArray JNICALL
-Java_sun_nio_fs_GioFileTypeDetector_probeGio
-    (JNIEnv* env, jclass this, jlong pathAddress)
-{
-    char* path = (char*)jlong_to_ptr(pathAddress);
-    GFile* gfile;
-    GFileInfo* gfileinfo;
-    jbyteArray result = NULL;
-
-    gfile = (*g_file_new_for_path)(path);
-    gfileinfo = (*g_file_query_info)(gfile, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
-        G_FILE_QUERY_INFO_NONE, NULL, NULL);
-    if (gfileinfo != NULL) {
-        const char* mime = (*g_file_info_get_content_type)(gfileinfo);
-        if (mime != NULL) {
-            jsize len = strlen(mime);
-            result = (*env)->NewByteArray(env, len);
-            if (result != NULL) {
-                (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)mime);
-            }
-        }
-        (*g_object_unref)(gfileinfo);
-    }
-    (*g_object_unref)(gfile);
-
-    return result;
-}
--- a/src/java.base/linux/native/libnio/fs/MagicFileTypeDetector.c	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jvm.h"
-#include "jlong.h"
-
-#include <dlfcn.h>
-#include <string.h>
-
-#define MAGIC_MIME_TYPE 0x000010 /* Return the MIME type */
-
-typedef struct magic_set magic_t;
-
-typedef magic_t* (*magic_open_func)(int flags);
-typedef int (*magic_load_func)(magic_t* cookie, const char* filename);
-typedef const char* (*magic_file_func)(magic_t* cookie, const char* filename);
-typedef void (*magic_close_func)(magic_t* cookie);
-
-static void* magic_handle;
-static magic_open_func magic_open;
-static magic_load_func magic_load;
-static magic_file_func magic_file;
-static magic_close_func magic_close;
-
-#include "sun_nio_fs_MagicFileTypeDetector.h"
-
-JNIEXPORT jboolean JNICALL
-Java_sun_nio_fs_MagicFileTypeDetector_initialize0
-    (JNIEnv* env, jclass this)
-{
-    magic_handle = dlopen("libmagic.so", RTLD_LAZY);
-    if (magic_handle == NULL) {
-        magic_handle = dlopen("libmagic.so.1", RTLD_LAZY);
-        if (magic_handle == NULL) {
-            return JNI_FALSE;
-        }
-    }
-
-    magic_open = (magic_open_func)dlsym(magic_handle, "magic_open");
-
-    magic_load = (magic_load_func)dlsym(magic_handle, "magic_load");
-
-    magic_file = (magic_file_func)dlsym(magic_handle, "magic_file");
-
-    magic_close = (magic_close_func)dlsym(magic_handle, "magic_close");
-
-    if (magic_open == NULL ||
-        magic_load == NULL ||
-        magic_file == NULL ||
-        magic_close == NULL)
-    {
-        dlclose(magic_handle);
-        return JNI_FALSE;
-    }
-
-    return JNI_TRUE;
-}
-
-JNIEXPORT jbyteArray JNICALL
-Java_sun_nio_fs_MagicFileTypeDetector_probe0
-    (JNIEnv* env, jclass this, jlong pathAddress)
-{
-    char* path = (char*)jlong_to_ptr(pathAddress);
-    magic_t* cookie;
-    jbyteArray result = NULL;
-
-    cookie = (*magic_open)(MAGIC_MIME_TYPE);
-
-    if (cookie != NULL) {
-        if ((*magic_load)(cookie, NULL) != -1) {
-            const char* type = (*magic_file)(cookie, path);
-            if (type != NULL) {
-                jsize len = strlen(type);
-                result = (*env)->NewByteArray(env, len);
-                if (result != NULL) {
-                    (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*)type);
-                }
-            }
-        }
-        (*magic_close)(cookie);
-    }
-
-    return result;
-}
--- a/src/java.base/share/classes/java/lang/System.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.base/share/classes/java/lang/System.java	Sat Jul 30 00:11:02 2016 +0000
@@ -236,10 +236,12 @@
      * @since   1.6
      */
      public static Console console() {
-         Console c = cons;
-         if (c == null) {
+         Console c;
+         if ((c = cons) == null) {
              synchronized (System.class) {
-                 cons = c = SharedSecrets.getJavaIOAccess().console();
+                 if ((c = cons) == null) {
+                     cons = c = SharedSecrets.getJavaIOAccess().console();
+                 }
              }
          }
          return c;
--- a/src/java.base/share/classes/java/lang/reflect/Executable.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.base/share/classes/java/lang/reflect/Executable.java	Sat Jul 30 00:11:02 2016 +0000
@@ -122,7 +122,7 @@
             sb.append(')');
 
             if (exceptionTypes.length > 0) {
-                StringJoiner joiner = new StringJoiner(",", "throws ", "");
+                StringJoiner joiner = new StringJoiner(",", " throws ", "");
                 for (Class<?> exceptionType : exceptionTypes) {
                     joiner.add(exceptionType.getTypeName());
                 }
--- a/src/java.base/share/classes/java/time/LocalDate.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.base/share/classes/java/time/LocalDate.java	Sat Jul 30 00:11:02 2016 +0000
@@ -338,6 +338,7 @@
      * @throws DateTimeException if the epoch day exceeds the supported date range
      */
     public static LocalDate ofEpochDay(long epochDay) {
+        EPOCH_DAY.checkValidValue(epochDay);
         long zeroDay = epochDay + DAYS_0000_TO_1970;
         // find the march-based year
         zeroDay -= 60;  // adjust to 0000-03-01 so leap day is at end of four year cycle
--- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Sat Jul 30 00:11:02 2016 +0000
@@ -928,7 +928,24 @@
      * second if non-zero, no colon
      * <li>{@code +HH:mm:ss} - hour, with minute if non-zero or with minute and
      * second if non-zero, with colon
+     * <li>{@code +H} - hour only, ignoring minute and second
+     * <li>{@code +Hmm} - hour, with minute if non-zero, ignoring second, no colon
+     * <li>{@code +H:mm} - hour, with minute if non-zero, ignoring second, with colon
+     * <li>{@code +HMM} - hour and minute, ignoring second, no colon
+     * <li>{@code +H:MM} - hour and minute, ignoring second, with colon
+     * <li>{@code +HMMss} - hour and minute, with second if non-zero, no colon
+     * <li>{@code +H:MM:ss} - hour and minute, with second if non-zero, with colon
+     * <li>{@code +HMMSS} - hour, minute and second, no colon
+     * <li>{@code +H:MM:SS} - hour, minute and second, with colon
+     * <li>{@code +Hmmss} - hour, with minute if non-zero or with minute and
+     * second if non-zero, no colon
+     * <li>{@code +H:mm:ss} - hour, with minute if non-zero or with minute and
+     * second if non-zero, with colon
      * </ul>
+     * Patterns containing "HH" will format and parse a two digit hour,
+     * zero-padded if necessary. Patterns containing "H" will format with no
+     * zero-padding, and parse either one or two digits.
+     * In lenient mode, the parser will be greedy and parse the maximum digits possible.
      * The "no offset" text controls what text is printed when the total amount of
      * the offset fields to be output is zero.
      * Example values would be 'Z', '+00:00', 'UTC' or 'GMT'.
@@ -3475,13 +3492,15 @@
      */
     static final class OffsetIdPrinterParser implements DateTimePrinterParser {
         static final String[] PATTERNS = new String[] {
-            "+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS", "+HHmmss", "+HH:mm:ss",
+                "+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS", "+HHmmss", "+HH:mm:ss",
+                "+H",  "+Hmm",  "+H:mm",  "+HMM",  "+H:MM",  "+HMMss",  "+H:MM:ss",  "+HMMSS",  "+H:MM:SS",  "+Hmmss",  "+H:mm:ss",
         };  // order used in pattern builder
         static final OffsetIdPrinterParser INSTANCE_ID_Z = new OffsetIdPrinterParser("+HH:MM:ss", "Z");
         static final OffsetIdPrinterParser INSTANCE_ID_ZERO = new OffsetIdPrinterParser("+HH:MM:ss", "0");
 
         private final String noOffsetText;
         private final int type;
+        private final int style;
 
         /**
          * Constructor.
@@ -3493,6 +3512,7 @@
             Objects.requireNonNull(pattern, "pattern");
             Objects.requireNonNull(noOffsetText, "noOffsetText");
             this.type = checkPattern(pattern);
+            this.style = type % 11;
             this.noOffsetText = noOffsetText;
         }
 
@@ -3505,6 +3525,14 @@
             throw new IllegalArgumentException("Invalid zone offset pattern: " + pattern);
         }
 
+        private boolean isPaddedHour() {
+            return type < 11;
+        }
+
+        private boolean isColon() {
+            return style > 0 && (style % 2) == 0;
+        }
+
         @Override
         public boolean format(DateTimePrintContext context, StringBuilder buf) {
             Long offsetSecs = context.getValue(OFFSET_SECONDS);
@@ -3520,15 +3548,17 @@
                 int absSeconds = Math.abs(totalSecs % 60);
                 int bufPos = buf.length();
                 int output = absHours;
-                buf.append(totalSecs < 0 ? "-" : "+")
-                    .append((char) (absHours / 10 + '0')).append((char) (absHours % 10 + '0'));
-                if ((type >= 3 && type < 9) || (type >= 9 && absSeconds > 0) || (type >= 1 && absMinutes > 0)) {
-                    buf.append((type % 2) == 0 ? ":" : "")
-                        .append((char) (absMinutes / 10 + '0')).append((char) (absMinutes % 10 + '0'));
+                buf.append(totalSecs < 0 ? "-" : "+");
+                if (isPaddedHour() || absHours >= 10) {
+                    formatZeroPad(false, absHours, buf);
+                } else {
+                    buf.append((char) (absHours + '0'));
+                }
+                if ((style >= 3 && style <= 8) || (style >= 9 && absSeconds > 0) || (style >= 1 && absMinutes > 0)) {
+                    formatZeroPad(isColon(), absMinutes, buf);
                     output += absMinutes;
-                    if (type == 7  || type == 8 || (type >= 5 && absSeconds > 0)) {
-                        buf.append((type % 2) == 0 ? ":" : "")
-                            .append((char) (absSeconds / 10 + '0')).append((char) (absSeconds % 10 + '0'));
+                    if (style == 7 || style == 8 || (style >= 5 && absSeconds > 0)) {
+                        formatZeroPad(isColon(), absSeconds, buf);
                         output += absSeconds;
                     }
                 }
@@ -3540,19 +3570,16 @@
             return true;
         }
 
+        private void formatZeroPad(boolean colon, int value, StringBuilder buf) {
+            buf.append(colon ? ":" : "")
+                    .append((char) (value / 10 + '0'))
+                    .append((char) (value % 10 + '0'));
+        }
+
         @Override
         public int parse(DateTimeParseContext context, CharSequence text, int position) {
             int length = text.length();
             int noOffsetLen = noOffsetText.length();
-            int parseType = type;
-            if (context.isStrict() == false) {
-                if ((parseType > 0 && (parseType % 2) == 0) ||
-                    (parseType == 0 && length > position + 3 && text.charAt(position + 3) == ':')) {
-                    parseType = 10;
-                } else {
-                    parseType = 9;
-                }
-            }
             if (noOffsetLen == 0) {
                 if (position == length) {
                     return context.setParsedField(OFFSET_SECONDS, 0, position, position);
@@ -3571,12 +3598,87 @@
             if (sign == '+' || sign == '-') {
                 // starts
                 int negative = (sign == '-' ? -1 : 1);
+                boolean isColon = isColon();
+                boolean paddedHour = isPaddedHour();
                 int[] array = new int[4];
                 array[0] = position + 1;
-                if ((parseNumber(array, 1, text, true, parseType) ||
-                        parseNumber(array, 2, text, parseType >= 3 && parseType < 9, parseType) ||
-                        parseNumber(array, 3, text, parseType == 7 || parseType == 8, parseType)) == false) {
-                    // success
+                int parseType = type;
+                // select parse type when lenient
+                if (!context.isStrict()) {
+                    if (paddedHour) {
+                        if (isColon || (parseType == 0 && length > position + 3 && text.charAt(position + 3) == ':')) {
+                            isColon = true; // needed in cases like ("+HH", "+01:01")
+                            parseType = 10;
+                        } else {
+                            parseType = 9;
+                        }
+                    } else {
+                        if (isColon || (parseType == 11 && length > position + 3 && (text.charAt(position + 2) == ':' || text.charAt(position + 3) == ':'))) {
+                            isColon = true;
+                            parseType = 21;  // needed in cases like ("+H", "+1:01")
+                        } else {
+                            parseType = 20;
+                        }
+                    }
+                }
+                // parse according to the selected pattern
+                switch (parseType) {
+                    case 0: // +HH
+                    case 11: // +H
+                        parseHour(text, paddedHour, array);
+                        break;
+                    case 1: // +HHmm
+                    case 2: // +HH:mm
+                    case 13: // +H:mm
+                        parseHour(text, paddedHour, array);
+                        parseMinute(text, isColon, false, array);
+                        break;
+                    case 3: // +HHMM
+                    case 4: // +HH:MM
+                    case 15: // +H:MM
+                        parseHour(text, paddedHour, array);
+                        parseMinute(text, isColon, true, array);
+                        break;
+                    case 5: // +HHMMss
+                    case 6: // +HH:MM:ss
+                    case 17: // +H:MM:ss
+                        parseHour(text, paddedHour, array);
+                        parseMinute(text, isColon, true, array);
+                        parseSecond(text, isColon, false, array);
+                        break;
+                    case 7: // +HHMMSS
+                    case 8: // +HH:MM:SS
+                    case 19: // +H:MM:SS
+                        parseHour(text, paddedHour, array);
+                        parseMinute(text, isColon, true, array);
+                        parseSecond(text, isColon, true, array);
+                        break;
+                    case 9: // +HHmmss
+                    case 10: // +HH:mm:ss
+                    case 21: // +H:mm:ss
+                        parseHour(text, paddedHour, array);
+                        parseOptionalMinuteSecond(text, isColon, array);
+                        break;
+                    case 12: // +Hmm
+                        parseVariableWidthDigits(text, 1, 4, array);
+                        break;
+                    case 14: // +HMM
+                        parseVariableWidthDigits(text, 3, 4, array);
+                        break;
+                    case 16: // +HMMss
+                        parseVariableWidthDigits(text, 3, 6, array);
+                        break;
+                    case 18: // +HMMSS
+                        parseVariableWidthDigits(text, 5, 6, array);
+                        break;
+                    case 20: // +Hmmss
+                        parseVariableWidthDigits(text, 1, 6, array);
+                        break;
+                }
+                if (array[0] > 0) {
+                    if (array[1] > 23 || array[2] > 59 || array[3] > 59) {
+                        throw new DateTimeException("Value out of range: Hour[0-23], Minute[0-59], Second[0-59]");
+                    }
                     long offsetSecs = negative * (array[1] * 3600L + array[2] * 60L + array[3]);
                     return context.setParsedField(OFFSET_SECONDS, offsetSecs, position, array[0]);
                 }
@@ -3588,42 +3690,118 @@
             return ~position;
         }
 
-        /**
-         * Parse a two digit zero-prefixed number.
-         *
-         * @param array  the array of parsed data, 0=pos,1=hours,2=mins,3=secs, not null
-         * @param arrayIndex  the index to parse the value into
-         * @param parseText  the offset ID, not null
-         * @param required  whether this number is required
-         * @param parseType the offset pattern type
-         * @return true if an error occurred
-         */
-        private boolean parseNumber(int[] array, int arrayIndex, CharSequence parseText, boolean required, int parseType) {
-            if ((parseType + 3) / 2 < arrayIndex) {
-                return false;  // ignore seconds/minutes
+        private void parseHour(CharSequence parseText, boolean paddedHour, int[] array) {
+            if (paddedHour) {
+                // parse two digits
+                if (!parseDigits(parseText, false, 1, array)) {
+                    array[0] = ~array[0];
+                }
+            } else {
+                // parse one or two digits
+                parseVariableWidthDigits(parseText, 1, 2, array);
             }
+        }
+
+        private void parseMinute(CharSequence parseText, boolean isColon, boolean mandatory, int[] array) {
+            if (!parseDigits(parseText, isColon, 2, array)) {
+                if (mandatory) {
+                    array[0] = ~array[0];
+                }
+            }
+        }
+
+        private void parseSecond(CharSequence parseText, boolean isColon, boolean mandatory, int[] array) {
+            if (!parseDigits(parseText, isColon, 3, array)) {
+                if (mandatory) {
+                    array[0] = ~array[0];
+                }
+            }
+        }
+
+        private void parseOptionalMinuteSecond(CharSequence parseText, boolean isColon, int[] array) {
+            if (parseDigits(parseText, isColon, 2, array)) {
+                parseDigits(parseText, isColon, 3, array);
+            }
+        }
+
+        private boolean parseDigits(CharSequence parseText, boolean isColon, int arrayIndex, int[] array) {
             int pos = array[0];
-            if ((parseType % 2) == 0 && arrayIndex > 1) {
+            if (pos < 0) {
+                return true;
+            }
+            if (isColon && arrayIndex != 1) { //  ':' will precede only in case of minute/second
                 if (pos + 1 > parseText.length() || parseText.charAt(pos) != ':') {
-                    return required;
+                    return false;
                 }
                 pos++;
             }
             if (pos + 2 > parseText.length()) {
-                return required;
+                return false;
             }
             char ch1 = parseText.charAt(pos++);
             char ch2 = parseText.charAt(pos++);
             if (ch1 < '0' || ch1 > '9' || ch2 < '0' || ch2 > '9') {
-                return required;
+                return false;
             }
             int value = (ch1 - 48) * 10 + (ch2 - 48);
             if (value < 0 || value > 59) {
-                return required;
+                return false;
             }
             array[arrayIndex] = value;
             array[0] = pos;
-            return false;
+            return true;
+        }
+
+        private void parseVariableWidthDigits(CharSequence parseText, int minDigits, int maxDigits, int[] array) {
+            // scan the text to find the available number of digits up to maxDigits
+            // so long as the number available is minDigits or more, the input is valid
+            // then parse the number of available digits
+            int pos = array[0];
+            int available = 0;
+            char[] chars = new char[maxDigits];
+            for (int i = 0; i < maxDigits; i++) {
+                if (pos + 1  > parseText.length()) {
+                    break;
+                }
+                char ch = parseText.charAt(pos++);
+                if (ch < '0' || ch > '9') {
+                    pos--;
+                    break;
+                }
+                chars[i] = ch;
+                available++;
+            }
+            if (available < minDigits) {
+                array[0] = ~array[0];
+                return;
+            }
+            switch (available) {
+                case 1:
+                    array[1] = (chars[0] - 48);
+                    break;
+                case 2:
+                    array[1] = ((chars[0] - 48) * 10 + (chars[1] - 48));
+                    break;
+                case 3:
+                    array[1] = (chars[0] - 48);
+                    array[2] = ((chars[1] - 48) * 10 + (chars[2] - 48));
+                    break;
+                case 4:
+                    array[1] = ((chars[0] - 48) * 10 + (chars[1] - 48));
+                    array[2] = ((chars[2] - 48) * 10 + (chars[3] - 48));
+                    break;
+                case 5:
+                    array[1] = (chars[0] - 48);
+                    array[2] = ((chars[1] - 48) * 10 + (chars[2] - 48));
+                    array[3] = ((chars[3] - 48) * 10 + (chars[4] - 48));
+                    break;
+                case 6:
+                    array[1] = ((chars[0] - 48) * 10 + (chars[1] - 48));
+                    array[2] = ((chars[2] - 48) * 10 + (chars[3] - 48));
+                    array[3] = ((chars[4] - 48) * 10 + (chars[5] - 48));
+                    break;
+            }
+            array[0] = pos;
         }
 
         @Override
--- a/src/java.base/share/classes/java/time/temporal/ChronoField.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.base/share/classes/java/time/temporal/ChronoField.java	Sat Jul 30 00:11:02 2016 +0000
@@ -427,8 +427,11 @@
      * <p>
      * This field is strictly defined to have the same meaning in all calendar systems.
      * This is necessary to ensure interoperation between calendars.
+     * <p>
+     * Range of EpochDay is between (LocalDate.MIN.toEpochDay(), LocalDate.MAX.toEpochDay())
+     * both inclusive.
      */
-    EPOCH_DAY("EpochDay", DAYS, FOREVER, ValueRange.of((long) (Year.MIN_VALUE * 365.25), (long) (Year.MAX_VALUE * 365.25))),
+    EPOCH_DAY("EpochDay", DAYS, FOREVER, ValueRange.of(-365243219162L, 365241780471L)),
     /**
      * The aligned week within a month.
      * <p>
--- a/src/java.base/share/classes/javax/crypto/CryptoPermissions.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.base/share/classes/javax/crypto/CryptoPermissions.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,9 +37,7 @@
 import java.io.BufferedReader;
 import java.io.ObjectStreamField;
 import java.io.ObjectInputStream;
-import java.io.ObjectInputStream.GetField;
 import java.io.ObjectOutputStream;
-import java.io.ObjectOutputStream.PutField;
 import java.io.IOException;
 
 /**
@@ -132,15 +130,18 @@
      *
      * @see isReadOnly
      */
+    @Override
     public void add(Permission permission) {
 
-        if (isReadOnly())
+        if (isReadOnly()) {
             throw new SecurityException("Attempt to add a Permission " +
                                         "to a readonly CryptoPermissions " +
                                         "object");
+        }
 
-        if (!(permission instanceof CryptoPermission))
+        if (!(permission instanceof CryptoPermission)) {
             return;
+        }
 
         CryptoPermission cryptoPerm = (CryptoPermission)permission;
         PermissionCollection pc =
@@ -161,6 +162,7 @@
      * in the PermissionCollection it belongs to, false if not.
      *
      */
+    @Override
     public boolean implies(Permission permission) {
         if (!(permission instanceof CryptoPermission)) {
             return false;
@@ -170,7 +172,13 @@
 
         PermissionCollection pc =
             getPermissionCollection(cryptoPerm.getAlgorithm());
-        return pc.implies(cryptoPerm);
+
+        if (pc != null) {
+            return pc.implies(cryptoPerm);
+        } else {
+            // none found
+            return false;
+        }
     }
 
     /**
@@ -179,6 +187,7 @@
      *
      * @return an enumeration of all the Permissions.
      */
+    @Override
     public Enumeration<Permission> elements() {
         // go through each Permissions in the hash table
         // and call their elements() function.
@@ -453,7 +462,7 @@
 final class PermissionsEnumerator implements Enumeration<Permission> {
 
     // all the perms
-    private Enumeration<PermissionCollection> perms;
+    private final Enumeration<PermissionCollection> perms;
     // the current set
     private Enumeration<Permission> permset;
 
@@ -462,17 +471,20 @@
         permset = getNextEnumWithMore();
     }
 
+    @Override
     public synchronized boolean hasMoreElements() {
         // if we enter with permissionimpl null, we know
         // there are no more left.
 
-        if (permset == null)
+        if (permset == null) {
             return  false;
+        }
 
         // try to see if there are any left in the current one
 
-        if (permset.hasMoreElements())
+        if (permset.hasMoreElements()) {
             return true;
+        }
 
         // get the next one that has something in it...
         permset = getNextEnumWithMore();
@@ -481,6 +493,7 @@
         return (permset != null);
     }
 
+    @Override
     public synchronized Permission nextElement() {
         // hasMoreElements will update permset to the next permset
         // with something in it...
@@ -496,8 +509,9 @@
         while (perms.hasMoreElements()) {
             PermissionCollection pc = perms.nextElement();
             Enumeration<Permission> next = pc.elements();
-            if (next.hasMoreElements())
+            if (next.hasMoreElements()) {
                 return next;
+            }
         }
         return null;
     }
--- a/src/java.base/share/classes/javax/net/ssl/HandshakeCompletedEvent.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.base/share/classes/javax/net/ssl/HandshakeCompletedEvent.java	Sat Jul 30 00:11:02 2016 +0000
@@ -153,10 +153,11 @@
      * @exception SSLPeerUnverifiedException if the peer is not verified.
      * @see #getPeerPrincipal()
      * @deprecated The {@link #getPeerCertificates()} method that returns an
-     *               array of {@code java.security.cert.Certificate} should
-     *               be used instead.
+     *          array of {@code java.security.cert.Certificate} should
+     *          be used instead.  This method is subject to removal in
+     *          a future version of Java SE.
      */
-    @Deprecated
+    @Deprecated(since="9", forRemoval=true)
     public javax.security.cert.X509Certificate [] getPeerCertificateChain()
             throws SSLPeerUnverifiedException
     {
--- a/src/java.base/share/classes/javax/net/ssl/SSLSession.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.base/share/classes/javax/net/ssl/SSLSession.java	Sat Jul 30 00:11:02 2016 +0000
@@ -273,10 +273,11 @@
      *          has not been verified
      * @see #getPeerPrincipal()
      * @deprecated The {@link #getPeerCertificates()} method that returns an
-     *               array of {@code java.security.cert.Certificate} should
-     *               be used instead.
+     *          array of {@code java.security.cert.Certificate} should
+     *          be used instead.  This method is subject to removal in
+     *          a future version of Java SE.
      */
-    @Deprecated
+    @Deprecated(since="9", forRemoval=true)
     public javax.security.cert.X509Certificate [] getPeerCertificateChain()
             throws SSLPeerUnverifiedException;
 
--- a/src/java.base/share/conf/security/java.policy	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.base/share/conf/security/java.policy	Sat Jul 30 00:11:02 2016 +0000
@@ -122,6 +122,14 @@
         permission java.util.PropertyPermission "*", "read";
 };
 
+grant codeBase "jrt:/java.xml.crypto" {
+        permission java.util.PropertyPermission "*", "read";
+        permission java.security.SecurityPermission "putProviderProperty.XMLDSig";
+        permission java.security.SecurityPermission "clearProviderProperties.XMLDSig";
+        permission java.security.SecurityPermission "removeProviderProperty.XMLDSig";
+        permission java.security.SecurityPermission "com.sun.org.apache.xml.internal.security.register";
+};
+
 grant codeBase "jrt:/java.xml.ws" {
         permission java.lang.RuntimePermission "accessClassInPackage.com.sun.xml.internal.*";
         permission java.lang.RuntimePermission "accessClassInPackage.com.sun.istack.internal";
--- a/src/java.base/share/native/libjimage/imageDecompressor.hpp	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.base/share/native/libjimage/imageDecompressor.hpp	Sat Jul 30 00:11:02 2016 +0000
@@ -74,8 +74,8 @@
  * meaning that the resource is equivalent to the not compressed resource.
  * In each iteration, the name of the compressor located in the current header
  * is used to retrieve the associated instance of ImageDecompressor.
- * For example “zip” is the name of the compressor that compresses resources
- * using the zip algorithm. The ZipDecompressor class name is also “zip”.
+ * For example "zip" is the name of the compressor that compresses resources
+ * using the zip algorithm. The ZipDecompressor class name is also "zip".
  * ImageDecompressor instances are retrieved from a static array in which
  * they are registered.
  */
--- a/src/java.base/share/native/libjimage/jimage.hpp	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.base/share/native/libjimage/jimage.hpp	Sat Jul 30 00:11:02 2016 +0000
@@ -101,7 +101,7 @@
  * Ex.
  *  const char* package = (*JImagePackageToModule)(image, "java/lang");
  *  tty->print_cr(package);
- *  —> java.base
+ *  -> java.base
  */
 
 extern "C" const char * JIMAGE_PackageToModule(JImageFile* jimage, const char* package_name);
@@ -133,7 +133,7 @@
 
 
 /*
- * JImageGetResource - Given an open image file (see JImageOpen), a resource’s
+ * JImageGetResource - Given an open image file (see JImageOpen), a resource's
  * location information (see JImageFindResource), a buffer of appropriate
  * size and the size, retrieve the bytes associated with the
  * resource. If the size is less than the resource size then the read is truncated.
@@ -165,7 +165,7 @@
  * Ex.
  *   bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version,
  *                  const char* package, const char* name, const char* extension, void* arg) {
- *     if (strcmp(extension, “class”) == 0) {
+ *     if (strcmp(extension, "class") == 0) {
  *       char path[JIMAGE_MAX_PATH];
  *       Thread* THREAD = Thread::current();
  *       jio_snprintf(path, JIMAGE_MAX_PATH - 1, "/%s/%s", package, name);
--- a/src/java.datatransfer/share/classes/module-info.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.datatransfer/share/classes/module-info.java	Sat Jul 30 00:11:02 2016 +0000
@@ -23,6 +23,11 @@
  * questions.
  */
 
+/**
+ * Provides interfaces and classes for transferring data between and
+ * within applications.
+ */
+
 module java.datatransfer {
     exports java.awt.datatransfer;
     exports sun.datatransfer to java.desktop;
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/AccessibilityEventMonitor.java	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,253 +0,0 @@
-/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.lwawt.macosx;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import javax.accessibility.Accessible;
-import javax.accessibility.AccessibleContext;
-import javax.accessibility.AccessibleRole;
-import javax.accessibility.AccessibleState;
-import javax.accessibility.AccessibleStateSet;
-import javax.swing.event.EventListenerList;
-
-/**
- * <P>{@code AccessibilityEventMonitor} implements a PropertyChange listener
- * on every UI object that implements interface {@code Accessible} in the Java
- * Virtual Machine.  The events captured by these listeners are made available
- * through listeners supported by {@code AccessibilityEventMonitor}.
- * With this, all the individual events on each of the UI object
- * instances are funneled into one set of PropertyChange listeners.
- *
- * This code is a subset of com.sun.java.accessibility.util.AccessibilityEventMonitor
- * which resides in module jdk.accessibility.  Due to modularization the code in
- * this package, java.desktop, can not be dependent on code in jdk.accessibility.
- */
-
-class AccessibilityEventMonitor {
-
-    /**
-     * The current list of registered {@link java.beans.PropertyChangeListener
-     * PropertyChangeListener} classes.
-     *
-     * @see #addPropertyChangeListener
-     */
-    private static final EventListenerList listenerList =
-        new EventListenerList();
-
-
-    /**
-     * The actual listener that is installed on the component instances.
-     * This listener calls the other registered listeners when an event
-     * occurs.  By doing things this way, the actual number of listeners
-     * installed on a component instance is drastically reduced.
-     */
-    private static final AccessibilityEventListener accessibilityListener =
-        new AccessibilityEventListener();
-
-    /**
-     * Adds the specified listener to receive all PropertyChange events on
-     * each UI object instance in the Java Virtual Machine as they occur.
-     * <P>Note: This listener is automatically added to all component
-     * instances created after this method is called.  In addition, it
-     * is only added to UI object instances that support this listener type.
-     *
-     * @param l the listener to add
-     * @param a  the Accessible object to add the PropertyChangeListener to
-     */
-
-    static void addPropertyChangeListener(PropertyChangeListener l, Accessible a) {
-        if (listenerList.getListenerCount(PropertyChangeListener.class) == 0) {
-            accessibilityListener.installListeners(a);
-        }
-        listenerList.add(PropertyChangeListener.class, l);
-    }
-
-    /**
-     * AccessibilityEventListener is the class that does all the work for
-     * AccessibilityEventMonitor.  It is not intended for use by any other
-     * class except AccessibilityEventMonitor.
-     */
-
-    private static class AccessibilityEventListener implements PropertyChangeListener {
-
-        /**
-         * Installs PropertyChange listeners to the Accessible object, and its
-         * children (so long as the object isn't of TRANSIENT state).
-         *
-         * @param a the Accessible object to add listeners to
-         */
-        private void installListeners(Accessible a) {
-            installListeners(a.getAccessibleContext());
-        }
-
-        /**
-         * Installs PropertyChange listeners to the AccessibleContext object,
-         * and its * children (so long as the object isn't of TRANSIENT state).
-         *
-         * @param ac the AccessibleContext to add listeners to
-         */
-        private void installListeners(AccessibleContext ac) {
-
-            if (ac != null) {
-                AccessibleStateSet states = ac.getAccessibleStateSet();
-                if (!states.contains(AccessibleState.TRANSIENT)) {
-                    ac.addPropertyChangeListener(this);
-                    /*
-                     * Don't add listeners to transient children. Components
-                     * with transient children should return an AccessibleStateSet
-                     * containing AccessibleState.MANAGES_DESCENDANTS. Components
-                     * may not explicitly return the MANAGES_DESCENDANTS state.
-                     * In this case, don't add listeners to the children of
-                     * lists, tables and trees.
-                     */
-                    AccessibleStateSet set = ac.getAccessibleStateSet();
-                    if (set.contains(AccessibleState.MANAGES_DESCENDANTS)) {
-                        return;
-                    }
-                    AccessibleRole role = ac.getAccessibleRole();
-                    if ( role == AccessibleRole.LIST ||
-                         role == AccessibleRole.TREE ) {
-                        return;
-                    }
-                    if (role == AccessibleRole.TABLE) {
-                        // handle Oracle tables containing tables
-                        Accessible child = ac.getAccessibleChild(0);
-                        if (child != null) {
-                            AccessibleContext ac2 = child.getAccessibleContext();
-                            if (ac2 != null) {
-                                role = ac2.getAccessibleRole();
-                                if (role != null && role != AccessibleRole.TABLE) {
-                                    return;
-                                }
-                            }
-                        }
-                    }
-                    int count = ac.getAccessibleChildrenCount();
-                    for (int i = 0; i < count; i++) {
-                        Accessible child = ac.getAccessibleChild(i);
-                        if (child != null) {
-                            installListeners(child);
-                        }
-                    }
-                }
-            }
-        }
-
-        /**
-         * Removes PropertyChange listeners for the given Accessible object,
-         * its children (so long as the object isn't of TRANSIENT state).
-         *
-         * @param a the Accessible object to remove listeners from
-         */
-        private void removeListeners(Accessible a) {
-            removeListeners(a.getAccessibleContext());
-        }
-
-        /**
-         * Removes PropertyChange listeners for the given AccessibleContext
-         * object, its children (so long as the object isn't of TRANSIENT
-         * state).
-         *
-         * @param a the Accessible object to remove listeners from
-         */
-        private void removeListeners(AccessibleContext ac) {
-
-            if (ac != null) {
-                // Listeners are not added to transient components.
-                AccessibleStateSet states = ac.getAccessibleStateSet();
-                if (!states.contains(AccessibleState.TRANSIENT)) {
-                    ac.removePropertyChangeListener(this);
-                    /*
-                     * Listeners are not added to transient children. Components
-                     * with transient children should return an AccessibleStateSet
-                     * containing AccessibleState.MANAGES_DESCENDANTS. Components
-                     * may not explicitly return the MANAGES_DESCENDANTS state.
-                     * In this case, don't remove listeners from the children of
-                     * lists, tables and trees.
-                     */
-                    if (states.contains(AccessibleState.MANAGES_DESCENDANTS)) {
-                        return;
-                    }
-                    AccessibleRole role = ac.getAccessibleRole();
-                    if ( role == AccessibleRole.LIST ||
-                         role == AccessibleRole.TABLE ||
-                         role == AccessibleRole.TREE ) {
-                        return;
-                    }
-                    int count = ac.getAccessibleChildrenCount();
-                    for (int i = 0; i < count; i++) {
-                        Accessible child = ac.getAccessibleChild(i);
-                        if (child != null) {
-                            removeListeners(child);
-                        }
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void propertyChange(PropertyChangeEvent e) {
-            // propogate the event
-            Object[] listeners =
-                AccessibilityEventMonitor.listenerList.getListenerList();
-            for (int i = listeners.length-2; i>=0; i-=2) {
-                if (listeners[i]==PropertyChangeListener.class) {
-                    ((PropertyChangeListener)listeners[i+1]).propertyChange(e);
-                }
-            }
-
-            // handle childbirth/death
-            String name = e.getPropertyName();
-            if (name.compareTo(AccessibleContext.ACCESSIBLE_CHILD_PROPERTY) == 0) {
-                Object oldValue = e.getOldValue();
-                Object newValue = e.getNewValue();
-
-                if ((oldValue == null) ^ (newValue == null)) { // one null, not both
-                    if (oldValue != null) {
-                        // this Accessible is a child that's going away
-                        if (oldValue instanceof Accessible) {
-                            Accessible a = (Accessible) oldValue;
-                            removeListeners(a.getAccessibleContext());
-                        } else if (oldValue instanceof AccessibleContext) {
-                            removeListeners((AccessibleContext) oldValue);
-                        }
-                    } else if (newValue != null) {
-                        // this Accessible is a child was just born
-                        if (newValue instanceof Accessible) {
-                            Accessible a = (Accessible) newValue;
-                            installListeners(a.getAccessibleContext());
-                        } else if (newValue instanceof AccessibleContext) {
-                            installListeners((AccessibleContext) newValue);
-                        }
-                    }
-                } else {
-                    System.out.println("ERROR in usage of PropertyChangeEvents for: " + e.toString());
-                }
-            }
-        }
-    }
-}
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java	Sat Jul 30 00:11:02 2016 +0000
@@ -285,7 +285,7 @@
     }
 
     public static int getAccessibleIndexInParent(final Accessible a, final Component c) {
-        if (a == null) return 0;
+        if (a == null) return -1;
 
         return invokeAndWait(new Callable<Integer>() {
             public Integer call() throws Exception {
@@ -468,6 +468,24 @@
         }, c);
     }
 
+    public static void requestSelection(final Accessible a, final Component c) {
+        if (a == null) return;
+        invokeLater(new Runnable() {
+            public void run() {
+                AccessibleContext ac = a.getAccessibleContext();
+                if (ac == null) return;
+                int i = ac.getAccessibleIndexInParent();
+                if (i == -1) return;
+                Accessible parent = ac.getAccessibleParent();
+                AccessibleContext pac = parent.getAccessibleContext();
+                if (pac == null) return;
+                AccessibleSelection as = pac.getAccessibleSelection();
+                if (as == null) return;
+                as.addAccessibleSelection(i);
+            }
+        }, c);
+    }
+
     public static Number getMaximumAccessibleValue(final Accessible a, final Component c) {
         if (a == null) return null;
 
@@ -572,9 +590,57 @@
         if (a == null) return null;
         return invokeAndWait(new Callable<Object[]>() {
             public Object[] call() throws Exception {
-                final ArrayList<Object> childrenAndRoles = new ArrayList<Object>();
+                ArrayList<Object> childrenAndRoles = new ArrayList<Object>();
                 _addChildren(a, whichChildren, allowIgnored, childrenAndRoles);
 
+                /* In the case of fetching a selection, need to check to see if
+                 * the active descendant is at the beginning of the list.  If it
+                 * is not it needs to be moved to the beginning of the list so
+                 * VoiceOver will annouce it correctly.  The list returned
+                 * from Java is always in order from top to bottom, but when shift
+                 * selecting downward (extending the list) or multi-selecting using
+                 * the VO keys control+option+command+return the active descendant
+                 * is not at the top of the list in the shift select down case and
+                 * may not be in the multi select case.
+                 */
+                if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
+                    if (!childrenAndRoles.isEmpty()) {
+                        AccessibleContext activeDescendantAC =
+                            CAccessible.getActiveDescendant(a);
+                        if (activeDescendantAC != null) {
+                            String activeDescendantName =
+                                activeDescendantAC.getAccessibleName();
+                            AccessibleRole activeDescendantRole =
+                                activeDescendantAC.getAccessibleRole();
+                            // Move active descendant to front of list.
+                            // List contains pairs of each selected item's
+                            // Accessible and AccessibleRole.
+                            ArrayList<Object> newArray  = new ArrayList<Object>();
+                            int count = childrenAndRoles.size();
+                            Accessible currentAccessible = null;
+                            AccessibleContext currentAC = null;
+                            String currentName = null;
+                            AccessibleRole currentRole = null;
+                            for (int i = 0; i < count; i+=2) {
+                                // Is this the active descendant?
+                                currentAccessible = (Accessible)childrenAndRoles.get(i);
+                                currentAC = currentAccessible.getAccessibleContext();
+                                currentName = currentAC.getAccessibleName();
+                                currentRole = (AccessibleRole)childrenAndRoles.get(i+1);
+                                if ( currentName.equals(activeDescendantName) &&
+                                     currentRole.equals(activeDescendantRole) ) {
+                                    newArray.add(0, currentAccessible);
+                                    newArray.add(1, currentRole);
+                                } else {
+                                    newArray.add(currentAccessible);
+                                    newArray.add(currentRole);
+                                }
+                            }
+                            childrenAndRoles = newArray;
+                        }
+                    }
+                }
+
                 if ((whichChildren < 0) || (whichChildren * 2 >= childrenAndRoles.size())) {
                     return childrenAndRoles.toArray();
                 }
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java	Sat Jul 30 00:11:02 2016 +0000
@@ -37,7 +37,11 @@
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 
-import sun.lwawt.macosx.CFRetainedResource;
+import static javax.accessibility.AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY;
+import static javax.accessibility.AccessibleContext.ACCESSIBLE_CARET_PROPERTY;
+import static javax.accessibility.AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY;
+import static javax.accessibility.AccessibleContext.ACCESSIBLE_TEXT_PROPERTY;
+
 
 class CAccessible extends CFRetainedResource implements Accessible {
     static Field getNativeAXResourceField() {
@@ -71,10 +75,13 @@
 
     private static native void unregisterFromCocoaAXSystem(long ptr);
     private static native void valueChanged(long ptr);
+    private static native void selectedTextChanged(long ptr);
     private static native void selectionChanged(long ptr);
 
     private Accessible accessible;
 
+    private AccessibleContext activeDescendant;
+
     private CAccessible(final Accessible accessible) {
         super(0L, true); // real pointer will be poked in by native
 
@@ -98,9 +105,9 @@
     }
 
     public void addNotificationListeners(Component c) {
-        AXTextChangeNotifier listener = new AXTextChangeNotifier();
         if (c instanceof Accessible) {
-            AccessibilityEventMonitor.addPropertyChangeListener(listener, (Accessible)c);
+            AccessibleContext ac = ((Accessible)c).getAccessibleContext();
+            ac.addPropertyChangeListener(new AXChangeNotifier());
         }
         if (c instanceof JProgressBar) {
             JProgressBar pb = (JProgressBar) c;
@@ -112,16 +119,23 @@
     }
 
 
-    private class AXTextChangeNotifier implements PropertyChangeListener {
+    private class AXChangeNotifier implements PropertyChangeListener {
 
         @Override
         public void propertyChange(PropertyChangeEvent e) {
             String name = e.getPropertyName();
             if ( ptr != 0 ) {
-                if (name.compareTo(AccessibleContext.ACCESSIBLE_CARET_PROPERTY) == 0) {
+                if (name.compareTo(ACCESSIBLE_CARET_PROPERTY) == 0) {
+                    selectedTextChanged(ptr);
+                } else if (name.compareTo(ACCESSIBLE_TEXT_PROPERTY) == 0 ) {
+                    valueChanged(ptr);
+                } else if (name.compareTo(ACCESSIBLE_SELECTION_PROPERTY) == 0 ) {
                     selectionChanged(ptr);
-                } else if (name.compareTo(AccessibleContext.ACCESSIBLE_TEXT_PROPERTY) == 0 ) {
-                    valueChanged(ptr);
+                }  else if (name.compareTo(ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0 ) {
+                    Object nv = e.getNewValue();
+                    if (nv instanceof AccessibleContext) {
+                        activeDescendant = (AccessibleContext)nv;
+                    }
                 }
             }
         }
@@ -137,4 +151,9 @@
     static Accessible getSwingAccessible(final Accessible a) {
         return (a instanceof CAccessible) ? ((CAccessible)a).accessible : a;
     }
+
+    static AccessibleContext getActiveDescendant(final Accessible a) {
+        return (a instanceof CAccessible) ? ((CAccessible)a).activeDescendant : null;
+    }
+
 }
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java	Sat Jul 30 00:11:02 2016 +0000
@@ -135,6 +135,7 @@
         int jkeyCode = KeyEvent.VK_UNDEFINED;
         int jkeyLocation = KeyEvent.KEY_LOCATION_UNKNOWN;
         boolean postsTyped = false;
+        boolean spaceKeyTyped = false;
 
         char testChar = KeyEvent.CHAR_UNDEFINED;
         boolean isDeadChar = (chars!= null && chars.length() == 0);
@@ -151,6 +152,11 @@
         } else {
             if (chars != null && chars.length() > 0) {
                 testChar = chars.charAt(0);
+
+                //Check if String chars contains SPACE character.
+                if (chars.trim().isEmpty()) {
+                    spaceKeyTyped = true;
+                }
             }
 
             char testCharIgnoringModifiers = charsIgnoringModifiers != null && charsIgnoringModifiers.length() > 0 ?
@@ -187,7 +193,7 @@
                                            NSEvent.nsToJavaEventType(eventType);
         }
 
-        char javaChar = NSEvent.nsToJavaChar(testChar, modifierFlags);
+        char javaChar = NSEvent.nsToJavaChar(testChar, modifierFlags, spaceKeyTyped);
         // Some keys may generate a KEY_TYPED, but we can't determine
         // what that character is. That's likely a bug, but for now we
         // just check for CHAR_UNDEFINED.
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSEvent.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSEvent.java	Sat Jul 30 00:11:02 2016 +0000
@@ -254,7 +254,7 @@
      * There is a small number of NS characters that need to be converted
      * into other characters before we pass them to AWT.
      */
-    static native char nsToJavaChar(char nsChar, int modifierFlags);
+    static native char nsToJavaChar(char nsChar, int modifierFlags, boolean spaceKeyTyped);
 
     static boolean isPopupTrigger(int jmodifiers) {
         final boolean isRightButtonDown = ((jmodifiers & InputEvent.BUTTON3_DOWN_MASK) != 0);
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTEvent.m	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTEvent.m	Sat Jul 30 00:11:02 2016 +0000
@@ -278,6 +278,16 @@
         java_awt_event_KeyEvent_VK_CONTROL
     },
     {
+        NSCommandKeyMask,
+        //kCGSFlagsMaskAppleLeftCommandKey,
+        //kCGSFlagsMaskAppleRightCommandKey,
+        55,
+        54,
+        java_awt_event_InputEvent_META_DOWN_MASK,
+        java_awt_event_InputEvent_META_MASK,
+        java_awt_event_KeyEvent_VK_META
+    },
+    {
         NSAlternateKeyMask,
         //kCGSFlagsMaskAppleLeftAlternateKey,
         //kCGSFlagsMaskAppleRightAlternateKey,
@@ -295,16 +305,6 @@
         java_awt_event_InputEvent_ALT_MASK | java_awt_event_InputEvent_ALT_GRAPH_MASK,
         java_awt_event_KeyEvent_VK_ALT | java_awt_event_KeyEvent_VK_ALT_GRAPH
     },
-	{
-		NSCommandKeyMask,
-		//kCGSFlagsMaskAppleLeftCommandKey,
-		//kCGSFlagsMaskAppleRightCommandKey,
-		55,
-		54,
-		java_awt_event_InputEvent_META_DOWN_MASK,
-		java_awt_event_InputEvent_META_MASK,
-		java_awt_event_KeyEvent_VK_META
-	},
     // NSNumericPadKeyMask
     {
         NSHelpKeyMask,
@@ -319,6 +319,7 @@
 };
 
 static BOOL leftAltKeyPressed;
+static BOOL altGRPressed = NO;
 
 /*
  * Almost all unicode characters just go from NS to Java with no translation.
@@ -349,7 +350,7 @@
     {0, 0, 0}
 };
 
-unichar NsCharToJavaChar(unichar nsChar, NSUInteger modifiers)
+unichar NsCharToJavaChar(unichar nsChar, NSUInteger modifiers, BOOL spaceKeyTyped)
 {
     const struct _char *cur;
     // Mask off just the keyboard modifiers from the event modifier mask.
@@ -382,6 +383,11 @@
         return java_awt_event_KeyEvent_CHAR_UNDEFINED;
     }
 
+    // nsChar receives value 0 when SPACE key is typed.
+    if (nsChar == 0 && spaceKeyTyped == YES) {
+        return java_awt_event_KeyEvent_VK_SPACE;
+    }
+	
     // otherwise return character unchanged
     return nsChar;
 }
@@ -554,20 +560,28 @@
  */
 jint NsKeyModifiersToJavaModifiers(NSUInteger nsFlags, BOOL isExtMods)
 {
-	jint javaModifiers = 0;
-	const struct _nsKeyToJavaModifier* cur;
+    jint javaModifiers = 0;
+    const struct _nsKeyToJavaModifier* cur;
 	
-	for (cur = nsKeyToJavaModifierTable; cur->nsMask != 0; ++cur) {
-		if ((cur->nsMask & nsFlags) != 0) {
-				javaModifiers |= isExtMods ? cur->javaExtMask : cur->javaMask;
-				if (cur->nsMask == NSAlternateKeyMask && leftAltKeyPressed == NO) {
-					continue;
-			}
-			break;
-		}
-	}
+    for (cur = nsKeyToJavaModifierTable; cur->nsMask != 0; ++cur) {
+        if ((cur->nsMask & nsFlags) != 0) {
+			
+            if (cur->nsMask == NSAlternateKeyMask) {
+                if (leftAltKeyPressed == YES) {
+                    javaModifiers |= isExtMods? cur->javaExtMask : cur->javaMask;
+                    if (altGRPressed == NO)
+                        break;
+                    } else {
+                        leftAltKeyPressed = YES;
+                        altGRPressed = YES;
+                        continue;
+                    }
+                }
+            javaModifiers |= isExtMods ? cur->javaExtMask : cur->javaMask;
+        }
+    }
 
-	return javaModifiers;
+    return javaModifiers;
 }
 
 /*
@@ -757,13 +771,13 @@
  */
 JNIEXPORT jint JNICALL
 Java_sun_lwawt_macosx_NSEvent_nsToJavaChar
-(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags)
+(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags, jboolean spaceKeyTyped)
 {
     jchar javaChar = 0;
 
 JNF_COCOA_ENTER(env);
 
-    javaChar = NsCharToJavaChar(nsChar, modifierFlags);
+    javaChar = NsCharToJavaChar(nsChar, modifierFlags, spaceKeyTyped);
 
 JNF_COCOA_EXIT(env);
 
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m	Sat Jul 30 00:11:02 2016 +0000
@@ -261,27 +261,10 @@
 {
     CGKeyCode keyCode = GetCGKeyCode(javaKeyCode);
 
-    if ((javaKeyCode >= java_awt_event_KeyEvent_VK_0) &&
-		(javaKeyCode <= java_awt_event_KeyEvent_VK_9))
-    {
-        AXUIElementRef elem = AXUIElementCreateSystemWide();
-        AXUIElementPostKeyboardEvent(elem, (CGCharCode)0, keyCode, keyPressed);
-        CFRelease(elem);
-    } else {
-        /*
-         * JDK-8155740: AXUIElementPostKeyboardEvent posts correct key codes for
-         * number keys whereas CGEventPost posts Numpad keys for corresponding
-         * number key. Hence AXUIElementPostKeyboardEvent is used for posting
-         * numbers and CGEventCreateKeyboardEvent/CGEventPost is used for other
-         * keys.
-         * Key code for modifier key is required to distinguish between ALT and
-         * ALT-GR key for fixing issue 8155740.
-         */
-        CGEventRef event = CGEventCreateKeyboardEvent(NULL, keyCode, keyPressed);
-        if (event != NULL) {
-            CGEventPost(kCGSessionEventTap, event);
-            CFRelease(event);
-        }
+    CGEventRef event = CGEventCreateKeyboardEvent(NULL, keyCode, keyPressed);
+    if (event != NULL) {
+        CGEventPost(kCGSessionEventTap, event);
+        CFRelease(event);
     }
 }
 
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityAction.m	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityAction.m	Sat Jul 30 00:11:02 2016 +0000
@@ -63,16 +63,20 @@
 
     jobject fCompLocal = (*env)->NewLocalRef(env, fComponent);
     if ((*env)->IsSameObject(env, fCompLocal, NULL)) {
-        return @"unknown";
+        return nil;
     }
     NSString *str = nil;
-    jobject jstr = JNFCallStaticObjectMethod(env, jm_getAccessibleActionDescription, fAccessibleAction, fIndex, fCompLocal);
+    jstring jstr = JNFCallStaticObjectMethod( env,
+                                              jm_getAccessibleActionDescription,
+                                              fAccessibleAction,
+                                              fIndex,
+                                              fCompLocal );
     if (jstr != NULL) {
-        NSString *str = JNFJavaToNSString(env, jstr); // AWT_THREADING Safe (AWTRunLoopMode)
+        str = JNFJavaToNSString(env, jstr); // AWT_THREADING Safe (AWTRunLoopMode)
         (*env)->DeleteLocalRef(env, jstr);
     }
     (*env)->DeleteLocalRef(env, fCompLocal);
-    return str == nil ? @"unknown" : str;
+    return str;
 }
 
 - (void)perform
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityUtilities.h	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityUtilities.h	Sat Jul 30 00:11:02 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,6 +55,7 @@
 BOOL isVertical(JNIEnv *env, jobject axContext, jobject component);
 BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component);
 BOOL isShowing(JNIEnv *env, jobject axContext, jobject component);
+BOOL isSelectable(JNIEnv *env, jobject axContext, jobject component);
 NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component);
 jint getAxTextCharCount(JNIEnv *env, jobject axText, jobject component);
 
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityUtilities.m	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityUtilities.m	Sat Jul 30 00:11:02 2016 +0000
@@ -151,6 +151,18 @@
     return showing;
 }
 
+BOOL isSelectable(JNIEnv *env, jobject axContext, jobject component)
+{
+    static JNF_STATIC_MEMBER_CACHE( jm_SELECTABLE,
+                                    sjc_AccessibleState,
+                                    "SELECTABLE",
+                                    "Ljavax/accessibility/AccessibleState;" );
+    jobject axSelectableState = JNFGetStaticObjectField(env, jm_SELECTABLE);
+    BOOL selectable = containsAxState(env, axContext, axSelectableState, component);
+    (*env)->DeleteLocalRef(env, axSelectableState);
+    return selectable;
+}
+
 NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component)
 {
     static JNF_STATIC_MEMBER_CACHE(jm_getLocationOnScreen, sjc_CAccessibility, "getLocationOnScreen", "(Ljavax/accessibility/AccessibleComponent;Ljava/awt/Component;)Ljava/awt/Point;");
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.h	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.h	Sat Jul 30 00:11:02 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,6 +50,7 @@
 - (id)initWithParent:(NSObject*)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole;
 - (void)unregisterFromCocoaAXSystem;
 - (void)postValueChanged;
+- (void)postSelectedTextChanged;
 - (void)postSelectionChanged;
 - (BOOL)isEqual:(id)anObject;
 - (BOOL)isAccessibleWithEnv:(JNIEnv *)env forAccessible:(jobject)accessible;
@@ -71,6 +72,7 @@
 - (NSString *)javaRole;
 - (BOOL)isMenu;
 - (BOOL)isSelected:(JNIEnv *)env;
+- (BOOL)isSelectable:(JNIEnv *)env;
 - (BOOL)isVisible:(JNIEnv *)env;
 
 // attribute names
@@ -85,6 +87,8 @@
 - (NSArray *)accessibilityChildrenAttribute;
 - (BOOL)accessibilityIsChildrenAttributeSettable;
 - (NSUInteger)accessibilityIndexOfChild:(id)child;
+- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute
+    index:(NSUInteger)index maxCount:(NSUInteger)maxCount;
 - (NSNumber *)accessibilityEnabledAttribute;
 - (BOOL)accessibilityIsEnabledAttributeSettable;
 - (NSNumber *)accessibilityFocusedAttribute;
@@ -92,6 +96,8 @@
 - (void)accessibilitySetFocusedAttribute:(id)value;
 - (NSString *)accessibilityHelpAttribute;
 - (BOOL)accessibilityIsHelpAttributeSettable;
+- (NSValue *)accessibilityIndexAttribute;
+- (BOOL)accessibilityIsIndexAttributeSettable;
 - (id)accessibilityMaxValueAttribute;
 - (BOOL)accessibilityIsMaxValueAttributeSettable;
 - (id)accessibilityMinValueAttribute;
@@ -108,6 +114,9 @@
 - (BOOL)accessibilityIsRoleDescriptionAttributeSettable;
 - (NSArray *)accessibilitySelectedChildrenAttribute;
 - (BOOL)accessibilityIsSelectedChildrenAttributeSettable;
+- (NSNumber *)accessibilitySelectedAttribute;
+- (BOOL)accessibilityIsSelectedAttributeSettable;
+- (void)accessibilitySetSelectedAttribute:(id)value;
 - (NSValue *)accessibilitySizeAttribute;
 - (BOOL)accessibilityIsSizeAttributeSettable;
 - (NSString *)accessibilitySubroleAttribute;
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m	Sat Jul 30 00:11:02 2016 +0000
@@ -201,10 +201,16 @@
     NSAccessibilityPostNotification(self, NSAccessibilityValueChangedNotification);
 }
 
+- (void)postSelectedTextChanged
+{
+    AWT_ASSERT_APPKIT_THREAD;
+    NSAccessibilityPostNotification(self, NSAccessibilitySelectedTextChangedNotification);
+}
+
 - (void)postSelectionChanged
 {
     AWT_ASSERT_APPKIT_THREAD;
-    NSAccessibilityPostNotification(self, NSAccessibilitySelectedTextChangedNotification);
+    NSAccessibilityPostNotification(self, NSAccessibilitySelectedChildrenChangedNotification);
 }
 
 - (BOOL)isEqual:(id)anObject
@@ -225,7 +231,7 @@
 {
     if (sAttributeNamesForRoleCache == nil) {
         sAttributeNamesLOCK = [[NSObject alloc] init];
-        sAttributeNamesForRoleCache = [[NSMutableDictionary alloc] initWithCapacity:10];
+        sAttributeNamesForRoleCache = [[NSMutableDictionary alloc] initWithCapacity:60];
     }
 
     if (sRoles == nil) {
@@ -281,6 +287,7 @@
 
 + (NSArray *)childrenOfParent:(JavaComponentAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored
 {
+    if (parent->fAccessible == NULL) return nil;
     jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
     if (jchildrenAndRoles == NULL) return nil;
 
@@ -370,7 +377,7 @@
 {
     static JNF_STATIC_MEMBER_CACHE(jm_getInitialAttributeStates, sjc_CAccessibility, "getInitialAttributeStates", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[Z");
 
-    NSMutableArray *attributeNames = [NSMutableArray arrayWithCapacity:10];
+    NSMutableArray *attributeNames = [NSMutableArray arrayWithCapacity:20];
     [attributeNames retain];
 
     // all elements respond to parent, role, role description, window, topLevelUIElement, help
@@ -449,6 +456,12 @@
     // children
     if (attributeStatesArray[6]) {
         [attributeNames addObject:NSAccessibilityChildrenAttribute];
+        if ([javaRole isEqualToString:@"list"]) {
+            [attributeNames addObject:NSAccessibilitySelectedChildrenAttribute];
+            [attributeNames addObject:NSAccessibilityVisibleChildrenAttribute];
+        }
+        // Just above, the below mentioned support has been added back in for lists.
+        // However, the following comments may still be useful for future fixes.
 //        [attributeNames addObject:NSAccessibilitySelectedChildrenAttribute];
 //        [attributeNames addObject:NSAccessibilityVisibleChildrenAttribute];
                 //According to AXRoles.txt:
@@ -567,6 +580,14 @@
     return isChildSelected(env, ((JavaComponentAccessibility *)[self parent])->fAccessible, fIndex, fComponent);
 }
 
+- (BOOL)isSelectable:(JNIEnv *)env
+{
+    jobject axContext = [self axContextWithEnv:env];
+    BOOL selectable = isSelectable(env, axContext, fComponent);
+    (*env)->DeleteLocalRef(env, axContext);
+    return selectable;
+}
+
 - (BOOL)isVisible:(JNIEnv *)env
 {
     if (fIndex == -1) {
@@ -586,18 +607,32 @@
 
     @synchronized(sAttributeNamesLOCK) {
         NSString *javaRole = [self javaRole];
-        NSArray *names = (NSArray *)[sAttributeNamesForRoleCache objectForKey:javaRole];
-        if (names != nil) return names;
-
-        names = [self initializeAttributeNamesWithEnv:env];
-        if (names != nil) {
+        NSArray *names =
+            (NSArray *)[sAttributeNamesForRoleCache objectForKey:javaRole];
+        if (names == nil) {
+            names = [self initializeAttributeNamesWithEnv:env];
 #ifdef JAVA_AX_DEBUG
             NSLog(@"Initializing: %s for %@: %@", __FUNCTION__, javaRole, names);
 #endif
             [sAttributeNamesForRoleCache setObject:names forKey:javaRole];
-            return names;
         }
-    }
+        // The above set of attributes is immutable per role, but some objects, if
+        // they are the child of a list, need to add the selected and index attributes.
+        id myParent = [self accessibilityParentAttribute];
+        if ([myParent isKindOfClass:[JavaComponentAccessibility class]]) {
+            NSString *parentRole = [(JavaComponentAccessibility *)myParent javaRole];
+            if ([parentRole isEqualToString:@"list"]) {
+                NSMutableArray *moreNames =
+                    [[NSMutableArray alloc] initWithCapacity: [names count] + 2];
+                [moreNames addObjectsFromArray: names];
+                [moreNames addObject:NSAccessibilitySelectedAttribute];
+                [moreNames addObject:NSAccessibilityIndexAttribute];
+                return moreNames;
+            }
+        }
+        return names;
+
+    }  // end @synchronized
 
 #ifdef JAVA_AX_DEBUG
     NSLog(@"Warning in %s: could not find attribute names for role: %@", __FUNCTION__, [self javaRole]);
@@ -656,7 +691,10 @@
 - (NSArray *)accessibilityChildrenAttribute
 {
     JNIEnv* env = [ThreadUtilities getJNIEnv];
-    NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_VISIBLE_CHILDREN allowIgnored:NO];
+    NSArray *children = [JavaComponentAccessibility childrenOfParent:self
+                                                    withEnv:env
+                                                    withChildrenCode:JAVA_AX_ALL_CHILDREN
+                                                    allowIgnored:NO];
 
     NSArray *value = nil;
     if ([children count] > 0) {
@@ -680,7 +718,12 @@
         return [super accessibilityIndexOfChild:child];
     }
 
-    return JNFCallStaticIntMethod([ThreadUtilities getJNIEnv], sjm_getAccessibleIndexInParent, ((JavaComponentAccessibility *)child)->fAccessible, ((JavaComponentAccessibility *)child)->fComponent);
+    jint returnValue =
+        JNFCallStaticIntMethod( [ThreadUtilities getJNIEnv],
+                                sjm_getAccessibleIndexInParent,
+                                ((JavaComponentAccessibility *)child)->fAccessible,
+                                ((JavaComponentAccessibility *)child)->fComponent );
+    return (returnValue == -1) ? NSNotFound : returnValue;
 }
 
 // Without this optimization accessibilityChildrenAttribute is called in order to get the entire array of children.
@@ -754,7 +797,7 @@
 
     jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
     if (val == NULL) {
-        return @"unknown";
+        return nil;
     }
     NSString* str = JNFJavaToNSString(env, val);
     (*env)->DeleteLocalRef(env, val);
@@ -766,6 +809,18 @@
     return NO;
 }
 
+- (NSValue *)accessibilityIndexAttribute
+{
+    NSInteger index = fIndex;
+    NSValue *returnValue = [NSValue value:&index withObjCType:@encode(NSInteger)];
+    return returnValue;
+}
+
+- (BOOL)accessibilityIsIndexAttributeSettable
+{
+    return NO;
+}
+
 // Element's maximum value (id)
 - (id)accessibilityMaxValueAttribute
 {
@@ -939,6 +994,33 @@
     return NO; // cmcnote: actually it should be. so need to write accessibilitySetSelectedChildrenAttribute also
 }
 
+- (NSNumber *)accessibilitySelectedAttribute
+{
+    return [NSNumber numberWithBool:[self isSelected:[ThreadUtilities getJNIEnv]]];
+}
+
+- (BOOL)accessibilityIsSelectedAttributeSettable
+{
+    if ([self isSelectable:[ThreadUtilities getJNIEnv]]) {
+        return YES;
+    } else {
+        return NO;
+    }
+}
+
+- (void)accessibilitySetSelectedAttribute:(id)value
+{
+    static JNF_STATIC_MEMBER_CACHE( jm_requestSelection,
+                                    sjc_CAccessibility,
+                                    "requestSelection",
+                                    "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)V" );
+    
+    if ([(NSNumber*)value boolValue]) {
+        JNIEnv* env = [ThreadUtilities getJNIEnv];
+        JNFCallStaticVoidMethod(env, jm_requestSelection, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
+    }
+}
+
 // Element size (NSValue)
 - (NSValue *)accessibilitySizeAttribute {
     JNIEnv* env = [ThreadUtilities getJNIEnv];
@@ -1005,7 +1087,7 @@
 
     jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
     if (val == NULL) {
-        return @"unknown";
+        return nil;
     }
     NSString* str = JNFJavaToNSString(env, val);
     (*env)->DeleteLocalRef(env, val);
@@ -1210,14 +1292,11 @@
 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessibility_focusChanged
 (JNIEnv *env, jobject jthis)
 {
-
 JNF_COCOA_ENTER(env);
     [ThreadUtilities performOnMainThread:@selector(postFocusChanged:) on:[JavaComponentAccessibility class] withObject:nil waitUntilDone:NO];
 JNF_COCOA_EXIT(env);
 }
 
-
-
 /*
  * Class:     sun_lwawt_macosx_CAccessible
  * Method:    valueChanged
@@ -1233,6 +1312,22 @@
 
 /*
  * Class:     sun_lwawt_macosx_CAccessible
+ * Method:    selectedTextChanged
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectedTextChanged
+(JNIEnv *env, jclass jklass, jlong element)
+{
+JNF_COCOA_ENTER(env);
+    [ThreadUtilities performOnMainThread:@selector(postSelectedTextChanged)
+                     on:(JavaComponentAccessibility *)jlong_to_ptr(element)
+                     withObject:nil
+                     waitUntilDone:NO];
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class:     sun_lwawt_macosx_CAccessible
  * Method:    selectionChanged
  * Signature: (I)V
  */
@@ -1244,7 +1339,6 @@
 JNF_COCOA_EXIT(env);
 }
 
-
 /*
  * Class:     sun_lwawt_macosx_CAccessible
  * Method:    unregisterFromCocoaAXSystem
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaTextAccessibility.h	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaTextAccessibility.h	Sat Jul 30 00:11:02 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,6 +60,4 @@
 - (NSValue *)accessibilityRangeForPositionAttributeForParameter:(id)parameter;
 - (NSValue *)accessibilityRangeForIndexAttributeForParameter:(id)parameter;
 
-// actions
-- (NSDictionary *)getActions:(JNIEnv *)env;
 @end
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaTextAccessibility.m	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaTextAccessibility.m	Sat Jul 30 00:11:02 2016 +0000
@@ -427,13 +427,15 @@
     return javaIntArrayToNSRangeValue(env, axTextRange);
 }
 
-- (NSDictionary *)getActions:(JNIEnv *)env {
-    // cmcnote: this isn't correct; text can have actions. Not yet implemented. radr://3941691
-    // Editable text has AXShowMenu. Textfields have AXConfirm. Static text has no actions.
-#ifdef JAVA_AX_DEBUG
-    NSLog(@"Not yet implemented: %s\n", __FUNCTION__);
-#endif
-    return nil;
-}
+/* 
+ * - (NSDictionary *)getActions:(JNIEnv *)env { ... }
+ *
+ * In the future, possibly add support: Editable text has AXShowMenu.
+ * Textfields have AXConfirm.
+ *
+ * Note: JLabels (static text) in JLists have a press/click selection action
+ *   which is currently handled in superclass JavaComponentAccessibility.
+ *   If function is added here be sure to use [super getActions:env] for JLabels.
+ */
 
 @end
--- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1339,14 +1339,14 @@
             Graphics g, int state, int x, int y, int w, int h) {
         ENGINE.paintExpander(g, context, Region.TREE,
                 GTKLookAndFeel.synthStateToGTKState(context.getRegion(), state),
-                ExpanderStyle.EXPANDED, "treeview", x, y, w, h);
+                ExpanderStyle.EXPANDED, "expander", x, y, w, h);
     }
 
     public void paintTreeCollapsedIcon(SynthContext context,
             Graphics g, int state, int x, int y, int w, int h) {
         ENGINE.paintExpander(g, context, Region.TREE,
                 GTKLookAndFeel.synthStateToGTKState(context.getRegion(), state),
-                ExpanderStyle.COLLAPSED, "treeview", x, y, w, h);
+                ExpanderStyle.COLLAPSED, "expander", x, y, w, h);
     }
 
     public void paintCheckBoxIcon(SynthContext context,
--- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java	Sat Jul 30 00:11:02 2016 +0000
@@ -854,6 +854,12 @@
             return indicatorSpacing + focusSize + focusPad;
         } else if (GTKLookAndFeel.is3() && "ComboBox.forceOpaque".equals(key)) {
             return true;
+        } else if ("Tree.expanderSize".equals(key)) {
+            Object value = getClassSpecificValue("expander-size");
+            if (value instanceof Integer) {
+                return (Integer)value + 4;
+            }
+            return null;
         }
 
         // Is it a stock icon ?
@@ -1136,7 +1142,6 @@
         CLASS_SPECIFIC_MAP.put("Slider.thumbWidth", "slider-length");
         CLASS_SPECIFIC_MAP.put("Slider.trackBorder", "trough-border");
         CLASS_SPECIFIC_MAP.put("SplitPane.size", "handle-size");
-        CLASS_SPECIFIC_MAP.put("Tree.expanderSize", "expander-size");
         CLASS_SPECIFIC_MAP.put("ScrollBar.thumbHeight", "slider-width");
         CLASS_SPECIFIC_MAP.put("ScrollBar.width", "slider-width");
         CLASS_SPECIFIC_MAP.put("TextArea.caretForeground", "cursor-color");
--- a/src/java.desktop/share/classes/java/awt/Desktop.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/java/awt/Desktop.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1013,8 +1013,8 @@
      * @param file the file
      * @return returns true if successfully moved the file to the trash.
      * @throws SecurityException If a security manager exists and its
-     *         {@link SecurityManager#checkWrite(java.lang.String)} method
-     *         denies write access to the file
+     *         {@link SecurityManager#checkDelete(java.lang.String)} method
+     *         denies deletion of the file
      * @throws UnsupportedOperationException if the current platform
      *         does not support the {@link Desktop.Action#MOVE_TO_TRASH} action
      * @throws NullPointerException if {@code file} is {@code null}
--- a/src/java.desktop/share/classes/java/awt/Font.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/java/awt/Font.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1813,35 +1813,31 @@
             return true;
         }
 
-        if (obj != null) {
-            try {
-                Font font = (Font)obj;
-                if (size == font.size &&
-                    style == font.style &&
-                    nonIdentityTx == font.nonIdentityTx &&
-                    hasLayoutAttributes == font.hasLayoutAttributes &&
-                    pointSize == font.pointSize &&
-                    name.equals(font.name)) {
+        if (obj instanceof Font) {
+            Font font = (Font)obj;
+            if (size == font.size &&
+                style == font.style &&
+                nonIdentityTx == font.nonIdentityTx &&
+                hasLayoutAttributes == font.hasLayoutAttributes &&
+                pointSize == font.pointSize &&
+                name.equals(font.name)) {
 
-                    /* 'values' is usually initialized lazily, except when
-                     * the font is constructed from a Map, or derived using
-                     * a Map or other values. So if only one font has
-                     * the field initialized we need to initialize it in
-                     * the other instance and compare.
-                     */
-                    if (values == null) {
-                        if (font.values == null) {
-                            return true;
-                        } else {
-                            return getAttributeValues().equals(font.values);
-                        }
+                /* 'values' is usually initialized lazily, except when
+                 * the font is constructed from a Map, or derived using
+                 * a Map or other values. So if only one font has
+                 * the field initialized we need to initialize it in
+                 * the other instance and compare.
+                 */
+                if (values == null) {
+                    if (font.values == null) {
+                        return true;
                     } else {
-                        return values.equals(font.getAttributeValues());
+                        return getAttributeValues().equals(font.values);
                     }
+                } else {
+                    return values.equals(font.getAttributeValues());
                 }
             }
-            catch (ClassCastException e) {
-            }
         }
         return false;
     }
--- a/src/java.desktop/share/classes/java/awt/Taskbar.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/java/awt/Taskbar.java	Sat Jul 30 00:11:02 2016 +0000
@@ -356,7 +356,7 @@
      *
      * Some platforms do not support string values and accept only integer
      * values. In this case, pass an integer represented as a string as parameter.
-     * This can be tested by {@code Feature.ICON_BADGE_STRING} and
+     * This can be tested by {@code Feature.ICON_BADGE_TEXT} and
      * {@code Feature.ICON_BADGE_NUMBER}.
      *
      * Passing {@code null} as parameter hides the badge.
@@ -364,7 +364,8 @@
      * @throws SecurityException if a security manager exists and it denies the
      * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
      * @throws UnsupportedOperationException if the current platform
-     * does not support the {@link Taskbar.Feature#ICON_BADGE_NUMBER} feature
+     * does not support the {@link Taskbar.Feature#ICON_BADGE_NUMBER}
+     * or {@link Taskbar.Feature#ICON_BADGE_TEXT} feature
      */
     public void setIconBadge(final String badge) {
         checkAWTPermission();
--- a/src/java.desktop/share/classes/java/awt/Toolkit.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/java/awt/Toolkit.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1388,9 +1388,7 @@
         // ensure that the proper libraries are loaded
         loadLibraries();
         initAssistiveTechnologies();
-        if (!GraphicsEnvironment.isHeadless()) {
-            initIDs();
-        }
+        initIDs();
     }
 
     /**
--- a/src/java.desktop/share/classes/javax/swing/JComboBox.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/javax/swing/JComboBox.java	Sat Jul 30 00:11:02 2016 +0000
@@ -168,6 +168,9 @@
     // Flag to ensure the we don't get multiple ActionEvents on item selection.
     private boolean selectingItem = false;
 
+    // Flag to indicate UI update is in progress
+    private transient boolean updateInProgress;
+
     /**
      * Creates a <code>JComboBox</code> that takes its items from an
      * existing <code>ComboBoxModel</code>.  Since the
@@ -268,11 +271,18 @@
      * @see JComponent#updateUI
      */
     public void updateUI() {
-        setUI((ComboBoxUI)UIManager.getUI(this));
+        if (!updateInProgress) {
+            updateInProgress = true;
+            try {
+                setUI((ComboBoxUI)UIManager.getUI(this));
 
-        ListCellRenderer<? super E> renderer = getRenderer();
-        if (renderer instanceof Component) {
-            SwingUtilities.updateComponentTreeUI((Component)renderer);
+                ListCellRenderer<? super E> renderer = getRenderer();
+                if (renderer instanceof Component) {
+                    SwingUtilities.updateComponentTreeUI((Component)renderer);
+                }
+            } finally {
+                updateInProgress = false;
+            }
         }
     }
 
--- a/src/java.desktop/share/classes/javax/swing/JList.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/javax/swing/JList.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -338,6 +338,11 @@
     private transient DropLocation dropLocation;
 
     /**
+     * Flag to indicate UI update is in progress
+     */
+    private transient boolean updateInProgress;
+
+    /**
      * A subclass of <code>TransferHandler.DropLocation</code> representing
      * a drop location for a <code>JList</code>.
      *
@@ -531,11 +536,18 @@
      * @see SwingUtilities#updateComponentTreeUI
      */
     public void updateUI() {
-        setUI((ListUI)UIManager.getUI(this));
-
-        ListCellRenderer<? super E> renderer = getCellRenderer();
-        if (renderer instanceof Component) {
-            SwingUtilities.updateComponentTreeUI((Component)renderer);
+        if (!updateInProgress) {
+            updateInProgress = true;
+            try {
+                setUI((ListUI)UIManager.getUI(this));
+
+                ListCellRenderer<? super E> renderer = getCellRenderer();
+                if (renderer instanceof Component) {
+                    SwingUtilities.updateComponentTreeUI((Component)renderer);
+                }
+            } finally {
+                updateInProgress = false;
+            }
         }
     }
 
@@ -3046,7 +3058,7 @@
         public Accessible getAccessibleAt(Point p) {
             int i = locationToIndex(p);
             if (i >= 0) {
-                return new AccessibleJListChild(JList.this, i);
+                return new ActionableAccessibleJListChild(JList.this, i);
             } else {
                 return null;
             }
@@ -3073,7 +3085,7 @@
             if (i >= getModel().getSize()) {
                 return null;
             } else {
-                return new AccessibleJListChild(JList.this, i);
+                return new ActionableAccessibleJListChild(JList.this, i);
             }
         }
 
@@ -3178,7 +3190,7 @@
         protected class AccessibleJListChild extends AccessibleContext
                 implements Accessible, AccessibleComponent {
             private JList<E>     parent = null;
-            private int       indexInParent;
+            int indexInParent;
             private Component component = null;
             private AccessibleContext accessibleContext = null;
             private ListModel<E> listModel;
@@ -3203,7 +3215,7 @@
                 return getComponentAtIndex(indexInParent);
             }
 
-            private AccessibleContext getCurrentAccessibleContext() {
+            AccessibleContext getCurrentAccessibleContext() {
                 Component c = getComponentAtIndex(indexInParent);
                 if (c instanceof Accessible) {
                     return c.getAccessibleContext();
@@ -3369,10 +3381,6 @@
                 }
             }
 
-            public AccessibleAction getAccessibleAction() {
-                return getCurrentAccessibleContext().getAccessibleAction();
-            }
-
            /**
             * Get the AccessibleComponent associated with this object.  In the
             * implementation of the Java Accessibility API for this class,
@@ -3587,7 +3595,13 @@
 
             public Point getLocationOnScreen() {
                 if (parent != null) {
-                    Point listLocation = parent.getLocationOnScreen();
+                    Point listLocation;
+                    try {
+                        listLocation = parent.getLocationOnScreen();
+                    } catch (IllegalComponentStateException e) {
+                        // This can happen if the component isn't visisble
+                        return null;
+                    }
                     Point componentLocation = parent.indexToLocation(indexInParent);
                     if (componentLocation != null) {
                         componentLocation.translate(listLocation.x, listLocation.y);
@@ -3728,6 +3742,57 @@
                     return null;
                 }
             }
+
         } // inner class AccessibleJListChild
+
+        private class ActionableAccessibleJListChild
+            extends AccessibleJListChild
+            implements AccessibleAction {
+
+            ActionableAccessibleJListChild(JList<E> parent, int indexInParent) {
+                super(parent, indexInParent);
+            }
+
+            @Override
+            public AccessibleAction getAccessibleAction() {
+                AccessibleContext ac = getCurrentAccessibleContext();
+                if (ac == null) {
+                    return null;
+                } else {
+                    AccessibleAction aa = ac.getAccessibleAction();
+                    if (aa != null) {
+                        return aa;
+                    } else {
+                        return this;
+                    }
+                }
+            }
+
+            @Override
+            public boolean doAccessibleAction(int i) {
+                if (i == 0) {
+                    JList.this.setSelectedIndex(indexInParent);
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+
+            @Override
+            public String getAccessibleActionDescription(int i) {
+                if (i == 0) {
+                    return UIManager.getString("AbstractButton.clickText");
+                } else {
+                    return null;
+                }
+            }
+
+            @Override
+            public int getAccessibleActionCount() {
+                return 1;
+            }
+
+        } // inner class ActionableAccessibleJListChild
+
     } // inner class AccessibleJList
 }
--- a/src/java.desktop/share/classes/javax/swing/JTable.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/javax/swing/JTable.java	Sat Jul 30 00:11:02 2016 +0000
@@ -455,6 +455,11 @@
     private transient DropLocation dropLocation;
 
     /**
+     * Flag to indicate UI update is in progress
+     */
+    private transient boolean updateInProgress;
+
+    /**
      * A subclass of <code>TransferHandler.DropLocation</code> representing
      * a drop location for a <code>JTable</code>.
      *
@@ -3621,36 +3626,46 @@
      * @see JComponent#updateUI
      */
     public void updateUI() {
-        // Update the UIs of the cell renderers, cell editors and header renderers.
-        TableColumnModel cm = getColumnModel();
-        for(int column = 0; column < cm.getColumnCount(); column++) {
-            TableColumn aColumn = cm.getColumn(column);
-            SwingUtilities.updateRendererOrEditorUI(aColumn.getCellRenderer());
-            SwingUtilities.updateRendererOrEditorUI(aColumn.getCellEditor());
-            SwingUtilities.updateRendererOrEditorUI(aColumn.getHeaderRenderer());
-        }
-
-        // Update the UIs of all the default renderers.
-        Enumeration<?> defaultRenderers = defaultRenderersByColumnClass.elements();
-        while (defaultRenderers.hasMoreElements()) {
-            SwingUtilities.updateRendererOrEditorUI(defaultRenderers.nextElement());
-        }
-
-        // Update the UIs of all the default editors.
-        Enumeration<?> defaultEditors = defaultEditorsByColumnClass.elements();
-        while (defaultEditors.hasMoreElements()) {
-            SwingUtilities.updateRendererOrEditorUI(defaultEditors.nextElement());
-        }
-
-        // Update the UI of the table header
-        if (tableHeader != null && tableHeader.getParent() == null) {
-            tableHeader.updateUI();
-        }
-
-        // Update UI applied to parent ScrollPane
-        configureEnclosingScrollPaneUI();
-
-        setUI((TableUI)UIManager.getUI(this));
+        if (updateInProgress) {
+            return;
+        }
+
+        updateInProgress = true;
+
+        try {
+            // Update the UIs of the cell renderers, cell editors and header renderers.
+            TableColumnModel cm = getColumnModel();
+            for(int column = 0; column < cm.getColumnCount(); column++) {
+                TableColumn aColumn = cm.getColumn(column);
+                SwingUtilities.updateRendererOrEditorUI(aColumn.getCellRenderer());
+                SwingUtilities.updateRendererOrEditorUI(aColumn.getCellEditor());
+                SwingUtilities.updateRendererOrEditorUI(aColumn.getHeaderRenderer());
+            }
+
+            // Update the UIs of all the default renderers.
+            Enumeration<?> defaultRenderers = defaultRenderersByColumnClass.elements();
+            while (defaultRenderers.hasMoreElements()) {
+                SwingUtilities.updateRendererOrEditorUI(defaultRenderers.nextElement());
+            }
+
+            // Update the UIs of all the default editors.
+            Enumeration<?> defaultEditors = defaultEditorsByColumnClass.elements();
+            while (defaultEditors.hasMoreElements()) {
+                SwingUtilities.updateRendererOrEditorUI(defaultEditors.nextElement());
+            }
+
+            // Update the UI of the table header
+            if (tableHeader != null && tableHeader.getParent() == null) {
+                tableHeader.updateUI();
+            }
+
+            // Update UI applied to parent ScrollPane
+            configureEnclosingScrollPaneUI();
+
+            setUI((TableUI)UIManager.getUI(this));
+        } finally {
+            updateInProgress = false;
+        }
     }
 
     /**
--- a/src/java.desktop/share/classes/javax/swing/JTree.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/javax/swing/JTree.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -321,6 +321,11 @@
     private transient DropLocation dropLocation;
 
     /**
+     * Flag to indicate UI update is in progress
+     */
+    private transient boolean updateInProgress;
+
+    /**
      * A subclass of <code>TransferHandler.DropLocation</code> representing
      * a drop location for a <code>JTree</code>.
      *
@@ -713,10 +718,19 @@
      * @see JComponent#updateUI
      */
     public void updateUI() {
-        setUI((TreeUI)UIManager.getUI(this));
-
-        SwingUtilities.updateRendererOrEditorUI(getCellRenderer());
-        SwingUtilities.updateRendererOrEditorUI(getCellEditor());
+        if (!updateInProgress) {
+
+            updateInProgress = true;
+
+            try {
+                setUI((TreeUI)UIManager.getUI(this));
+
+                SwingUtilities.updateRendererOrEditorUI(getCellRenderer());
+                SwingUtilities.updateRendererOrEditorUI(getCellEditor());
+            } finally {
+                updateInProgress = false;
+            }
+        }
     }
 
 
--- a/src/java.desktop/share/classes/javax/swing/table/JTableHeader.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/javax/swing/table/JTableHeader.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -118,6 +118,11 @@
       */
     private TableCellRenderer defaultRenderer;
 
+    /**
+     * Flag to indicate UI update is in progress
+     */
+    private transient boolean updateInProgress;
+
 //
 // Constructors
 //
@@ -475,11 +480,18 @@
      * @see JComponent#updateUI
      */
     public void updateUI(){
-        setUI((TableHeaderUI)UIManager.getUI(this));
+        if (!updateInProgress) {
+            updateInProgress = true;
+            try {
+                setUI((TableHeaderUI)UIManager.getUI(this));
 
-        TableCellRenderer renderer = getDefaultRenderer();
-        if (renderer instanceof Component) {
-            SwingUtilities.updateComponentTreeUI((Component)renderer);
+                TableCellRenderer renderer = getDefaultRenderer();
+                if (renderer instanceof Component) {
+                    SwingUtilities.updateComponentTreeUI((Component)renderer);
+                }
+            } finally {
+                updateInProgress = false;
+            }
         }
     }
 
--- a/src/java.desktop/share/classes/module-info.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/module-info.java	Sat Jul 30 00:11:02 2016 +0000
@@ -23,6 +23,10 @@
  * questions.
  */
 
+/**
+  * java.desktop defines and exports the user interface, graphics
+  * and imaging APIs of the Java SE platform.
+  */
 module java.desktop {
     requires public java.datatransfer;
     requires public java.xml;
--- a/src/java.desktop/share/classes/sun/awt/image/OffScreenImageSource.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/sun/awt/image/OffScreenImageSource.java	Sat Jul 30 00:11:02 2016 +0000
@@ -187,17 +187,19 @@
             sendPixels();
             theConsumer.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
 
-            try {
-                theConsumer.imageComplete(ImageConsumer.STATICIMAGEDONE);
-            } catch (RuntimeException e) {
-                // We did not previously call this method here and
-                // some image consumer filters were not prepared for it to be
-                // called at this time. We allow them to have runtime issues
-                // for this one call only without triggering the IMAGEERROR
-                // condition below.
-                e.printStackTrace();
+            // If 'theconsumer' has not unregistered itself after previous call
+            if (theConsumer != null) {
+                try {
+                    theConsumer.imageComplete(ImageConsumer.STATICIMAGEDONE);
+                } catch (RuntimeException e) {
+                    // We did not previously call this method here and
+                    // some image consumer filters were not prepared for it to be
+                    // called at this time. We allow them to have runtime issues
+                    // for this one call only without triggering the IMAGEERROR
+                    // condition below.
+                    e.printStackTrace();
+                }
             }
-
         } catch (NullPointerException e) {
             e.printStackTrace();
 
--- a/src/java.desktop/share/classes/sun/font/GlyphList.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/sun/font/GlyphList.java	Sat Jul 30 00:11:02 2016 +0000
@@ -28,6 +28,7 @@
 import java.awt.Font;
 import java.awt.font.GlyphVector;
 import java.awt.font.FontRenderContext;
+import java.util.concurrent.atomic.AtomicBoolean;
 import sun.java2d.loops.FontInfo;
 
 /*
@@ -151,8 +152,8 @@
      * occur and if it did, it would just lead to some extra garbage being
      * created.
      */
-    private static GlyphList reusableGL = new GlyphList();
-    private static boolean inUse;
+    private static final GlyphList reusableGL = new GlyphList();
+    private static final AtomicBoolean inUse = new AtomicBoolean();
 
 
     void ensureCapacity(int len) {
@@ -184,24 +185,10 @@
 //     }
 
     public static GlyphList getInstance() {
-        /* The following heuristic is that if the reusable instance is
-         * in use, it probably still will be in a micro-second, so avoid
-         * synchronising on the class and just allocate a new instance.
-         * The cost is one extra boolean test for the normal case, and some
-         * small number of cases where we allocate an extra object when
-         * in fact the reusable one would be freed very soon.
-         */
-        if (inUse) {
+        if (inUse.compareAndSet(false, true)) {
+            return reusableGL;
+        } else {
             return new GlyphList();
-        } else {
-            synchronized(GlyphList.class) {
-                if (inUse) {
-                    return new GlyphList();
-                } else {
-                    inUse = true;
-                    return reusableGL;
-                }
-            }
         }
     }
 
@@ -212,17 +199,10 @@
      * will be discarded so the re-allocation overhead is high.
      */
 //     public static GlyphList getInstance(int sz) {
-//      if (inUse) {
+//      if (inUse.compareAndSet(false, true) {
+//          return reusableGL;
+//      } else {
 //          return new GlyphList(sz);
-//      } else {
-//          synchronized(GlyphList.class) {
-//              if (inUse) {
-//                  return new GlyphList();
-//              } else {
-//                  inUse = true;
-//                  return reusableGL;
-//              }
-//          }
 //      }
 //     }
 
@@ -423,7 +403,7 @@
             }
             usePositions = false;
             strikelist = null; // remove reference to the strike list
-            inUse = false;
+            inUse.set(false);
         }
     }
 
--- a/src/java.desktop/share/classes/sun/print/ServiceDialog.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/sun/print/ServiceDialog.java	Sat Jul 30 00:11:02 2016 +0000
@@ -74,7 +74,7 @@
 import java.awt.event.KeyEvent;
 import java.net.URISyntaxException;
 import java.lang.reflect.Field;
-
+import java.net.MalformedURLException;
 
 /**
  * A class which implements a cross-platform print dialog.
@@ -932,12 +932,18 @@
                 allowedToPrintToFile() : false;
 
             // setup Destination (print-to-file) widgets
-            if (psCurrent.isAttributeCategorySupported(dstCategory)) {
-                dstSupported = true;
-            }
             Destination dst = (Destination)asCurrent.get(dstCategory);
             if (dst != null) {
-                dstSelected = true;
+                try {
+                     dst.getURI().toURL();
+                     if (psCurrent.isAttributeValueSupported(dst, docFlavor,
+                                                             asCurrent)) {
+                         dstSupported = true;
+                         dstSelected = true;
+                     }
+                 } catch (MalformedURLException ex) {
+                     dstSupported = true;
+                 }
             }
             cbPrintToFile.setEnabled(dstSupported && dstAllowed);
             cbPrintToFile.setSelected(dstSelected && dstAllowed
@@ -1294,8 +1300,16 @@
                 if (sc == null) {
                     sc = SheetCollate.UNCOLLATED;
                 }
+                if (sc != null &&
+                    !psCurrent.isAttributeValueSupported(sc, docFlavor, asCurrent)) {
+                    scSupported = false;
+                }
+            } else {
+                if (!psCurrent.isAttributeValueSupported(sc, docFlavor, asCurrent)) {
+                    scSupported = false;
+                }
             }
-            cbCollate.setSelected(sc == SheetCollate.COLLATED);
+            cbCollate.setSelected(sc == SheetCollate.COLLATED && scSupported);
             updateCollateCB();
         }
     }
--- a/src/java.desktop/share/classes/sun/swing/CachedPainter.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/sun/swing/CachedPainter.java	Sat Jul 30 00:11:02 2016 +0000
@@ -25,6 +25,7 @@
 package sun.swing;
 
 import java.awt.*;
+import java.awt.geom.AffineTransform;
 import java.awt.image.*;
 import java.util.*;
 
@@ -99,9 +100,7 @@
         }
     }
 
-    private void paint0(Component c, Graphics g, int x,
-                         int y, int w, int h, Object... args) {
-        Object key = getClass();
+    private Image getImage(Object key, Component c, int w, int h, Object... args) {
         GraphicsConfiguration config = getGraphicsConfiguration(c);
         ImageCache cache = getCache(key);
         Image image = cache.getImage(key, config, w, h, args);
@@ -133,14 +132,40 @@
                 g2.dispose();
             }
 
-            // Render to the passed in Graphics
-            paintImage(c, g, x, y, w, h, image, args);
-
             // If we did this 3 times and the contents are still lost
             // assume we're painting to a VolatileImage that is bogus and
             // give up.  Presumably we'll be called again to paint.
         } while ((image instanceof VolatileImage) &&
                  ((VolatileImage)image).contentsLost() && ++attempts < 3);
+
+        return image;
+    }
+
+    private void paint0(Component c, Graphics g, int x,
+                        int y, int w, int h, Object... args) {
+        Object key = getClass();
+        GraphicsConfiguration config = getGraphicsConfiguration(c);
+        ImageCache cache = getCache(key);
+        Image image = cache.getImage(key, config, w, h, args);
+
+        if (image == null) {
+            double sx = 1;
+            double sy = 1;
+            if (g instanceof Graphics2D) {
+                AffineTransform tx = ((Graphics2D) g).getTransform();
+                sx = tx.getScaleX();
+                sy = tx.getScaleY();
+            }
+            image = new PainterMultiResolutionCachedImage(sx, sy, w, h);
+            cache.setImage(key, config, w, h, args, image);
+        }
+
+        if (image instanceof PainterMultiResolutionCachedImage) {
+            ((PainterMultiResolutionCachedImage) image).setParams(c, args);
+        }
+
+        // Render to the passed in Graphics
+        paintImage(c, g, x, y, w, h, image, args);
     }
 
     /**
@@ -210,4 +235,62 @@
         }
         return c.getGraphicsConfiguration();
     }
-}
+
+    class PainterMultiResolutionCachedImage extends AbstractMultiResolutionImage {
+
+        private final double scaleX;
+        private final double scaleY;
+        private final int baseWidth;
+        private final int baseHeight;
+        private Component c;
+        private Object[] args;
+
+        public PainterMultiResolutionCachedImage(double scaleX, double scaleY,
+                                                 int baseWidth, int baseHeight) {
+            this.scaleX = scaleX;
+            this.scaleY = scaleY;
+            this.baseWidth = baseWidth;
+            this.baseHeight = baseHeight;
+        }
+
+        public void setParams(Component c, Object[] args) {
+            this.c = c;
+            this.args = args;
+        }
+
+        @Override
+        public int getWidth(ImageObserver observer) {
+            return baseWidth;
+        }
+
+        @Override
+        public int getHeight(ImageObserver observer) {
+            return baseHeight;
+        }
+
+        @Override
+        public Image getResolutionVariant(double destWidth, double destHeight) {
+            int w = (int) Math.ceil(destWidth);
+            int h = (int) Math.ceil(destHeight);
+            return getImage(this, c, w, h, args);
+        }
+
+        @Override
+        protected Image getBaseImage() {
+            return getResolutionVariant(baseWidth, baseHeight);
+        }
+
+        @Override
+        public java.util.List<Image> getResolutionVariants() {
+
+            if (scaleX == 1 && scaleY == 1) {
+                return Arrays.asList(getResolutionVariant(baseWidth, baseHeight));
+            }
+
+            return Arrays.asList(
+                    getResolutionVariant(baseWidth, baseHeight),
+                    getResolutionVariant(scaleX * baseWidth, scaleY * baseHeight)
+            );
+        }
+    }
+}
\ No newline at end of file
--- a/src/java.desktop/share/classes/sun/swing/FilePane.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/share/classes/sun/swing/FilePane.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1748,8 +1748,8 @@
         if (listSelectionModel != null) {
             listSelectionModel.clearSelection();
             if (listSelectionModel instanceof DefaultListSelectionModel) {
-                ((DefaultListSelectionModel)listSelectionModel).moveLeadSelectionIndex(0);
-                listSelectionModel.setAnchorSelectionIndex(0);
+                ((DefaultListSelectionModel)listSelectionModel).moveLeadSelectionIndex(-1);
+                listSelectionModel.setAnchorSelectionIndex(-1);
             }
         }
     }
--- a/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,9 @@
 import java.awt.event.ComponentEvent;
 import java.awt.event.InvocationEvent;
 import java.awt.event.WindowEvent;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 import sun.awt.IconInfo;
 import sun.util.logging.PlatformLogger;
@@ -52,6 +55,8 @@
     XContentWindow content;
     Insets currentInsets;
     XFocusProxyWindow focusProxy;
+    static final Map<Class<?>,Insets> lastKnownInsets =
+                                   Collections.synchronizedMap(new HashMap<>());
 
     XDecoratedPeer(Window target) {
         super(target);
@@ -74,6 +79,9 @@
         winAttr.initialFocus = true;
 
         currentInsets = new Insets(0,0,0,0);
+        if (XWM.getWMID() == XWM.UNITY_COMPIZ_WM) {
+            currentInsets = lastKnownInsets.get(getClass());
+        }
         applyGuessedInsets();
 
         Rectangle bounds = (Rectangle)params.get(BOUNDS);
@@ -297,7 +305,25 @@
         if (ev.get_atom() == XWM.XA_KDE_NET_WM_FRAME_STRUT.getAtom()
             || ev.get_atom() == XWM.XA_NET_FRAME_EXTENTS.getAtom())
         {
-            getWMSetInsets(XAtom.get(ev.get_atom()));
+            if (XWM.getWMID() != XWM.UNITY_COMPIZ_WM) {
+                getWMSetInsets(XAtom.get(ev.get_atom()));
+            } else {
+                if(!isReparented()) {
+                    return;
+                }
+                wm_set_insets = null;
+                Insets in = getWMSetInsets(XAtom.get(ev.get_atom()));
+                if (isNull(in)) {
+                    return;
+                }
+                if (!isEmbedded() && !isTargetUndecorated()) {
+                    lastKnownInsets.put(getClass(), in);
+                }
+                if (!in.equals(dimensions.getInsets())) {
+                    handleCorrectInsets(in);
+                }
+                insets_corrected = true;
+            }
         }
     }
 
@@ -370,7 +396,7 @@
                     }
                 }
 
-                if (correctWM != null) {
+                if (correctWM != null && XWM.getWMID() != XWM.UNITY_COMPIZ_WM) {
                     handleCorrectInsets(correctWM);
                 }
             }
@@ -664,6 +690,9 @@
 
     boolean no_reparent_artifacts = false;
     public void handleConfigureNotifyEvent(XEvent xev) {
+        if (XWM.getWMID() == XWM.UNITY_COMPIZ_WM && !insets_corrected) {
+            return;
+        }
         assert (SunToolkit.isAWTLockHeldByCurrentThread());
         XConfigureEvent xe = xev.get_xconfigure();
         if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
@@ -1010,7 +1039,22 @@
         if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
             focusLog.fine("WM_TAKE_FOCUS on {0}", this);
         }
-        requestWindowFocus(cl.get_data(1), true);
+
+        if (XWM.getWMID() == XWM.UNITY_COMPIZ_WM) {
+            // JDK-8159460
+            Window focusedWindow = XKeyboardFocusManagerPeer.getInstance()
+                    .getCurrentFocusedWindow();
+            Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
+            if (activeWindow != target) {
+                requestWindowFocus(cl.get_data(1), true);
+            } else {
+                WindowEvent we = new WindowEvent(focusedWindow,
+                        WindowEvent.WINDOW_GAINED_FOCUS);
+                sendEvent(we);
+            }
+        } else {
+            requestWindowFocus(cl.get_data(1), true);
+        }
     }
 
     /**
--- a/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java	Sat Jul 30 00:11:02 2016 +0000
@@ -35,8 +35,16 @@
 
 class XRobotPeer implements RobotPeer {
 
-    private static volatile boolean isGtkSupported;
+    static final boolean tryGtk;
+    static {
+        loadNativeLibraries();
+        tryGtk = Boolean.getBoolean("awt.robot.gtk");
+    }
+
+    private static boolean isGtkSupported =  false;
+    private static volatile boolean useGtk;
     private X11GraphicsConfig   xgc = null;
+
     /*
      * native implementation uses some static shared data (pipes, processes)
      * so use a class lock to synchronize native method calls
@@ -49,13 +57,14 @@
         setup(tk.getNumberOfButtons(),
                 AWTAccessor.getInputEventAccessor().getButtonDownMasks());
 
-        Toolkit toolkit = Toolkit.getDefaultToolkit();
-        if (!isGtkSupported) {
-            if (toolkit instanceof UNIXToolkit
-                    && ((UNIXToolkit) toolkit).loadGTK()) {
+        boolean isGtkSupported = false;
+        if (tryGtk) {
+            if (tk instanceof UNIXToolkit && ((UNIXToolkit) tk).loadGTK()) {
                 isGtkSupported = true;
             }
         }
+
+        useGtk = (tryGtk && isGtkSupported);
     }
 
     @Override
@@ -104,7 +113,7 @@
     public int getRGBPixel(int x, int y) {
         int pixelArray[] = new int[1];
         getRGBPixelsImpl(xgc, x, y, 1, 1, xgc.getScale(), pixelArray,
-                         isGtkSupported);
+                         useGtk);
         return pixelArray[0];
     }
 
@@ -112,11 +121,12 @@
     public int [] getRGBPixels(Rectangle bounds) {
         int pixelArray[] = new int[bounds.width*bounds.height];
         getRGBPixelsImpl(xgc, bounds.x, bounds.y, bounds.width, bounds.height,
-                         xgc.getScale(), pixelArray, isGtkSupported);
+                         xgc.getScale(), pixelArray, useGtk);
         return pixelArray;
     }
 
     private static synchronized native void setup(int numberOfButtons, int[] buttonDownMasks);
+    private static native void loadNativeLibraries();
 
     private static synchronized native void mouseMoveImpl(X11GraphicsConfig xgc, int x, int y);
     private static synchronized native void mousePressImpl(int buttons);
--- a/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java	Sat Jul 30 00:11:02 2016 +0000
@@ -32,6 +32,7 @@
 
 import sun.awt.UNIXToolkit;
 import java.security.AccessController;
+import java.security.PrivilegedAction;
 import sun.security.action.GetPropertyAction;
 
 final class XTaskbarPeer implements TaskbarPeer {
@@ -40,6 +41,14 @@
     private static boolean initExecuted = false;
 
     private PopupMenu menu = null;
+    private static boolean isUnity;
+
+    static {
+        String de = AccessController.doPrivileged(
+                        (PrivilegedAction<String>) ()
+                                -> System.getenv("XDG_CURRENT_DESKTOP"));
+        isUnity = de != null && de.equals("Unity");
+    }
 
     private static void initWithLock() {
         XToolkit.awtLock();
@@ -68,6 +77,9 @@
     }
 
     static boolean isTaskbarSupported() {
+        if (!isUnity) {
+            return false;
+        }
         initWithLock();
         return nativeLibraryLoaded;
     }
@@ -107,6 +119,8 @@
                 val = Long.parseLong(badge);
                 visible = true;
             } catch (NumberFormatException e) {
+                throw new UnsupportedOperationException("The " + Feature.ICON_BADGE_TEXT
+                    + " feature is not supported on the current platform!");
             }
         }
         setBadge(val, visible);
--- a/src/java.desktop/unix/classes/sun/awt/X11/XWM.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XWM.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -104,7 +104,8 @@
         COMPIZ_WM = 12,
         LG3D_WM = 13,
         CWM_WM = 14,
-        MUTTER_WM = 15;
+        MUTTER_WM = 15,
+        UNITY_COMPIZ_WM = 16;
     public String toString() {
         switch  (WMID) {
           case NO_WM:
@@ -129,6 +130,8 @@
               return "Metacity";
           case COMPIZ_WM:
               return "Compiz";
+            case UNITY_COMPIZ_WM:
+              return "Unity Compiz";
           case LG3D_WM:
               return "LookingGlass";
           case CWM_WM:
@@ -572,6 +575,10 @@
         return isNetWMName("compiz");
     }
 
+    static boolean isUnityCompiz() {
+        return isNetWMName("Compiz");
+    }
+
     static boolean isLookingGlass() {
         return isNetWMName("LG3D");
     }
@@ -790,6 +797,8 @@
                 awt_wmgr = CWM_WM;
             } else if (doIsIceWM && isIceWM()) {
                 awt_wmgr = XWM.ICE_WM;
+            } else if (isUnityCompiz()) {
+                awt_wmgr = XWM.UNITY_COMPIZ_WM;
             }
             /*
              * We don't check for legacy WM when we already know that WM
@@ -1351,6 +1360,9 @@
               case LG3D_WM:
                   res = zeroInsets;
                   break;
+              case UNITY_COMPIZ_WM:
+                  res = new Insets(28, 1, 1, 1);
+                  break;
               case MOTIF_WM:
               case OPENLOOK_WM:
               default:
--- a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java	Sat Jul 30 00:11:02 2016 +0000
@@ -777,6 +777,7 @@
                 case XWM.METACITY_WM:
                 case XWM.MUTTER_WM:
                 case XWM.SAWFISH_WM:
+                case XWM.UNITY_COMPIZ_WM:
                 {
                     Point xlocation = queryXLocation();
                     if (log.isLoggable(PlatformLogger.Level.FINE)) {
--- a/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java	Sat Jul 30 00:11:02 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -281,7 +281,7 @@
                                                  int width, int height,
                                                  int displayMode);
     private static native void resetNativeData(int screen);
-    private static native int getNativeScaleFactor(int screen);
+    private static native double getNativeScaleFactor(int screen);
 
     /**
      * Returns true only if:
@@ -516,6 +516,11 @@
         return scale;
     }
 
+    public int getNativeScale() {
+        isXrandrExtensionSupported();
+        return (int)Math.round(getNativeScaleFactor(screen));
+    }
+
     private int initScaleFactor() {
 
         if (SunGraphicsEnvironment.isUIScaleEnabled()) {
@@ -525,8 +530,7 @@
             if (debugScale >= 1) {
                 return (int) debugScale;
             }
-
-            int nativeScale = getNativeScaleFactor(screen);
+            int nativeScale = getNativeScale();
             return nativeScale >= 1 ? nativeScale : 1;
         }
 
--- a/src/java.desktop/unix/native/common/awt/systemscale/systemScale.c	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/unix/native/common/awt/systemscale/systemScale.c	Sat Jul 30 00:11:02 2016 +0000
@@ -22,23 +22,171 @@
 */
 
 #include "systemScale.h"
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm_md.h"
+#include <dlfcn.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
-int getNativeScaleFactor() {
+typedef void* g_settings_schema_source_get_default();
+typedef void* g_settings_schema_source_ref(void *);
+typedef void g_settings_schema_source_unref(void *);
+typedef void* g_settings_schema_source_lookup(void *, char *, int);
+typedef int g_settings_schema_has_key(void *, char *);
+typedef void* g_settings_new_full(void *, void *, char *);
+typedef void* g_settings_get_value(void *, char *);
+typedef int g_variant_is_of_type(void *, char *);
+typedef unsigned long g_variant_n_children(void *);
+typedef void* g_variant_get_child_value(void *, unsigned long);
+typedef void  g_variant_unref(void *);
+typedef char*  g_variant_get_string(void *, unsigned long *);
+typedef int  g_variant_get_int32(void *);
+typedef double  g_variant_get_double(void *);
 
-    static int scale = -2.0;
+static g_settings_schema_has_key* fp_g_settings_schema_has_key;
+static g_settings_new_full* fp_g_settings_new_full;
+static g_settings_get_value* fp_g_settings_get_value;
+static g_variant_is_of_type* fp_g_variant_is_of_type;
+static g_variant_n_children* fp_g_variant_n_children;
+static g_variant_get_child_value* fp_g_variant_get_child_value;
+static g_variant_get_string* fp_g_variant_get_string;
+static g_variant_get_int32* fp_g_variant_get_int32;
+static g_variant_get_double* fp_g_variant_get_double;
+static g_variant_unref* fp_g_variant_unref;
 
-    if (scale == -2) {
-        scale = getScale("J2D_UISCALE");
+static void* get_schema_value(char *name, char *key) {
+    static void *lib_handle;
+    static int initialized = 0;
+    static void * default_schema;
+    static g_settings_schema_source_lookup* schema_lookup;
+    void *schema = NULL, *fp = NULL;
+    if (!initialized) {
+        initialized = 1;
+        lib_handle = dlopen(JNI_LIB_NAME("gio-2.0"), RTLD_GLOBAL | RTLD_LAZY);
+        if (!lib_handle) {
+            CHECK_NULL_RETURN(lib_handle =
+                          dlopen(VERSIONED_JNI_LIB_NAME("gio-2.0", "0"),
+                                                RTLD_GLOBAL | RTLD_LAZY), NULL);
+        }
+        CHECK_NULL_RETURN(fp_g_settings_schema_has_key =
+                          (g_settings_schema_has_key*)
+                          dlsym(lib_handle, "g_settings_schema_has_key"), NULL);
+        CHECK_NULL_RETURN(fp_g_settings_new_full =
+                          (g_settings_new_full*)
+                          dlsym(lib_handle, "g_settings_new_full"), NULL);
+        CHECK_NULL_RETURN(fp_g_settings_get_value =
+                          (g_settings_get_value*)
+                          dlsym(lib_handle, "g_settings_get_value"), NULL);
+        CHECK_NULL_RETURN(fp_g_variant_is_of_type =
+                          (g_variant_is_of_type*)
+                          dlsym(lib_handle, "g_variant_is_of_type"), NULL);
+        CHECK_NULL_RETURN(fp_g_variant_n_children =
+                          (g_variant_n_children*)
+                          dlsym(lib_handle, "g_variant_n_children"), NULL);
+        CHECK_NULL_RETURN(fp_g_variant_get_child_value =
+                          (g_variant_get_child_value*)
+                          dlsym(lib_handle, "g_variant_get_child_value"), NULL);
+        CHECK_NULL_RETURN(fp_g_variant_get_string =
+                          (g_variant_get_string*)
+                          dlsym(lib_handle, "g_variant_get_string"), NULL);
+        CHECK_NULL_RETURN(fp_g_variant_get_int32 =
+                          (g_variant_get_int32*)
+                          dlsym(lib_handle, "g_variant_get_int32"), NULL);
+        CHECK_NULL_RETURN(fp_g_variant_get_double =
+                          (g_variant_get_double*)
+                          dlsym(lib_handle, "g_variant_get_double"), NULL);
+        CHECK_NULL_RETURN(fp_g_variant_unref =
+                          (g_variant_unref*)
+                          dlsym(lib_handle, "g_variant_unref"), NULL);
+
+        fp = dlsym(lib_handle, "g_settings_schema_source_get_default");
+        if (fp) {
+            default_schema = ((g_settings_schema_source_get_default*)fp)();
+        }
+        if (default_schema) {
+            fp = dlsym(lib_handle, "g_settings_schema_source_ref");
+            if (fp) {
+                ((g_settings_schema_source_ref*)fp)(default_schema);
+            }
+        }
+        schema_lookup = (g_settings_schema_source_lookup*)
+                           dlsym(lib_handle, "g_settings_schema_source_lookup");
     }
 
-    if (scale >= 1) {
-        return (int) scale;
+    if (!default_schema || !schema_lookup) {
+        return NULL;
     }
-    return getScale("GDK_SCALE");
+
+    schema = schema_lookup(default_schema, name, 1);
+    if (schema) {
+        if (fp_g_settings_schema_has_key(schema, key)) {
+            void *settings = fp_g_settings_new_full(schema, NULL, NULL);
+            if (settings) {
+                return fp_g_settings_get_value(settings, key);
+            }
+        }
+    }
+    return NULL;
 }
 
-int getScale(const char *name) {
+
+static double getDesktopScale(char *output_name) {
+    double result = -1;
+    if(output_name) {
+        void *value = get_schema_value("com.ubuntu.user-interface",
+                                                                "scale-factor");
+        if (value) {
+            if(fp_g_variant_is_of_type(value, "a{si}")) {
+                int num = fp_g_variant_n_children(value);
+                int i = 0;
+                while (i < num) {
+                    void *entry = fp_g_variant_get_child_value(value, i++);
+                    if (entry) {
+                        void *screen = fp_g_variant_get_child_value(entry, 0);
+                        void *scale = fp_g_variant_get_child_value(entry, 1);
+                        if (screen && scale) {
+                            char *name = fp_g_variant_get_string(screen, NULL);
+                            if (name && strcmp(name, output_name)) {
+                                result = fp_g_variant_get_int32(scale) / 8.;
+                            }
+                            fp_g_variant_unref(screen);
+                            fp_g_variant_unref(scale);
+                        }
+                        fp_g_variant_unref(entry);
+                    }
+                    if (result > 0) {
+                        break;
+                    }
+                }
+            }
+            fp_g_variant_unref(value);
+        }
+        if (result > 0) {
+            value = get_schema_value("com.canonical.Unity.Interface",
+                                                           "text-scale-factor");
+            if (value && fp_g_variant_is_of_type(value, "d")) {
+                result *= fp_g_variant_get_double(value);
+                fp_g_variant_unref(value);
+            }
+        }
+    }
+
+    if (result <= 0) {
+        void *value = get_schema_value("org.gnome.desktop.interface",
+                                                         "text-scaling-factor");
+        if (value && fp_g_variant_is_of_type(value, "d")) {
+            result = fp_g_variant_get_double(value);
+            fp_g_variant_unref(value);
+        }
+    }
+
+    return result;
+
+}
+
+static int getScale(const char *name) {
     char *uiScale = getenv(name);
     if (uiScale != NULL) {
         double scale = strtod(uiScale, NULL);
@@ -50,3 +198,26 @@
     return -1;
 }
 
+double getNativeScaleFactor(char *output_name) {
+    static int scale = -2.0;
+    double native_scale = 0;
+    int gdk_scale = 0;
+
+    if (scale == -2) {
+        scale = getScale("J2D_UISCALE");
+    }
+
+    if (scale > 0) {
+        return scale;
+    }
+
+    native_scale = getDesktopScale(output_name);
+
+    if (native_scale <= 0) {
+        native_scale = 1;
+    }
+
+    gdk_scale = getScale("GDK_SCALE");
+
+    return gdk_scale > 0 ? native_scale * gdk_scale : native_scale;
+}
--- a/src/java.desktop/unix/native/common/awt/systemscale/systemScale.h	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/unix/native/common/awt/systemscale/systemScale.h	Sat Jul 30 00:11:02 2016 +0000
@@ -26,8 +26,7 @@
 #include <signal.h>
 #include <stdlib.h>
 
-int getNativeScaleFactor();
-int getScale(const char *uiScale);
+double getNativeScaleFactor();
 
 #endif
 
--- a/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c	Sat Jul 30 00:11:02 2016 +0000
@@ -2141,15 +2141,50 @@
  * End DisplayMode/FullScreen support
  */
 
+static char *get_output_screen_name(JNIEnv *env, int screen) {
+    if (!awt_XRRGetScreenResources || !awt_XRRGetOutputInfo) {
+        return NULL;
+    }
+    char *name = NULL;
+    AWT_LOCK();
+    int scr = 0, out = 0;
+    if (usingXinerama && XScreenCount(awt_display) > 0) {
+        out = screen;
+    } else {
+        scr = screen;
+    }
+
+    XRRScreenResources *res = awt_XRRGetScreenResources(awt_display,
+                                                  RootWindow(awt_display, scr));
+    if (res) {
+       if (res->noutput > out) {
+            XRROutputInfo *output_info = awt_XRRGetOutputInfo(awt_display,
+                                                        res, res->outputs[out]);
+            if (output_info) {
+                if (output_info->name) {
+                    name = strdup(output_info->name);
+                }
+                awt_XRRFreeOutputInfo(output_info);
+            }
+        }
+        awt_XRRFreeScreenResources(res);
+    }
+    AWT_UNLOCK();
+    return name;
+}
 
 /*
  * Class:     sun_awt_X11GraphicsDevice
  * Method:    getNativeScaleFactor
- * Signature: (I)I
+ * Signature: (I)D
  */
-JNIEXPORT jint JNICALL
+JNIEXPORT jdouble JNICALL
 Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor
     (JNIEnv *env, jobject this, jint screen) {
-
-    return getNativeScaleFactor();
+    char *name = get_output_screen_name(env, screen);
+    double scale = getNativeScaleFactor(name);
+    if (name) {
+        free(name);
+    }
+    return scale;
 }
--- a/src/java.desktop/unix/native/libawt_xawt/awt/awt_Robot.c	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/awt_Robot.c	Sat Jul 30 00:11:02 2016 +0000
@@ -27,6 +27,9 @@
     #error This file should not be included in headless library
 #endif
 
+#include "jvm_md.h"
+#include <dlfcn.h>
+
 #include "awt_p.h"
 #include "awt_GraphicsEnv.h"
 #define XK_MISCELLANY
@@ -50,11 +53,46 @@
 #include <sys/socket.h>
 #endif
 
+static Bool   (*compositeQueryExtension)   (Display*, int*, int*);
+static Status (*compositeQueryVersion)     (Display*, int*, int*);
+static Window (*compositeGetOverlayWindow) (Display *, Window);
+
 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
 
 static jint * masks;
 static jint num_buttons;
 
+static void *xCompositeHandle;
+
+static const char* XCOMPOSITE = JNI_LIB_NAME("Xcomposite");
+static const char* XCOMPOSITE_VERSIONED = VERSIONED_JNI_LIB_NAME("Xcomposite", "1");
+
+static Bool checkXCompositeFunctions(void) {
+    return (compositeQueryExtension   != NULL   &&
+            compositeQueryVersion     != NULL   &&
+            compositeGetOverlayWindow != NULL);
+}
+
+static void initXCompositeFunctions(void) {
+
+    if (xCompositeHandle == NULL) {
+        xCompositeHandle = dlopen(XCOMPOSITE, RTLD_LAZY | RTLD_GLOBAL);
+        if (xCompositeHandle == NULL) {
+            xCompositeHandle = dlopen(XCOMPOSITE_VERSIONED, RTLD_LAZY | RTLD_GLOBAL);
+        }
+    }
+    //*(void **)(&asyncGetCallTraceFunction)
+    if (xCompositeHandle != NULL) {
+        *(void **)(&compositeQueryExtension) = dlsym(xCompositeHandle, "XCompositeQueryExtension");
+        *(void **)(&compositeQueryVersion) = dlsym(xCompositeHandle, "XCompositeQueryVersion");
+        *(void **)(&compositeGetOverlayWindow) = dlsym(xCompositeHandle, "XCompositeGetOverlayWindow");
+    }
+
+    if (xCompositeHandle && !checkXCompositeFunctions()) {
+        dlclose(xCompositeHandle);
+    }
+}
+
 static int32_t isXTestAvailable() {
     int32_t major_opcode, first_event, first_error;
     int32_t  event_basep, error_basep, majorp, minorp;
@@ -89,6 +127,35 @@
     return isXTestAvailable;
 }
 
+static Bool hasXCompositeOverlayExtension(Display *display) {
+
+    int xoverlay = False;
+    int eventBase, errorBase;
+    if (checkXCompositeFunctions() &&
+        compositeQueryExtension(display, &eventBase, &errorBase))
+    {
+        int major = 0;
+        int minor = 0;
+
+        compositeQueryVersion(display, &major, &minor);
+        if (major > 0 || minor >= 3) {
+            xoverlay = True;
+        }
+    }
+
+    return xoverlay;
+}
+
+static jboolean isXCompositeDisplay(Display *display, int screenNumber) {
+
+    char NET_WM_CM_Sn[25];
+    snprintf(NET_WM_CM_Sn, sizeof(NET_WM_CM_Sn), "_NET_WM_CM_S%d\0", screenNumber);
+
+    Atom managerSelection = XInternAtom(display, NET_WM_CM_Sn, 0);
+    Window owner = XGetSelectionOwner(display, managerSelection);
+
+    return owner != 0;
+}
 
 static XImage *getWindowImage(Display * display, Window window,
                               int32_t x, int32_t y,
@@ -211,7 +278,7 @@
                              jint jheight,
                              jint scale,
                              jintArray pixelArray,
-                             jboolean isGtkSupported) {
+                             jboolean useGtk) {
     XImage *image;
     jint *ary;               /* Array of jints for sending pixel values back
                               * to parent process.
@@ -238,6 +305,14 @@
 
     rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen);
 
+    if (!useGtk) {
+        if (hasXCompositeOverlayExtension(awt_display) &&
+            isXCompositeDisplay(awt_display, adata->awt_visInfo.screen))
+        {
+            rootWindow = compositeGetOverlayWindow(awt_display, rootWindow);
+        }
+    }
+
     if (!XGetWindowAttributes(awt_display, rootWindow, &attr)
             || sx + swidth <= attr.x
             || attr.x + attr.width <= sx
@@ -262,7 +337,7 @@
 
     int index;
 
-    if (isGtkSupported) {
+    if (useGtk) {
         gtk->gdk_threads_enter();
         gtk_failed = gtk->get_drawable_data(env, pixelArray, x, y, width,
                                             height, jwidth, dx, dy, scale);
@@ -454,3 +529,8 @@
 
     AWT_UNLOCK();
 }
+
+JNIEXPORT void JNICALL
+Java_sun_awt_X11_XRobotPeer_loadNativeLibraries (JNIEnv *env, jclass cls) {
+    initXCompositeFunctions();
+}
--- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c	Sat Jul 30 00:11:02 2016 +0000
@@ -1586,13 +1586,17 @@
     fp_gtk_style_context_save (context);
 
     GtkStateFlags flags = get_gtk_flags(state_type);
+    if (expander_style == GTK_EXPANDER_EXPANDED) {
+        flags |= GTK_STATE_FLAG_ACTIVE;
+    }
+
     fp_gtk_style_context_set_state(context, flags);
 
     if (detail != 0) {
         transform_detail_string(detail, context);
     }
 
-    fp_gtk_render_expander (context, cr, x, y, width, height);
+    fp_gtk_render_expander (context, cr, x + 2, y + 2, width - 4, height - 4);
 
     fp_gtk_style_context_restore (context);
 }
--- a/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.h	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.h	Sat Jul 30 00:11:02 2016 +0000
@@ -11,7 +11,7 @@
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file thats
+ * version 2 for more details (a copy is included in the LICENSE file that
  * accompanied this code).
  *
  * You should have received a copy of the GNU General Public License version
--- a/src/java.desktop/windows/classes/sun/awt/windows/WComponentPeer.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WComponentPeer.java	Sat Jul 30 00:11:02 2016 +0000
@@ -55,6 +55,7 @@
 
 import java.awt.dnd.DropTarget;
 import java.awt.dnd.peer.DropTargetPeer;
+import java.awt.geom.AffineTransform;
 import sun.awt.AWTAccessor;
 
 import sun.util.logging.PlatformLogger;
@@ -1128,6 +1129,12 @@
         }
 
         if (shape != null) {
+            AffineTransform tx = winGraphicsConfig.getDefaultTransform();
+            double scaleX = tx.getScaleX();
+            double scaleY = tx.getScaleY();
+            if (scaleX != 1 || scaleY != 1) {
+                shape = shape.getScaledRegion(scaleX, scaleY);
+            }
             setRectangularShape(shape.getLoX(), shape.getLoY(), shape.getHiX(), shape.getHiY(),
                     (shape.isRectangular() ? null : shape));
         } else {
--- a/src/java.desktop/windows/native/libawt/windows/awt_Cursor.cpp	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Cursor.cpp	Sat Jul 30 00:11:02 2016 +0000
@@ -473,8 +473,14 @@
 
     POINT p;
     ::GetCursorPos(&p);
-    env->SetIntField(point, AwtCursor::pointXID, (jint)p.x);
-    env->SetIntField(point, AwtCursor::pointYID, (jint)p.y);
+    HMONITOR monitor = MonitorFromPoint(p, MONITOR_DEFAULTTOPRIMARY);
+    int screen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(monitor);
+    Devices::InstanceAccess devices;
+    AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
+    int x = (device == NULL) ? p.x : device->ScaleDownX(p.x);
+    int y = (device == NULL) ? p.y : device->ScaleDownY(p.y);
+    env->SetIntField(point, AwtCursor::pointXID, x);
+    env->SetIntField(point, AwtCursor::pointYID, y);
 
     CATCH_BAD_ALLOC;
 }
--- a/src/java.desktop/windows/native/libfontmanager/fontpath.c	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.desktop/windows/native/libfontmanager/fontpath.c	Sat Jul 30 00:11:02 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,20 @@
 
 #define BSIZE (max(512, MAX_PATH+1))
 
+/* Typically all local references held by a JNI function are automatically
+ * released by JVM when the function returns. However, there is a limit to the
+ * number of local references that can remain active. If the local references
+ * continue to grow, it could result in out of memory error. Henceforth, we
+ * invoke DeleteLocalRef on objects that are no longer needed for execution in
+ * the JNI function.
+ */
+#define DeleteLocalReference(env, jniRef) \
+    do { \
+        if (jniRef != NULL) { \
+            (*env)->DeleteLocalRef(env, jniRef); \
+            jniRef = NULL; \
+        } \
+    } while (0)
 
 JNIEXPORT jstring JNICALL Java_sun_awt_Win32FontManager_getFontPath(JNIEnv *env, jobject thiz, jboolean noType1)
 {
@@ -88,81 +102,9 @@
     jobject locale;
 } GdiFontMapInfo;
 
-/* IS_NT means NT or later OSes which support Unicode.
- * We have to painfully deal with the ASCII and non-ASCII case we
- * we really want to get the font names as unicode wherever possible.
- * UNICODE_OS is 0 to mean uninitialised, 1 to mean not a unicode OS,
- * 2 to mean a unicode OS.
- */
-
-#define UC_UNKNOWN 0
-#define UC_NO     1
-#define UC_YES    2
-static int UNICODE_OS = UC_UNKNOWN;
-static int GetOSVersion () {
-    OSVERSIONINFO vinfo;
-    vinfo.dwOSVersionInfoSize = sizeof(vinfo);
-    GetVersionEx(&vinfo);
-    if ((int)vinfo.dwMajorVersion > 4) {
-        UNICODE_OS = UC_YES;
-    } else if ((int)vinfo.dwMajorVersion < 4) {
-        UNICODE_OS = UC_NO;
-    } else {
-        if ((int)vinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
-            UNICODE_OS = UC_NO;
-        } else {
-            UNICODE_OS = UC_YES;
-        }
-    }
-    return UNICODE_OS;
-}
-
-#define IS_NT ((UNICODE_OS == UC_UNKNOWN) \
-   ? (GetOSVersion() == UC_YES) : (UNICODE_OS == UC_YES))
-
-/* NT is W2K & XP. WIN is Win9x */
+/* Registry entry for fonts */
 static const char FONTKEY_NT[] =
     "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
-static const char FONTKEY_WIN[] =
-    "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts";
-
-/* Callback for call to EnumFontFamiliesEx in the EnumFamilyNames function.
- * Expects to be called once for each face name in the family specified
- * in the call. We extract the full name for the font which is expected
- * to be in the "system encoding" and create canonical and lower case
- * Java strings for the name which are added to the maps. The lower case
- * name is used as key to the family name value in the font to family map,
- * the canonical name is one of the"list" of members of the family.
- */
-static int CALLBACK EnumFontFacesInFamilyProcA(
-  ENUMLOGFONTEXA *lpelfe,
-  NEWTEXTMETRICEX *lpntme,
-  int FontType,
-  LPARAM lParam )
-{
-    GdiFontMapInfo *fmi = (GdiFontMapInfo*)lParam;
-    JNIEnv *env = fmi->env;
-    jstring fullname, fullnameLC;
-
-    /* Both Vista and XP return DEVICE_FONTTYPE for OTF fonts */
-    if (FontType != TRUETYPE_FONTTYPE && FontType != DEVICE_FONTTYPE) {
-        return 1;
-    }
-
-    /* printf("FULL=%s\n",lpelfe->elfFullName);fflush(stdout);  */
-
-    fullname = JNU_NewStringPlatform(env, lpelfe->elfFullName);
-    if (fullname == NULL) {
-        (*env)->ExceptionClear(env);
-        return 1;
-    }
-    fullnameLC = (*env)->CallObjectMethod(env, fullname,
-                                          fmi->toLowerCaseMID, fmi->locale);
-    (*env)->CallBooleanMethod(env, fmi->list, fmi->addMID, fullname);
-    (*env)->CallObjectMethod(env, fmi->fontToFamilyMap,
-                             fmi->putMID, fullnameLC, fmi->family);
-    return 1;
-}
 
 typedef struct CheckFamilyInfo {
   wchar_t *family;
@@ -219,6 +161,14 @@
     return info.isDifferent;
 }
 
+/* Callback for call to EnumFontFamiliesEx in the EnumFamilyNames function.
+ * Expects to be called once for each face name in the family specified
+ * in the call. We extract the full name for the font which is expected
+ * to be in the "system encoding" and create canonical and lower case
+ * Java strings for the name which are added to the maps. The lower case
+ * name is used as key to the family name value in the font to family map,
+ * the canonical name is one of the"list" of members of the family.
+ */
 static int CALLBACK EnumFontFacesInFamilyProcW(
   ENUMLOGFONTEXW *lpelfe,
   NEWTEXTMETRICEX *lpntme,
@@ -229,6 +179,19 @@
     JNIEnv *env = fmi->env;
     jstring fullname, fullnameLC;
 
+    /* Exceptions indicate critical errors such that program cannot continue
+     * with further execution. Henceforth, the function returns immediately
+     * on pending exceptions. In these situations, the function also returns
+     * 0 indicating windows API to stop further enumeration and callbacks.
+     *
+     * The JNI functions do not clear the pending exceptions. This allows the
+     * caller (Java code) to check and handle exceptions in the best possible
+     * way.
+     */
+    if ((*env)->ExceptionCheck(env)) {
+        return 0;
+    }
+
     /* Both Vista and XP return DEVICE_FONTTYPE for OTF fonts */
     if (FontType != TRUETYPE_FONTTYPE && FontType != DEVICE_FONTTYPE) {
         return 1;
@@ -250,11 +213,30 @@
         (*env)->ExceptionClear(env);
         return 1;
     }
+
+    (*env)->CallBooleanMethod(env, fmi->list, fmi->addMID, fullname);
+    if ((*env)->ExceptionCheck(env)) {
+        /* Delete the created reference before return */
+        DeleteLocalReference(env, fullname);
+        return 0;
+    }
+
     fullnameLC = (*env)->CallObjectMethod(env, fullname,
                                           fmi->toLowerCaseMID, fmi->locale);
-    (*env)->CallBooleanMethod(env, fmi->list, fmi->addMID, fullname);
+    /* Delete the created reference after its usage */
+    DeleteLocalReference(env, fullname);
+    if ((*env)->ExceptionCheck(env)) {
+        return 0;
+    }
+
     (*env)->CallObjectMethod(env, fmi->fontToFamilyMap,
                              fmi->putMID, fullnameLC, fmi->family);
+    /* Delete the created reference after its usage */
+    DeleteLocalReference(env, fullnameLC);
+    if ((*env)->ExceptionCheck(env)) {
+        return 0;
+    }
+
     return 1;
 }
 
@@ -270,62 +252,6 @@
  * Because we set fmi->list to be the newly created list the call back
  * can safely add to that list without a search.
  */
-static int CALLBACK EnumFamilyNamesA(
-  ENUMLOGFONTEXA *lpelfe,    /* pointer to logical-font data */
-  NEWTEXTMETRICEX *lpntme,   /* pointer to physical-font data */
-  int FontType,              /* type of font */
-  LPARAM lParam)             /* application-defined data */
-{
-    GdiFontMapInfo *fmi = (GdiFontMapInfo*)lParam;
-    JNIEnv *env = fmi->env;
-    jstring familyLC;
-    LOGFONTA lfa;
-
-    /* Both Vista and XP return DEVICE_FONTTYPE for OTF fonts */
-    if (FontType != TRUETYPE_FONTTYPE && FontType != DEVICE_FONTTYPE) {
-        return 1;
-    }
-
-    /* Windows lists fonts which have a vmtx (vertical metrics) table twice.
-     * Once using their normal name, and again preceded by '@'. These appear
-     * in font lists in some windows apps, such as wordpad. We don't want
-     * these so we skip any font where the first character is '@'
-     */
-    if (lpelfe->elfLogFont.lfFaceName[0] == '@') {
-        return 1;
-    }
-    fmi->family = JNU_NewStringPlatform(env,lpelfe->elfLogFont.lfFaceName);
-    if (fmi->family == NULL) {
-        (*env)->ExceptionClear(env);
-        return 1;
-    }
-    familyLC = (*env)->CallObjectMethod(env, fmi->family,
-                                        fmi->toLowerCaseMID, fmi->locale);
-    /* check if already seen this family with a different charset */
-    if ((*env)->CallBooleanMethod(env,fmi->familyToFontListMap,
-                                  fmi->containsKeyMID, familyLC)) {
-        return 1;
-    }
-    fmi->list = (*env)->NewObject(env,
-                                  fmi->arrayListClass, fmi->arrayListCtr, 4);
-    if (fmi->list == NULL) {
-        (*env)->ExceptionClear(env);
-        return 1;
-    }
-    (*env)->CallObjectMethod(env, fmi->familyToFontListMap,
-                             fmi->putMID, familyLC, fmi->list);
-
-/*  printf("FAMILY=%s\n", lpelfe->elfLogFont.lfFaceName);fflush(stdout); */
-
-    memset(&lfa, 0, sizeof(lfa));
-    strcpy(lfa.lfFaceName, lpelfe->elfLogFont.lfFaceName);
-    lfa.lfCharSet = lpelfe->elfLogFont.lfCharSet;
-    EnumFontFamiliesExA(screenDC, &lfa,
-                        (FONTENUMPROCA)EnumFontFacesInFamilyProcA,
-                        lParam, 0L);
-    return 1;
-}
-
 static int CALLBACK EnumFamilyNamesW(
   ENUMLOGFONTEXW *lpelfe,    /* pointer to logical-font data */
   NEWTEXTMETRICEX *lpntme,  /* pointer to physical-font data */
@@ -338,6 +264,19 @@
     size_t slen;
     LOGFONTW lfw;
 
+    /* Exceptions indicate critical errors such that program cannot continue
+     * with further execution. Henceforth, the function returns immediately
+     * on pending exceptions. In these situations, the function also returns
+     * 0 indicating windows API to stop further enumeration and callbacks.
+     *
+     * The JNI functions do not clear the pending exceptions. This allows the
+     * caller (Java code) to check and handle exceptions in the best possible
+     * way.
+     */
+    if ((*env)->ExceptionCheck(env)) {
+        return 0;
+    }
+
     /* Both Vista and XP return DEVICE_FONTTYPE for OTF fonts */
     if (FontType != TRUETYPE_FONTTYPE && FontType != DEVICE_FONTTYPE) {
         return 1;
@@ -362,21 +301,51 @@
         (*env)->ExceptionClear(env);
         return 1;
     }
+
     familyLC = (*env)->CallObjectMethod(env, fmi->family,
                                         fmi->toLowerCaseMID, fmi->locale);
+    /* Delete the created reference after its usage */
+    if ((*env)->ExceptionCheck(env)) {
+        DeleteLocalReference(env, fmi->family);
+        return 0;
+    }
+
     /* check if already seen this family with a different charset */
-    if ((*env)->CallBooleanMethod(env,fmi->familyToFontListMap,
-                                  fmi->containsKeyMID, familyLC)) {
+    jboolean mapHasKey = (*env)->CallBooleanMethod(env,
+                                                   fmi->familyToFontListMap,
+                                                   fmi->containsKeyMID,
+                                                   familyLC);
+    if ((*env)->ExceptionCheck(env)) {
+        /* Delete the created references before return */
+        DeleteLocalReference(env, fmi->family);
+        DeleteLocalReference(env, familyLC);
+        return 0;
+    } else if (mapHasKey) {
+        /* Delete the created references before return */
+        DeleteLocalReference(env, fmi->family);
+        DeleteLocalReference(env, familyLC);
         return 1;
     }
+
     fmi->list = (*env)->NewObject(env,
                                   fmi->arrayListClass, fmi->arrayListCtr, 4);
     if (fmi->list == NULL) {
-        (*env)->ExceptionClear(env);
-        return 1;
+        /* Delete the created references before return */
+        DeleteLocalReference(env, fmi->family);
+        DeleteLocalReference(env, familyLC);
+        return 0;
     }
+
     (*env)->CallObjectMethod(env, fmi->familyToFontListMap,
                              fmi->putMID, familyLC, fmi->list);
+    /* Delete the created reference after its usage */
+    DeleteLocalReference(env, familyLC);
+    if ((*env)->ExceptionCheck(env)) {
+        /* Delete the created reference before return */
+        DeleteLocalReference(env, fmi->family);
+        DeleteLocalReference(env, fmi->list);
+        return 0;
+    }
 
     memset(&lfw, 0, sizeof(lfw));
     wcscpy(lfw.lfFaceName, lpelfe->elfLogFont.lfFaceName);
@@ -384,10 +353,13 @@
     EnumFontFamiliesExW(screenDC, &lfw,
                         (FONTENUMPROCW)EnumFontFacesInFamilyProcW,
                         lParam, 0L);
+
+    /* Delete the created reference after its usage in the enum function */
+    DeleteLocalReference(env, fmi->family);
+    DeleteLocalReference(env, fmi->list);
     return 1;
 }
 
-
 /* It looks like TrueType fonts have " (TrueType)" tacked on the end of their
  * name, so we can try to use that to distinguish TT from other fonts.
  * However if a program "installed" a font in the registry the key may
@@ -410,33 +382,6 @@
  * Note: OpenType fonts seems to have " (TrueType)" suffix on Vista
  *   but " (OpenType)" on XP.
  */
-
-static BOOL RegistryToBaseTTNameA(LPSTR name) {
-    static const char TTSUFFIX[] = " (TrueType)";
-    static const char OTSUFFIX[] = " (OpenType)";
-    size_t TTSLEN = strlen(TTSUFFIX);
-    char *suffix;
-
-    size_t len = strlen(name);
-    if (len == 0) {
-        return FALSE;
-    }
-    if (name[len-1] != ')') {
-        return FALSE;
-    }
-    if (len <= TTSLEN) {
-        return FALSE;
-    }
-
-    /* suffix length is the same for truetype and opentype fonts */
-    suffix = name + len - TTSLEN;
-    if (strcmp(suffix, TTSUFFIX) == 0 || strcmp(suffix, OTSUFFIX) == 0) {
-        suffix[0] = '\0'; /* truncate name */
-        return TRUE;
-    }
-    return FALSE;
-}
-
 static BOOL RegistryToBaseTTNameW(LPWSTR name) {
     static const wchar_t TTSUFFIX[] = L" (TrueType)";
     static const wchar_t OTSUFFIX[] = L" (OpenType)";
@@ -462,71 +407,12 @@
     return FALSE;
 }
 
-static void registerFontA(GdiFontMapInfo *fmi, jobject fontToFileMap,
-                          LPCSTR name, LPCSTR data) {
-    LPSTR ptr1, ptr2;
-    jstring fontStr;
-    JNIEnv *env = fmi->env;
-    size_t dslen = strlen(data);
-    jstring fileStr = JNU_NewStringPlatform(env, data);
-    if (fileStr == NULL) {
-        (*env)->ExceptionClear(env);
-        return;
-    }
-
-    /* TTC or ttc means it may be a collection. Need to parse out
-     * multiple font face names separated by " & "
-     * By only doing this for fonts which look like collections based on
-     * file name we are adhering to MS recommendations for font file names
-     * so it seems that we can be sure that this identifies precisely
-     * the MS-supplied truetype collections.
-     * This avoids any potential issues if a TTF file happens to have
-     * a & in the font name (I can't find anything which prohibits this)
-     * and also means we only parse the key in cases we know to be
-     * worthwhile.
-     */
-    if ((data[dslen-1] == 'C' || data[dslen-1] == 'c') &&
-        (ptr1 = strstr(name, " & ")) != NULL) {
-        ptr1+=3;
-        while (ptr1 >= name) { /* marginally safer than while (true) */
-            while ((ptr2 = strstr(ptr1, " & ")) != NULL) {
-                    ptr1 = ptr2+3;
-            }
-            fontStr = JNU_NewStringPlatform(env, ptr1);
-            if (fontStr == NULL) {
-                (*env)->ExceptionClear(env);
-                return;
-            }
-            fontStr = (*env)->CallObjectMethod(env, fontStr,
-                                               fmi->toLowerCaseMID,
-                                               fmi->locale);
-            (*env)->CallObjectMethod(env, fontToFileMap, fmi->putMID,
-                                     fontStr, fileStr);
-            if (ptr1 == name) {
-                break;
-            } else {
-                *(ptr1-3) ='\0';
-                ptr1 = (LPSTR)name;
-            }
-        }
-    } else {
-        fontStr = JNU_NewStringPlatform(env, name);
-        if (fontStr == NULL) {
-            (*env)->ExceptionClear(env);
-            return;
-        }
-        fontStr = (*env)->CallObjectMethod(env, fontStr,
-                                           fmi->toLowerCaseMID, fmi->locale);
-        (*env)->CallObjectMethod(env, fontToFileMap, fmi->putMID,
-                                 fontStr, fileStr);
-    }
-}
-
 static void registerFontW(GdiFontMapInfo *fmi, jobject fontToFileMap,
                           LPWSTR name, LPWSTR data) {
 
     wchar_t *ptr1, *ptr2;
     jstring fontStr;
+    jstring fontStrLC;
     JNIEnv *env = fmi->env;
     size_t dslen = wcslen(data);
     jstring fileStr = (*env)->NewString(env, data, (jsize)dslen);
@@ -557,13 +443,32 @@
             fontStr = (*env)->NewString(env, ptr1, (jsize)wcslen(ptr1));
             if (fontStr == NULL) {
                 (*env)->ExceptionClear(env);
+                /* Delete the created reference before return */
+                DeleteLocalReference(env, fileStr);
                 return;
             }
-            fontStr = (*env)->CallObjectMethod(env, fontStr,
-                                               fmi->toLowerCaseMID,
-                                               fmi->locale);
+
+            fontStrLC = (*env)->CallObjectMethod(env, fontStr,
+                                                 fmi->toLowerCaseMID,
+                                                 fmi->locale);
+            /* Delete the created reference after its usage */
+            DeleteLocalReference(env, fontStr);
+            if ((*env)->ExceptionCheck(env)) {
+                /* Delete the created reference before return */
+                DeleteLocalReference(env, fileStr);
+                return;
+            }
+
             (*env)->CallObjectMethod(env, fontToFileMap, fmi->putMID,
-                                     fontStr, fileStr);
+                                     fontStrLC, fileStr);
+            /* Delete the reference after its usage */
+            DeleteLocalReference(env, fontStrLC);
+            if ((*env)->ExceptionCheck(env)) {
+                /* Delete the created reference before return */
+                DeleteLocalReference(env, fileStr);
+                return;
+            }
+
             if (ptr1 == name) {
                 break;
             } else {
@@ -575,13 +480,34 @@
         fontStr = (*env)->NewString(env, name, (jsize)wcslen(name));
         if (fontStr == NULL) {
             (*env)->ExceptionClear(env);
+            /* Delete the created reference before return */
+            DeleteLocalReference(env, fileStr);
             return;
         }
-        fontStr = (*env)->CallObjectMethod(env, fontStr,
+
+        fontStrLC = (*env)->CallObjectMethod(env, fontStr,
                                            fmi->toLowerCaseMID, fmi->locale);
+        /* Delete the created reference after its usage */
+        DeleteLocalReference(env, fontStr);
+        if ((*env)->ExceptionCheck(env)) {
+            /* Delete the created reference before return */
+            DeleteLocalReference(env, fileStr);
+            return;
+        }
+
         (*env)->CallObjectMethod(env, fontToFileMap, fmi->putMID,
-                                 fontStr, fileStr);
+                                 fontStrLC, fileStr);
+        /* Delete the created reference after its usage */
+        DeleteLocalReference(env, fontStrLC);
+        if ((*env)->ExceptionCheck(env)) {
+            /* Delete the created reference before return */
+            DeleteLocalReference(env, fileStr);
+            return;
+        }
     }
+
+    /* Delete the created reference after its usage */
+    DeleteLocalReference(env, fileStr);
 }
 
 /* Obtain all the fontname -> filename mappings.
@@ -595,7 +521,6 @@
 {
 #define MAX_BUFFER (FILENAME_MAX+1)
     const wchar_t wname[MAX_BUFFER];
-    const char cname[MAX_BUFFER];
     const char data[MAX_BUFFER];
 
     DWORD type;
@@ -604,10 +529,10 @@
     DWORD dwNameSize;
     DWORD dwDataValueSize;
     DWORD nval;
-    LPCSTR fontKeyName;
     DWORD dwNumValues, dwMaxValueNameLen, dwMaxValueDataLen;
     DWORD numValues = 0;
-    jclass classID;
+    jclass classIDHashMap;
+    jclass classIDString;
     jmethodID putMID;
     GdiFontMapInfo fmi;
 
@@ -619,11 +544,11 @@
         familyToFontListMap == NULL) {
         return;
     }
-    classID = (*env)->FindClass(env, "java/util/HashMap");
-    if (classID == NULL) {
+    classIDHashMap = (*env)->FindClass(env, "java/util/HashMap");
+    if (classIDHashMap == NULL) {
         return;
     }
-    putMID = (*env)->GetMethodID(env, classID, "put",
+    putMID = (*env)->GetMethodID(env, classIDHashMap, "put",
                  "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
     if (putMID == NULL) {
         return;
@@ -634,7 +559,8 @@
     fmi.familyToFontListMap = familyToFontListMap;
     fmi.putMID = putMID;
     fmi.locale = locale;
-    fmi.containsKeyMID = (*env)->GetMethodID(env, classID, "containsKey",
+    fmi.containsKeyMID = (*env)->GetMethodID(env, classIDHashMap,
+                                             "containsKey",
                                              "(Ljava/lang/Object;)Z");
     if (fmi.containsKeyMID == NULL) {
         return;
@@ -654,12 +580,13 @@
     if (fmi.addMID == NULL) {
         return;
     }
-    classID = (*env)->FindClass(env, "java/lang/String");
-    if (classID == NULL) {
+
+    classIDString = (*env)->FindClass(env, "java/lang/String");
+    if (classIDString == NULL) {
         return;
     }
     fmi.toLowerCaseMID =
-        (*env)->GetMethodID(env, classID, "toLowerCase",
+        (*env)->GetMethodID(env, classIDString, "toLowerCase",
                             "(Ljava/util/Locale;)Ljava/lang/String;");
     if (fmi.toLowerCaseMID == NULL) {
         return;
@@ -669,44 +596,29 @@
     if (screenDC == NULL) {
         return;
     }
+
     /* Enumerate fonts via GDI to build maps of fonts and families */
-    if (IS_NT) {
-        LOGFONTW lfw;
-        memset(&lfw, 0, sizeof(lfw));
-        lfw.lfCharSet = DEFAULT_CHARSET;  /* all charsets */
-        wcscpy(lfw.lfFaceName, L"");      /* one face per family (CHECK) */
-        EnumFontFamiliesExW(screenDC, &lfw,
-                            (FONTENUMPROCW)EnumFamilyNamesW,
-                            (LPARAM)(&fmi), 0L);
-    } else {
-        LOGFONT lfa;
-        memset(&lfa, 0, sizeof(lfa));
-        lfa.lfCharSet = DEFAULT_CHARSET; /* all charsets */
-        strcpy(lfa.lfFaceName, "");      /* one face per family */
-        ret = EnumFontFamiliesExA(screenDC, &lfa,
-                            (FONTENUMPROCA)EnumFamilyNamesA,
-                            (LPARAM)(&fmi), 0L);
-    }
+    LOGFONTW lfw;
+    memset(&lfw, 0, sizeof(lfw));
+    lfw.lfCharSet = DEFAULT_CHARSET;  /* all charsets */
+    wcscpy(lfw.lfFaceName, L"");      /* one face per family (CHECK) */
+    EnumFontFamiliesExW(screenDC, &lfw,
+                        (FONTENUMPROCW)EnumFamilyNamesW,
+                        (LPARAM)(&fmi), 0L);
 
     /* Use the windows registry to map font names to files */
-    fontKeyName = (IS_NT) ? FONTKEY_NT : FONTKEY_WIN;
     ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                       fontKeyName, 0L, KEY_READ, &hkeyFonts);
+                       FONTKEY_NT, 0L, KEY_READ, &hkeyFonts);
     if (ret != ERROR_SUCCESS) {
         ReleaseDC(NULL, screenDC);
         screenDC = NULL;
         return;
     }
 
-    if (IS_NT) {
-        ret = RegQueryInfoKeyW(hkeyFonts, NULL, NULL, NULL, NULL, NULL, NULL,
-                               &dwNumValues, &dwMaxValueNameLen,
-                               &dwMaxValueDataLen, NULL, NULL);
-    } else {
-        ret = RegQueryInfoKeyA(hkeyFonts, NULL, NULL, NULL, NULL, NULL, NULL,
-                               &dwNumValues, &dwMaxValueNameLen,
-                               &dwMaxValueDataLen, NULL, NULL);
-    }
+    ret = RegQueryInfoKeyW(hkeyFonts, NULL, NULL, NULL, NULL, NULL, NULL,
+                           &dwNumValues, &dwMaxValueNameLen,
+                           &dwMaxValueDataLen, NULL, NULL);
+
     if (ret != ERROR_SUCCESS ||
         dwMaxValueNameLen >= MAX_BUFFER ||
         dwMaxValueDataLen >= MAX_BUFFER) {
@@ -718,39 +630,30 @@
     for (nval = 0; nval < dwNumValues; nval++ ) {
         dwNameSize = MAX_BUFFER;
         dwDataValueSize = MAX_BUFFER;
-        if (IS_NT) {
-            ret = RegEnumValueW(hkeyFonts, nval, (LPWSTR)wname, &dwNameSize,
-                                NULL, &type, (LPBYTE)data, &dwDataValueSize);
-        } else {
-            ret = RegEnumValueA(hkeyFonts, nval, (LPSTR)cname, &dwNameSize,
-                                NULL, &type, (LPBYTE)data, &dwDataValueSize);
-        }
+        ret = RegEnumValueW(hkeyFonts, nval, (LPWSTR)wname, &dwNameSize,
+                            NULL, &type, (LPBYTE)data, &dwDataValueSize);
+
         if (ret != ERROR_SUCCESS) {
             break;
         }
         if (type != REG_SZ) { /* REG_SZ means a null-terminated string */
             continue;
         }
-        if (IS_NT) {
-            if (!RegistryToBaseTTNameW((LPWSTR)wname) ) {
-                /* If the filename ends with ".ttf" or ".otf" also accept it.
-                 * Not expecting to need to do this for .ttc files.
-                 * Also note this code is not mirrored in the "A" (win9x) path.
-                 */
-                LPWSTR dot = wcsrchr((LPWSTR)data, L'.');
-                if (dot == NULL || ((wcsicmp(dot, L".ttf") != 0)
-                                      && (wcsicmp(dot, L".otf") != 0))) {
-                    continue;  /* not a TT font... */
-                }
+
+        if (!RegistryToBaseTTNameW((LPWSTR)wname) ) {
+            /* If the filename ends with ".ttf" or ".otf" also accept it.
+             * Not expecting to need to do this for .ttc files.
+             * Also note this code is not mirrored in the "A" (win9x) path.
+             */
+            LPWSTR dot = wcsrchr((LPWSTR)data, L'.');
+            if (dot == NULL || ((wcsicmp(dot, L".ttf") != 0)
+                                  && (wcsicmp(dot, L".otf") != 0))) {
+                continue;  /* not a TT font... */
             }
-            registerFontW(&fmi, fontToFileMap, (LPWSTR)wname, (LPWSTR)data);
-        } else {
-            if (!RegistryToBaseTTNameA((LPSTR)cname)) {
-                continue; /* not a TT font... */
-            }
-            registerFontA(&fmi, fontToFileMap, cname, (LPCSTR)data);
         }
+        registerFontW(&fmi, fontToFileMap, (LPWSTR)wname, (LPWSTR)data);
     }
+
     RegCloseKey(hkeyFonts);
     ReleaseDC(NULL, screenDC);
     screenDC = NULL;
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapPoolManager.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapPoolManager.java	Sat Jul 30 00:11:02 2016 +0000
@@ -39,6 +39,7 @@
 
 import com.sun.jndi.ldap.pool.PoolCleaner;
 import com.sun.jndi.ldap.pool.Pool;
+import jdk.internal.misc.InnocuousThread;
 
 /**
  * Contains utilities for managing connection pools of LdapClient.
@@ -163,7 +164,17 @@
 
         if (idleTimeout > 0) {
             // Create cleaner to expire idle connections
-            new PoolCleaner(idleTimeout, pools).start();
+            PrivilegedAction<Void> pa = new PrivilegedAction<Void>() {
+                public Void run() {
+                    Thread t = InnocuousThread.newSystemThread(
+                            "LDAP PoolCleaner",
+                            new PoolCleaner(idleTimeout, pools));
+                    assert t.getContextClassLoader() == null;
+                    t.setDaemon(true);
+                    t.start();
+                    return null;
+                }};
+            AccessController.doPrivileged(pa);
         }
 
         if (debug) {
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PoolCleaner.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PoolCleaner.java	Sat Jul 30 00:11:02 2016 +0000
@@ -30,7 +30,7 @@
  *
  * @author Rosanna Lee
  */
-final public class PoolCleaner extends Thread {
+final public class PoolCleaner implements Runnable {
     final private Pool[] pools;
     final private long period;
 
@@ -42,9 +42,9 @@
         super();
         this.period = period;
         this.pools = pools.clone();
-        setDaemon(true);
     }
 
+    @Override
     public void run() {
         long threshold;
         while (true) {
--- a/src/java.rmi/share/classes/sun/rmi/transport/GC.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.rmi/share/classes/sun/rmi/transport/GC.java	Sat Jul 30 00:11:02 2016 +0000
@@ -29,6 +29,7 @@
 import java.security.PrivilegedAction;
 import java.util.SortedSet;
 import java.util.TreeSet;
+import jdk.internal.misc.InnocuousThread;
 
 
 /**
@@ -90,8 +91,9 @@
             }});
     }
 
-    private static class Daemon extends Thread {
+    private static class Daemon implements Runnable {
 
+        @Override
         public void run() {
             for (;;) {
                 long l;
@@ -129,23 +131,17 @@
             }
         }
 
-        private Daemon(ThreadGroup tg) {
-            super(tg, null, "GC Daemon", 0L, false);
-        }
-
-        /* Create a new daemon thread in the root thread group */
+        /* Create a new daemon thread */
         public static void create() {
             PrivilegedAction<Void> pa = new PrivilegedAction<Void>() {
                 public Void run() {
-                    ThreadGroup tg = Thread.currentThread().getThreadGroup();
-                    for (ThreadGroup tgn = tg;
-                         tgn != null;
-                         tg = tgn, tgn = tg.getParent());
-                    Daemon d = new Daemon(tg);
-                    d.setDaemon(true);
-                    d.setPriority(Thread.MIN_PRIORITY + 1);
-                    d.start();
-                    GC.daemon = d;
+                    Thread t = InnocuousThread.newSystemThread("RMI GC Daemon",
+                                                               new Daemon());
+                    assert t.getContextClassLoader() == null;
+                    t.setDaemon(true);
+                    t.setPriority(Thread.MIN_PRIORITY + 1);
+                    t.start();
+                    GC.daemon = t;
                     return null;
                 }};
             AccessController.doPrivileged(pa);
--- a/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/TransformService.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/TransformService.java	Sat Jul 30 00:11:02 2016 +0000
@@ -39,8 +39,6 @@
 import javax.xml.crypto.XMLCryptoContext;
 import javax.xml.crypto.dsig.spec.TransformParameterSpec;
 
-import sun.security.jca.*;
-import sun.security.jca.GetInstance.Instance;
 
 /**
  * A Service Provider Interface for transform and canonicalization algorithms.
@@ -165,18 +163,23 @@
         if (mechanismType.equals("DOM")) {
             dom = true;
         }
-        List<Service> services = GetInstance.getServices("TransformService", algorithm);
-        for (Iterator<Service> t = services.iterator(); t.hasNext(); ) {
-            Service s = t.next();
-            String value = s.getAttribute("MechanismType");
-            if ((value == null && dom) ||
-                (value != null && value.equals(mechanismType))) {
-                Instance instance = GetInstance.getInstance(s, null);
-                TransformService ts = (TransformService) instance.impl;
-                ts.algorithm = algorithm;
-                ts.mechanism = mechanismType;
-                ts.provider = instance.provider;
-                return ts;
+
+        Provider[] provs = Security.getProviders();
+        for (Provider p : provs) {
+            Service s = p.getService("TransformService", algorithm);
+            if (s != null) {
+                String value = s.getAttribute("MechanismType");
+                if ((value == null && dom) ||
+                    (value != null && value.equals(mechanismType))) {
+                    Object obj = s.newInstance(null);
+                    if (obj instanceof TransformService) {
+                        TransformService ts = (TransformService) obj;
+                        ts.algorithm = algorithm;
+                        ts.mechanism = mechanismType;
+                        ts.provider = p;
+                        return ts;
+                    }
+                }
             }
         }
         throw new NoSuchAlgorithmException
@@ -215,21 +218,24 @@
         if (mechanismType.equals("DOM")) {
             dom = true;
         }
-        Service s = GetInstance.getService
-            ("TransformService", algorithm, provider);
-        String value = s.getAttribute("MechanismType");
-        if ((value == null && dom) ||
-            (value != null && value.equals(mechanismType))) {
-            Instance instance = GetInstance.getInstance(s, null);
-            TransformService ts = (TransformService) instance.impl;
-            ts.algorithm = algorithm;
-            ts.mechanism = mechanismType;
-            ts.provider = instance.provider;
-            return ts;
+        Service s = provider.getService("TransformService", algorithm);
+        if (s != null) {
+            String value = s.getAttribute("MechanismType");
+            if ((value == null && dom) ||
+                (value != null && value.equals(mechanismType))) {
+                Object obj = s.newInstance(null);
+                if (obj instanceof TransformService) {
+                    TransformService ts = (TransformService) obj;
+                    ts.algorithm = algorithm;
+                    ts.mechanism = mechanismType;
+                    ts.provider = provider;
+                    return ts;
+                }
+            }
         }
         throw new NoSuchAlgorithmException
             (algorithm + " algorithm and " + mechanismType
-                 + " mechanism not available");
+                 + " mechanism not available from " + provider.getName());
     }
 
     /**
@@ -268,21 +274,25 @@
         if (mechanismType.equals("DOM")) {
             dom = true;
         }
-        Service s = GetInstance.getService
-            ("TransformService", algorithm, provider);
-        String value = s.getAttribute("MechanismType");
-        if ((value == null && dom) ||
-            (value != null && value.equals(mechanismType))) {
-            Instance instance = GetInstance.getInstance(s, null);
-            TransformService ts = (TransformService) instance.impl;
-            ts.algorithm = algorithm;
-            ts.mechanism = mechanismType;
-            ts.provider = instance.provider;
-            return ts;
+        Provider p = Security.getProvider(provider);
+        Service s = p.getService("TransformService", algorithm);
+        if (s != null) {
+            String value = s.getAttribute("MechanismType");
+            if ((value == null && dom) ||
+                (value != null && value.equals(mechanismType))) {
+                Object obj = s.newInstance(null);
+                if (obj instanceof TransformService) {
+                    TransformService ts = (TransformService) obj;
+                    ts.algorithm = algorithm;
+                    ts.mechanism = mechanismType;
+                    ts.provider = p;
+                    return ts;
+                }
+            }
         }
         throw new NoSuchAlgorithmException
             (algorithm + " algorithm and " + mechanismType
-                 + " mechanism not available");
+                 + " mechanism not available from " + provider);
     }
 
     private static class MechanismMapEntry implements Map.Entry<String,String> {
--- a/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/XMLSignatureFactory.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/XMLSignatureFactory.java	Sat Jul 30 00:11:02 2016 +0000
@@ -43,11 +43,10 @@
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.Provider;
+import java.security.Provider.Service;
 import java.security.Security;
 import java.util.List;
 
-import sun.security.jca.*;
-import sun.security.jca.GetInstance.Instance;
 
 /**
  * A factory for creating {@link XMLSignature} objects from scratch or
@@ -198,17 +197,26 @@
         if (mechanismType == null) {
             throw new NullPointerException("mechanismType cannot be null");
         }
-        Instance instance;
-        try {
-            instance = GetInstance.getInstance
-                ("XMLSignatureFactory", null, mechanismType);
-        } catch (NoSuchAlgorithmException nsae) {
-            throw new NoSuchMechanismException(nsae);
+        Provider[] provs = Security.getProviders();
+        for (Provider p : provs) {
+            Service s = p.getService("XMLSignatureFactory", mechanismType);
+            if (s != null) {
+                Object obj = null;
+                try {
+                    obj = s.newInstance(null);
+                } catch (NoSuchAlgorithmException nsae) {
+                    throw new NoSuchMechanismException(nsae);
+                }
+                if (obj instanceof XMLSignatureFactory) {
+                    XMLSignatureFactory factory = (XMLSignatureFactory) obj;
+                    factory.mechanismType = mechanismType;
+                    factory.provider = p;
+                    return factory;
+                }
+            }
         }
-        XMLSignatureFactory factory = (XMLSignatureFactory) instance.impl;
-        factory.mechanismType = mechanismType;
-        factory.provider = instance.provider;
-        return factory;
+        throw new NoSuchMechanismException
+            ("Mechanism " + mechanismType + " not available");
     }
 
     /**
@@ -240,17 +248,25 @@
             throw new NullPointerException("provider cannot be null");
         }
 
-        Instance instance;
-        try {
-            instance = GetInstance.getInstance
-                ("XMLSignatureFactory", null, mechanismType, provider);
-        } catch (NoSuchAlgorithmException nsae) {
-            throw new NoSuchMechanismException(nsae);
+        Service s = provider.getService("XMLSignatureFactory", mechanismType);
+        if (s != null) {
+            Object obj = null;
+            try {
+                obj = s.newInstance(null);
+            } catch (NoSuchAlgorithmException nsae) {
+                throw new NoSuchMechanismException(nsae);
+            }
+
+            if (obj instanceof XMLSignatureFactory) {
+                XMLSignatureFactory factory = (XMLSignatureFactory) obj;
+                factory.mechanismType = mechanismType;
+                factory.provider = provider;
+                return factory;
+            }
         }
-        XMLSignatureFactory factory = (XMLSignatureFactory) instance.impl;
-        factory.mechanismType = mechanismType;
-        factory.provider = instance.provider;
-        return factory;
+        throw new NoSuchMechanismException
+            ("Mechanism " + mechanismType + " not available from " +
+             provider.getName());
     }
 
     /**
@@ -288,17 +304,24 @@
             throw new NoSuchProviderException();
         }
 
-        Instance instance;
-        try {
-            instance = GetInstance.getInstance
-                ("XMLSignatureFactory", null, mechanismType, provider);
-        } catch (NoSuchAlgorithmException nsae) {
-            throw new NoSuchMechanismException(nsae);
+        Provider p = Security.getProvider(provider);
+        Service s = p.getService("XMLSignatureFactory", mechanismType);
+        if (s != null) {
+            Object obj = null;
+            try {
+                obj = s.newInstance(null);
+            } catch (NoSuchAlgorithmException nsae) {
+                throw new NoSuchMechanismException(nsae);
+            }
+            if (obj instanceof XMLSignatureFactory) {
+                XMLSignatureFactory factory = (XMLSignatureFactory) obj;
+                factory.mechanismType = mechanismType;
+                factory.provider = p;
+                return factory;
+            }
         }
-        XMLSignatureFactory factory = (XMLSignatureFactory) instance.impl;
-        factory.mechanismType = mechanismType;
-        factory.provider = instance.provider;
-        return factory;
+        throw new NoSuchMechanismException
+            ("Mechanism " + mechanismType + " not available from " + provider);
     }
 
     /**
--- a/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/keyinfo/KeyInfoFactory.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/keyinfo/KeyInfoFactory.java	Sat Jul 30 00:11:02 2016 +0000
@@ -32,6 +32,7 @@
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.Provider;
+import java.security.Provider.Service;
 import java.security.PublicKey;
 import java.security.Security;
 import java.security.cert.X509CRL;
@@ -43,8 +44,6 @@
 import javax.xml.crypto.dom.DOMStructure;
 import javax.xml.crypto.dsig.*;
 
-import sun.security.jca.*;
-import sun.security.jca.GetInstance.Instance;
 
 /**
  * A factory for creating {@link KeyInfo} objects from scratch or for
@@ -153,17 +152,26 @@
         if (mechanismType == null) {
             throw new NullPointerException("mechanismType cannot be null");
         }
-        Instance instance;
-        try {
-            instance = GetInstance.getInstance
-                ("KeyInfoFactory", null, mechanismType);
-        } catch (NoSuchAlgorithmException nsae) {
-            throw new NoSuchMechanismException(nsae);
+        Provider[] provs = Security.getProviders();
+        for (Provider p : provs) {
+            Service s = p.getService("KeyInfoFactory", mechanismType);
+            if (s != null) {
+                Object obj = null;
+                try {
+                    obj = s.newInstance(null);
+                } catch (NoSuchAlgorithmException nsae) {
+                    throw new NoSuchMechanismException(nsae);
+                }
+                if (obj instanceof KeyInfoFactory) {
+                    KeyInfoFactory factory = (KeyInfoFactory) obj;
+                    factory.mechanismType = mechanismType;
+                    factory.provider = p;
+                    return factory;
+                }
+            }
         }
-        KeyInfoFactory factory = (KeyInfoFactory) instance.impl;
-        factory.mechanismType = mechanismType;
-        factory.provider = instance.provider;
-        return factory;
+        throw new NoSuchMechanismException
+            ("Mechanism " + mechanismType + " not available");
     }
 
     /**
@@ -195,17 +203,24 @@
             throw new NullPointerException("provider cannot be null");
         }
 
-        Instance instance;
-        try {
-            instance = GetInstance.getInstance
-                ("KeyInfoFactory", null, mechanismType, provider);
-        } catch (NoSuchAlgorithmException nsae) {
-            throw new NoSuchMechanismException(nsae);
+        Service s = provider.getService("KeyInfoFactory", mechanismType);
+        if (s != null) {
+            Object obj = null;
+            try {
+                obj = s.newInstance(null);
+            } catch (NoSuchAlgorithmException nsae) {
+                throw new NoSuchMechanismException(nsae);
+            }
+
+            if (obj instanceof KeyInfoFactory) {
+                KeyInfoFactory factory = (KeyInfoFactory) obj;
+                factory.mechanismType = mechanismType;
+                factory.provider = provider;
+                return factory;
+            }
         }
-        KeyInfoFactory factory = (KeyInfoFactory) instance.impl;
-        factory.mechanismType = mechanismType;
-        factory.provider = instance.provider;
-        return factory;
+        throw new NoSuchMechanismException
+            ("Mechanism " + mechanismType + " not available from " + provider.getName());
     }
 
     /**
@@ -242,18 +257,24 @@
         } else if (provider.length() == 0) {
             throw new NoSuchProviderException();
         }
-
-        Instance instance;
-        try {
-            instance = GetInstance.getInstance
-                ("KeyInfoFactory", null, mechanismType, provider);
-        } catch (NoSuchAlgorithmException nsae) {
-            throw new NoSuchMechanismException(nsae);
+        Provider p = Security.getProvider(provider);
+        Service s = p.getService("KeyInfoFactory", mechanismType);
+        if (s != null) {
+            Object obj = null;
+            try {
+                obj = s.newInstance(null);
+            } catch (NoSuchAlgorithmException nsae) {
+                throw new NoSuchMechanismException(nsae);
+            }
+            if (obj instanceof KeyInfoFactory) {
+                KeyInfoFactory factory = (KeyInfoFactory) obj;
+                factory.mechanismType = mechanismType;
+                factory.provider = p;
+                return factory;
+            }
         }
-        KeyInfoFactory factory = (KeyInfoFactory) instance.impl;
-        factory.mechanismType = mechanismType;
-        factory.provider = instance.provider;
-        return factory;
+        throw new NoSuchMechanismException
+            ("Mechanism " + mechanismType + " not available from " + provider);
     }
 
     /**
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java	Sat Jul 30 00:11:02 2016 +0000
@@ -58,8 +58,8 @@
 import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
 import jdk.tools.jlink.internal.plugins.FileCopierPlugin.SymImageFile;
 import jdk.tools.jlink.internal.ExecutableImage;
-import jdk.tools.jlink.plugin.ModulePool;
-import jdk.tools.jlink.plugin.ModuleEntry;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 import jdk.tools.jlink.plugin.PluginException;
 
 /**
@@ -170,10 +170,10 @@
     }
 
     @Override
-    public void storeFiles(ModulePool files) {
+    public void storeFiles(ResourcePool files) {
         try {
             files.entries().forEach(f -> {
-                if (!f.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
+                if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
                     try {
                         accept(f);
                     } catch (IOException ioExp) {
@@ -181,17 +181,17 @@
                     }
                 }
             });
-            files.modules().forEach(m -> {
+            files.moduleView().modules().forEach(m -> {
                 // Only add modules that contain packages
-                if (!m.getAllPackages().isEmpty()) {
+                if (!m.packages().isEmpty()) {
                     // Skip the fake module used by FileCopierPlugin when copying files.
-                    if (m.getName().equals(FileCopierPlugin.FAKE_MODULE)) {
+                    if (m.name().equals(FileCopierPlugin.FAKE_MODULE)) {
                         return;
                     }
-                    modules.add(m.getName());
+                    modules.add(m.name());
                 }
             });
-            storeFiles(modules, files.getReleaseProperties());
+            storeFiles(modules, files.releaseProperties());
 
             if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
                 // launchers in the bin directory need execute permission
@@ -226,16 +226,16 @@
      * @param modules The set of modules that the runtime image contains.
      * @throws IOException
      */
-    protected void prepareApplicationFiles(ModulePool imageContent, Set<String> modules) throws IOException {
+    protected void prepareApplicationFiles(ResourcePool imageContent, Set<String> modules) throws IOException {
         // generate launch scripts for the modules with a main class
         for (String module : modules) {
             String path = "/" + module + "/module-info.class";
-            Optional<ModuleEntry> res = imageContent.findEntry(path);
+            Optional<ResourcePoolEntry> res = imageContent.findEntry(path);
             if (!res.isPresent()) {
                 throw new IOException("module-info.class not found for " + module + " module");
             }
             Optional<String> mainClass;
-            ByteArrayInputStream stream = new ByteArrayInputStream(res.get().getBytes());
+            ByteArrayInputStream stream = new ByteArrayInputStream(res.get().contentBytes());
             mainClass = ModuleDescriptor.read(stream).mainClass();
             if (mainClass.isPresent()) {
                 Path cmd = root.resolve("bin").resolve(module);
@@ -298,14 +298,14 @@
         }
     }
 
-    private void accept(ModuleEntry file) throws IOException {
-        String fullPath = file.getPath();
-        String module = "/" + file.getModule() + "/";
+    private void accept(ResourcePoolEntry file) throws IOException {
+        String fullPath = file.path();
+        String module = "/" + file.moduleName() + "/";
         String filename = fullPath.substring(module.length());
         // Remove radical native|config|...
         filename = filename.substring(filename.indexOf('/') + 1);
-        try (InputStream in = file.stream()) {
-            switch (file.getType()) {
+        try (InputStream in = file.content()) {
+            switch (file.type()) {
                 case NATIVE_LIB:
                     writeEntry(in, destFile(nativeDir(filename), filename));
                     break;
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java	Sat Jul 30 00:11:02 2016 +0000
@@ -29,7 +29,7 @@
 
 import jdk.tools.jlink.internal.ExecutableImage;
 import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
 
 /**
  * Implement this interface to develop your own image layout. First the jimage
@@ -45,7 +45,7 @@
      * @param release the release properties
      * @throws PluginException
      */
-    public default void storeFiles(ModulePool content, Properties release) {
+    public default void storeFiles(ResourcePool content, Properties release) {
         storeFiles(content);
     }
 
@@ -55,7 +55,7 @@
      * @param content Pool of module content.
      * @throws PluginException
      */
-    public default void storeFiles(ModulePool content) {
+    public default void storeFiles(ResourcePool content) {
         throw new UnsupportedOperationException("storeFiles");
     }
 
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/AbstractModuleEntry.java	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.tools.jlink.internal;
-
-import java.util.Objects;
-import jdk.tools.jlink.plugin.ModuleEntry;
-
-/**
- * A LinkModuleEntry is the elementary unit of data inside an image. It is
- * generally a file. e.g.: a java class file, a resource file, a shared library,
- * ...
- * <br>
- * A LinkModuleEntry is identified by a path of the form:
- * <ul>
- * <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
- * name}</li>
- * <li>For other files (shared lib, launchers, config, ...):/{module name}/
- * {@literal bin|conf|native}/{dir1}>/.../{dirN}/{file name}</li>
- * </ul>
- */
-abstract class AbstractModuleEntry implements ModuleEntry {
-    private final String path;
-    private final String module;
-    private final Type type;
-
-    /**
-     * Create a new AbstractModuleEntry.
-     *
-     * @param module The module name.
-     * @param path The data path identifier.
-     * @param type The data type.
-     */
-    AbstractModuleEntry(String module, String path, Type type) {
-        this.module = Objects.requireNonNull(module);
-        this.path = Objects.requireNonNull(path);
-        this.type = Objects.requireNonNull(type);
-    }
-
-    @Override
-    public final String getModule() {
-        return module;
-    }
-
-    @Override
-    public final String getPath() {
-        return path;
-    }
-
-    @Override
-    public final Type getType() {
-        return type;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(this.path);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (!(other instanceof AbstractModuleEntry)) {
-            return false;
-        }
-        AbstractModuleEntry f = (AbstractModuleEntry) other;
-        return f.path.equals(path);
-    }
-
-    @Override
-    public String toString() {
-        return getPath();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/AbstractResourcePoolEntry.java	Sat Jul 30 00:11:02 2016 +0000
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.tools.jlink.internal;
+
+import java.util.Objects;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
+
+/**
+ * A LinkResourcePoolEntry is the elementary unit of data inside an image. It is
+ * generally a file. e.g.: a java class file, a resource file, a shared library,
+ * ...
+ * <br>
+ * A LinkResourcePoolEntry is identified by a path of the form:
+ * <ul>
+ * <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
+ * name}</li>
+ * <li>For other files (shared lib, launchers, config, ...):/{module name}/
+ * {@literal bin|conf|native}/{dir1}>/.../{dirN}/{file name}</li>
+ * </ul>
+ */
+abstract class AbstractResourcePoolEntry implements ResourcePoolEntry {
+    private final String path;
+    private final String module;
+    private final Type type;
+
+    /**
+     * Create a new AbstractResourcePoolEntry.
+     *
+     * @param module The module name.
+     * @param path The data path identifier.
+     * @param type The data type.
+     */
+    AbstractResourcePoolEntry(String module, String path, Type type) {
+        this.module = Objects.requireNonNull(module);
+        this.path = Objects.requireNonNull(path);
+        this.type = Objects.requireNonNull(type);
+    }
+
+    @Override
+    public final String moduleName() {
+        return module;
+    }
+
+    @Override
+    public final String path() {
+        return path;
+    }
+
+    @Override
+    public final Type type() {
+        return type;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(this.path);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (!(other instanceof AbstractResourcePoolEntry)) {
+            return false;
+        }
+        AbstractResourcePoolEntry f = (AbstractResourcePoolEntry) other;
+        return f.path.equals(path);
+    }
+
+    @Override
+    public String toString() {
+        return path();
+    }
+}
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ArchiveEntryModuleEntry.java	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.tools.jlink.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UncheckedIOException;
-import java.util.Objects;
-import jdk.tools.jlink.plugin.ModuleEntry;
-
-/**
- * A ModuleEntry backed by a given Archive Entry.
- */
-final class ArchiveEntryModuleEntry extends AbstractModuleEntry {
-    private final Archive.Entry entry;
-
-    /**
-     * Create a new ArchiveModuleEntry.
-     *
-     * @param module The module name.
-     * @param path The data path identifier.
-     * @param entry The archive Entry.
-     */
-    ArchiveEntryModuleEntry(String module, String path, Archive.Entry entry) {
-        super(module, path, getImageFileType(Objects.requireNonNull(entry)));
-        this.entry = entry;
-    }
-
-    @Override
-    public InputStream stream() {
-        try {
-            return entry.stream();
-        } catch (IOException ex) {
-            throw new UncheckedIOException(ex);
-        }
-    }
-
-    @Override
-    public long getLength() {
-        return entry.size();
-    }
-
-    private static ModuleEntry.Type getImageFileType(Archive.Entry entry) {
-        switch(entry.type()) {
-            case CLASS_OR_RESOURCE:
-                return ModuleEntry.Type.CLASS_OR_RESOURCE;
-            case CONFIG:
-                return ModuleEntry.Type.CONFIG;
-            case NATIVE_CMD:
-                return ModuleEntry.Type.NATIVE_CMD;
-            case NATIVE_LIB:
-                return ModuleEntry.Type.NATIVE_LIB;
-            default:
-                return ModuleEntry.Type.OTHER;
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ArchiveEntryResourcePoolEntry.java	Sat Jul 30 00:11:02 2016 +0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.tools.jlink.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UncheckedIOException;
+import java.util.Objects;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
+
+/**
+ * A ResourcePoolEntry backed by a given Archive Entry.
+ */
+final class ArchiveEntryResourcePoolEntry extends AbstractResourcePoolEntry {
+    private final Archive.Entry entry;
+
+    /**
+     * Create a new ArchiveResourcePoolEntry.
+     *
+     * @param module The module name.
+     * @param path The data path identifier.
+     * @param entry The archive Entry.
+     */
+    ArchiveEntryResourcePoolEntry(String module, String path, Archive.Entry entry) {
+        super(module, path, getImageFileType(Objects.requireNonNull(entry)));
+        this.entry = entry;
+    }
+
+    @Override
+    public InputStream content() {
+        try {
+            return entry.stream();
+        } catch (IOException ex) {
+            throw new UncheckedIOException(ex);
+        }
+    }
+
+    @Override
+    public long contentLength() {
+        return entry.size();
+    }
+
+    private static ResourcePoolEntry.Type getImageFileType(Archive.Entry entry) {
+        switch(entry.type()) {
+            case CLASS_OR_RESOURCE:
+                return ResourcePoolEntry.Type.CLASS_OR_RESOURCE;
+            case CONFIG:
+                return ResourcePoolEntry.Type.CONFIG;
+            case NATIVE_CMD:
+                return ResourcePoolEntry.Type.NATIVE_CMD;
+            case NATIVE_LIB:
+                return ResourcePoolEntry.Type.NATIVE_LIB;
+            default:
+                return ResourcePoolEntry.Type.OTHER;
+        }
+    }
+}
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ByteArrayModuleEntry.java	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.tools.jlink.internal;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UncheckedIOException;
-import java.util.Objects;
-
-/**
- * A ModuleEntry backed by a given byte[].
- */
-class ByteArrayModuleEntry extends AbstractModuleEntry {
-    private final byte[] buffer;
-
-    /**
-     * Create a new ByteArrayModuleEntry.
-     *
-     * @param module The module name.
-     * @param path The data path identifier.
-     * @param type The data type.
-     * @param buf  The byte buffer.
-     */
-    ByteArrayModuleEntry(String module, String path, Type type, byte[] buffer) {
-        super(module, path, type);
-        this.buffer = Objects.requireNonNull(buffer);
-    }
-
-    @Override
-    public byte[] getBytes() {
-        return buffer.clone();
-    }
-
-    @Override
-    public InputStream stream() {
-        return new ByteArrayInputStream(buffer);
-    }
-
-    @Override
-    public void write(OutputStream out) {
-        try {
-            out.write(buffer);
-        } catch (IOException ex) {
-            throw new UncheckedIOException(ex);
-        }
-    }
-
-    @Override
-    public long getLength() {
-        return buffer.length;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ByteArrayResourcePoolEntry.java	Sat Jul 30 00:11:02 2016 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.tools.jlink.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.util.Objects;
+
+/**
+ * A ResourcePoolEntry backed by a given byte[].
+ */
+class ByteArrayResourcePoolEntry extends AbstractResourcePoolEntry {
+    private final byte[] buffer;
+
+    /**
+     * Create a new ByteArrayResourcePoolEntry.
+     *
+     * @param module The module name.
+     * @param path The data path identifier.
+     * @param type The data type.
+     * @param buf  The byte buffer.
+     */
+    ByteArrayResourcePoolEntry(String module, String path, Type type, byte[] buffer) {
+        super(module, path, type);
+        this.buffer = Objects.requireNonNull(buffer);
+    }
+
+    @Override
+    public byte[] contentBytes() {
+        return buffer.clone();
+    }
+
+    @Override
+    public InputStream content() {
+        return new ByteArrayInputStream(buffer);
+    }
+
+    @Override
+    public void write(OutputStream out) {
+        try {
+            out.write(buffer);
+        } catch (IOException ex) {
+            throw new UncheckedIOException(ex);
+        }
+    }
+
+    @Override
+    public long contentLength() {
+        return buffer.length;
+    }
+}
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java	Sat Jul 30 00:11:02 2016 +0000
@@ -42,9 +42,10 @@
 import java.util.stream.Stream;
 import jdk.tools.jlink.internal.Archive.Entry;
 import jdk.tools.jlink.internal.Archive.Entry.EntryType;
-import jdk.tools.jlink.internal.ModulePoolImpl.CompressedModuleData;
+import jdk.tools.jlink.internal.ResourcePoolManager.CompressedModuleData;
 import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.plugin.ModuleEntry;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 
 /**
  * An image (native endian.)
@@ -140,7 +141,7 @@
                                     }));
             ByteOrder order = ByteOrder.nativeOrder();
             BasicImageWriter writer = new BasicImageWriter(order);
-            ModulePoolImpl pool = createPools(archives, entriesForModule, order, writer);
+            ResourcePoolManager pool = createPoolManager(archives, entriesForModule, order, writer);
             try (OutputStream fos = Files.newOutputStream(jimageFile);
                     BufferedOutputStream bos = new BufferedOutputStream(fos);
                     DataOutputStream out = new DataOutputStream(bos)) {
@@ -158,52 +159,61 @@
             ByteOrder byteOrder)
             throws IOException {
         BasicImageWriter writer = new BasicImageWriter(byteOrder);
-        ModulePoolImpl allContent = createPools(archives,
+        ResourcePoolManager allContent = createPoolManager(archives,
                 entriesForModule, byteOrder, writer);
-        ModulePoolImpl result = generateJImage(allContent,
+        ResourcePool result = generateJImage(allContent,
              writer, plugins, plugins.getJImageFileOutputStream());
 
         //Handle files.
         try {
-            plugins.storeFiles(allContent, result, writer);
+            plugins.storeFiles(allContent.resourcePool(), result, writer);
         } catch (Exception ex) {
+            if (JlinkTask.DEBUG) {
+                ex.printStackTrace();
+            }
             throw new IOException(ex);
         }
     }
 
-    private static ModulePoolImpl generateJImage(ModulePoolImpl allContent,
+    private static ResourcePool generateJImage(ResourcePoolManager allContent,
             BasicImageWriter writer,
             ImagePluginStack pluginSupport,
             DataOutputStream out
     ) throws IOException {
-        ModulePoolImpl resultResources;
+        ResourcePool resultResources;
         try {
             resultResources = pluginSupport.visitResources(allContent);
         } catch (PluginException pe) {
+            if (JlinkTask.DEBUG) {
+                pe.printStackTrace();
+            }
             throw pe;
         } catch (Exception ex) {
+            if (JlinkTask.DEBUG) {
+                ex.printStackTrace();
+            }
             throw new IOException(ex);
         }
         Set<String> duplicates = new HashSet<>();
         long[] offset = new long[1];
 
-        List<ModuleEntry> content = new ArrayList<>();
+        List<ResourcePoolEntry> content = new ArrayList<>();
         List<String> paths = new ArrayList<>();
                  // the order of traversing the resources and the order of
         // the module content being written must be the same
         resultResources.entries().forEach(res -> {
-            if (res.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
-                String path = res.getPath();
+            if (res.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
+                String path = res.path();
                 content.add(res);
-                long uncompressedSize = res.getLength();
+                long uncompressedSize = res.contentLength();
                 long compressedSize = 0;
                 if (res instanceof CompressedModuleData) {
                     CompressedModuleData comp
                             = (CompressedModuleData) res;
-                    compressedSize = res.getLength();
+                    compressedSize = res.contentLength();
                     uncompressedSize = comp.getUncompressedSize();
                 }
-                long onFileSize = res.getLength();
+                long onFileSize = res.contentLength();
 
                 if (duplicates.contains(path)) {
                     System.err.format("duplicate resource \"%s\", skipping%n",
@@ -239,11 +249,11 @@
         return resultResources;
     }
 
-    private static ModulePoolImpl createPools(Set<Archive> archives,
+    private static ResourcePoolManager createPoolManager(Set<Archive> archives,
             Map<String, List<Entry>> entriesForModule,
             ByteOrder byteOrder,
             BasicImageWriter writer) throws IOException {
-        ModulePoolImpl resources = new ModulePoolImpl(byteOrder, new StringTable() {
+        ResourcePoolManager resources = new ResourcePoolManager(byteOrder, new StringTable() {
 
             @Override
             public int addString(String str) {
@@ -273,7 +283,7 @@
                     path = "/" + mn + "/" + entry.path();
                 }
 
-                resources.add(new ArchiveEntryModuleEntry(mn, path, entry));
+                resources.add(new ArchiveEntryResourcePoolEntry(mn, path, entry));
             }
         }
         return resources;
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java	Sat Jul 30 00:11:02 2016 +0000
@@ -37,7 +37,7 @@
 import jdk.tools.jlink.plugin.Plugin;
 import jdk.tools.jlink.plugin.PluginException;
 import jdk.tools.jlink.plugin.Plugin.Category;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
 
 /**
  * Plugins configuration.
@@ -122,7 +122,7 @@
                 }
 
                 @Override
-                public void storeFiles(ModulePool files) {
+                public void storeFiles(ResourcePool files) {
                     throw new PluginException("No directory setup to store files");
                 }
             };
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java	Sat Jul 30 00:11:02 2016 +0000
@@ -46,9 +46,10 @@
 import jdk.tools.jlink.plugin.Plugin;
 import jdk.tools.jlink.builder.ImageBuilder;
 import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.plugin.ModulePool;
-import jdk.tools.jlink.plugin.LinkModule;
-import jdk.tools.jlink.plugin.ModuleEntry;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolModule;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
+import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
 
 /**
  * Plugins Stack. Plugins entry point to apply transformations onto resources
@@ -61,36 +62,47 @@
         ExecutableImage retrieve(ImagePluginStack stack) throws IOException;
     }
 
-    public static final class OrderedResourcePool extends ModulePoolImpl {
+    public static final class OrderedResourcePoolManager extends ResourcePoolManager {
+        class OrderedResourcePool extends ResourcePoolImpl {
+            List<ResourcePoolEntry> getOrderedList() {
+                return OrderedResourcePoolManager.this.getOrderedList();
+            }
+        }
 
-        private final List<ModuleEntry> orderedList = new ArrayList<>();
+        private final List<ResourcePoolEntry> orderedList = new ArrayList<>();
+        private final ResourcePoolImpl poolImpl = new OrderedResourcePool();
 
-        public OrderedResourcePool(ByteOrder order, StringTable table) {
+        public OrderedResourcePoolManager(ByteOrder order, StringTable table) {
             super(order, table);
         }
 
+        @Override
+        public ResourcePool resourcePool() {
+            return poolImpl;
+        }
+
         /**
          * Add a resource.
          *
          * @param resource The Resource to add.
          */
         @Override
-        public void add(ModuleEntry resource) {
+        public void add(ResourcePoolEntry resource) {
             super.add(resource);
             orderedList.add(resource);
         }
 
-        List<ModuleEntry> getOrderedList() {
+        List<ResourcePoolEntry> getOrderedList() {
             return Collections.unmodifiableList(orderedList);
         }
     }
 
-    private final static class CheckOrderResourcePool extends ModulePoolImpl {
+    private final static class CheckOrderResourcePoolManager extends ResourcePoolManager {
 
-        private final List<ModuleEntry> orderedList;
+        private final List<ResourcePoolEntry> orderedList;
         private int currentIndex;
 
-        public CheckOrderResourcePool(ByteOrder order, List<ModuleEntry> orderedList, StringTable table) {
+        public CheckOrderResourcePoolManager(ByteOrder order, List<ResourcePoolEntry> orderedList, StringTable table) {
             super(order, table);
             this.orderedList = Objects.requireNonNull(orderedList);
         }
@@ -101,10 +113,10 @@
          * @param resource The Resource to add.
          */
         @Override
-        public void add(ModuleEntry resource) {
-            ModuleEntry ordered = orderedList.get(currentIndex);
+        public void add(ResourcePoolEntry resource) {
+            ResourcePoolEntry ordered = orderedList.get(currentIndex);
             if (!resource.equals(ordered)) {
-                throw new PluginException("Resource " + resource.getPath() + " not in the right order");
+                throw new PluginException("Resource " + resource.path() + " not in the right order");
             }
             super.add(resource);
             currentIndex += 1;
@@ -209,17 +221,16 @@
      * @return The result of the visit.
      * @throws IOException
      */
-    public ModulePoolImpl visitResources(ModulePoolImpl resources)
+    public ResourcePool visitResources(ResourcePoolManager resources)
             throws Exception {
         Objects.requireNonNull(resources);
-        resources.setReadOnly();
         if (resources.isEmpty()) {
-            return new ModulePoolImpl(resources.getByteOrder(),
-                    resources.getStringTable());
+            return new ResourcePoolManager(resources.byteOrder(),
+                    resources.getStringTable()).resourcePool();
         }
         PreVisitStrings previsit = new PreVisitStrings();
         resourcePrevisitors.stream().forEach((p) -> {
-            p.previsit(resources, previsit);
+            p.previsit(resources.resourcePool(), previsit);
         });
 
         // Store the strings resulting from the previsit.
@@ -228,89 +239,80 @@
             resources.getStringTable().addString(s);
         });
 
-        ModulePoolImpl current = resources;
-        List<ModuleEntry> frozenOrder = null;
+        ResourcePool resPool = resources.resourcePool();
+        List<ResourcePoolEntry> frozenOrder = null;
         for (Plugin p : plugins) {
-            current.setReadOnly();
-            ModulePoolImpl output = null;
+            ResourcePoolManager resMgr = null;
             if (p == lastSorter) {
                 if (frozenOrder != null) {
                     throw new Exception("Order of resources is already frozen. Plugin "
                             + p.getName() + " is badly located");
                 }
                 // Create a special Resource pool to compute the indexes.
-                output = new OrderedResourcePool(current.getByteOrder(),
+                resMgr = new OrderedResourcePoolManager(resPool.byteOrder(),
                         resources.getStringTable());
             } else {// If we have an order, inject it
                 if (frozenOrder != null) {
-                    output = new CheckOrderResourcePool(current.getByteOrder(),
+                    resMgr = new CheckOrderResourcePoolManager(resPool.byteOrder(),
                             frozenOrder, resources.getStringTable());
                 } else {
-                    output = new ModulePoolImpl(current.getByteOrder(),
+                    resMgr = new ResourcePoolManager(resPool.byteOrder(),
                             resources.getStringTable());
                 }
             }
-            p.visit(current, output);
-            if (output.isEmpty()) {
+            resPool = p.transform(resPool, resMgr.resourcePoolBuilder());
+            if (resPool.isEmpty()) {
                 throw new Exception("Invalid resource pool for plugin " + p);
             }
-            if (output instanceof OrderedResourcePool) {
-                frozenOrder = ((OrderedResourcePool) output).getOrderedList();
+            if (resPool instanceof OrderedResourcePoolManager.OrderedResourcePool) {
+                frozenOrder = ((OrderedResourcePoolManager.OrderedResourcePool)resPool).getOrderedList();
             }
-
-            current = output;
         }
-        current.setReadOnly();
-        return current;
+        return resPool;
     }
 
     /**
-     * This pool wrap the original pool and automatically uncompress ModuleEntry
+     * This pool wrap the original pool and automatically uncompress ResourcePoolEntry
      * if needed.
      */
-    private class LastPool implements ModulePool {
-        private class LastModule implements LinkModule {
+    private class LastPoolManager extends ResourcePoolManager {
+        private class LastModule implements ResourcePoolModule {
 
-            final LinkModule module;
+            final ResourcePoolModule module;
 
-            LastModule(LinkModule module) {
+            LastModule(ResourcePoolModule module) {
                 this.module = module;
             }
 
             @Override
-            public String getName() {
-                return module.getName();
+            public String name() {
+                return module.name();
             }
 
             @Override
-            public Optional<ModuleEntry> findEntry(String path) {
-                Optional<ModuleEntry> d = module.findEntry(path);
+            public Optional<ResourcePoolEntry> findEntry(String path) {
+                Optional<ResourcePoolEntry> d = module.findEntry(path);
                 return d.isPresent()? Optional.of(getUncompressed(d.get())) : Optional.empty();
             }
 
             @Override
-            public ModuleDescriptor getDescriptor() {
-                return module.getDescriptor();
+            public ModuleDescriptor descriptor() {
+                return module.descriptor();
             }
 
             @Override
-            public void add(ModuleEntry data) {
-                throw new PluginException("pool is readonly");
-            }
-
-            @Override
-            public Set<String> getAllPackages() {
-                return module.getAllPackages();
+            public Set<String> packages() {
+                return module.packages();
             }
 
             @Override
             public String toString() {
-                return getName();
+                return name();
             }
 
             @Override
-            public Stream<ModuleEntry> entries() {
-                List<ModuleEntry> lst = new ArrayList<>();
+            public Stream<ResourcePoolEntry> entries() {
+                List<ResourcePoolEntry> lst = new ArrayList<>();
                 module.entries().forEach(md -> {
                     lst.add(getUncompressed(md));
                 });
@@ -318,31 +320,27 @@
             }
 
             @Override
-            public int getEntryCount() {
-                return module.getEntryCount();
+            public int entryCount() {
+                return module.entryCount();
             }
         }
-        private final ModulePoolImpl pool;
+
+        private final ResourcePool pool;
         Decompressor decompressor = new Decompressor();
-        Collection<ModuleEntry> content;
+        Collection<ResourcePoolEntry> content;
 
-        LastPool(ModulePoolImpl pool) {
+        LastPoolManager(ResourcePool pool) {
             this.pool = pool;
         }
 
         @Override
-        public boolean isReadOnly() {
-            return true;
-        }
-
-        @Override
-        public void add(ModuleEntry resource) {
+        public void add(ResourcePoolEntry resource) {
             throw new PluginException("pool is readonly");
         }
 
         @Override
-        public Optional<LinkModule> findModule(String name) {
-            Optional<LinkModule> module = pool.findModule(name);
+        public Optional<ResourcePoolModule> findModule(String name) {
+            Optional<ResourcePoolModule> module = pool.moduleView().findModule(name);
             return module.isPresent()? Optional.of(new LastModule(module.get())) : Optional.empty();
         }
 
@@ -352,17 +350,17 @@
          * @return The collection of modules.
          */
         @Override
-        public Stream<? extends LinkModule> modules() {
-            List<LinkModule> modules = new ArrayList<>();
-            pool.modules().forEach(m -> {
+        public Stream<ResourcePoolModule> modules() {
+            List<ResourcePoolModule> modules = new ArrayList<>();
+            pool.moduleView().modules().forEach(m -> {
                 modules.add(new LastModule(m));
             });
             return modules.stream();
         }
 
         @Override
-        public int getModuleCount() {
-            return pool.getModuleCount();
+        public int moduleCount() {
+            return pool.moduleView().moduleCount();
         }
 
         /**
@@ -371,7 +369,7 @@
          * @return The stream of resources;
          */
         @Override
-        public Stream<? extends ModuleEntry> entries() {
+        public Stream<ResourcePoolEntry> entries() {
             if (content == null) {
                 content = new ArrayList<>();
                 pool.entries().forEach(md -> {
@@ -382,8 +380,8 @@
         }
 
         @Override
-        public int getEntryCount() {
-            return pool.getEntryCount();
+        public int entryCount() {
+            return pool.entryCount();
         }
 
         /**
@@ -393,22 +391,22 @@
          * @return A Resource instance if the resource is found
          */
         @Override
-        public Optional<ModuleEntry> findEntry(String path) {
+        public Optional<ResourcePoolEntry> findEntry(String path) {
             Objects.requireNonNull(path);
-            Optional<ModuleEntry> res = pool.findEntry(path);
+            Optional<ResourcePoolEntry> res = pool.findEntry(path);
             return res.isPresent()? Optional.of(getUncompressed(res.get())) : Optional.empty();
         }
 
         @Override
-        public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context) {
+        public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context) {
             Objects.requireNonNull(path);
             Objects.requireNonNull(context);
-            Optional<ModuleEntry> res = pool.findEntryInContext(path, context);
+            Optional<ResourcePoolEntry> res = pool.findEntryInContext(path, context);
             return res.map(this::getUncompressed);
         }
 
         @Override
-        public boolean contains(ModuleEntry res) {
+        public boolean contains(ResourcePoolEntry res) {
             return pool.contains(res);
         }
 
@@ -418,29 +416,27 @@
         }
 
         @Override
-        public void transformAndCopy(Function<ModuleEntry, ModuleEntry> visitor, ModulePool output) {
-            pool.transformAndCopy(visitor, output);
+        public ByteOrder byteOrder() {
+            return pool.byteOrder();
         }
 
         @Override
-        public ByteOrder getByteOrder() {
-            return pool.getByteOrder();
+        public Map<String, String> releaseProperties() {
+            return pool.releaseProperties();
         }
 
-        @Override
-        public Map<String, String> getReleaseProperties() {
-            return Collections.unmodifiableMap(pool.getReleaseProperties());
-        }
-
-        private ModuleEntry getUncompressed(ModuleEntry res) {
+        private ResourcePoolEntry getUncompressed(ResourcePoolEntry res) {
             if (res != null) {
-                if (res instanceof ModulePoolImpl.CompressedModuleData) {
+                if (res instanceof ResourcePoolManager.CompressedModuleData) {
                     try {
-                        byte[] bytes = decompressor.decompressResource(getByteOrder(),
-                                (int offset) -> pool.getStringTable().getString(offset),
-                                res.getBytes());
-                        res = res.create(bytes);
+                        byte[] bytes = decompressor.decompressResource(byteOrder(),
+                                (int offset) -> ((ResourcePoolImpl)pool).getStringTable().getString(offset),
+                                res.contentBytes());
+                        res = res.copyWithContent(bytes);
                     } catch (IOException ex) {
+                        if (JlinkTask.DEBUG) {
+                            ex.printStackTrace();
+                        }
                         throw new PluginException(ex);
                     }
                 }
@@ -457,24 +453,24 @@
      * @param writer
      * @throws java.lang.Exception
      */
-    public void storeFiles(ModulePoolImpl original, ModulePoolImpl transformed,
+    public void storeFiles(ResourcePool original, ResourcePool transformed,
             BasicImageWriter writer)
             throws Exception {
         Objects.requireNonNull(original);
         Objects.requireNonNull(transformed);
-        Optional<LinkModule> javaBase = transformed.findModule("java.base");
+        Optional<ResourcePoolModule> javaBase = transformed.moduleView().findModule("java.base");
         javaBase.ifPresent(mod -> {
             try {
-                Map<String, String> release = transformed.getReleaseProperties();
+                Map<String, String> release = transformed.releaseProperties();
                 // fill release information available from transformed "java.base" module!
-                ModuleDescriptor desc = mod.getDescriptor();
+                ModuleDescriptor desc = mod.descriptor();
                 desc.osName().ifPresent(s -> release.put("OS_NAME", s));
                 desc.osVersion().ifPresent(s -> release.put("OS_VERSION", s));
                 desc.osArch().ifPresent(s -> release.put("OS_ARCH", s));
             } catch (Exception ignored) {}
         });
 
-        imageBuilder.storeFiles(new LastPool(transformed));
+        imageBuilder.storeFiles(new LastPoolManager(transformed).resourcePool());
     }
 
     public ExecutableImage getExecutableImage() throws IOException {
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java	Sat Jul 30 00:11:02 2016 +0000
@@ -61,7 +61,7 @@
  * ## Should use jdk.joptsimple some day.
  */
 public class JlinkTask {
-    private static final boolean DEBUG = Boolean.getBoolean("jlink.debug");
+    static final boolean DEBUG = Boolean.getBoolean("jlink.debug");
 
     private static <T extends Throwable> void fail(Class<T> type,
             String format,
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModuleEntryFactory.java	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jlink.internal;
-
-import java.nio.file.Path;
-import java.util.Objects;
-import jdk.tools.jlink.plugin.ModuleEntry;
-
-public final class ModuleEntryFactory {
-    private ModuleEntryFactory() {}
-
-    public static ModuleEntry create(String path,
-            ModuleEntry.Type type, byte[] content) {
-        return new ByteArrayModuleEntry(moduleFrom(path), path, type, content);
-    }
-
-    public static ModuleEntry create(String path,
-            ModuleEntry.Type type, Path file) {
-        return new PathModuleEntry(moduleFrom(path), path, type, file);
-    }
-
-    public static ModuleEntry create(ModuleEntry original, byte[] content) {
-        return new ByteArrayModuleEntry(original.getModule(),
-                original.getPath(), original.getType(), content);
-    }
-
-    public static ModuleEntry create(ModuleEntry original, Path file) {
-        return new PathModuleEntry(original.getModule(),
-                original.getPath(), original.getType(), file);
-    }
-
-    static String moduleFrom(String path) {
-        Objects.requireNonNull(path);
-        if (path.isEmpty() || path.charAt(0) != '/') {
-            throw new IllegalArgumentException(path + " must start with /");
-        }
-        int idx = path.indexOf('/', 1);
-        if (idx == -1) {
-            throw new IllegalArgumentException("/ missing after module: " + path);
-        }
-        return path.substring(1, idx);
-    }
-
-    static String packageFrom(String path) {
-        Objects.requireNonNull(path);
-        int idx = path.lastIndexOf('/');
-        if (idx == -1) {
-            throw new IllegalArgumentException("/ missing from path: " + path);
-        }
-        if (path.startsWith("/")) {
-            int jdx = path.indexOf('/', 1);
-            if (jdx == -1) {
-                throw new IllegalArgumentException("/ missing after module: " + path);
-            }
-            return path.substring(jdx + 1, idx);
-        } else {
-            return path.substring(0, idx);
-        }
-    }
-}
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModulePoolImpl.java	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,436 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jlink.internal;
-
-import java.lang.module.ModuleDescriptor;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Stream;
-import jdk.internal.jimage.decompressor.CompressedResourceHeader;
-import jdk.tools.jlink.plugin.ModulePool;
-import jdk.tools.jlink.plugin.LinkModule;
-import jdk.tools.jlink.plugin.ModuleEntry;
-import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
-
-/**
- * Pool of module data.
- */
-public class ModulePoolImpl implements ModulePool {
-
-    private class ModuleImpl implements LinkModule {
-
-        final Map<String, ModuleEntry> moduleContent = new LinkedHashMap<>();
-        private ModuleDescriptor descriptor;
-        final String name;
-
-        private ModuleImpl(String name) {
-            this.name = name;
-        }
-
-        @Override
-        public String getName() {
-            return name;
-        }
-
-        @Override
-        public Optional<ModuleEntry> findEntry(String path) {
-            if (!path.startsWith("/")) {
-                path = "/" + path;
-            }
-            if (!path.startsWith("/" + name)) {
-                path = "/" + name + path;
-            }
-            return Optional.ofNullable(moduleContent.get(path));
-        }
-
-        @Override
-        public ModuleDescriptor getDescriptor() {
-            if (descriptor == null) {
-                String p = "/" + name + "/module-info.class";
-                Optional<ModuleEntry> content = findEntry(p);
-                if (!content.isPresent()) {
-                    throw new PluginException("No module-info for " + name
-                            + " module");
-                }
-                ByteBuffer bb = ByteBuffer.wrap(content.get().getBytes());
-                descriptor = ModuleDescriptor.read(bb);
-            }
-            return descriptor;
-        }
-
-        @Override
-        public void add(ModuleEntry data) {
-            if (isReadOnly()) {
-                throw new PluginException("ModulePool is readonly");
-            }
-            Objects.requireNonNull(data);
-            if (!data.getModule().equals(name)) {
-                throw new PluginException("Can't add resource " + data.getPath()
-                        + " to module " + name);
-            }
-            ModulePoolImpl.this.add(data);
-        }
-
-        @Override
-        public Set<String> getAllPackages() {
-            Set<String> pkgs = new HashSet<>();
-            moduleContent.values().stream().filter(m -> m.getType().
-                    equals(ModuleEntry.Type.CLASS_OR_RESOURCE)).forEach(res -> {
-                // Module metadata only contains packages with .class files
-                if (ImageFileCreator.isClassPackage(res.getPath())) {
-                    String[] split = ImageFileCreator.splitPath(res.getPath());
-                    String pkg = split[1];
-                    if (pkg != null && !pkg.isEmpty()) {
-                        pkgs.add(pkg);
-                    }
-                }
-            });
-            return pkgs;
-        }
-
-        @Override
-        public String toString() {
-            return getName();
-        }
-
-        @Override
-        public Stream<? extends ModuleEntry> entries() {
-            return moduleContent.values().stream();
-        }
-
-        @Override
-        public int getEntryCount() {
-            return moduleContent.values().size();
-        }
-    }
-
-    private final Map<String, ModuleEntry> resources = new LinkedHashMap<>();
-    private final Map<String, ModuleImpl> modules = new LinkedHashMap<>();
-    private final ModuleImpl fileCopierModule = new ModuleImpl(FileCopierPlugin.FAKE_MODULE);
-    private Map<String, String> releaseProps = new HashMap<>();
-
-    private final ByteOrder order;
-
-    private boolean isReadOnly;
-    private final StringTable table;
-
-    public ModulePoolImpl() {
-        this(ByteOrder.nativeOrder());
-    }
-
-    public ModulePoolImpl(ByteOrder order) {
-        this(order, new StringTable() {
-
-            @Override
-            public int addString(String str) {
-                return -1;
-            }
-
-            @Override
-            public String getString(int id) {
-                return null;
-            }
-        });
-    }
-
-    public ModulePoolImpl(ByteOrder order, StringTable table) {
-        this.order = Objects.requireNonNull(order);
-        this.table = Objects.requireNonNull(table);
-    }
-
-    /**
-     * Add a ModuleEntry.
-     *
-     * @param data The ModuleEntry to add.
-     */
-    @Override
-    public void add(ModuleEntry data) {
-        if (isReadOnly()) {
-            throw new PluginException("ModulePool is readonly");
-        }
-        Objects.requireNonNull(data);
-        if (resources.get(data.getPath()) != null) {
-            throw new PluginException("Resource " + data.getPath()
-                    + " already present");
-        }
-        String modulename = data.getModule();
-        ModuleImpl m = modules.get(modulename);
-        // ## TODO: FileCopierPlugin should not add content to a module
-        // FAKE_MODULE is not really a module to be added in the image
-        if (FileCopierPlugin.FAKE_MODULE.equals(modulename)) {
-            m = fileCopierModule;
-        }
-        if (m == null) {
-            m = new ModuleImpl(modulename);
-            modules.put(modulename, m);
-        }
-        resources.put(data.getPath(), data);
-        m.moduleContent.put(data.getPath(), data);
-    }
-
-    /**
-     * Retrieves the module for the provided name.
-     *
-     * @param name The module name
-     * @return the module of matching name, if found
-     */
-    @Override
-    public Optional<LinkModule> findModule(String name) {
-        Objects.requireNonNull(name);
-        return Optional.ofNullable(modules.get(name));
-    }
-
-    /**
-     * The stream of modules contained in this ModulePool.
-     *
-     * @return The stream of modules.
-     */
-    @Override
-    public Stream<? extends LinkModule> modules() {
-        return modules.values().stream();
-    }
-
-    /**
-     * Return the number of LinkModule count in this ModulePool.
-     *
-     * @return the module count.
-     */
-    @Override
-    public int getModuleCount() {
-        return modules.size();
-    }
-
-    /**
-     * Get all ModuleEntry contained in this ModulePool instance.
-     *
-     * @return The stream of LinkModuleEntries.
-     */
-    @Override
-    public Stream<? extends ModuleEntry> entries() {
-        return resources.values().stream();
-    }
-
-    /**
-     * Return the number of ModuleEntry count in this ModulePool.
-     *
-     * @return the entry count.
-     */
-    @Override
-    public int getEntryCount() {
-        return resources.values().size();
-    }
-
-    /**
-     * Get the ModuleEntry for the passed path.
-     *
-     * @param path A data path
-     * @return A ModuleEntry instance or null if the data is not found
-     */
-    @Override
-    public Optional<ModuleEntry> findEntry(String path) {
-        Objects.requireNonNull(path);
-        return Optional.ofNullable(resources.get(path));
-    }
-
-    /**
-     * Get the ModuleEntry for the passed path restricted to supplied context.
-     *
-     * @param path A data path
-     * @param context A context of the search
-     * @return A ModuleEntry instance or null if the data is not found
-     */
-    @Override
-    public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context) {
-        Objects.requireNonNull(path);
-        Objects.requireNonNull(context);
-        LinkModule module = modules.get(context.getModule());
-        Objects.requireNonNull(module);
-        Optional<ModuleEntry> entry = module.findEntry(path);
-        // Navigating other modules via requires and exports is problematic
-        // since we cannot construct the runtime model of loaders and layers.
-        return entry;
-     }
-
-    /**
-     * Check if the ModulePool contains the given ModuleEntry.
-     *
-     * @param data The module data to check existence for.
-     * @return The module data or null if not found.
-     */
-    @Override
-    public boolean contains(ModuleEntry data) {
-        Objects.requireNonNull(data);
-        return findEntry(data.getPath()).isPresent();
-    }
-
-    /**
-     * Check if the ModulePool contains some content at all.
-     *
-     * @return True, no content, false otherwise.
-     */
-    @Override
-    public boolean isEmpty() {
-        return resources.isEmpty();
-    }
-
-    /**
-     * Visit each ModuleEntry in this ModulePool to transform it and
-     * copy the transformed ModuleEntry to the output ModulePool.
-     *
-     * @param transform The function called for each ModuleEntry found in
-     * the ModulePool. The transform function should return a
-     * ModuleEntry instance which will be added to the output or it should
-     * return null if the passed ModuleEntry is to be ignored for the
-     * output.
-     *
-     * @param output The ModulePool to be filled with Visitor returned
-     * ModuleEntry.
-     */
-    @Override
-    public void transformAndCopy(Function<ModuleEntry, ModuleEntry> transform,
-            ModulePool output) {
-        entries().forEach(resource -> {
-            ModuleEntry res = transform.apply(resource);
-            if (res != null) {
-                output.add(res);
-            }
-        });
-    }
-
-    /**
-     * The ByteOrder currently in use when generating the jimage file.
-     *
-     * @return The ByteOrder.
-     */
-    @Override
-    public ByteOrder getByteOrder() {
-        return order;
-    }
-
-    @Override
-    public Map<String, String> getReleaseProperties() {
-        return isReadOnly()? Collections.unmodifiableMap(releaseProps) : releaseProps;
-    }
-
-    public StringTable getStringTable() {
-        return table;
-    }
-
-    /**
-     * Make this Resources instance read-only. No resource can be added.
-     */
-    public void setReadOnly() {
-        isReadOnly = true;
-    }
-
-    /**
-     * Read only state.
-     *
-     * @return true if readonly false otherwise.
-     */
-    @Override
-    public boolean isReadOnly() {
-        return isReadOnly;
-    }
-
-    /**
-     * A resource that has been compressed.
-     */
-    public static final class CompressedModuleData extends ByteArrayModuleEntry {
-
-        final long uncompressed_size;
-
-        private CompressedModuleData(String module, String path,
-                byte[] content, long uncompressed_size) {
-            super(module, path, ModuleEntry.Type.CLASS_OR_RESOURCE, content);
-            this.uncompressed_size = uncompressed_size;
-        }
-
-        public long getUncompressedSize() {
-            return uncompressed_size;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof CompressedModuleData)) {
-                return false;
-            }
-            CompressedModuleData f = (CompressedModuleData) other;
-            return f.getPath().equals(getPath());
-        }
-
-        @Override
-        public int hashCode() {
-            return super.hashCode();
-        }
-    }
-
-    public static CompressedModuleData newCompressedResource(ModuleEntry original,
-            ByteBuffer compressed,
-            String plugin, String pluginConfig, StringTable strings,
-            ByteOrder order) {
-        Objects.requireNonNull(original);
-        Objects.requireNonNull(compressed);
-        Objects.requireNonNull(plugin);
-
-        boolean isTerminal = !(original instanceof CompressedModuleData);
-        long uncompressed_size = original.getLength();
-        if (original instanceof CompressedModuleData) {
-            CompressedModuleData comp = (CompressedModuleData) original;
-            uncompressed_size = comp.getUncompressedSize();
-        }
-        int nameOffset = strings.addString(plugin);
-        int configOffset = -1;
-        if (pluginConfig != null) {
-            configOffset = strings.addString(plugin);
-        }
-        CompressedResourceHeader rh
-                = new CompressedResourceHeader(compressed.limit(), original.getLength(),
-                        nameOffset, configOffset, isTerminal);
-        // Merge header with content;
-        byte[] h = rh.getBytes(order);
-        ByteBuffer bb = ByteBuffer.allocate(compressed.limit() + h.length);
-        bb.order(order);
-        bb.put(h);
-        bb.put(compressed);
-        byte[] contentWithHeader = bb.array();
-
-        CompressedModuleData compressedResource
-                = new CompressedModuleData(original.getModule(), original.getPath(),
-                        contentWithHeader, uncompressed_size);
-        return compressedResource;
-    }
-
-}
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PathModuleEntry.java	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classfile" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.tools.jlink.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UncheckedIOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Objects;
-
-/**
- * A ModuleEntry backed by a given nio Path.
- */
-public class PathModuleEntry extends AbstractModuleEntry {
-    private final Path file;
-
-    /**
-     * Create a new PathModuleEntry.
-     *
-     * @param module The module name.
-     * @param path The path for the resource content.
-     * @param type The data type.
-     * @param file The data file identifier.
-     */
-    public PathModuleEntry(String module, String path, Type type, Path file) {
-        super(module, path, type);
-        this.file = Objects.requireNonNull(file);
-        if (!Files.isRegularFile(file)) {
-            throw new IllegalArgumentException(file + " not a file");
-        }
-    }
-
-    @Override
-    public final InputStream stream() {
-        try {
-            return Files.newInputStream(file);
-        } catch (IOException ex) {
-            throw new UncheckedIOException(ex);
-        }
-    }
-
-    @Override
-    public final long getLength() {
-        try {
-            return Files.size(file);
-        } catch (IOException ex) {
-            throw new UncheckedIOException(ex);
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PathResourcePoolEntry.java	Sat Jul 30 00:11:02 2016 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classfile" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.tools.jlink.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Objects;
+
+/**
+ * A ResourcePoolEntry backed by a given nio Path.
+ */
+public class PathResourcePoolEntry extends AbstractResourcePoolEntry {
+    private final Path file;
+
+    /**
+     * Create a new PathResourcePoolEntry.
+     *
+     * @param module The module name.
+     * @param path The path for the resource content.
+     * @param type The data type.
+     * @param file The data file identifier.
+     */
+    public PathResourcePoolEntry(String module, String path, Type type, Path file) {
+        super(module, path, type);
+        this.file = Objects.requireNonNull(file);
+        if (!Files.isRegularFile(file)) {
+            throw new IllegalArgumentException(file + " not a file");
+        }
+    }
+
+    @Override
+    public final InputStream content() {
+        try {
+            return Files.newInputStream(file);
+        } catch (IOException ex) {
+            throw new UncheckedIOException(ex);
+        }
+    }
+
+    @Override
+    public final long contentLength() {
+        try {
+            return Files.size(file);
+        } catch (IOException ex) {
+            throw new UncheckedIOException(ex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolEntryFactory.java	Sat Jul 30 00:11:02 2016 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.internal;
+
+import java.nio.file.Path;
+import java.util.Objects;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
+
+public final class ResourcePoolEntryFactory {
+    private ResourcePoolEntryFactory() {}
+
+    public static ResourcePoolEntry create(String path,
+            ResourcePoolEntry.Type type, byte[] content) {
+        return new ByteArrayResourcePoolEntry(moduleFrom(path), path, type, content);
+    }
+
+    public static ResourcePoolEntry create(String path,
+            ResourcePoolEntry.Type type, Path file) {
+        return new PathResourcePoolEntry(moduleFrom(path), path, type, file);
+    }
+
+    public static ResourcePoolEntry create(ResourcePoolEntry original, byte[] content) {
+        return new ByteArrayResourcePoolEntry(original.moduleName(),
+                original.path(), original.type(), content);
+    }
+
+    public static ResourcePoolEntry create(ResourcePoolEntry original, Path file) {
+        return new PathResourcePoolEntry(original.moduleName(),
+                original.path(), original.type(), file);
+    }
+
+    private static String moduleFrom(String path) {
+        Objects.requireNonNull(path);
+        if (path.isEmpty() || path.charAt(0) != '/') {
+            throw new IllegalArgumentException(path + " must start with /");
+        }
+        String noRoot = path.substring(1);
+        int idx = noRoot.indexOf('/');
+        if (idx == -1) {
+            throw new IllegalArgumentException("/ missing after module: " + path);
+        }
+        return noRoot.substring(0, idx);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolManager.java	Sat Jul 30 00:11:02 2016 +0000
@@ -0,0 +1,469 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.internal;
+
+import java.lang.module.ModuleDescriptor;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import jdk.internal.jimage.decompressor.CompressedResourceHeader;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
+import jdk.tools.jlink.plugin.ResourcePoolModule;
+import jdk.tools.jlink.plugin.ResourcePoolModuleView;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
+
+/**
+ * A manager for pool of resources.
+ */
+public class ResourcePoolManager {
+
+    class ResourcePoolModuleImpl implements ResourcePoolModule {
+
+        final Map<String, ResourcePoolEntry> moduleContent = new LinkedHashMap<>();
+        private ModuleDescriptor descriptor;
+        final String name;
+
+        private ResourcePoolModuleImpl(String name) {
+            this.name = name;
+        }
+
+        @Override
+        public String name() {
+            return name;
+        }
+
+        @Override
+        public Optional<ResourcePoolEntry> findEntry(String path) {
+            if (!path.startsWith("/")) {
+                path = "/" + path;
+            }
+            if (!path.startsWith("/" + name)) {
+                path = "/" + name + path;
+            }
+            return Optional.ofNullable(moduleContent.get(path));
+        }
+
+        @Override
+        public ModuleDescriptor descriptor() {
+            if (descriptor == null) {
+                String p = "/" + name + "/module-info.class";
+                Optional<ResourcePoolEntry> content = findEntry(p);
+                if (!content.isPresent()) {
+                    throw new PluginException("No module-info for " + name
+                            + " module");
+                }
+                ByteBuffer bb = ByteBuffer.wrap(content.get().contentBytes());
+                descriptor = ModuleDescriptor.read(bb);
+            }
+            return descriptor;
+        }
+
+        @Override
+        public Set<String> packages() {
+            Set<String> pkgs = new HashSet<>();
+            moduleContent.values().stream().filter(m -> m.type().
+                    equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)).forEach(res -> {
+                // Module metadata only contains packages with .class files
+                if (ImageFileCreator.isClassPackage(res.path())) {
+                    String[] split = ImageFileCreator.splitPath(res.path());
+                    String pkg = split[1];
+                    if (pkg != null && !pkg.isEmpty()) {
+                        pkgs.add(pkg);
+                    }
+                }
+            });
+            return pkgs;
+        }
+
+        @Override
+        public String toString() {
+            return name();
+        }
+
+        @Override
+        public Stream<ResourcePoolEntry> entries() {
+            return moduleContent.values().stream();
+        }
+
+        @Override
+        public int entryCount() {
+            return moduleContent.values().size();
+        }
+    }
+
+    public class ResourcePoolImpl implements ResourcePool {
+        @Override
+        public ResourcePoolModuleView moduleView() {
+            return ResourcePoolManager.this.moduleView();
+        }
+
+        @Override
+        public Stream<ResourcePoolEntry> entries() {
+            return ResourcePoolManager.this.entries();
+        }
+
+        @Override
+        public int entryCount() {
+            return ResourcePoolManager.this.entryCount();
+        }
+
+        @Override
+        public Optional<ResourcePoolEntry> findEntry(String path) {
+            return ResourcePoolManager.this.findEntry(path);
+        }
+
+        @Override
+        public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context) {
+            return ResourcePoolManager.this.findEntryInContext(path, context);
+        }
+
+        @Override
+        public boolean contains(ResourcePoolEntry data) {
+            return ResourcePoolManager.this.contains(data);
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return ResourcePoolManager.this.isEmpty();
+        }
+
+        @Override
+        public ByteOrder byteOrder() {
+            return ResourcePoolManager.this.byteOrder();
+        }
+
+        @Override
+        public Map<String, String> releaseProperties() {
+            return ResourcePoolManager.this.releaseProperties();
+        }
+
+        public StringTable getStringTable() {
+            return ResourcePoolManager.this.getStringTable();
+        }
+    }
+
+    class ResourcePoolBuilderImpl implements ResourcePoolBuilder {
+        private boolean built;
+
+        @Override
+        public void add(ResourcePoolEntry data) {
+            if (built) {
+                throw new IllegalStateException("resource pool already built!");
+            }
+            ResourcePoolManager.this.add(data);
+        }
+
+        @Override
+        public ResourcePool build() {
+            built = true;
+            return ResourcePoolManager.this.resourcePool();
+        }
+    }
+
+    class ResourcePoolModuleViewImpl implements ResourcePoolModuleView {
+        @Override
+        public Optional<ResourcePoolModule> findModule(String name) {
+            return ResourcePoolManager.this.findModule(name);
+        }
+
+        @Override
+        public Stream<ResourcePoolModule> modules() {
+            return ResourcePoolManager.this.modules();
+        }
+
+        @Override
+        public int moduleCount() {
+            return ResourcePoolManager.this.moduleCount();
+        }
+    }
+
+    private final Map<String, ResourcePoolEntry> resources = new LinkedHashMap<>();
+    private final Map<String, ResourcePoolModule> modules = new LinkedHashMap<>();
+    private final ResourcePoolModuleImpl fileCopierModule = new ResourcePoolModuleImpl(FileCopierPlugin.FAKE_MODULE);
+    private Map<String, String> releaseProps = new HashMap<>();
+    private final ByteOrder order;
+    private final StringTable table;
+    private final ResourcePool poolImpl;
+    private final ResourcePoolBuilder poolBuilderImpl;
+    private final ResourcePoolModuleView moduleViewImpl;
+
+    public ResourcePoolManager() {
+        this(ByteOrder.nativeOrder());
+    }
+
+    public ResourcePoolManager(ByteOrder order) {
+        this(order, new StringTable() {
+
+            @Override
+            public int addString(String str) {
+                return -1;
+            }
+
+            @Override
+            public String getString(int id) {
+                return null;
+            }
+        });
+    }
+
+    public ResourcePoolManager(ByteOrder order, StringTable table) {
+        this.order = Objects.requireNonNull(order);
+        this.table = Objects.requireNonNull(table);
+        this.poolImpl = new ResourcePoolImpl();
+        this.poolBuilderImpl = new ResourcePoolBuilderImpl();
+        this.moduleViewImpl = new ResourcePoolModuleViewImpl();
+    }
+
+    public ResourcePool resourcePool() {
+        return poolImpl;
+    }
+
+    public ResourcePoolBuilder resourcePoolBuilder() {
+        return poolBuilderImpl;
+    }
+
+    public ResourcePoolModuleView moduleView() {
+        return moduleViewImpl;
+    }
+
+    /**
+     * Add a ResourcePoolEntry.
+     *
+     * @param data The ResourcePoolEntry to add.
+     */
+    public void add(ResourcePoolEntry data) {
+        Objects.requireNonNull(data);
+        if (resources.get(data.path()) != null) {
+            throw new PluginException("Resource " + data.path()
+                    + " already present");
+        }
+        String modulename = data.moduleName();
+        ResourcePoolModuleImpl m = (ResourcePoolModuleImpl)modules.get(modulename);
+        // ## TODO: FileCopierPlugin should not add content to a module
+        // FAKE_MODULE is not really a module to be added in the image
+        if (FileCopierPlugin.FAKE_MODULE.equals(modulename)) {
+            m = fileCopierModule;
+        }
+        if (m == null) {
+            m = new ResourcePoolModuleImpl(modulename);
+            modules.put(modulename, m);
+        }
+        resources.put(data.path(), data);
+        m.moduleContent.put(data.path(), data);
+    }
+
+    /**
+     * Retrieves the module for the provided name.
+     *
+     * @param name The module name
+     * @return the module of matching name, if found
+     */
+    public Optional<ResourcePoolModule> findModule(String name) {
+        Objects.requireNonNull(name);
+        return Optional.ofNullable(modules.get(name));
+    }
+
+    /**
+     * The stream of modules contained in this ResourcePool.
+     *
+     * @return The stream of modules.
+     */
+    public Stream<ResourcePoolModule> modules() {
+        return modules.values().stream();
+    }
+
+    /**
+     * Return the number of ResourcePoolModule count in this ResourcePool.
+     *
+     * @return the module count.
+     */
+    public int moduleCount() {
+        return modules.size();
+    }
+
+    /**
+     * Get all ResourcePoolEntry contained in this ResourcePool instance.
+     *
+     * @return The stream of ResourcePoolModuleEntries.
+     */
+    public Stream<ResourcePoolEntry> entries() {
+        return resources.values().stream();
+    }
+
+    /**
+     * Return the number of ResourcePoolEntry count in this ResourcePool.
+     *
+     * @return the entry count.
+     */
+    public int entryCount() {
+        return resources.values().size();
+    }
+
+    /**
+     * Get the ResourcePoolEntry for the passed path.
+     *
+     * @param path A data path
+     * @return A ResourcePoolEntry instance or null if the data is not found
+     */
+    public Optional<ResourcePoolEntry> findEntry(String path) {
+        Objects.requireNonNull(path);
+        return Optional.ofNullable(resources.get(path));
+    }
+
+    /**
+     * Get the ResourcePoolEntry for the passed path restricted to supplied context.
+     *
+     * @param path A data path
+     * @param context A context of the search
+     * @return A ResourcePoolEntry instance or null if the data is not found
+     */
+    public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context) {
+        Objects.requireNonNull(path);
+        Objects.requireNonNull(context);
+        ResourcePoolModule module = modules.get(context.moduleName());
+        Objects.requireNonNull(module);
+        Optional<ResourcePoolEntry> entry = module.findEntry(path);
+        // Navigating other modules via requires and exports is problematic
+        // since we cannot construct the runtime model of loaders and layers.
+        return entry;
+     }
+
+    /**
+     * Check if the ResourcePool contains the given ResourcePoolEntry.
+     *
+     * @param data The module data to check existence for.
+     * @return The module data or null if not found.
+     */
+    public boolean contains(ResourcePoolEntry data) {
+        Objects.requireNonNull(data);
+        return findEntry(data.path()).isPresent();
+    }
+
+    /**
+     * Check if the ResourcePool contains some content at all.
+     *
+     * @return True, no content, false otherwise.
+     */
+    public boolean isEmpty() {
+        return resources.isEmpty();
+    }
+
+    /**
+     * The ByteOrder currently in use when generating the jimage file.
+     *
+     * @return The ByteOrder.
+     */
+    public ByteOrder byteOrder() {
+        return order;
+    }
+
+    public Map<String, String> releaseProperties() {
+        return releaseProps;
+    }
+
+    public StringTable getStringTable() {
+        return table;
+    }
+
+    /**
+     * A resource that has been compressed.
+     */
+    public static final class CompressedModuleData extends ByteArrayResourcePoolEntry {
+
+        final long uncompressed_size;
+
+        private CompressedModuleData(String module, String path,
+                byte[] content, long uncompressed_size) {
+            super(module, path, ResourcePoolEntry.Type.CLASS_OR_RESOURCE, content);
+            this.uncompressed_size = uncompressed_size;
+        }
+
+        public long getUncompressedSize() {
+            return uncompressed_size;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof CompressedModuleData)) {
+                return false;
+            }
+            CompressedModuleData f = (CompressedModuleData) other;
+            return f.path().equals(path());
+        }
+
+        @Override
+        public int hashCode() {
+            return super.hashCode();
+        }
+    }
+
+    public static CompressedModuleData newCompressedResource(ResourcePoolEntry original,
+            ByteBuffer compressed,
+            String plugin, String pluginConfig, StringTable strings,
+            ByteOrder order) {
+        Objects.requireNonNull(original);
+        Objects.requireNonNull(compressed);
+        Objects.requireNonNull(plugin);
+
+        boolean isTerminal = !(original instanceof CompressedModuleData);
+        long uncompressed_size = original.contentLength();
+        if (original instanceof CompressedModuleData) {
+            CompressedModuleData comp = (CompressedModuleData) original;
+            uncompressed_size = comp.getUncompressedSize();
+        }
+        int nameOffset = strings.addString(plugin);
+        int configOffset = -1;
+        if (pluginConfig != null) {
+            configOffset = strings.addString(plugin);
+        }
+        CompressedResourceHeader rh
+                = new CompressedResourceHeader(compressed.limit(), original.contentLength(),
+                        nameOffset, configOffset, isTerminal);
+        // Merge header with content;
+        byte[] h = rh.getBytes(order);
+        ByteBuffer bb = ByteBuffer.allocate(compressed.limit() + h.length);
+        bb.order(order);
+        bb.put(h);
+        bb.put(compressed);
+        byte[] contentWithHeader = bb.array();
+
+        CompressedModuleData compressedResource
+                = new CompressedModuleData(original.moduleName(), original.path(),
+                        contentWithHeader, uncompressed_size);
+        return compressedResource;
+    }
+}
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePrevisitor.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePrevisitor.java	Sat Jul 30 00:11:02 2016 +0000
@@ -24,7 +24,7 @@
  */
 package jdk.tools.jlink.internal;
 
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
 
 /**
  * Plugin wishing to pre-visit the resources must implement this interface.
@@ -43,5 +43,5 @@
      * @param strings StringTable instance. Add string to the StringTable to track string
      * usage.
      */
-    public void previsit(ModulePool resources, StringTable strings);
+    public void previsit(ResourcePool resources, StringTable strings);
 }
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ClassForNamePlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ClassForNamePlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -29,7 +29,8 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
 import jdk.tools.jlink.plugin.Plugin.Category;
 import jdk.internal.org.objectweb.asm.ClassReader;
 import static jdk.internal.org.objectweb.asm.ClassReader.*;
@@ -44,7 +45,7 @@
 import jdk.internal.org.objectweb.asm.tree.LineNumberNode;
 import jdk.internal.org.objectweb.asm.tree.MethodInsnNode;
 import jdk.internal.org.objectweb.asm.tree.MethodNode;
-import jdk.tools.jlink.plugin.ModuleEntry;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 import jdk.tools.jlink.plugin.Plugin;
 
 public final class ClassForNamePlugin implements Plugin {
@@ -55,8 +56,8 @@
                               path.length() - ".class".length());
     }
 
-    private static int getAccess(ModuleEntry resource) {
-        ClassReader cr = new ClassReader(resource.getBytes());
+    private static int getAccess(ResourcePoolEntry resource) {
+        ClassReader cr = new ClassReader(resource.contentBytes());
 
         return cr.getAccess();
     }
@@ -67,8 +68,8 @@
         return index == -1 ? "" : binaryName.substring(0, index);
     }
 
-    private ModuleEntry transform(ModuleEntry resource, ModulePool pool) {
-        byte[] inBytes = resource.getBytes();
+    private ResourcePoolEntry transform(ResourcePoolEntry resource, ResourcePool pool) {
+        byte[] inBytes = resource.contentBytes();
         ClassReader cr = new ClassReader(inBytes);
         ClassNode cn = new ClassNode();
         cr.accept(cn, EXPAND_FRAMES);
@@ -76,7 +77,7 @@
         boolean modified = false;
         LdcInsnNode ldc = null;
 
-        String thisPackage = getPackage(binaryClassName(resource.getPath()));
+        String thisPackage = getPackage(binaryClassName(resource.path()));
 
         for (MethodNode mn : ms) {
             InsnList il = mn.instructions;
@@ -96,7 +97,7 @@
                         min.desc.equals("(Ljava/lang/String;)Ljava/lang/Class;")) {
                         String ldcClassName = ldc.cst.toString();
                         String thatClassName = ldcClassName.replaceAll("\\.", "/");
-                        Optional<ModuleEntry> thatClass =
+                        Optional<ResourcePoolEntry> thatClass =
                             pool.findEntryInContext(thatClassName + ".class", resource);
 
                         if (thatClass.isPresent()) {
@@ -128,7 +129,7 @@
             cn.accept(cw);
             byte[] outBytes = cw.toByteArray();
 
-            return resource.create(outBytes);
+            return resource.copyWithContent(outBytes);
         }
 
         return resource;
@@ -140,13 +141,13 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         Objects.requireNonNull(in);
         Objects.requireNonNull(out);
 
         in.entries()
             .forEach(resource -> {
-                String path = resource.getPath();
+                String path = resource.path();
 
                 if (path.endsWith(".class") && !path.endsWith("/module-info.class")) {
                     out.add(transform(resource, in));
@@ -154,6 +155,7 @@
                     out.add(resource);
                 }
             });
+        return out.build();
     }
 
     @Override
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -26,10 +26,12 @@
 
 import java.util.Map;
 
-import jdk.tools.jlink.internal.ModulePoolImpl;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
 import jdk.tools.jlink.plugin.Plugin;
 import jdk.tools.jlink.internal.ImagePluginStack;
+import jdk.tools.jlink.internal.ResourcePoolManager;
 import jdk.tools.jlink.internal.ResourcePrevisitor;
 import jdk.tools.jlink.internal.StringTable;
 
@@ -53,21 +55,22 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         if (ss != null && zip != null) {
-            ModulePool output = new ImagePluginStack.OrderedResourcePool(in.getByteOrder(),
-                    ((ModulePoolImpl) in).getStringTable());
-            ss.visit(in, output);
-            zip.visit(output, out);
+            ResourcePoolManager resMgr = new ImagePluginStack.OrderedResourcePoolManager(
+                    in.byteOrder(), ((ResourcePoolImpl)in).getStringTable());
+            return zip.transform(ss.transform(in, resMgr.resourcePoolBuilder()), out);
         } else if (ss != null) {
-            ss.visit(in, out);
+            return ss.transform(in, out);
         } else if (zip != null) {
-            zip.visit(in, out);
+            return zip.transform(in, out);
         }
+
+        return out.build();
     }
 
     @Override
-    public void previsit(ModulePool resources, StringTable strings) {
+    public void previsit(ResourcePool resources, StringTable strings) {
         if (ss != null) {
             ss.previsit(resources, strings);
         }
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -27,8 +27,9 @@
 import java.util.Map;
 import java.util.function.Predicate;
 import jdk.tools.jlink.plugin.Plugin;
-import jdk.tools.jlink.plugin.ModulePool;
-import jdk.tools.jlink.plugin.ModuleEntry;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 
 /**
  *
@@ -45,13 +46,14 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         in.transformAndCopy((file) -> {
-            if (!file.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
-                file = predicate.test(file.getPath()) ? file : null;
+            if (!file.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
+                file = predicate.test(file.path()) ? file : null;
             }
             return file;
         }, out);
+        return out.build();
     }
 
     @Override
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -27,8 +27,9 @@
 import java.util.Map;
 import java.util.function.Predicate;
 import jdk.tools.jlink.plugin.Plugin;
-import jdk.tools.jlink.plugin.ModuleEntry;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 
 /**
  *
@@ -45,13 +46,14 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         in.transformAndCopy((resource) -> {
-            if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
-                resource = predicate.test(resource.getPath()) ? resource : null;
+            if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
+                resource = predicate.test(resource.path()) ? resource : null;
             }
             return resource;
         }, out);
+        return out.build();
     }
 
     @Override
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -36,8 +36,9 @@
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import jdk.tools.jlink.plugin.Plugin;
-import jdk.tools.jlink.plugin.ModulePool;
-import jdk.tools.jlink.plugin.ModuleEntry;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 import jdk.tools.jlink.plugin.PluginException;
 
 /**
@@ -97,25 +98,25 @@
      * e.g.: /java.base/native/amd64/server/libjvm.so
      * /java.base/native/server/libjvm.dylib
      */
-    private List<ModuleEntry> getVMs(ModulePool in) {
+    private List<ResourcePoolEntry> getVMs(ResourcePool in) {
         String jvmlib = jvmlib();
-        List<ModuleEntry> ret = in.findModule("java.base").get().entries().filter((t) -> {
-            return t.getPath().endsWith("/" + jvmlib);
+        List<ResourcePoolEntry> ret = in.moduleView().findModule("java.base").get().entries().filter((t) -> {
+            return t.path().endsWith("/" + jvmlib);
         }).collect(Collectors.toList());
         return ret;
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         String jvmlib = jvmlib();
         TreeSet<Jvm> existing = new TreeSet<>(new JvmComparator());
         TreeSet<Jvm> removed = new TreeSet<>(new JvmComparator());
         if (!keepAll) {
             // First retrieve all available VM names and removed VM
-            List<ModuleEntry> jvms = getVMs(in);
+            List<ResourcePoolEntry> jvms = getVMs(in);
             for (Jvm jvm : Jvm.values()) {
-                for (ModuleEntry md : jvms) {
-                    if (md.getPath().endsWith("/" + jvm.getName() + "/" + jvmlib)) {
+                for (ResourcePoolEntry md : jvms) {
+                    if (md.path().endsWith("/" + jvm.getName() + "/" + jvmlib)) {
                         existing.add(jvm);
                         if (isRemoved(md)) {
                             removed.add(jvm);
@@ -134,8 +135,8 @@
         // Rewrite the jvm.cfg file.
         in.transformAndCopy((file) -> {
             if (!keepAll) {
-                if (file.getType().equals(ModuleEntry.Type.NATIVE_LIB)) {
-                    if (file.getPath().endsWith(JVM_CFG)) {
+                if (file.type().equals(ResourcePoolEntry.Type.NATIVE_LIB)) {
+                    if (file.path().endsWith(JVM_CFG)) {
                         try {
                             file = handleJvmCfgFile(file, existing, removed);
                         } catch (IOException ex) {
@@ -148,10 +149,11 @@
             return file;
         }, out);
 
+        return out.build();
     }
 
-    private boolean isRemoved(ModuleEntry file) {
-        return !predicate.test(file.getPath());
+    private boolean isRemoved(ResourcePoolEntry file) {
+        return !predicate.test(file.path());
     }
 
     @Override
@@ -206,7 +208,7 @@
         predicate = ResourceFilter.excludeFilter(exclude);
     }
 
-    private ModuleEntry handleJvmCfgFile(ModuleEntry orig,
+    private ResourcePoolEntry handleJvmCfgFile(ResourcePoolEntry orig,
             TreeSet<Jvm> existing,
             TreeSet<Jvm> removed) throws IOException {
         if (keepAll) {
@@ -215,7 +217,7 @@
         StringBuilder builder = new StringBuilder();
         // Keep comments
         try (BufferedReader reader
-                = new BufferedReader(new InputStreamReader(orig.stream(),
+                = new BufferedReader(new InputStreamReader(orig.content(),
                         StandardCharsets.UTF_8))) {
             reader.lines().forEach((s) -> {
                 if (s.startsWith("#")) {
@@ -242,7 +244,7 @@
 
         byte[] content = builder.toString().getBytes(StandardCharsets.UTF_8);
 
-        return orig.create(content);
+        return orig.copyWithContent(content);
     }
 
     private static String jvmlib() {
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/FileCopierPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/FileCopierPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -37,10 +37,11 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import jdk.tools.jlink.internal.PathModuleEntry;
+import jdk.tools.jlink.internal.PathResourcePoolEntry;
 import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.plugin.ModuleEntry;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 import jdk.tools.jlink.plugin.Plugin;
 import jdk.tools.jlink.internal.Utils;
 
@@ -64,12 +65,12 @@
     /**
      * Symbolic link to another path.
      */
-    public static abstract class SymImageFile extends PathModuleEntry {
+    public static abstract class SymImageFile extends PathResourcePoolEntry {
 
         private final String targetPath;
 
         public SymImageFile(String targetPath, String module, String path,
-                ModuleEntry.Type type, Path file) {
+                ResourcePoolEntry.Type type, Path file) {
             super(module, path, type, file);
             this.targetPath = targetPath;
         }
@@ -82,7 +83,7 @@
     private static final class SymImageFileImpl extends SymImageFile {
 
         public SymImageFileImpl(String targetPath, Path file, String module,
-                String path, ModuleEntry.Type type) {
+                String path, ResourcePoolEntry.Type type) {
             super(targetPath, module, path, type, file);
         }
     }
@@ -90,11 +91,11 @@
     private static final class DirectoryCopy implements FileVisitor<Path> {
 
         private final Path source;
-        private final ModulePool pool;
+        private final ResourcePoolBuilder pool;
         private final String targetDir;
         private final List<SymImageFile> symlinks = new ArrayList<>();
 
-        DirectoryCopy(Path source, ModulePool pool, String targetDir) {
+        DirectoryCopy(Path source, ResourcePoolBuilder pool, String targetDir) {
             this.source = source;
             this.pool = pool;
             this.targetDir = targetDir;
@@ -128,7 +129,7 @@
                 }
                 SymImageFileImpl impl = new SymImageFileImpl(symTarget.toString(),
                         file, path, Objects.requireNonNull(file.getFileName()).toString(),
-                        ModuleEntry.Type.OTHER);
+                        ResourcePoolEntry.Type.OTHER);
                 symlinks.add(impl);
             } else {
                 addFile(pool, file, path);
@@ -152,14 +153,14 @@
         }
     }
 
-    private static void addFile(ModulePool pool, Path file, String path)
+    private static void addFile(ResourcePoolBuilder pool, Path file, String path)
             throws IOException {
         Objects.requireNonNull(pool);
         Objects.requireNonNull(file);
         Objects.requireNonNull(path);
-        ModuleEntry impl = ModuleEntry.create(
+        ResourcePoolEntry impl = ResourcePoolEntry.create(
                 "/" + FAKE_MODULE + "/other/" + path,
-                ModuleEntry.Type.OTHER, file);
+                ResourcePoolEntry.Type.OTHER, file);
         try {
             pool.add(impl);
         } catch (Exception ex) {
@@ -211,7 +212,7 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         in.transformAndCopy((file) -> {
             return file;
         }, out);
@@ -238,6 +239,8 @@
         } catch (IOException ex) {
             throw new UncheckedIOException(ex);
         }
+
+        return out.build();
     }
 
     @Override
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -31,9 +31,10 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
-import jdk.tools.jlink.plugin.ModuleEntry;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
 import jdk.tools.jlink.plugin.Plugin;
 
 /**
@@ -145,22 +146,22 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         in.entries().forEach(data -> {
-            if (("/java.base/" + BMH + ".class").equals(data.getPath())) {
+            if (("/java.base/" + BMH + ".class").equals(data.path())) {
                 // Add BoundMethodHandle unchanged
                 out.add(data);
                 speciesTypes.forEach(types -> generateConcreteClass(types, data, out));
             } else {
-                if (!out.contains(data)) {
-                    out.add(data);
-                }
+                out.add(data);
             }
         });
+
+        return out.build();
     }
 
     @SuppressWarnings("unchecked")
-    private void generateConcreteClass(String types, ModuleEntry data, ModulePool out) {
+    private void generateConcreteClass(String types, ResourcePoolEntry data, ResourcePoolBuilder out) {
         try {
             // Generate class
             Map.Entry<String, byte[]> result = (Map.Entry<String, byte[]>)
@@ -169,12 +170,10 @@
             byte[] bytes = result.getValue();
 
             // Add class to pool
-            ModuleEntry ndata = ModuleEntry.create(
+            ResourcePoolEntry ndata = ResourcePoolEntry.create(
                     "/java.base/" + className + ".class",
                     bytes);
-            if (!out.contains(ndata)) {
-                out.add(ndata);
-            }
+            out.add(ndata);
         } catch (Exception ex) {
             throw new PluginException(ex);
         }
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -42,10 +42,11 @@
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.tools.jlink.internal.ResourcePrevisitor;
 import jdk.tools.jlink.internal.StringTable;
-import jdk.tools.jlink.plugin.LinkModule;
-import jdk.tools.jlink.plugin.ModuleEntry;
+import jdk.tools.jlink.plugin.ResourcePoolModule;
 import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 import jdk.tools.jlink.plugin.Plugin;
 import sun.util.cldr.CLDRBaseLocaleDataMetaInfo;
 import sun.util.locale.provider.LocaleProviderAdapter;
@@ -151,24 +152,26 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         in.transformAndCopy((resource) -> {
-            if (resource.getModule().equals(MODULENAME)) {
-                String path = resource.getPath();
+            if (resource.moduleName().equals(MODULENAME)) {
+                String path = resource.path();
                 resource = predicate.test(path) ? resource: null;
                 if (resource != null &&
-                    resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
-                    byte[] bytes = resource.getBytes();
+                    resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
+                    byte[] bytes = resource.contentBytes();
                     ClassReader cr = new ClassReader(bytes);
                     if (Arrays.stream(cr.getInterfaces())
                         .anyMatch(i -> i.contains(METAINFONAME)) &&
                         stripUnsupportedLocales(bytes, cr)) {
-                        resource = resource.create(bytes);
+                        resource = resource.copyWithContent(bytes);
                     }
                 }
             }
             return resource;
         }, out);
+
+        return out.build();
     }
 
     @Override
@@ -205,14 +208,14 @@
     }
 
     @Override
-    public void previsit(ModulePool resources, StringTable strings) {
+    public void previsit(ResourcePool resources, StringTable strings) {
         final Pattern p = Pattern.compile(".*((Data_)|(Names_))(?<tag>.*)\\.class");
-        Optional<LinkModule> optMod = resources.findModule(MODULENAME);
+        Optional<ResourcePoolModule> optMod = resources.moduleView().findModule(MODULENAME);
 
         // jdk.localedata module validation
         if (optMod.isPresent()) {
-            LinkModule module = optMod.get();
-            Set<String> packages = module.getAllPackages();
+            ResourcePoolModule module = optMod.get();
+            Set<String> packages = module.packages();
             if (!packages.containsAll(LOCALEDATA_PACKAGES)) {
                 throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".missingpackages") +
                     LOCALEDATA_PACKAGES.stream()
@@ -221,7 +224,7 @@
             }
 
             available = Stream.concat(module.entries()
-                                        .map(md -> p.matcher(md.getPath()))
+                                        .map(md -> p.matcher(md.path()))
                                         .filter(m -> m.matches())
                                         .map(m -> m.group("tag").replaceAll("_", "-")),
                                     Stream.concat(Stream.of(jaJPJPTag), Stream.of(thTHTHTag)))
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -35,8 +35,9 @@
 import java.util.Map;
 import java.util.function.ToIntFunction;
 import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.plugin.ModuleEntry;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 import jdk.tools.jlink.plugin.Plugin;
 import jdk.tools.jlink.internal.Utils;
 
@@ -62,20 +63,20 @@
     }
 
     static class SortWrapper {
-        private final ModuleEntry resource;
+        private final ResourcePoolEntry resource;
         private final int ordinal;
 
-        SortWrapper(ModuleEntry resource, int ordinal) {
+        SortWrapper(ResourcePoolEntry resource, int ordinal) {
             this.resource = resource;
             this.ordinal = ordinal;
         }
 
-        ModuleEntry getResource() {
+        ResourcePoolEntry getResource() {
             return resource;
         }
 
         String getPath() {
-            return resource.getPath();
+            return resource.path();
         }
 
         int getOrdinal() {
@@ -95,8 +96,8 @@
         return path;
     }
 
-    private int getOrdinal(ModuleEntry resource) {
-        String path = resource.getPath();
+    private int getOrdinal(ResourcePoolEntry resource) {
+        String path = resource.path();
 
         Integer value = orderedPaths.get(stripModule(path));
 
@@ -126,17 +127,19 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         in.entries()
-                .filter(resource -> resource.getType()
-                        .equals(ModuleEntry.Type.CLASS_OR_RESOURCE))
+                .filter(resource -> resource.type()
+                        .equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE))
                 .map((resource) -> new SortWrapper(resource, getOrdinal(resource)))
                 .sorted(OrderResourcesPlugin::compare)
                 .forEach((wrapper) -> out.add(wrapper.getResource()));
         in.entries()
-                .filter(other -> !other.getType()
-                        .equals(ModuleEntry.Type.CLASS_OR_RESOURCE))
+                .filter(other -> !other.type()
+                        .equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE))
                 .forEach((other) -> out.add(other));
+
+        return out.build();
     }
 
     @Override
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -33,7 +33,8 @@
 import java.util.Set;
 import java.util.function.Function;
 import jdk.tools.jlink.internal.Utils;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
 import jdk.tools.jlink.plugin.Plugin.Category;
 import jdk.tools.jlink.plugin.Plugin.State;
 import jdk.tools.jlink.plugin.Plugin;
@@ -117,9 +118,8 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
-        in.transformAndCopy(Function.identity(), out);
-        out.getReleaseProperties().putAll(in.getReleaseProperties());
-        out.getReleaseProperties().putAll(release);
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
+        in.releaseProperties().putAll(release);
+        return in;
     }
 }
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StringSharingPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StringSharingPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -55,11 +55,13 @@
 import jdk.internal.jimage.decompressor.CompressIndexes;
 import jdk.internal.jimage.decompressor.SignatureParser;
 import jdk.internal.jimage.decompressor.StringSharingDecompressor;
-import jdk.tools.jlink.internal.ModulePoolImpl;
+import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
 import jdk.tools.jlink.plugin.Plugin;
 import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.plugin.ModuleEntry;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
+import jdk.tools.jlink.internal.ResourcePoolManager;
 import jdk.tools.jlink.internal.ResourcePrevisitor;
 import jdk.tools.jlink.internal.StringTable;
 
@@ -226,22 +228,22 @@
             }
         }
 
-        public byte[] transform(ModuleEntry resource, ModulePool out,
+        public byte[] transform(ResourcePoolEntry resource, ResourcePoolBuilder out,
                 StringTable strings) throws IOException, Exception {
-            byte[] content = resource.getBytes();
+            byte[] content = resource.contentBytes();
             ClassFile cf;
             try (InputStream stream = new ByteArrayInputStream(content)) {
                 cf = ClassFile.read(stream);
             } catch (ConstantPoolException ex) {
                 throw new IOException("Compressor EX " + ex + " for "
-                        + resource.getPath() + " content.length " + content.length, ex);
+                        + resource.path() + " content.length " + content.length, ex);
             }
             DescriptorsScanner scanner = new DescriptorsScanner(cf);
             return optimize(resource, out, strings, scanner.scan(), content);
         }
 
         @SuppressWarnings("fallthrough")
-        private byte[] optimize(ModuleEntry resource, ModulePool resources,
+        private byte[] optimize(ResourcePoolEntry resource, ResourcePoolBuilder resources,
                 StringTable strings,
                 Set<Integer> descriptorIndexes, byte[] content) throws Exception {
             DataInputStream stream = new DataInputStream(new ByteArrayInputStream(content));
@@ -347,23 +349,25 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool result) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder result) {
         CompactCPHelper visit = new CompactCPHelper();
         in.transformAndCopy((resource) -> {
-            ModuleEntry res = resource;
-            if (predicate.test(resource.getPath()) && resource.getPath().endsWith(".class")) {
+            ResourcePoolEntry res = resource;
+            if (predicate.test(resource.path()) && resource.path().endsWith(".class")) {
                 byte[] compressed = null;
                 try {
-                    compressed = visit.transform(resource, result, ((ModulePoolImpl) in).getStringTable());
+                    compressed = visit.transform(resource, result, ((ResourcePoolImpl)in).getStringTable());
                 } catch (Exception ex) {
                     throw new PluginException(ex);
                 }
-                res = ModulePoolImpl.newCompressedResource(resource,
+                res = ResourcePoolManager.newCompressedResource(resource,
                         ByteBuffer.wrap(compressed), getName(), null,
-                        ((ModulePoolImpl) in).getStringTable(), in.getByteOrder());
+                        ((ResourcePoolImpl)in).getStringTable(), in.byteOrder());
             }
             return res;
         }, result);
+
+        return result.build();
     }
 
     @Override
@@ -392,11 +396,11 @@
     }
 
     @Override
-    public void previsit(ModulePool resources, StringTable strings) {
+    public void previsit(ResourcePool resources, StringTable strings) {
         CompactCPHelper preVisit = new CompactCPHelper();
         resources.entries().forEach(resource -> {
-            if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)
-                    && resource.getPath().endsWith(".class") && predicate.test(resource.getPath())) {
+            if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+                    && resource.path().endsWith(".class") && predicate.test(resource.path())) {
                 try {
                     preVisit.transform(resource, null, strings);
                 } catch (Exception ex) {
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -27,8 +27,9 @@
 import java.util.function.Predicate;
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.ClassWriter;
-import jdk.tools.jlink.plugin.ModuleEntry;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 import jdk.tools.jlink.plugin.Plugin;
 
 /**
@@ -58,27 +59,29 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         //remove *.diz files as well as debug attributes.
         in.transformAndCopy((resource) -> {
-            ModuleEntry res = resource;
-            if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
-                String path = resource.getPath();
+            ResourcePoolEntry res = resource;
+            if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
+                String path = resource.path();
                 if (path.endsWith(".class")) {
                     if (path.endsWith("module-info.class")) {
                         // XXX. Do we have debug info? Is Asm ready for module-info?
                     } else {
-                        ClassReader reader = new ClassReader(resource.getBytes());
+                        ClassReader reader = new ClassReader(resource.contentBytes());
                         ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
                         reader.accept(writer, ClassReader.SKIP_DEBUG);
                         byte[] content = writer.toByteArray();
-                        res = resource.create(content);
+                        res = resource.copyWithContent(content);
                     }
                 }
-            } else if (predicate.test(res.getPath())) {
+            } else if (predicate.test(res.path())) {
                 res = null;
             }
             return res;
         }, out);
+
+        return out.build();
     }
 }
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripNativeCommandsPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripNativeCommandsPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -24,8 +24,9 @@
  */
 package jdk.tools.jlink.internal.plugins;
 
-import jdk.tools.jlink.plugin.ModuleEntry;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 import jdk.tools.jlink.plugin.Plugin;
 
 /**
@@ -47,10 +48,12 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         in.transformAndCopy((file) -> {
-            return file.getType() == ModuleEntry.Type.NATIVE_CMD ? null : file;
+            return file.type() == ResourcePoolEntry.Type.NATIVE_CMD ? null : file;
         }, out);
+
+        return out.build();
     }
 
     @Override
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModuleDescriptorPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModuleDescriptorPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -51,10 +51,11 @@
 
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
 import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.plugin.ResourcePool;
 import jdk.tools.jlink.plugin.Plugin;
 import jdk.tools.jlink.internal.plugins.SystemModuleDescriptorPlugin.Builder.*;
-import jdk.tools.jlink.plugin.ModuleEntry;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 
 /**
  * Jlink plugin to reconstitute module descriptors for installed modules.
@@ -107,7 +108,7 @@
 
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         if (!enabled) {
             throw new PluginException(NAME + " was set");
         }
@@ -116,30 +117,30 @@
 
         // generate the byte code to create ModuleDescriptors
         // skip parsing module-info.class and skip name check
-        in.modules().forEach(module -> {
-            Optional<ModuleEntry> optData = module.findEntry("module-info.class");
+        in.moduleView().modules().forEach(module -> {
+            Optional<ResourcePoolEntry> optData = module.findEntry("module-info.class");
             if (! optData.isPresent()) {
                 // automatic module not supported yet
                 throw new PluginException("module-info.class not found for " +
-                                          module.getName() + " module");
+                                          module.name() + " module");
             }
-            ModuleEntry data = optData.get();
-            assert module.getName().equals(data.getModule());
+            ResourcePoolEntry data = optData.get();
+            assert module.name().equals(data.moduleName());
             try {
-                ByteArrayInputStream bain = new ByteArrayInputStream(data.getBytes());
+                ByteArrayInputStream bain = new ByteArrayInputStream(data.contentBytes());
                 ModuleDescriptor md = ModuleDescriptor.read(bain);
                 validateNames(md);
 
-                ModuleDescriptorBuilder mbuilder = builder.module(md, module.getAllPackages());
+                ModuleDescriptorBuilder mbuilder = builder.module(md, module.packages());
                 int packages = md.exports().size() + md.conceals().size();
                 if (md.conceals().isEmpty() &&
-                        packages != module.getAllPackages().size()) {
+                        packages != module.packages().size()) {
                     // add ConcealedPackages attribute if not exist
                     bain.reset();
                     ModuleInfoRewriter minfoWriter =
                         new ModuleInfoRewriter(bain, mbuilder.conceals());
                     // replace with the overridden version
-                    data = data.create(minfoWriter.getBytes());
+                    data = data.copyWithContent(minfoWriter.getBytes());
                 }
                 out.add(data);
             } catch (IOException e) {
@@ -150,16 +151,18 @@
         // Generate the new class
         ClassWriter cwriter = builder.build();
         in.entries().forEach(data -> {
-            if (data.getPath().endsWith("module-info.class"))
+            if (data.path().endsWith("module-info.class"))
                 return;
-            if (builder.isOverriddenClass(data.getPath())) {
+            if (builder.isOverriddenClass(data.path())) {
                 byte[] bytes = cwriter.toByteArray();
-                ModuleEntry ndata = data.create(bytes);
+                ResourcePoolEntry ndata = data.copyWithContent(bytes);
                 out.add(ndata);
             } else {
                 out.add(data);
             }
         });
+
+        return out.build();
     }
 
     /*
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ZipPlugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ZipPlugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -31,9 +31,11 @@
 import java.util.Map;
 import java.util.function.Predicate;
 import java.util.zip.Deflater;
-import jdk.tools.jlink.internal.ModulePoolImpl;
-import jdk.tools.jlink.plugin.ModuleEntry;
-import jdk.tools.jlink.plugin.ModulePool;
+import jdk.tools.jlink.internal.ResourcePoolManager;
+import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
 import jdk.tools.jlink.plugin.Plugin;
 
 /**
@@ -112,18 +114,20 @@
     }
 
     @Override
-    public void visit(ModulePool in, ModulePool out) {
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         in.transformAndCopy((resource) -> {
-            ModuleEntry res = resource;
-            if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)
-                    && predicate.test(resource.getPath())) {
+            ResourcePoolEntry res = resource;
+            if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+                    && predicate.test(resource.path())) {
                 byte[] compressed;
-                compressed = compress(resource.getBytes());
-                res = ModulePoolImpl.newCompressedResource(resource,
+                compressed = compress(resource.contentBytes());
+                res = ResourcePoolManager.newCompressedResource(resource,
                         ByteBuffer.wrap(compressed), getName(), null,
-                        ((ModulePoolImpl) in).getStringTable(), in.getByteOrder());
+                        ((ResourcePoolImpl)in).getStringTable(), in.byteOrder());
             }
             return res;
         }, out);
+
+        return out.build();
     }
 }
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/LinkModule.java	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jlink.plugin;
-
-import java.lang.module.ModuleDescriptor;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Stream;
-
-/**
-  * Link-time representation of a Java module.
-  */
-public interface LinkModule {
-
-    /**
-     * The module name.
-     *
-     * @return The name.
-     */
-    public String getName();
-
-    /**
-     * Retrieves a LinkModuleEntry from the given path (e.g:
-     * /mymodule/com.foo.bar/MyClass.class)
-     *
-     * @param path The piece of data path.
-     * @return A LinkModuleEntry of the given path, if found.
-     */
-    public Optional<ModuleEntry> findEntry(String path);
-
-    /**
-     * The module descriptor of this module.
-     *
-     * @return The module descriptor.
-     */
-    public ModuleDescriptor getDescriptor();
-
-    /**
-     * Add a LinkModuleEntry to this module.
-     *
-     * @param data The LinkModuleEntry to add.
-     */
-    public void add(ModuleEntry data);
-
-    /**
-     * Retrieves all the packages located in this module.
-     *
-     * @return The set of packages.
-     */
-    public Set<String> getAllPackages();
-
-    /**
-     * Retrieves the stream of LinkModuleEntry.
-     *
-     * @return The LinkModuleEntry stream.
-     */
-    public Stream<? extends ModuleEntry> entries();
-
-    /**
-     * Return the number of LinkModuleEntry count in this LinkModule.
-     *
-     * @return the entry count.
-     */
-    public int getEntryCount();
-}
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ModuleEntry.java	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jlink.plugin;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UncheckedIOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import jdk.tools.jlink.internal.ModuleEntryFactory;
-
-/**
- * A ModuleEntry is the elementary unit of data inside an image. It is
- * generally a file. e.g.: a java class file, a resource file, a shared library.
- * <br>
- * A ModuleEntry is identified by a path of the form:
- * <ul>
- * <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
- * name}</li>
- * <li>For other files (shared lib, launchers, config, ...):/{module name}/
- * {@literal bin|conf|native}/{dir1}/.../{dirN}/{file name}</li>
- * </ul>
- */
-public interface ModuleEntry {
-
-    /**
-     * Type of module data.
-     * <li>
-     * <ul>CLASS_OR_RESOURCE: A java class or resource file.</ul>
-     * <ul>CONFIG: A configuration file.</ul>
-     * <ul>NATIVE_CMD: A native process launcher.</ul>
-     * <ul>NATIVE_LIB: A native library.</ul>
-     * <ul>OTHER: Other kind of file.</ul>
-     * </li>
-     */
-    public enum Type {
-        CLASS_OR_RESOURCE,
-        CONFIG,
-        NATIVE_CMD,
-        NATIVE_LIB,
-        OTHER
-    }
-    /**
-     * The ModuleEntry module name.
-     *
-     * @return The module name.
-     */
-    public String getModule();
-
-    /**
-     * The ModuleEntry path.
-     *
-     * @return The module path.
-     */
-    public String getPath();
-
-    /**
-     * The ModuleEntry's type.
-     *
-     * @return The data type.
-     */
-    public Type getType();
-
-    /**
-     * The ModuleEntry content as an array of bytes.
-     *
-     * @return An Array of bytes.
-     */
-    public default byte[] getBytes() {
-        try (InputStream is = stream()) {
-            return is.readAllBytes();
-        } catch (IOException ex) {
-            throw new UncheckedIOException(ex);
-        }
-    }
-
-    /**
-     * The ModuleEntry content length.
-     *
-     * @return The length.
-     */
-    public long getLength();
-
-    /**
-     * The ModuleEntry stream.
-     *
-     * @return The module data stream.
-     */
-    public InputStream stream();
-
-    /**
-     * Write the content of this ModuleEntry to stream.
-     *
-     * @param out the output stream
-     */
-    public default void write(OutputStream out) {
-        try {
-            out.write(getBytes());
-        } catch (IOException ex) {
-            throw new UncheckedIOException(ex);
-        }
-    }
-
-    /**
-     * Create a ModuleEntry with new content but other information
-     * copied from this ModuleEntry.
-     *
-     * @param content The new resource content.
-     * @return A new ModuleEntry.
-     */
-    public default ModuleEntry create(byte[] content) {
-        return ModuleEntryFactory.create(this, content);
-    }
-
-    /**
-     * Create a ModuleEntry with new content but other information
-     * copied from this ModuleEntry.
-     *
-     * @param file The new resource content.
-     * @return A new ModuleEntry.
-     */
-    public default ModuleEntry create(Path file) {
-        return ModuleEntryFactory.create(this, file);
-    }
-
-    /**
-     * Create a ModuleEntry for a resource of the given type.
-     *
-     * @param path The resource path.
-     * @param type The ModuleEntry type.
-     * @param content The resource content.
-     * @return A new ModuleEntry.
-     */
-    public static ModuleEntry create(String path,
-            ModuleEntry.Type type, byte[] content) {
-        return ModuleEntryFactory.create(path, type, content);
-    }
-
-    /**
-     * Create a ModuleEntry for a resource of type {@link Type#CLASS_OR_RESOURCE}.
-     *
-     * @param path The resource path.
-     * @param content The resource content.
-     * @return A new ModuleEntry.
-     */
-    public static ModuleEntry create(String path, byte[] content) {
-        return create(path, Type.CLASS_OR_RESOURCE, content);
-    }
-
-    /**
-     * Create a ModuleEntry for a resource of the given type.
-     *
-     * @param path The resource path.
-     * @param type The ModuleEntry type.
-     * @param file The resource file.
-     * @return A new ModuleEntry.
-     */
-    public static ModuleEntry create(String path,
-            ModuleEntry.Type type, Path file) {
-        return ModuleEntryFactory.create(path, type, file);
-    }
-
-    /**
-     * Create a ModuleEntry for a resource of type {@link Type#CLASS_OR_RESOURCE}.
-     *
-     * @param path The resource path.
-     * @param file The resource file.
-     * @return A new ModuleEntry.
-     */
-    public static ModuleEntry create(String path, Path file) {
-        return create(path, Type.CLASS_OR_RESOURCE, file);
-    }
-}
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ModulePool.java	Fri Jul 29 10:18:47 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jlink.plugin;
-
-import java.nio.ByteOrder;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.stream.Stream;
-
-/**
- * Pool of module data.
- */
-public interface ModulePool {
-/**
-     * Is this a read-only ModulePool?
-     *
-     * @return true if this is a read-only configuration.
-     */
-    public boolean isReadOnly();
-
-    /**
-     * Add a ModuleEntry.
-     *
-     * @param data The ModuleEntry to add.
-     */
-    public void add(ModuleEntry data);
-    /**
-     * Retrieves the module for the provided name.
-     *
-     * @param name The module name
-     * @return the module of matching name, if found
-     */
-    public Optional<LinkModule> findModule(String name);
-
-    /**
-     * The stream of modules contained in this ModulePool.
-     *
-     * @return The stream of modules.
-     */
-    public Stream<? extends LinkModule> modules();
-
-    /**
-     * Return the number of LinkModule count in this ModulePool.
-     *
-     * @return the module count.
-     */
-    public int getModuleCount();
-
-    /**
-     * Get all ModuleEntry contained in this ModulePool instance.
-     *
-     * @return The stream of LinkModuleEntries.
-     */
-    public Stream<? extends ModuleEntry> entries();
-
-    /**
-     * Return the number of ModuleEntry count in this ModulePool.
-     *
-     * @return the entry count.
-     */
-    public int getEntryCount();
-
-    /**
-     * Get the ModuleEntry for the passed path.
-     *
-     * @param path A data path
-     * @return A ModuleEntry instance or null if the data is not found
-     */
-    public Optional<ModuleEntry> findEntry(String path);
-
-    /**
-     * Get the ModuleEntry for the passed path restricted to supplied context.
-     *
-     * @param path A data path
-     * @param context A context of the search
-     * @return A ModuleEntry instance or null if the data is not found
-     */
-    public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context);
-
-    /**
-     * Check if the ModulePool contains the given ModuleEntry.
-     *
-     * @param data The module data to check existence for.
-     * @return The module data or null if not found.
-     */
-    public boolean contains(ModuleEntry data);
-
-    /**
-     * Check if the ModulePool contains some content at all.
-     *
-     * @return True, no content, false otherwise.
-     */
-    public boolean isEmpty();
-
-    /**
-     * Visit each ModuleEntry in this ModulePool to transform it and copy
-     * the transformed ModuleEntry to the output ModulePool.
-     *
-     * @param transform The function called for each ModuleEntry found in the
-     * ModulePool. The transform function should return a ModuleEntry
-     * instance which will be added to the output or it should return null if
-     * the passed ModuleEntry is to be ignored for the output.
-     *
-     * @param output The ModulePool to be filled with Visitor returned
-     * ModuleEntry.
-     */
-    public void transformAndCopy(Function<ModuleEntry, ModuleEntry> transform, ModulePool output);
-
-    /**
-     * The ByteOrder currently in use when generating the jimage file.
-     *
-     * @return The ByteOrder.
-     */
-    public ByteOrder getByteOrder();
-
-    /**
-     * Release properties such as OS, CPU name, version etc.
-     *
-     * @return the release properties
-     */
-    public Map<String, String> getReleaseProperties();
-}
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java	Fri Jul 29 10:18:47 2016 +0200
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java	Sat Jul 30 00:11:02 2016 +0000
@@ -191,5 +191,5 @@
      *
      * @throws PluginException
      */
-    public void visit(ModulePool in, ModulePool out);
+    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePool.java	Sat Jul 30 00:11:02 2016 +0000
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.plugin;
+
+import java.nio.ByteOrder;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+/**
+ * A Pool of Java resources.
+ */
+public interface ResourcePool {
+    /**
+     * Return the module view of this resource pool.
+     *
+     * @return a module based view of this resource pool.
+     */
+    public ResourcePoolModuleView moduleView();
+
+    /**
+     * Get all ResourcePoolEntry contained in this ResourcePool instance.
+     *
+     * @return The stream of ResourcePoolEntries.
+     */
+    public Stream<ResourcePoolEntry> entries();
+
+    /**
+     * Return the number of ResourcePoolEntry count in this ResourcePool.
+     *
+     * @return the entry count.
+     */
+    public int entryCount();
+
+    /**
+     * Get the ResourcePoolEntry for the passed path.
+     *
+     * @param path A data path
+     * @return A ResourcePoolEntry instance or null if the data is not found
+     */
+    public Optional<ResourcePoolEntry> findEntry(String path);
+
+    /**
+     * Get the ModuleEntry for the passed path restricted to supplied context.
+     *
+     * @param path A data path
+     * @param context A context of the search
+     * @return A ModuleEntry instance or null if the data is not found
+     */
+    public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context);
+
+    /**
+     * Check if the ResourcePool contains the given ResourcePoolEntry.
+     *
+     * @param data The module data to check existence for.
+     * @return The module data or null if not found.
+     */
+    public boolean contains(ResourcePoolEntry data);
+
+    /**
+     * Check if the ResourcePool contains some content at all.
+     *
+     * @return True, no content, false otherwise.
+     */
+    public boolean isEmpty();
+
+    /**
+     * The ByteOrder currently in use when generating the jimage file.
+     *
+     * @return The ByteOrder.
+     */
+    public ByteOrder byteOrder();
+
+    /**
+     * Release properties such as OS, CPU name, version etc.
+     *
+     * @return the release properties
+     */
+    public Map<String, String> releaseProperties();
+
+    /**
+     * Visit each ResourcePoolEntry in this ResourcePool to transform it and copy
+     * the transformed ResourcePoolEntry to the output ResourcePoolBuilder.
+     *
+     * @param transform The function called for each ResourcePoolEntry found in the
+     * ResourcePool. The transform function should return a ResourcePoolEntry
+     * instance which will be added to the output or it should return null if
+     * the passed ResourcePoolEntry is to be ignored for the output.
+     *
+     * @param outBuilder The ResourcePoolBuilder to be filled with Visitor returned
+     * ResourcePoolEntries.
+     */
+    public default void transformAndCopy(
+            Function<ResourcePoolEntry, ResourcePoolEntry> transform,
+            ResourcePoolBuilder outBuilder) {
+        entries().forEach(resource -> {
+            ResourcePoolEntry res = transform.apply(resource);
+            if (res != null) {
+                outBuilder.add(res);
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolBuilder.java	Sat Jul 30 00:11:02 2016 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.plugin;
+
+import java.nio.ByteOrder;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+/**
+ * Resource pool builder to build a resource pool by incrementally
+ * adding a set of resources one at a time.
+ */
+public interface ResourcePoolBuilder {
+    /**
+     * Add a ResourcePoolEntry.
+     *
+     * @param data The ResourcePoolEntry to add.
+     */
+    public void add(ResourcePoolEntry data);
+
+    /**
+     * Done with adding resource entries. Construct
+     * a ResourcePool with the added resource entries.
+     *
+     * @return a new ResourcePool filled with entries added.
+     */
+    public ResourcePool build();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolEntry.java	Sat Jul 30 00:11:02 2016 +0000
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.plugin;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import jdk.tools.jlink.internal.ResourcePoolEntryFactory;
+
+/**
+ * A ResourcePoolEntry is the elementary unit of data inside an image. It is
+ * generally a file. e.g.: a java class file, a resource file, a shared library.
+ * <br>
+ * A ResourcePoolEntry is identified by a path of the form:
+ * <ul>
+ * <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
+ * name}</li>
+ * <li>For other files (shared lib, launchers, config, ...):/{module name}/
+ * {@literal bin|conf|native}/{dir1}/.../{dirN}/{file name}</li>
+ * </ul>
+ */
+public interface ResourcePoolEntry {
+
+    /**
+     * Type of module data.
+     * <li>
+     * <ul>CLASS_OR_RESOURCE: A java class or resource file.</ul>
+     * <ul>CONFIG: A configuration file.</ul>
+     * <ul>NATIVE_CMD: A native process launcher.</ul>
+     * <ul>NATIVE_LIB: A native library.</ul>
+     * <ul>OTHER: Other kind of file.</ul>
+     * </li>
+     */
+    public enum Type {
+        CLASS_OR_RESOURCE,
+        CONFIG,
+        NATIVE_CMD,
+        NATIVE_LIB,
+        OTHER
+    }
+
+    /**
+     * The module name of this ResourcePoolEntry.
+     *
+     * @return The module name.
+     */
+    public String moduleName();
+
+    /**
+     * The path of this ResourcePoolEntry.
+     *
+     * @return The module path.
+     */
+    public String path();
+
+    /**
+     * The ResourcePoolEntry's type.
+     *
+     * @return The data type.
+     */
+    public Type type();
+
+    /**
+     * The ResourcePoolEntry content length.
+     *
+     * @return The content length.
+     */
+    public long contentLength();
+
+    /**
+     * The ResourcePoolEntry content as an InputStream.
+     *
+     * @return The resource content as an InputStream.
+     */
+    public InputStream content();
+
+    /**
+     * The ResourcePoolEntry content as an array of bytes.
+     *
+     * @return An Array of bytes.
+     */
+    public default byte[] contentBytes() {
+        try (InputStream is = content()) {
+            return is.readAllBytes();
+        } catch (IOException ex) {
+            throw new UncheckedIOException(ex);
+        }
+    }
+
+    /**
+     * Write the content of this ResourcePoolEntry to an OutputStream.
+     *
+     * @param out the output stream
+     */
+    public default void write(OutputStream out) {
+        try {
+            out.write(contentBytes());
+        } catch (IOException ex) {
+            throw new UncheckedIOException(ex);
+        }
+    }
+
+    /**
+     * Create a ResourcePoolEntry with new content but other information
+     * copied from this ResourcePoolEntry.
+     *
+     * @param content The new resource content.
+     * @return A new ResourcePoolEntry.
+     */
+    public default ResourcePoolEntry copyWithContent(byte[] content) {
+        return ResourcePoolEntryFactory.create(this, content);
+    }
+
+    /**
+     * Create a ResourcePoolEntry with new content but other information
+     * copied from this ResourcePoolEntry.
+     *
+     * @param file The new resource content.
+     * @return A new ResourcePoolEntry.
+     */
+    public default ResourcePoolEntry copyWithContent(Path file) {
+        return ResourcePoolEntryFactory.create(this, file);
+    }
+
+    /**
+     * Create a ResourcePoolEntry for a resource of the given type.
+     *
+     * @param path The resource path.
+     * @param type The ResourcePoolEntry type.
+     * @param content The resource content.
+     * @return A new ResourcePoolEntry.
+     */
+    public static ResourcePoolEntry create(String path,
+            ResourcePoolEntry.Type type, byte[] content) {
+        return ResourcePoolEntryFactory.create(path, type, content);
+    }
+
+    /**
+     * Create a ResourcePoolEntry for a resource of type {@link Type#CLASS_OR_RESOURCE}.
+     *
+     * @param path The resource path.
+     * @param content The resource content.
+     * @return A new ResourcePoolEntry.
+     */
+    public static ResourcePoolEntry create(String path, byte[] content) {
+        return create(path, Type.CLASS_OR_RESOURCE, content);
+    }
+
+    /**
+     * Create a ResourcePoolEntry for a resource of the given type.
+     *
+     * @param path The resource path.
+     * @param type The ResourcePoolEntry type.
+     * @param file The resource file.
+     * @return A new ResourcePoolEntry.
+     */
+    public static ResourcePoolEntry create(String path,
+            ResourcePoolEntry.Type ty