Merge
authorohair
Tue, 01 Dec 2009 08:54:10 -0800
changeset 4343 41c142b31e48
parent 4342 9f3aa1172803 (current diff)
parent 4340 ec6ba551fa78 (diff)
child 4345 28e064ec21bb
Merge
jdk/test/tools/launcher/SolarisDataModel.sh
jdk/test/tools/launcher/SolarisRunpath.sh
jdk/test/tools/launcher/libraryCaller.c
jdk/test/tools/launcher/libraryCaller.h
jdk/test/tools/launcher/libraryCaller.java
--- a/jdk/make/java/jli/Makefile	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/make/java/jli/Makefile	Tue Dec 01 08:54:10 2009 -0800
@@ -96,6 +96,7 @@
 
 
 ifneq ($(PLATFORM), windows)	# UNIX systems
+        LD_RUNPATH_EXTRAS += ..
 	LIB_LOCATION = $(LIBDIR)/$(LIBARCH)/jli
 	# Note: its important to keep this order meaning -lc is the
 	# last library otherwise it could cause compatibility issues
--- a/jdk/make/java/main/java/Makefile	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/make/java/main/java/Makefile	Tue Dec 01 08:54:10 2009 -0800
@@ -61,8 +61,5 @@
 
 ifeq ($(PLATFORM), solaris)
 LDFLAGS += -R$(OPENWIN_LIB)
-endif
-
-ifeq ($(PLATFORM), solaris)
 LDFLAGS += -M mapfile-$(ARCH)
 endif
--- a/jdk/make/java/redist/Makefile	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/make/java/redist/Makefile	Tue Dec 01 08:54:10 2009 -0800
@@ -194,10 +194,8 @@
 # For backwards compatability, make a link of the 32-bit client JVM to $(LIBDIR)
 IMPORT_LIST += $(LIB_LOCATION)/$(JVM_NAME)
 
-# create a link from lib/libjvm.so to client/libjvm.so
 $(LIB_LOCATION)/$(JVM_NAME): $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_NAME)
 	@$(prep-target)
-	$(LN) -s $(CLIENT_LOCATION)/$(JVM_NAME) $@
 
 #  solaris   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ solaris
 endif # 32bit solaris
--- a/jdk/make/sun/javazic/tzdata/VERSION	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/VERSION	Tue Dec 01 08:54:10 2009 -0800
@@ -21,4 +21,4 @@
 # CA 95054 USA or visit www.sun.com if you need additional information or
 # have any questions.
 #
-tzdata2009l
+tzdata2009r
--- a/jdk/make/sun/javazic/tzdata/antarctica	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/antarctica	Tue Dec 01 08:54:10 2009 -0800
@@ -102,15 +102,38 @@
 # Davis, Vestfold Hills, -6835+07759, since 1957-01-13
 #	(except 1964-11 - 1969-02)
 # Mawson, Holme Bay, -6736+06253, since 1954-02-13
+
+# From Steffen Thorsen (2009-03-11):
+# Three Australian stations in Antarctica have changed their time zone:
+# Casey moved from UTC+8 to UTC+11
+# Davis moved from UTC+7 to UTC+5
+# Mawson moved from UTC+6 to UTC+5
+# The changes occurred on 2009-10-18 at 02:00 (local times).
+#
+# Government source: (Australian Antarctic Division)
+# <a href="http://www.aad.gov.au/default.asp?casid=37079">
+# http://www.aad.gov.au/default.asp?casid=37079
+# </a>
+#
+# We have more background information here:
+# <a href="http://www.timeanddate.com/news/time/antarctica-new-times.html">
+# http://www.timeanddate.com/news/time/antarctica-new-times.html
+# </a>
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Antarctica/Casey	0	-	zzz	1969
-			8:00	-	WST	# Western (Aus) Standard Time
+			8:00	-	WST	2009 Oct 18 2:00
+						# Western (Aus) Standard Time
+			11:00	-	CAST	# Casey Time
 Zone Antarctica/Davis	0	-	zzz	1957 Jan 13
 			7:00	-	DAVT	1964 Nov # Davis Time
 			0	-	zzz	1969 Feb
-			7:00	-	DAVT
+			7:00	-	DAVT	2009 Oct 18 2:0
+			5:00	-	DAVT
 Zone Antarctica/Mawson	0	-	zzz	1954 Feb 13
-			6:00	-	MAWT	# Mawson Time
+			6:00	-	MAWT	2009 Oct 18 2:00
+						# Mawson Time
+			5:00	-	MAWT
 # References:
 # <a href="http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html">
 # Casey Weather (1998-02-26)
--- a/jdk/make/sun/javazic/tzdata/asia	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/asia	Tue Dec 01 08:54:10 2009 -0800
@@ -21,7 +21,6 @@
 # CA 95054 USA or visit www.sun.com if you need additional information or
 # have any questions.
 #
-# <pre>
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -194,11 +193,30 @@
 #
 # No DST end date has been announced yet.
 
-# From Arthur David Olson (2009-07-11):
-# Arbitrarily end DST at the end of 2009 so that a POSIX-sytle time zone string
-# can appear in the Dhaka binary file and for the benefit of old glibc
-# reimplementations of the time zone software that mishandle permanent DST.
-# A change will be required once the end date is known.
+# From Alexander Krivenyshev (2009-09-25):
+# Bangladesh won't go back to Standard Time from October 1, 2009, 
+# instead it will continue DST measure till the cabinet makes a fresh decision. 
+#
+# Following report by same newspaper-"The Daily Star Friday":
+# "DST change awaits cabinet decision-Clock won't go back by 1-hr from Oct 1"
+# <a href="http://www.thedailystar.net/newDesign/news-details.php?nid=107021">
+# http://www.thedailystar.net/newDesign/news-details.php?nid=107021
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh04.html">
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh04.html
+# </a>
+
+# From Steffen Thorsen (2009-10-13):
+# IANS (Indo-Asian News Service) now reports:
+# Bangladesh has decided that the clock advanced by an hour to make 
+# maximum use of daylight hours as an energy saving measure would 
+# "continue for an indefinite period."
+#
+# One of many places where it is published:
+# <a href="http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html">
+# http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html
+# </a>
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Dhaka	6:01:40 -	LMT	1890
@@ -208,8 +226,7 @@
 			6:30	-	BURT	1951 Sep 30
 			6:00	-	DACT	1971 Mar 26 # Dacca Time
 			6:00	-	BDT	2009 Jun 19 23:00 # Bangladesh Time
-			6:00	1:00	BDST	2010
-			6:00	-	BDT
+			6:00	1:00	BDST
 
 # Bhutan
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -373,14 +390,84 @@
 			5:00	-	KAST	1980 May
 			8:00	PRC	C%sT
 
+
+# From Lee Yiu Chung (2009-10-24):
+# I found there are some mistakes for the historial DST rule for Hong
+# Kong. Accoring to the DST record from Hong Kong Observatory (actually,
+# it is not [an] observatory, but the official meteorological agency of HK,
+# and also serves as the official timing agency), there are some missing
+# and incorrect rules. Although the exact switch over time is missing, I
+# think 3:30 is correct. The official DST record for Hong Kong can be
+# obtained from
+# <a href="http://www.hko.gov.hk/gts/time/Summertime.htm">
+# http://www.hko.gov.hk/gts/time/Summertime.htm
+# </a>.
+
+# From Arthur David Olson (2009-10-28):
+# Here are the dates given at
+# <a href="http://www.hko.gov.hk/gts/time/Summertime.htm">
+# http://www.hko.gov.hk/gts/time/Summertime.htm
+# </a>
+# as of 2009-10-28:
+# Year        Period
+# 1941        1 Apr to 30 Sep
+# 1942        Whole year 
+# 1943        Whole year
+# 1944        Whole year
+# 1945        Whole year
+# 1946        20 Apr to 1 Dec
+# 1947        13 Apr to 30 Dec
+# 1948        2 May to 31 Oct
+# 1949        3 Apr to 30 Oct
+# 1950        2 Apr to 29 Oct
+# 1951        1 Apr to 28 Oct
+# 1952        6 Apr to 25 Oct
+# 1953        5 Apr to 1 Nov
+# 1954        21 Mar to 31 Oct
+# 1955        20 Mar to 6 Nov
+# 1956        18 Mar to 4 Nov
+# 1957        24 Mar to 3 Nov
+# 1958        23 Mar to 2 Nov
+# 1959        22 Mar to 1 Nov
+# 1960        20 Mar to 6 Nov
+# 1961        19 Mar to 5 Nov
+# 1962        18 Mar to 4 Nov
+# 1963        24 Mar to 3 Nov
+# 1964        22 Mar to 1 Nov
+# 1965        18 Apr to 17 Oct
+# 1966        17 Apr to 16 Oct
+# 1967        16 Apr to 22 Oct
+# 1968        21 Apr to 20 Oct
+# 1969        20 Apr to 19 Oct
+# 1970        19 Apr to 18 Oct
+# 1971        18 Apr to 17 Oct
+# 1972        16 Apr to 22 Oct
+# 1973        22 Apr to 21 Oct
+# 1973/74     30 Dec 73 to 20 Oct 74
+# 1975        20 Apr to 19 Oct
+# 1976        18 Apr to 17 Oct
+# 1977        Nil
+# 1978        Nil
+# 1979        13 May to 21 Oct
+# 1980 to Now Nil
+# The page does not give start or end times of day.
+# The page does not give a start date for 1942.
+# The page does not givw an end date for 1945.
+# The Japanese occupation of Hong Kong began on 1941-12-25.
+# The Japanese surrender of Hong Kong was signed 1945-09-15.
+# For lack of anything better, use start of those days as the transition times.
+
 # Hong Kong (Xianggang)
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	HK	1941	only	-	Apr	1	3:30	1:00	S
+Rule	HK	1941	only	-	Sep	30	3:30	0	-
 Rule	HK	1946	only	-	Apr	20	3:30	1:00	S
 Rule	HK	1946	only	-	Dec	1	3:30	0	-
 Rule	HK	1947	only	-	Apr	13	3:30	1:00	S
 Rule	HK	1947	only	-	Dec	30	3:30	0	-
 Rule	HK	1948	only	-	May	2	3:30	1:00	S
-Rule	HK	1948	1952	-	Oct	lastSun	3:30	0	-
+Rule	HK	1948	1951	-	Oct	lastSun	3:30	0	-
+Rule	HK	1952	only	-	Oct	25	3:30	0	-
 Rule	HK	1949	1953	-	Apr	Sun>=1	3:30	1:00	S
 Rule	HK	1953	only	-	Nov	1	3:30	0	-
 Rule	HK	1954	1964	-	Mar	Sun>=18	3:30	1:00	S
@@ -388,13 +475,15 @@
 Rule	HK	1955	1964	-	Nov	Sun>=1	3:30	0	-
 Rule	HK	1965	1977	-	Apr	Sun>=16	3:30	1:00	S
 Rule	HK	1965	1977	-	Oct	Sun>=16	3:30	0	-
-Rule	HK	1979	1980	-	May	Sun>=8	3:30	1:00	S
-Rule	HK	1979	1980	-	Oct	Sun>=16	3:30	0	-
+Rule	HK	1973	only	-	Dec	30	3:30	1:00	S
+Rule	HK	1979	only	-	May	Sun>=8	3:30	1:00	S
+Rule	HK	1979	only	-	Oct	Sun>=16	3:30	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
+			8:00	HK	HK%sT	1941 Dec 25
+			9:00	-	JST	1945 Sep 15
 			8:00	HK	HK%sT
 
-
 ###############################################################################
 
 # Taiwan
@@ -1696,16 +1785,66 @@
 # advance clocks in the country by one hour from April 15 to
 # conserve energy"
 
-# From Arthur David Olson (2009-04-10):
-# Assume for now that Pakistan will end DST in 2009 as it did in 2008.
+# From Steffen Thorsen (2009-09-17):
+# "The News International," Pakistan reports that: "The Federal
+# Government has decided to restore the previous time by moving the
+# clocks backward by one hour from October 1. A formal announcement to
+# this effect will be made after the Prime Minister grants approval in
+# this regard." 
+# <a href="http://www.thenews.com.pk/updates.asp?id=87168">
+# http://www.thenews.com.pk/updates.asp?id=87168
+# </a>
+
+# From Alexander Krivenyshev (2009-09-28):
+# According to Associated Press Of Pakistan, it is confirmed that
+# Pakistan clocks across the country would be turned back by an hour from October
+# 1, 2009.
+#
+# "Clocks to go back one hour from 1 Oct"
+# <a href="http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=86715&Itemid=2">
+# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=86715&Itemid=2
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan07.htm">
+# http://www.worldtimezone.com/dst_news/dst_news_pakistan07.htm
+# </a>
+
+# From Steffen Thorsen (2009-09-29):
+# Alexander Krivenyshev wrote:
+# > According to Associated Press Of Pakistan, it is confirmed that
+# > Pakistan clocks across the country would be turned back by an hour from October
+# > 1, 2009.
+#
+# Now they seem to have changed their mind, November 1 is the new date:
+# <a href="http://www.thenews.com.pk/top_story_detail.asp?Id=24742">
+# http://www.thenews.com.pk/top_story_detail.asp?Id=24742
+# </a>
+# "The country's clocks will be reversed by one hour on November 1.
+# Officials of Federal Ministry for Interior told this to Geo News on
+# Monday."
+#
+# And more importantly, it seems that these dates will be kept every year:
+# "It has now been decided that clocks will be wound forward by one hour
+# on April 15 and reversed by an hour on November 1 every year without
+# obtaining prior approval, the officials added."
+#
+# We have confirmed this year's end date with both with the Ministry of
+# Water and Power and the Pakistan Electric Power Company:
+# <a href="http://www.timeanddate.com/news/time/pakistan-ends-dst09.html">
+# http://www.timeanddate.com/news/time/pakistan-ends-dst09.html
+# </a>
+
+# From Christoph Goehre (2009-10-01):
+# [T]he German Consulate General in Karachi reported me today that Pakistan
+# will go back to standard time on 1st of November.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule Pakistan	2002	only	-	Apr	Sun>=2	0:01	1:00	S
 Rule Pakistan	2002	only	-	Oct	Sun>=2	0:01	0	-
 Rule Pakistan	2008	only	-	Jun	1	0:00	1:00	S
 Rule Pakistan	2008	only	-	Nov	1	0:00	0	-
-Rule Pakistan	2009	only	-	Apr	15	0:00	1:00	S
-Rule Pakistan	2009	only	-	Nov	1	0:00	0	-
+Rule Pakistan	2009	max	-	Apr	15	0:00	1:00	S
+Rule Pakistan	2009	max	-	Nov	1	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Karachi	4:28:12 -	LMT	1907
 			5:30	-	IST	1942 Sep
@@ -1858,6 +1997,42 @@
 # http://www.worldtimezone.com/dst_news/dst_news_westbank01.html
 # </a>
 
+# From Steffen Thorsen (2009-08-31):
+# Palestine's Council of Ministers announced that they will revert back to
+# winter time on Friday, 2009-09-04.
+#
+# One news source:
+# <a href="http://www.safa.ps/ara/?action=showdetail&seid=4158">
+# http://www.safa.ps/ara/?action=showdetail&seid=4158
+# </a>
+# (Palestinian press agency, Arabic),
+# Google translate: "Decided that the Palestinian government in Ramallah
+# headed by Salam Fayyad, the start of work in time for the winter of
+# 2009, starting on Friday approved the fourth delay Sept. clock sixty
+# minutes per hour as of Friday morning."
+#
+# We are not sure if Gaza will do the same, last year they had a different
+# end date, we will keep this page updated:
+# <a href="http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html">
+# http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html
+# </a>
+
+# From Alexander Krivenyshev (2009-09-02):
+# Seems that Gaza Strip will go back to Winter Time same date as West Bank.
+#
+# According to Palestinian Ministry Of Interior, West Bank and Gaza Strip plan
+# to change time back to Standard time on September 4, 2009.
+#
+# "Winter time unite the West Bank and Gaza"
+# (from Palestinian National Authority):
+# <a href="http://www.moi.gov.ps/en/?page=633167343250594025&nid=11505
+# http://www.moi.gov.ps/en/?page=633167343250594025&nid=11505
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html>
+# http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html
+# </a>
+
 # The rules for Egypt are stolen from the `africa' file.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
@@ -1876,7 +2051,7 @@
 Rule Palestine	2007	only	-	Sep	Thu>=8	2:00	0	-
 Rule Palestine	2008	only	-	Aug	lastFri	2:00	0	-
 Rule Palestine	2009	max	-	Mar	lastFri	0:00	1:00	S
-Rule Palestine	2009	max	-	Sep	lastMon	2:00	0	-
+Rule Palestine	2009	max	-	Sep	Fri>=1	2:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
@@ -2154,9 +2329,23 @@
 # http://www.timeanddate.com/news/time/syria-dst-starts-march-27-2009.html
 # </a>
 
+# From Steffen Thorsen (2009-10-27):
+# The Syrian Arab News Network on 2009-09-29 reported that Syria will 
+# revert back to winter (standard) time on midnight between Thursday 
+# 2009-10-29 and Friday 2009-10-30:
+# <a href="http://www.sana.sy/ara/2/2009/09/29/247012.htm">
+# http://www.sana.sy/ara/2/2009/09/29/247012.htm (Arabic)
+# </a>
+
+# From Arthur David Olson (2009-10-28):
+# We'll see if future DST switching times turn out to be end of the last
+# Thursday of the month or the start of the last Friday of the month or
+# something else. For now, use the start of the last Friday.
+
 Rule	Syria	2008	only	-	Apr	Fri>=1	0:00	1:00	S
-Rule	Syria	2008	max	-	Nov	1	0:00	0	-
+Rule	Syria	2008	only	-	Nov	1	0:00	0	-
 Rule	Syria	2009	max	-	Mar	lastFri	0:00	1:00	S
+Rule	Syria	2009	max	-	Oct	lastFri	0:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Damascus	2:25:12 -	LMT	1920	# Dimashq
--- a/jdk/make/sun/javazic/tzdata/australasia	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/australasia	Tue Dec 01 08:54:10 2009 -0800
@@ -465,10 +465,56 @@
 # http://www.worldtimezone.com/dst_news/dst_news_samoa01.html
 # </a>
 
+# From Steffen Thorsen (2009-08-27):
+# Samoa's parliament passed the Daylight Saving Bill 2009, and will start 
+# daylight saving time on the first Sunday of October 2009 and end on the 
+# last Sunday of March 2010. We hope that the full text will be published 
+# soon, but we believe that the bill is only valid for 2009-2010. Samoa's 
+# Daylight Saving Act 2009 will be enforced as soon as the Head of State 
+# executes a proclamation publicizing this Act.
+#
+# Some background information here, which will be updated once we have 
+# more details:
+# <a href="http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html">
+# http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html
+# </a>
+
+# From Alexander Krivenyshev (2009-10-03):
+# First, my deepest condolences to people of Samoa islands and all families and
+# loved ones around the world who lost their lives in the earthquake and tsunami.
+#
+# Considering the recent devastation on Samoa by earthquake and tsunami and that
+# many government offices/ ministers are closed- not sure if "Daylight Saving
+# Bill 2009" will be implemented in next few days- on October 4, 2009.
+#
+# Here is reply from Consulate-General of Samoa in New Zealand
+# ---------------------------
+# Consul General
+# consulgeneral@samoaconsulate.org.nz
+#
+# Talofa Alexander,
+#
+# Thank you for your sympathy for our country but at this time we have not
+# been informed about the Daylight Savings Time Change.  Most Ministries in
+# Apia are closed or relocating due to weather concerns.
+#
+# When we do find out if they are still proceeding with the time change we
+# will advise you soonest.
+#
+# Kind Regards,
+# Lana
+# for: Consul General
+
+# From Steffen Thorsen (2009-10-05):
+# We have called a hotel in Samoa and asked about local time there - they 
+# are still on standard time.
+
 Zone Pacific/Apia	 12:33:04 -	LMT	1879 Jul  5
 			-11:26:56 -	LMT	1911
 			-11:30	-	SAMT	1950		# Samoa Time
-			-11:00	-	WST			# Samoa Time
+			-11:00	-	WST	2009 Oct 4
+			-11:00	1:00	WSDT	2010 Mar 28
+			-11:00	-	WST
 
 # Solomon Is
 # excludes Bougainville, for which see Papua New Guinea
--- a/jdk/make/sun/javazic/tzdata/europe	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/europe	Tue Dec 01 08:54:10 2009 -0800
@@ -2094,9 +2094,43 @@
 			 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
+
+# From Alexander Krivenyshev (2009-10-13):
+# Kemerovo oblast' (Kemerovo region) in Russia will change current time zone on
+# March 28, 2010:
+# from current Russia Zone 6 - Krasnoyarsk Time Zone (KRA) UTC +0700
+# to Russia Zone 5 - Novosibirsk Time Zone (NOV) UTC +0600
+#
+# This is according to Government of Russia decree # 740, on September
+# 14, 2009 "Application in the territory of the Kemerovo region the Fifth
+# time zone." ("Russia Zone 5" or old "USSR Zone 5" is GMT +0600)
+#
+# Russian Government web site (Russian language)
+# <a href="http://www.government.ru/content/governmentactivity/rfgovernmentdecisions/archiv">
+# http://www.government.ru/content/governmentactivity/rfgovernmentdecisions/archive/2009/09/14/991633.htm
+# </a>
+# or Russian-English translation by WorldTimeZone.com with reference
+# map to local region and new Russia Time Zone map after March 28, 2010
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_russia03.html">
+# http://www.worldtimezone.com/dst_news/dst_news_russia03.html
+# </a>
+#
+# Thus, when Russia will switch to DST on the night of March 28, 2010
+# Kemerovo region (Kemerovo oblast') will not change the clock.
+#
+# As a result, Kemerovo oblast' will be in the same time zone as
+# Novosibirsk, Omsk, Tomsk, Barnaul and Altai Republic.
+
+Zone Asia/Novokuznetsk	 5:48:48 -	NMT	1920 Jan  6
+			 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 # Novosibirsk/Novokuznetsk Time
+
 #
 # From Oscar van Vlijmen (2001-08-25): [This region consists of]
-# Kemerovskaya oblast', Krasnoyarskij kraj,
+# Krasnoyarskij kraj,
 # Tajmyrskij (Dolgano-Nenetskij) avtonomnyj okrug,
 # Respublika Tuva, Respublika Khakasiya, Evenkijskij avtonomnyj okrug.
 Zone Asia/Krasnoyarsk	 6:11:20 -	LMT	1920 Jan  6
--- a/jdk/make/sun/javazic/tzdata/southamerica	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/southamerica	Tue Dec 01 08:54:10 2009 -0800
@@ -237,9 +237,23 @@
 # http://www.jujuy.gov.ar/index2/partes_prensa/18_10_08/235-181008.doc
 # </a>
 
+# From fullinet (2009-10-18):
+# As announced in
+# <a hef="http://www.argentina.gob.ar/argentina/portal/paginas.dhtml?pagina=356">
+# http://www.argentina.gob.ar/argentina/portal/paginas.dhtml?pagina=356
+# </a>
+# (an official .gob.ar) under title: "Sin Cambio de Hora" (english: "No hour change")
+#
+# "Por el momento, el Gobierno Nacional resolvio no modificar la hora
+# oficial, decision que estaba en estudio para su implementacion el
+# domingo 18 de octubre. Desde el Ministerio de Planificacion se anuncio
+# que la Argentina hoy, en estas condiciones meteorologicas, no necesita
+# la modificacion del huso horario, ya que 2009 nos encuentra con
+# crecimiento en la produccion y distribucion energetica."
+
 Rule	Arg	2007	only	-	Dec	30	0:00	1:00	S
-Rule	Arg	2008	max	-	Mar	Sun>=15	0:00	0	-
-Rule	Arg	2008	max	-	Oct	Sun>=15	0:00	1:00	S
+Rule	Arg	2008	2009	-	Mar	Sun>=15	0:00	0	-
+Rule	Arg	2008	only	-	Oct	Sun>=15	0:00	1:00	S
  
 # From Mariano Absatz (2004-05-21):
 # Today it was officially published that the Province of Mendoza is changing
@@ -411,15 +425,40 @@
 # during 2009, this timezone change will run from 00:00 the third Sunday
 # in March until 24:00 of the second Saturday in October.
 
-# From Arthur David Olson (2009-03-16):
-# The unofficial claim at
-# <a href="http://www.timeanddate.com/news/time/san-luis-new-time-zone.html">
-# http://www.timeanddate.com/news/time/san-luis-new-time-zone.html
+# From Mariano Absatz (2009-10-16):
+# ...the Province of San Luis is a case in itself.
+#
+# The Law at
+# <a href="http://www.diputadossanluis.gov.ar/diputadosasp/paginas/verNorma.asp?NormaID=276>"
+# http://www.diputadossanluis.gov.ar/diputadosasp/paginas/verNorma.asp?NormaID=276
 # </a>
-# is that "The province will most likely follow the next daylight saving schedule,
-# which is planned for the second Sunday in October."
+# is ambiguous because establishes a calendar from the 2nd Sunday in
+# October at 0:00 thru the 2nd Saturday in March at 24:00 and the
+# complement of that starting on the 2nd Sunday of March at 0:00 and
+# ending on the 2nd Saturday of March at 24:00.
+#
+# This clearly breaks every time the 1st of March or October is a Sunday.
+#
+# IMHO, the "spirit of the Law" is to make the changes at 0:00 on the 2nd
+# Sunday of October and March.
+#
+# The problem is that the changes in the rest of the Provinces that did
+# change in 2007/2008, were made according to the Federal Law and Decrees
+# that did so on the 3rd Sunday of October and March.
+#
+# In fact, San Luis actually switched from UTC-4 to UTC-3 last Sunday
+# (October 11th) at 0:00.
+#
+# So I guess a new set of rules, besides "Arg", must be made and the last
+# America/Argentina/San_Luis entries should change to use these...
+#
+# I'm enclosing a patch that does what I say... regretfully, the San Luis
+# timezone must be called "WART/WARST" even when most of the time (like,
+# right now) WARST == ART... that is, since last Sunday, all the country
+# is using UTC-3, but in my patch, San Luis calls it "WARST" and the rest
+# of the country calls it "ART".
+# ...
 
-#
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #
 # Buenos Aires (BA), Capital Federal (CF),
@@ -552,6 +591,10 @@
 			-3:00	-	ART
 #
 # San Luis (SL)
+
+Rule	SanLuis	2008	max	-	Mar	Sun>=8	0:00	0	-
+Rule	SanLuis	2007	max	-	Oct	Sun>=8	0:00	1:00	S
+
 Zone America/Argentina/San_Luis -4:25:24 - LMT	1894 Oct 31
 			-4:16:48 -	CMT	1920 May
 			-4:00	-	ART	1930 Dec
@@ -566,8 +609,7 @@
 			-3:00	-	ART	2004 May 31
 			-4:00	-	WART	2004 Jul 25
 			-3:00	Arg	AR%sT	2008 Jan 21
-			-3:00	-	ART	2009 Mar 15
-			-4:00	Arg	WAR%sT
+			-4:00	SanLuis	WAR%sT
 #
 # Santa Cruz (SC)
 Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31
--- a/jdk/make/sun/javazic/tzdata/zone.tab	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/make/sun/javazic/tzdata/zone.tab	Tue Dec 01 08:54:10 2009 -0800
@@ -352,6 +352,7 @@
 RU	+5651+06036	Asia/Yekaterinburg	Moscow+02 - Urals
 RU	+5500+07324	Asia/Omsk	Moscow+03 - west Siberia
 RU	+5502+08255	Asia/Novosibirsk	Moscow+03 - Novosibirsk
+RU	+5345+08707	Asia/Novokuznetsk	Moscow+03 - Novokuznetsk
 RU	+5601+09250	Asia/Krasnoyarsk	Moscow+04 - Yenisei River
 RU	+5216+10420	Asia/Irkutsk	Moscow+05 - Lake Baikal
 RU	+6200+12940	Asia/Yakutsk	Moscow+06 - Lena River
--- a/jdk/src/share/bin/java.c	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/bin/java.c	Tue Dec 01 08:54:10 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1995-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,15 +41,13 @@
  * options are turned into "-foo" options to the vm.  This option
  * filtering is handled in a number of places in the launcher, some of
  * it in machine-dependent code.  In this file, the function
- * CheckJVMType removes vm style options and TranslateApplicationArgs
- * removes "-J" prefixes.  On unix platforms, the
- * CreateExecutionEnvironment function from the unix java_md.c file
- * processes and removes -d<n> options.  However, in case
- * CreateExecutionEnvironment does not need to exec because
- * LD_LIBRARY_PATH is set acceptably and the data model does not need
- * to be changed, ParseArguments will screen out the redundant -d<n>
- * options and prevent them from being passed to the vm; this is done
- * by RemovableOption.
+ * CheckJvmType removes vm style options and TranslateApplicationArgs
+ * removes "-J" prefixes.  The CreateExecutionEnvironment function processes
+ * and removes -d<n> options. On unix, there is a possibility that the running
+ * data model may not match to the desired data model, in this case an exec is
+ * required to start the desired model. If the data models match, then
+ * ParseArguments will remove the -d<n> flags. If the data models do not match
+ * the CreateExecutionEnviroment will remove the -d<n> flags.
  */
 
 
@@ -1891,11 +1889,11 @@
  * Return JNI_TRUE for an option string that has no effect but should
  * _not_ be passed on to the vm; return JNI_FALSE otherwise.  On
  * Solaris SPARC, this screening needs to be done if:
- * 1) LD_LIBRARY_PATH does _not_ need to be reset and
- * 2) -d32 or -d64 is passed to a binary with a matching data model
- *    (the exec in SetLibraryPath removes -d<n> options and points the
- *    exec to the proper binary).  When this exec is not done, these options
- *    would end up getting passed onto the vm.
+ *    -d32 or -d64 is passed to a binary with an unmatched data model
+ *    (the exec in CreateExecutionEnvironment removes -d<n> options and points the
+ *    exec to the proper binary).  In the case of when the data model and the
+ *    requested version is matched, an exec would not occur, and these options
+ *    were erroneously passed to the vm.
  */
 jboolean
 RemovableOption(char * option)
--- a/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java	Tue Dec 01 08:54:10 2009 -0800
@@ -99,4 +99,58 @@
      */
     public Object inquireSecContext(InquireType type)
             throws GSSException;
+
+    /**
+     * Requests that the delegation policy be respected. When a true value is
+     * requested, the underlying context would use the delegation policy
+     * defined by the environment as a hint to determine whether credentials
+     * delegation should be performed. This request can only be made on the
+     * context initiator's side and it has to be done prior to the first
+     * call to <code>initSecContext</code>.
+     * <p>
+     * When this flag is false, delegation will only be tried when the
+     * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag}
+     * is true.
+     * <p>
+     * When this flag is true but the
+     * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag}
+     * is false, delegation will be only tried if the delegation policy permits
+     * delegation.
+     * <p>
+     * When both this flag and the
+     * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag}
+     * are true, delegation will be always tried. However, if the delegation
+     * policy does not permit delegation, the value of
+     * {@link #getDelegPolicyState} will be false, even
+     * if delegation is performed successfully.
+     * <p>
+     * In any case, if the delegation is not successful, the value returned
+     * by {@link GSSContext#getCredDelegState()} is false, and the value
+     * returned by {@link #getDelegPolicyState()} is also false.
+     * <p>
+     * Not all mechanisms support delegation policy. Therefore, the
+     * application should check to see if the request was honored with the
+     * {@link #getDelegPolicyState() getDelegPolicyState} method. When
+     * delegation policy is not supported, <code>requestDelegPolicy</code>
+     * should return silently without throwing an exception.
+     * <p>
+     * Note: for the Kerberos 5 mechanism, the delegation policy is expressed
+     * through the OK-AS-DELEGATE flag in the service ticket. When it's true,
+     * the KDC permits delegation to the target server. In a cross-realm
+     * environment, in order for delegation be permitted, all cross-realm TGTs
+     * on the authentication path must also have the OK-AS-DELAGATE flags set.
+     * @param state true if the policy should be respected
+     * @throws GSSException containing the following
+     * major error codes:
+     *   {@link GSSException#FAILURE GSSException.FAILURE}
+     */
+    public void requestDelegPolicy(boolean state) throws GSSException;
+
+    /**
+     * Returns the delegation policy response. Called after a security context
+     * is established. This method can be only called on the initiator's side.
+     * See {@link ExtendedGSSContext#requestDelegPolicy}.
+     * @return the delegation policy response
+     */
+    public boolean getDelegPolicyState();
 }
--- a/jdk/src/share/classes/java/applet/Applet.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/java/applet/Applet.java	Tue Dec 01 08:54:10 2009 -0800
@@ -230,6 +230,21 @@
     }
 
     /**
+     * Indicates if this container is a validate root.
+     * <p>
+     * {@code Applet} objects are the validate roots, and, therefore, they
+     * override this method to return {@code true}.
+     *
+     * @return {@code true}
+     * @since 1.7
+     * @see java.awt.Container#isValidateRoot
+     */
+    @Override
+    public boolean isValidateRoot() {
+        return true;
+    }
+
+    /**
      * Requests that the argument string be displayed in the
      * "status window". Many browsers and applet viewers
      * provide such a window, where the application can inform users of
--- a/jdk/src/share/classes/java/awt/AWTPermission.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/java/awt/AWTPermission.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -92,7 +92,15 @@
  *   <td>Enter full-screen exclusive mode</td>
  *   <td>Entering full-screen exclusive mode allows direct access to
  * low-level graphics card memory.  This could be used to spoof the
- * system, since the program is in direct control of rendering.</td>
+ * system, since the program is in direct control of rendering. Depending on
+ * the implementation, the security warning may not be shown for the windows
+ * used to enter the full-screen exclusive mode (assuming that the {@code
+ * fullScreenExclusive} permission has been granted to this application). Note
+ * that this behavior does not mean that the {@code
+ * showWindowWithoutWarningBanner} permission will be automatically granted to
+ * the application which has the {@code fullScreenExclusive} permission:
+ * non-full-screen windows will continue to be shown with the security
+ * warning.</td>
  * </tr>
  *
  * <tr>
--- a/jdk/src/share/classes/java/awt/Component.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/java/awt/Component.java	Tue Dec 01 08:54:10 2009 -0800
@@ -2764,8 +2764,11 @@
     }
 
     /**
-     * Ensures that this component has a valid layout.  This method is
-     * primarily intended to operate on instances of <code>Container</code>.
+     * Validates this component.
+     * <p>
+     * The meaning of the term <i>validating</i> is defined by the ancestors of
+     * this class. See {@link Container#validate} for more details.
+     *
      * @see       #invalidate
      * @see       #doLayout()
      * @see       LayoutManager
@@ -2794,12 +2797,24 @@
     }
 
     /**
-     * Invalidates this component.  This component and all parents
-     * above it are marked as needing to be laid out.  This method can
-     * be called often, so it needs to execute quickly.
+     * Invalidates this component and its ancestors.
+     * <p>
+     * All the ancestors of this component up to the nearest validate root are
+     * marked invalid also. If there is no a validate root container for this
+     * component, all of its ancestors up to the root of the hierarchy are
+     * marked invalid as well. Marking a container <i>invalid</i> indicates
+     * that the container needs to be laid out.
+     * <p>
+     * This method is called automatically when any layout-related information
+     * changes (e.g. setting the bounds of the component, or adding the
+     * component to a container).
+     * <p>
+     * This method might be called often, so it should work fast.
+     *
      * @see       #validate
      * @see       #doLayout
      * @see       LayoutManager
+     * @see       java.awt.Container#isValidateRoot
      * @since     JDK1.0
      */
     public void invalidate() {
@@ -2818,9 +2833,18 @@
             if (!isMaximumSizeSet()) {
                 maxSize = null;
             }
-            if (parent != null) {
-                parent.invalidateIfValid();
-            }
+            invalidateParent();
+        }
+    }
+
+    /**
+     * Invalidates the parent of this component if any.
+     *
+     * This method MUST BE invoked under the TreeLock.
+     */
+    void invalidateParent() {
+        if (parent != null) {
+            parent.invalidateIfValid();
         }
     }
 
@@ -6727,12 +6751,13 @@
                     }
                 }
             } else {
-                // It's native.  If the parent is lightweight it
-                // will need some help.
-                Container parent = this.parent;
-                if (parent != null && parent.peer instanceof LightweightPeer) {
+                // It's native. If the parent is lightweight it will need some
+                // help.
+                Container parent = getContainer();
+                if (parent != null && parent.isLightweight()) {
                     relocateComponent();
-                    if (!isRecursivelyVisible()) {
+                    if (!parent.isRecursivelyVisibleUpToHeavyweightContainer())
+                    {
                         peer.setVisible(false);
                     }
                 }
--- a/jdk/src/share/classes/java/awt/Container.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/java/awt/Container.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1492,20 +1492,59 @@
     }
 
     /**
-     * Invalidates the container.  The container and all parents
-     * above it are marked as needing to be laid out.  This method can
-     * be called often, so it needs to execute quickly.
+     * Indicates if this container is a <i>validate root</i>.
+     * <p>
+     * Layout-related changes, such as bounds of the validate root descendants,
+     * do not affect the layout of the validate root parent. This peculiarity
+     * enables the {@code invalidate()} method to stop invalidating the
+     * component hierarchy when the method encounters a validate root.
+     * <p>
+     * If a component hierarchy contains validate roots, the {@code validate()}
+     * method must be invoked on the validate root of a previously invalidated
+     * component, rather than on the top-level container (such as a {@code
+     * Frame} object) to restore the validity of the hierarchy later.
+     * <p>
+     * The {@code Window} class and the {@code Applet} class are the validate
+     * roots in AWT.  Swing introduces more validate roots.
      *
-     * <p> If the {@code LayoutManager} installed on this container is
-     * an instance of {@code LayoutManager2}, then
-     * {@link LayoutManager2#invalidateLayout(Container)} is invoked on
-     * it supplying this {@code Container} as the argument.
+     * @return whether this container is a validate root
+     * @see #invalidate
+     * @see java.awt.Component#invalidate
+     * @see javax.swing.JComponent#isValidateRoot
+     * @see javax.swing.JComponent#revalidate
+     * @since 1.7
+     */
+    public boolean isValidateRoot() {
+        return false;
+    }
+
+    /**
+     * Invalidates the parent of the container unless the container
+     * is a validate root.
+     */
+    @Override
+    void invalidateParent() {
+        if (!isValidateRoot()) {
+            super.invalidateParent();
+        }
+    }
+
+    /**
+     * Invalidates the container.
+     * <p>
+     * If the {@code LayoutManager} installed on this container is an instance
+     * of the {@code LayoutManager2} interface, then
+     * the {@link LayoutManager2#invalidateLayout(Container)} method is invoked
+     * on it supplying this {@code Container} as the argument.
+     * <p>
+     * Afterwards this method marks this container invalid, and invalidates its
+     * ancestors. See the {@link Component#invalidate} method for more details.
      *
      * @see #validate
      * @see #layout
-     * @see LayoutManager
-     * @see LayoutManager2#invalidateLayout(Container)
+     * @see LayoutManager2
      */
+    @Override
     public void invalidate() {
         LayoutManager layoutMgr = this.layoutMgr;
         if (layoutMgr instanceof LayoutManager2) {
@@ -1518,52 +1557,90 @@
     /**
      * Validates this container and all of its subcomponents.
      * <p>
-     * The <code>validate</code> method is used to cause a container
-     * to lay out its subcomponents again. It should be invoked when
-     * this container's subcomponents are modified (added to or
-     * removed from the container, or layout-related information
-     * changed) after the container has been displayed.
-     *
-     * <p>If this {@code Container} is not valid, this method invokes
+     * Validating a container means laying out its subcomponents.
+     * Layout-related changes, such as setting the bounds of a component, or
+     * adding a component to the container, invalidate the container
+     * automatically.  Note that the ancestors of the container may be
+     * invalidated also (see {@link Component#invalidate} for details.)
+     * Therefore, to restore the validity of the hierarchy, the {@code
+     * validate()} method should be invoked on a validate root of an
+     * invalidated component, or on the top-most container if the hierarchy
+     * does not contain validate roots.
+     * <p>
+     * Validating the container may be a quite time-consuming operation. For
+     * performance reasons a developer may postpone the validation of the
+     * hierarchy till a set of layout-related operations completes, e.g. after
+     * adding all the children to the container.
+     * <p>
+     * If this {@code Container} is not valid, this method invokes
      * the {@code validateTree} method and marks this {@code Container}
      * as valid. Otherwise, no action is performed.
-     * <p>
-     * Note that the {@code invalidate()} method may invalidate not only the
-     * component it is called upon, but also the parents of the component.
-     * Therefore, to restore the validity of the hierarchy, the {@code
-     * validate()} method must be invoked on the top-most invalid container of
-     * the hierarchy. For performance reasons a developer may postpone the
-     * validation of the hierarchy till a bunch of layout-related operations
-     * completes, e.g. after adding all the children to the container.
      *
      * @see #add(java.awt.Component)
      * @see #invalidate
+     * @see Container#isValidateRoot
      * @see javax.swing.JComponent#revalidate()
      * @see #validateTree
      */
     public void validate() {
-        /* Avoid grabbing lock unless really necessary. */
-        if (!isValid()) {
-            boolean updateCur = false;
-            synchronized (getTreeLock()) {
-                if (!isValid() && peer != null) {
-                    ContainerPeer p = null;
-                    if (peer instanceof ContainerPeer) {
-                        p = (ContainerPeer) peer;
-                    }
-                    if (p != null) {
-                        p.beginValidate();
-                    }
-                    validateTree();
-                    if (p != null) {
-                        p.endValidate();
+        boolean updateCur = false;
+        synchronized (getTreeLock()) {
+            if ((!isValid() || descendUnconditionallyWhenValidating)
+                    && peer != null)
+            {
+                ContainerPeer p = null;
+                if (peer instanceof ContainerPeer) {
+                    p = (ContainerPeer) peer;
+                }
+                if (p != null) {
+                    p.beginValidate();
+                }
+                validateTree();
+                if (p != null) {
+                    p.endValidate();
+                    // Avoid updating cursor if this is an internal call.
+                    // See validateUnconditionally() for details.
+                    if (!descendUnconditionallyWhenValidating) {
                         updateCur = isVisible();
                     }
                 }
             }
-            if (updateCur) {
-                updateCursorImmediately();
+        }
+        if (updateCur) {
+            updateCursorImmediately();
+        }
+    }
+
+    /**
+     * Indicates whether valid containers should also traverse their
+     * children and call the validateTree() method on them.
+     *
+     * Synchronization: TreeLock.
+     *
+     * The field is allowed to be static as long as the TreeLock itself is
+     * static.
+     *
+     * @see #validateUnconditionally()
+     */
+    private static boolean descendUnconditionallyWhenValidating = false;
+
+    /**
+     * Unconditionally validate the component hierarchy.
+     */
+    final void validateUnconditionally() {
+        boolean updateCur = false;
+        synchronized (getTreeLock()) {
+            descendUnconditionallyWhenValidating = true;
+
+            validate();
+            if (peer instanceof ContainerPeer) {
+                updateCur = isVisible();
             }
+
+            descendUnconditionallyWhenValidating = false;
+        }
+        if (updateCur) {
+            updateCursorImmediately();
         }
     }
 
@@ -1578,16 +1655,20 @@
      */
     protected void validateTree() {
         checkTreeLock();
-        if (!isValid()) {
+        if (!isValid() || descendUnconditionallyWhenValidating) {
             if (peer instanceof ContainerPeer) {
                 ((ContainerPeer)peer).beginLayout();
             }
-            doLayout();
+            if (!isValid()) {
+                doLayout();
+            }
             for (int i = 0; i < component.size(); i++) {
                 Component comp = component.get(i);
                 if (   (comp instanceof Container)
                        && !(comp instanceof Window)
-                       && !comp.isValid()) {
+                       && (!comp.isValid() ||
+                           descendUnconditionallyWhenValidating))
+                {
                     ((Container)comp).validateTree();
                 } else {
                     comp.validate();
@@ -4092,16 +4173,29 @@
         }
     }
 
-    /*
+    /**
+     * Checks if the container and its direct lightweight containers are
+     * visible.
+     *
      * Consider the heavyweight container hides or shows the HW descendants
      * automatically. Therefore we care of LW containers' visibility only.
+     *
+     * This method MUST be invoked under the TreeLock.
      */
-    private boolean isRecursivelyVisibleUpToHeavyweightContainer() {
+    final boolean isRecursivelyVisibleUpToHeavyweightContainer() {
         if (!isLightweight()) {
             return true;
         }
-        return isVisible() && (getContainer() == null ||
-             getContainer().isRecursivelyVisibleUpToHeavyweightContainer());
+
+        for (Container cont = getContainer();
+                cont != null && cont.isLightweight();
+                cont = cont.getContainer())
+        {
+            if (!cont.isVisible()) {
+                return false;
+            }
+        }
+        return true;
     }
 
     @Override
--- a/jdk/src/share/classes/java/awt/EventQueue.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/java/awt/EventQueue.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1027,7 +1027,9 @@
 
         synchronized (lock) {
             Toolkit.getEventQueue().postEvent(event);
-            lock.wait();
+            while (!event.isDispatched()) {
+                lock.wait();
+            }
         }
 
         Throwable eventThrowable = event.getThrowable();
--- a/jdk/src/share/classes/java/awt/Frame.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/java/awt/Frame.java	Tue Dec 01 08:54:10 2009 -0800
@@ -845,8 +845,11 @@
      * others by setting those fields you want to accept from system
      * to <code>Integer.MAX_VALUE</code>.
      * <p>
-     * On some systems only the size portion of the bounds is taken
-     * into account.
+     * Note, the given maximized bounds are used as a hint for the native
+     * system, because the underlying platform may not support setting the
+     * location and/or size of the maximized windows.  If that is the case, the
+     * provided values do not affect the appearance of the frame in the
+     * maximized state.
      *
      * @param bounds  bounds for the maximized state
      * @see #getMaximizedBounds()
--- a/jdk/src/share/classes/java/awt/Window.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/java/awt/Window.java	Tue Dec 01 08:54:10 2009 -0800
@@ -767,7 +767,7 @@
             isPacked = true;
         }
 
-        validate();
+        validateUnconditionally();
     }
 
     /**
@@ -943,7 +943,7 @@
         if (peer == null) {
             addNotify();
         }
-        validate();
+        validateUnconditionally();
 
         isInShow = true;
         if (visible) {
@@ -2600,6 +2600,21 @@
     }
 
     /**
+     * Indicates if this container is a validate root.
+     * <p>
+     * {@code Window} objects are the validate roots, and, therefore, they
+     * override this method to return {@code true}.
+     *
+     * @return {@code true}
+     * @since 1.7
+     * @see java.awt.Container#isValidateRoot
+     */
+    @Override
+    public boolean isValidateRoot() {
+        return true;
+    }
+
+    /**
      * Dispatches an event to this window or one of its sub components.
      * @param e the event
      */
--- a/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1184,7 +1184,7 @@
     */
 
     public boolean isRepresentationClassRemote() {
-        return java.rmi.Remote.class.isAssignableFrom(representationClass);
+        return DataTransferer.isRemote(representationClass);
     }
 
    /**
--- a/jdk/src/share/classes/java/awt/event/InvocationEvent.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/java/awt/event/InvocationEvent.java	Tue Dec 01 08:54:10 2009 -0800
@@ -78,11 +78,22 @@
 
     /**
      * The (potentially null) Object whose notifyAll() method will be called
-     * immediately after the Runnable.run() method returns.
+     * immediately after the Runnable.run() method has returned or thrown an exception.
+     *
+     * @see #isDispatched
      */
     protected Object notifier;
 
     /**
+     * Indicates whether the <code>run()</code> method of the <code>runnable</code>
+     * was executed or not.
+     *
+     * @see #isDispatched
+     * @since 1.7
+     */
+    private volatile boolean dispatched = false;
+
+    /**
      * Set to true if dispatch() catches Throwable and stores it in the
      * exception instance variable. If false, Throwables are propagated up
      * to the EventDispatchThread's dispatch loop.
@@ -144,7 +155,7 @@
      * source which will execute the runnable's <code>run</code>
      * method when dispatched.  If notifier is non-<code>null</code>,
      * <code>notifyAll()</code> will be called on it
-     * immediately after <code>run</code> returns.
+     * immediately after <code>run</code> has returned or thrown an exception.
      * <p>An invocation of the form <tt>InvocationEvent(source,
      * runnable, notifier, catchThrowables)</tt>
      * behaves in exactly the same way as the invocation of
@@ -159,7 +170,8 @@
      *                          executed
      * @param notifier          The {@code Object} whose <code>notifyAll</code>
      *                          method will be called after
-     *                          <code>Runnable.run</code> has returned
+     *                          <code>Runnable.run</code> has returned or
+     *                          thrown an exception
      * @param catchThrowables   Specifies whether <code>dispatch</code>
      *                          should catch Throwable when executing
      *                          the <code>Runnable</code>'s <code>run</code>
@@ -180,8 +192,8 @@
      * Constructs an <code>InvocationEvent</code> with the specified
      * source and ID which will execute the runnable's <code>run</code>
      * method when dispatched.  If notifier is non-<code>null</code>,
-     * <code>notifyAll</code> will be called on it
-     * immediately after <code>run</code> returns.
+     * <code>notifyAll</code> will be called on it immediately after
+     * <code>run</code> has returned or thrown an exception.
      * <p>This method throws an
      * <code>IllegalArgumentException</code> if <code>source</code>
      * is <code>null</code>.
@@ -195,7 +207,8 @@
      *                          <code>run</code> method will be executed
      * @param notifier          The <code>Object</code> whose <code>notifyAll</code>
      *                          method will be called after
-     *                          <code>Runnable.run</code> has returned
+     *                          <code>Runnable.run</code> has returned or
+     *                          thrown an exception
      * @param catchThrowables   Specifies whether <code>dispatch</code>
      *                          should catch Throwable when executing the
      *                          <code>Runnable</code>'s <code>run</code>
@@ -217,27 +230,33 @@
 
     /**
      * Executes the Runnable's <code>run()</code> method and notifies the
-     * notifier (if any) when <code>run()</code> returns.
+     * notifier (if any) when <code>run()</code> has returned or thrown an exception.
+     *
+     * @see #isDispatched
      */
     public void dispatch() {
-        if (catchExceptions) {
-            try {
+        try {
+            if (catchExceptions) {
+                try {
+                    runnable.run();
+                }
+                catch (Throwable t) {
+                    if (t instanceof Exception) {
+                        exception = (Exception) t;
+                    }
+                    throwable = t;
+                }
+            }
+            else {
                 runnable.run();
             }
-            catch (Throwable t) {
-                if (t instanceof Exception) {
-                    exception = (Exception) t;
+        } finally {
+            dispatched = true;
+
+            if (notifier != null) {
+                synchronized (notifier) {
+                    notifier.notifyAll();
                 }
-                throwable = t;
-            }
-        }
-        else {
-            runnable.run();
-        }
-
-        if (notifier != null) {
-            synchronized (notifier) {
-                notifier.notifyAll();
             }
         }
     }
@@ -278,6 +297,40 @@
     }
 
     /**
+     * Returns {@code true} if the event is dispatched or any exception is
+     * thrown while dispatching, {@code false} otherwise. The method should
+     * be called by a waiting thread that calls the {@code notifier.wait()} method.
+     * Since spurious wakeups are possible (as explained in {@link Object#wait()}),
+     * this method should be used in a waiting loop to ensure that the event
+     * got dispatched:
+     * <pre>
+     *     while (!event.isDispatched()) {
+     *         notifier.wait();
+     *     }
+     * </pre>
+     * If the waiting thread wakes up without dispatching the event,
+     * the {@code isDispatched()} method returns {@code false}, and
+     * the {@code while} loop executes once more, thus, causing
+     * the awakened thread to revert to the waiting mode.
+     * <p>
+     * If the {@code notifier.notifyAll()} happens before the waiting thread
+     * enters the {@code notifier.wait()} method, the {@code while} loop ensures
+     * that the waiting thread will not enter the {@code notifier.wait()} method.
+     * Otherwise, there is no guarantee that the waiting thread will ever be woken
+     * from the wait.
+     *
+     * @return {@code true} if the event has been dispatched, or any exception
+     * has been thrown while dispatching, {@code false} otherwise
+     * @see #dispatch
+     * @see #notifier
+     * @see #catchExceptions
+     * @since 1.7
+     */
+    public boolean isDispatched() {
+        return dispatched;
+    }
+
+    /**
      * Returns a parameter string identifying this event.
      * This method is useful for event-logging and for debugging.
      *
--- a/jdk/src/share/classes/java/awt/font/NumericShaper.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/java/awt/font/NumericShaper.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,13 @@
 
 package java.awt.font;
 
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.Set;
+
 /**
  * The <code>NumericShaper</code> class is used to convert Latin-1 (European)
  * digits to other Unicode decimal digits.  Users of this class will
@@ -64,13 +71,261 @@
  *      NumericShaper.getContextualShaper(NumericShaper.ARABIC |
  *                                              NumericShaper.TAMIL,
  *                                              NumericShaper.EUROPEAN);
- *   shaper.shape(text. start, count);
+ *   shaper.shape(text, start, count);
+ * </pre></blockquote>
+ *
+ * <p><b>Bit mask- and enum-based Unicode ranges</b></p>
+ *
+ * <p>This class supports two different programming interfaces to
+ * represent Unicode ranges for script-specific digits: bit
+ * mask-based ones, such as {@link #ARABIC NumericShaper.ARABIC}, and
+ * enum-based ones, such as {@link NumericShaper.Range#ARABIC}.
+ * Multiple ranges can be specified by ORing bit mask-based constants,
+ * such as:
+ * <blockquote><pre>
+ * NumericShaper.ARABIC | NumericShaper.TAMIL
  * </pre></blockquote>
+ * or creating a {@code Set} with the {@link NumericShaper.Range}
+ * constants, such as:
+ * <blockquote><pre>
+ * EnumSet.of(NumericShaper.Scirpt.ARABIC, NumericShaper.Range.TAMIL)
+ * </pre></blockquote>
+ * The enum-based ranges are a super set of the bit mask-based ones.
+ *
+ * <p>If the two interfaces are mixed (including serialization),
+ * Unicode range values are mapped to their counterparts where such
+ * mapping is possible, such as {@code NumericShaper.Range.ARABIC}
+ * from/to {@code NumericShaper.ARABIC}.  If any unmappable range
+ * values are specified, such as {@code NumericShaper.Range.BALINESE},
+ * those ranges are ignored.
  *
  * @since 1.4
  */
 
 public final class NumericShaper implements java.io.Serializable {
+    /**
+     * A {@code NumericShaper.Range} represents a Unicode range of a
+     * script having its own decimal digits. For example, the {@link
+     * NumericShaper.Range#THAI} range has the Thai digits, THAI DIGIT
+     * ZERO (U+0E50) to THAI DIGIT NINE (U+0E59).
+     *
+     * <p>The <code>Range</code> enum replaces the traditional bit
+     * mask-based values (e.g., {@link NumericShaper#ARABIC}), and
+     * supports more Unicode ranges than the bit mask-based ones. For
+     * example, the following code using the bit mask:
+     * <blockquote><pre>
+     * NumericShaper.getContextualShaper(NumericShaper.ARABIC |
+     *                                     NumericShaper.TAMIL,
+     *                                   NumericShaper.EUROPEAN);
+     * </pre></blockquote>
+     * can be written using this enum as:
+     * <blockquote><pre>
+     * NumericShaper.getContextualShaper(EnumSet.of(
+     *                                     NumericShaper.Range.ARABIC,
+     *                                     NumericShaper.Range.TAMIL),
+     *                                   NumericShaper.Range.EUROPEAN);
+     * </pre></blockquote>
+     *
+     * @since 1.7
+     */
+    public static enum Range {
+        /**
+         * The Latin (European) range with the Latin (ASCII) digits.
+         */
+        EUROPEAN        ('\u0030', '\u0000', '\u0300'),
+        /**
+         * The Arabic range with the Arabic-Indic digits.
+         */
+        ARABIC          ('\u0660', '\u0600', '\u0780'),
+        /**
+         * The Arabic range with the Eastern Arabic-Indic digits.
+         */
+        EASTERN_ARABIC  ('\u06f0', '\u0600', '\u0780'),
+        /**
+         * The Devanagari range with the Devanagari digits.
+         */
+        DEVANAGARI      ('\u0966', '\u0900', '\u0980'),
+        /**
+         * The Bengali range with the Bengali digits.
+         */
+        BENGALI         ('\u09e6', '\u0980', '\u0a00'),
+        /**
+         * The Gurmukhi range with the Gurmukhi digits.
+         */
+        GURMUKHI        ('\u0a66', '\u0a00', '\u0a80'),
+        /**
+         * The Gujarati range with the Gujarati digits.
+         */
+        GUJARATI        ('\u0ae6', '\u0b00', '\u0b80'),
+        /**
+         * The Oriya range with the Oriya digits.
+         */
+        ORIYA           ('\u0b66', '\u0b00', '\u0b80'),
+        /**
+         * The Tamil range with the Tamil digits.
+         */
+        TAMIL           ('\u0be6', '\u0b80', '\u0c00'),
+        /**
+         * The Telugu range with the Telugu digits.
+         */
+        TELUGU          ('\u0c66', '\u0c00', '\u0c80'),
+        /**
+         * The Kannada range with the Kannada digits.
+         */
+        KANNADA         ('\u0ce6', '\u0c80', '\u0d00'),
+        /**
+         * The Malayalam range with the Malayalam digits.
+         */
+        MALAYALAM       ('\u0d66', '\u0d00', '\u0d80'),
+        /**
+         * The Thai range with the Thai digits.
+         */
+        THAI            ('\u0e50', '\u0e00', '\u0e80'),
+        /**
+         * The Lao range with the Lao digits.
+         */
+        LAO             ('\u0ed0', '\u0e80', '\u0f00'),
+        /**
+         * The Tibetan range with the Tibetan digits.
+         */
+        TIBETAN         ('\u0f20', '\u0f00', '\u1000'),
+        /**
+         * The Myanmar range with the Myanmar digits.
+         */
+        MYANMAR         ('\u1040', '\u1000', '\u1080'),
+        /**
+         * The Ethiopic range with the Ethiopic digits. Ethiopic
+         * does not have a decimal digit 0 so Latin (European) 0 is
+         * used.
+         */
+        ETHIOPIC        ('\u1369', '\u1200', '\u1380') {
+            @Override
+            char getNumericBase() { return 1; }
+        },
+        /**
+         * The Khmer range with the Khmer digits.
+         */
+        KHMER           ('\u17e0', '\u1780', '\u1800'),
+        /**
+         * The Mongolian range with the Mongolian digits.
+         */
+        MONGOLIAN       ('\u1810', '\u1800', '\u1900'),
+        /**
+         * The N'Ko range with the N'Ko digits.
+         */
+        NKO             ('\u07c0', '\u07c0', '\u0800'),
+        /**
+         * The Myanmar range with the Myanmar Shan digits.
+         */
+        MYANMAR_SHAN    ('\u1090', '\u1000', '\u10a0'),
+        /**
+         * The Limbu range with the Limbu digits.
+         */
+        LIMBU           ('\u1946', '\u1900', '\u1950'),
+        /**
+         * The New Tai Lue range with the New Tai Lue digits.
+         */
+        NEW_TAI_LUE     ('\u19d0', '\u1980', '\u19e0'),
+        /**
+         * The Balinese range with the Balinese digits.
+         */
+        BALINESE        ('\u1b50', '\u1b00', '\u1b80'),
+        /**
+         * The Sundanese range with the Sundanese digits.
+         */
+        SUNDANESE       ('\u1bb0', '\u1b80', '\u1bc0'),
+        /**
+         * The Lepcha range with the Lepcha digits.
+         */
+        LEPCHA          ('\u1c40', '\u1c00', '\u1c50'),
+        /**
+         * The Ol Chiki range with the Ol Chiki digits.
+         */
+        OL_CHIKI        ('\u1c50', '\u1c50', '\u1c80'),
+        /**
+         * The Vai range with the Vai digits.
+         */
+        VAI             ('\ua620', '\ua500', '\ua640'),
+        /**
+         * The Saurashtra range with the Saurashtra digits.
+         */
+        SAURASHTRA      ('\ua8d0', '\ua880', '\ua8e0'),
+        /**
+         * The Kayah Li range with the Kayah Li digits.
+         */
+        KAYAH_LI        ('\ua900', '\ua900', '\ua930'),
+        /**
+         * The Cham range with the Cham digits.
+         */
+        CHAM            ('\uaa50', '\uaa00', '\uaa60');
+
+        private static final Range[] ranges = Range.class.getEnumConstants();
+        static {
+            // sort ranges[] by base for binary search
+            Arrays.sort(ranges,
+                        new Comparator<Range>() {
+                            public int compare(Range s1, Range s2) {
+                                return s1.base > s2.base ? 1 : s1.base == s2.base ? 0 : -1;
+                            }
+                        });
+        }
+
+        private static int toRangeIndex(Range script) {
+            int index = script.ordinal();
+            return index < NUM_KEYS ? index : -1;
+        }
+
+        private static Range indexToRange(int index) {
+            return index < NUM_KEYS ? Range.values()[index] : null;
+        }
+
+        private static int toRangeMask(Set<Range> ranges) {
+            int m = 0;
+            for (Range range : ranges) {
+                int index = range.ordinal();
+                if (index < NUM_KEYS) {
+                    m |= 1 << index;
+                }
+            }
+            return m;
+        }
+
+        private static Set<Range> maskToRangeSet(int mask) {
+            Set<Range> set = EnumSet.noneOf(Range.class);
+            Range[] a = Range.values();
+            for (int i = 0; i < NUM_KEYS; i++) {
+                if ((mask & (1 << i)) != 0) {
+                    set.add(a[i]);
+                }
+            }
+            return set;
+        }
+
+        // base character of range digits
+        private final int base;
+        // Unicode range
+        private final int start, // inclusive
+                          end;   // exclusive
+
+        private Range(int base, int start, int end) {
+            this.base = base - ('0' + getNumericBase());
+            this.start = start;
+            this.end = end;
+        }
+
+        private int getDigitBase() {
+            return base;
+        }
+
+        char getNumericBase() {
+            return 0;
+        }
+
+        private boolean inRange(int c) {
+            return start <= c && c < end;
+        }
+    }
+
     /** index of context for contextual shaping - values range from 0 to 18 */
     private int key;
 
@@ -79,6 +334,25 @@
      */
     private int mask;
 
+    /**
+     * The context {@code Range} for contextual shaping or the {@code
+     * Range} for non-contextual shaping. {@code null} for the bit
+     * mask-based API.
+     *
+     * @since 1.7
+     */
+    private Range shapingRange;
+
+    /**
+     * {@code Set<Range>} indicating which Unicode ranges to
+     * shape. {@code null} for the bit mask-based API.
+     *
+     * @since 1.7
+     */
+    private transient Set<Range> rangeSet;
+
+    private static final long serialVersionUID = -8022764705923730308L;
+
     /** Identifies the Latin-1 (European) and extended range, and
      *  Latin-1 (European) decimal base.
      */
@@ -105,9 +379,8 @@
     /** Identifies the ORIYA range and decimal base. */
     public static final int ORIYA = 1<<7;
 
-    /** Identifies the TAMIL range and decimal base. Tamil does not have a
-     *  decimal digit 0 so Latin-1 (European) 0 is used.
-     */
+    /** Identifies the TAMIL range and decimal base. */
+    // TAMIL DIGIT ZERO was added in Unicode 4.1
     public static final int TAMIL = 1<<8;
 
     /** Identifies the TELUGU range and decimal base. */
@@ -140,7 +413,12 @@
     /** Identifies the MONGOLIAN range and decimal base. */
     public static final int MONGOLIAN = 1<<18;
 
-    /** Identifies all ranges, for full contextual shaping. */
+    /** Identifies all ranges, for full contextual shaping.
+     *
+     * <p>This constant specifies all of the bit mask-based
+     * ranges. Use {@code EmunSet.allOf(NumericShaper.Range.class)} to
+     * specify all of the enum-based ranges.
+     */
     public static final int ALL_RANGES = 0x0007ffff;
 
     private static final int EUROPEAN_KEY = 0;
@@ -163,42 +441,20 @@
     private static final int KHMER_KEY = 17;
     private static final int MONGOLIAN_KEY = 18;
 
-    private static final int NUM_KEYS = 19;
-
-    private static final String[] keyNames = {
-        "EUROPEAN",
-        "ARABIC",
-        "EASTERN_ARABIC",
-        "DEVANAGARI",
-        "BENGALI",
-        "GURMUKHI",
-        "GUJARATI",
-        "ORIYA",
-        "TAMIL",
-        "TELUGU",
-        "KANNADA",
-        "MALAYALAM",
-        "THAI",
-        "LAO",
-        "TIBETAN",
-        "MYANMAR",
-        "ETHIOPIC",
-        "KHMER",
-        "MONGOLIAN"
-    };
+    private static final int NUM_KEYS = MONGOLIAN_KEY + 1; // fixed
 
     private static final int CONTEXTUAL_MASK = 1<<31;
 
     private static final char[] bases = {
         '\u0030' - '\u0030', // EUROPEAN
-        '\u0660' - '\u0030', // ARABIC
-        '\u06f0' - '\u0030', // EASTERN_ARABIC
+        '\u0660' - '\u0030', // ARABIC-INDIC
+        '\u06f0' - '\u0030', // EXTENDED ARABIC-INDIC (EASTERN_ARABIC)
         '\u0966' - '\u0030', // DEVANAGARI
         '\u09e6' - '\u0030', // BENGALI
         '\u0a66' - '\u0030', // GURMUKHI
         '\u0ae6' - '\u0030', // GUJARATI
         '\u0b66' - '\u0030', // ORIYA
-        '\u0be7' - '\u0030', // TAMIL - note missing zero
+        '\u0be6' - '\u0030', // TAMIL - zero was added in Unicode 4.1
         '\u0c66' - '\u0030', // TELUGU
         '\u0ce6' - '\u0030', // KANNADA
         '\u0d66' - '\u0030', // MALAYALAM
@@ -206,7 +462,7 @@
         '\u0ed0' - '\u0030', // LAO
         '\u0f20' - '\u0030', // TIBETAN
         '\u1040' - '\u0030', // MYANMAR
-        '\u1369' - '\u0030', // ETHIOPIC
+        '\u1369' - '\u0031', // ETHIOPIC - no zero
         '\u17e0' - '\u0030', // KHMER
         '\u1810' - '\u0030', // MONGOLIAN
     };
@@ -215,14 +471,14 @@
 
     private static final char[] contexts = {
         '\u0000', '\u0300', // 'EUROPEAN' (really latin-1 and extended)
-        '\u0600', '\u0700', // ARABIC
-        '\u0600', '\u0700', // EASTERN_ARABIC -- note overlap with arabic
+        '\u0600', '\u0780', // ARABIC
+        '\u0600', '\u0780', // EASTERN_ARABIC -- note overlap with arabic
         '\u0900', '\u0980', // DEVANAGARI
         '\u0980', '\u0a00', // BENGALI
         '\u0a00', '\u0a80', // GURMUKHI
         '\u0a80', '\u0b00', // GUJARATI
         '\u0b00', '\u0b80', // ORIYA
-        '\u0b80', '\u0c00', // TAMIL - note missing zero
+        '\u0b80', '\u0c00', // TAMIL
         '\u0c00', '\u0c80', // TELUGU
         '\u0c80', '\u0d00', // KANNADA
         '\u0d00', '\u0d80', // MALAYALAM
@@ -230,7 +486,7 @@
         '\u0e80', '\u0f00', // LAO
         '\u0f00', '\u1000', // TIBETAN
         '\u1000', '\u1080', // MYANMAR
-        '\u1200', '\u1380', // ETHIOPIC
+        '\u1200', '\u1380', // ETHIOPIC - note missing zero
         '\u1780', '\u1800', // KHMER
         '\u1800', '\u1900', // MONGOLIAN
         '\uffff',
@@ -254,378 +510,290 @@
         return (ctCache & 0x1) == 0 ? (ctCache / 2) : EUROPEAN_KEY;
     }
 
+    // cache for the NumericShaper.Range version
+    private transient volatile Range currentRange = Range.EUROPEAN;
+
+    private Range rangeForCodePoint(int codepoint) {
+        Range range = currentRange;
+        if (range.inRange(codepoint)) {
+            return range;
+        }
+
+        final Range[] ranges = Range.ranges;
+        int lo = 0;
+        int hi = ranges.length - 1;
+        while (lo <= hi) {
+            int mid = (lo + hi) / 2;
+            range = ranges[mid];
+            if (codepoint < range.start) {
+                hi = mid - 1;
+            } else if (codepoint >= range.end) {
+                lo = mid + 1;
+            } else {
+                currentRange = range;
+                return range;
+            }
+        }
+        return Range.EUROPEAN;
+    }
+
     /*
      * A range table of strong directional characters (types L, R, AL).
      * Even (left) indexes are starts of ranges of non-strong-directional (or undefined)
      * characters, odd (right) indexes are starts of ranges of strong directional
      * characters.
      */
-    private static char[] strongTable = {
-        '\u0000', '\u0041',
-        '\u005b', '\u0061',
-        '\u007b', '\u00aa',
-        '\u00ab', '\u00b5',
-        '\u00b6', '\u00ba',
-        '\u00bb', '\u00c0',
-        '\u00d7', '\u00d8',
-        '\u00f7', '\u00f8',
-        '\u0220', '\u0222',
-        '\u0234', '\u0250',
-        '\u02ae', '\u02b0',
-        '\u02b9', '\u02bb',
-        '\u02c2', '\u02d0',
-        '\u02d2', '\u02e0',
-        '\u02e5', '\u02ee',
-        '\u02ef', '\u037a',
-        '\u037b', '\u0386',
-        '\u0387', '\u0388',
-        '\u038b', '\u038c',
-        '\u038d', '\u038e',
-        '\u03a2', '\u03a3',
-        '\u03cf', '\u03d0',
-        '\u03d8', '\u03da',
-        '\u03f4', '\u0400',
-        '\u0483', '\u048c',
-        '\u04c5', '\u04c7',
-        '\u04c9', '\u04cb',
-        '\u04cd', '\u04d0',
-        '\u04f6', '\u04f8',
-        '\u04fa', '\u0531',
-        '\u0557', '\u0559',
-        '\u0560', '\u0561',
-        '\u0588', '\u0589',
-        '\u058a', '\u05be',
-        '\u05bf', '\u05c0',
-        '\u05c1', '\u05c3',
-        '\u05c4', '\u05d0',
-        '\u05eb', '\u05f0',
-        '\u05f5', '\u061b',
-        '\u061c', '\u061f',
-        '\u0620', '\u0621',
-        '\u063b', '\u0640',
-        '\u064b', '\u066d',
-        '\u066e', '\u0671',
-        '\u06d6', '\u06e5',
-        '\u06e7', '\u06fa',
-        '\u06ff', '\u0700',
-        '\u070e', '\u0710',
-        '\u0711', '\u0712',
-        '\u072d', '\u0780',
-        '\u07a6', '\u0903',
-        '\u0904', '\u0905',
-        '\u093a', '\u093d',
-        '\u0941', '\u0949',
-        '\u094d', '\u0950',
-        '\u0951', '\u0958',
-        '\u0962', '\u0964',
-        '\u0971', '\u0982',
-        '\u0984', '\u0985',
-        '\u098d', '\u098f',
-        '\u0991', '\u0993',
-        '\u09a9', '\u09aa',
-        '\u09b1', '\u09b2',
-        '\u09b3', '\u09b6',
-        '\u09ba', '\u09be',
-        '\u09c1', '\u09c7',
-        '\u09c9', '\u09cb',
-        '\u09cd', '\u09d7',
-        '\u09d8', '\u09dc',
-        '\u09de', '\u09df',
-        '\u09e2', '\u09e6',
-        '\u09f2', '\u09f4',
-        '\u09fb', '\u0a05',
-        '\u0a0b', '\u0a0f',
-        '\u0a11', '\u0a13',
-        '\u0a29', '\u0a2a',
-        '\u0a31', '\u0a32',
-        '\u0a34', '\u0a35',
-        '\u0a37', '\u0a38',
-        '\u0a3a', '\u0a3e',
-        '\u0a41', '\u0a59',
-        '\u0a5d', '\u0a5e',
-        '\u0a5f', '\u0a66',
-        '\u0a70', '\u0a72',
-        '\u0a75', '\u0a83',
-        '\u0a84', '\u0a85',
-        '\u0a8c', '\u0a8d',
-        '\u0a8e', '\u0a8f',
-        '\u0a92', '\u0a93',
-        '\u0aa9', '\u0aaa',
-        '\u0ab1', '\u0ab2',
-        '\u0ab4', '\u0ab5',
-        '\u0aba', '\u0abd',
-        '\u0ac1', '\u0ac9',
-        '\u0aca', '\u0acb',
-        '\u0acd', '\u0ad0',
-        '\u0ad1', '\u0ae0',
-        '\u0ae1', '\u0ae6',
-        '\u0af0', '\u0b02',
-        '\u0b04', '\u0b05',
-        '\u0b0d', '\u0b0f',
-        '\u0b11', '\u0b13',
-        '\u0b29', '\u0b2a',
-        '\u0b31', '\u0b32',
-        '\u0b34', '\u0b36',
-        '\u0b3a', '\u0b3d',
-        '\u0b3f', '\u0b40',
-        '\u0b41', '\u0b47',
-        '\u0b49', '\u0b4b',
-        '\u0b4d', '\u0b57',
-        '\u0b58', '\u0b5c',
-        '\u0b5e', '\u0b5f',
-        '\u0b62', '\u0b66',
-        '\u0b71', '\u0b83',
-        '\u0b84', '\u0b85',
-        '\u0b8b', '\u0b8e',
-        '\u0b91', '\u0b92',
-        '\u0b96', '\u0b99',
-        '\u0b9b', '\u0b9c',
-        '\u0b9d', '\u0b9e',
-        '\u0ba0', '\u0ba3',
-        '\u0ba5', '\u0ba8',
-        '\u0bab', '\u0bae',
-        '\u0bb6', '\u0bb7',
-        '\u0bba', '\u0bbe',
-        '\u0bc0', '\u0bc1',
-        '\u0bc3', '\u0bc6',
-        '\u0bc9', '\u0bca',
-        '\u0bcd', '\u0bd7',
-        '\u0bd8', '\u0be7',
-        '\u0bf3', '\u0c01',
-        '\u0c04', '\u0c05',
-        '\u0c0d', '\u0c0e',
-        '\u0c11', '\u0c12',
-        '\u0c29', '\u0c2a',
-        '\u0c34', '\u0c35',
-        '\u0c3a', '\u0c41',
-        '\u0c45', '\u0c60',
-        '\u0c62', '\u0c66',
-        '\u0c70', '\u0c82',
-        '\u0c84', '\u0c85',
-        '\u0c8d', '\u0c8e',
-        '\u0c91', '\u0c92',
-        '\u0ca9', '\u0caa',
-        '\u0cb4', '\u0cb5',
-        '\u0cba', '\u0cbe',
-        '\u0cbf', '\u0cc0',
-        '\u0cc5', '\u0cc7',
-        '\u0cc9', '\u0cca',
-        '\u0ccc', '\u0cd5',
-        '\u0cd7', '\u0cde',
-        '\u0cdf', '\u0ce0',
-        '\u0ce2', '\u0ce6',
-        '\u0cf0', '\u0d02',
-        '\u0d04', '\u0d05',
-        '\u0d0d', '\u0d0e',
-        '\u0d11', '\u0d12',
-        '\u0d29', '\u0d2a',
-        '\u0d3a', '\u0d3e',
-        '\u0d41', '\u0d46',
-        '\u0d49', '\u0d4a',
-        '\u0d4d', '\u0d57',
-        '\u0d58', '\u0d60',
-        '\u0d62', '\u0d66',
-        '\u0d70', '\u0d82',
-        '\u0d84', '\u0d85',
-        '\u0d97', '\u0d9a',
-        '\u0db2', '\u0db3',
-        '\u0dbc', '\u0dbd',
-        '\u0dbe', '\u0dc0',
-        '\u0dc7', '\u0dcf',
-        '\u0dd2', '\u0dd8',
-        '\u0de0', '\u0df2',
-        '\u0df5', '\u0e01',
-        '\u0e31', '\u0e32',
-        '\u0e34', '\u0e40',
-        '\u0e47', '\u0e4f',
-        '\u0e5c', '\u0e81',
-        '\u0e83', '\u0e84',
-        '\u0e85', '\u0e87',
-        '\u0e89', '\u0e8a',
-        '\u0e8b', '\u0e8d',
-        '\u0e8e', '\u0e94',
-        '\u0e98', '\u0e99',
-        '\u0ea0', '\u0ea1',
-        '\u0ea4', '\u0ea5',
-        '\u0ea6', '\u0ea7',
-        '\u0ea8', '\u0eaa',
-        '\u0eac', '\u0ead',
-        '\u0eb1', '\u0eb2',
-        '\u0eb4', '\u0ebd',
-        '\u0ebe', '\u0ec0',
-        '\u0ec5', '\u0ec6',
-        '\u0ec7', '\u0ed0',
-        '\u0eda', '\u0edc',
-        '\u0ede', '\u0f00',
-        '\u0f18', '\u0f1a',
-        '\u0f35', '\u0f36',
-        '\u0f37', '\u0f38',
-        '\u0f39', '\u0f3e',
-        '\u0f48', '\u0f49',
-        '\u0f6b', '\u0f7f',
-        '\u0f80', '\u0f85',
-        '\u0f86', '\u0f88',
-        '\u0f8c', '\u0fbe',
-        '\u0fc6', '\u0fc7',
-        '\u0fcd', '\u0fcf',
-        '\u0fd0', '\u1000',
-        '\u1022', '\u1023',
-        '\u1028', '\u1029',
-        '\u102b', '\u102c',
-        '\u102d', '\u1031',
-        '\u1032', '\u1038',
-        '\u1039', '\u1040',
-        '\u1058', '\u10a0',
-        '\u10c6', '\u10d0',
-        '\u10f7', '\u10fb',
-        '\u10fc', '\u1100',
-        '\u115a', '\u115f',
-        '\u11a3', '\u11a8',
-        '\u11fa', '\u1200',
-        '\u1207', '\u1208',
-        '\u1247', '\u1248',
-        '\u1249', '\u124a',
-        '\u124e', '\u1250',
-        '\u1257', '\u1258',
-        '\u1259', '\u125a',
-        '\u125e', '\u1260',
-        '\u1287', '\u1288',
-        '\u1289', '\u128a',
-        '\u128e', '\u1290',
-        '\u12af', '\u12b0',
-        '\u12b1', '\u12b2',
-        '\u12b6', '\u12b8',
-        '\u12bf', '\u12c0',
-        '\u12c1', '\u12c2',
-        '\u12c6', '\u12c8',
-        '\u12cf', '\u12d0',
-        '\u12d7', '\u12d8',
-        '\u12ef', '\u12f0',
-        '\u130f', '\u1310',
-        '\u1311', '\u1312',
-        '\u1316', '\u1318',
-        '\u131f', '\u1320',
-        '\u1347', '\u1348',
-        '\u135b', '\u1361',
-        '\u137d', '\u13a0',
-        '\u13f5', '\u1401',
-        '\u1677', '\u1681',
-        '\u169b', '\u16a0',
-        '\u16f1', '\u1780',
-        '\u17b7', '\u17be',
-        '\u17c6', '\u17c7',
-        '\u17c9', '\u17d4',
-        '\u17db', '\u17dc',
-        '\u17dd', '\u17e0',
-        '\u17ea', '\u1810',
-        '\u181a', '\u1820',
-        '\u1878', '\u1880',
-        '\u18a9', '\u1e00',
-        '\u1e9c', '\u1ea0',
-        '\u1efa', '\u1f00',
-        '\u1f16', '\u1f18',
-        '\u1f1e', '\u1f20',
-        '\u1f46', '\u1f48',
-        '\u1f4e', '\u1f50',
-        '\u1f58', '\u1f59',
-        '\u1f5a', '\u1f5b',
-        '\u1f5c', '\u1f5d',
-        '\u1f5e', '\u1f5f',
-        '\u1f7e', '\u1f80',
-        '\u1fb5', '\u1fb6',
-        '\u1fbd', '\u1fbe',
-        '\u1fbf', '\u1fc2',
-        '\u1fc5', '\u1fc6',
-        '\u1fcd', '\u1fd0',
-        '\u1fd4', '\u1fd6',
-        '\u1fdc', '\u1fe0',
-        '\u1fed', '\u1ff2',
-        '\u1ff5', '\u1ff6',
-        '\u1ffd', '\u200e',
-        '\u2010', '\u207f',
-        '\u2080', '\u2102',
-        '\u2103', '\u2107',
-        '\u2108', '\u210a',
-        '\u2114', '\u2115',
-        '\u2116', '\u2119',
-        '\u211e', '\u2124',
-        '\u2125', '\u2126',
-        '\u2127', '\u2128',
-        '\u2129', '\u212a',
-        '\u212e', '\u212f',
-        '\u2132', '\u2133',
-        '\u213a', '\u2160',
-        '\u2184', '\u2336',
-        '\u237b', '\u2395',
-        '\u2396', '\u249c',
-        '\u24ea', '\u3005',
-        '\u3008', '\u3021',
-        '\u302a', '\u3031',
-        '\u3036', '\u3038',
-        '\u303b', '\u3041',
-        '\u3095', '\u309d',
-        '\u309f', '\u30a1',
-        '\u30fb', '\u30fc',
-        '\u30ff', '\u3105',
-        '\u312d', '\u3131',
-        '\u318f', '\u3190',
-        '\u31b8', '\u3200',
-        '\u321d', '\u3220',
-        '\u3244', '\u3260',
-        '\u327c', '\u327f',
-        '\u32b1', '\u32c0',
-        '\u32cc', '\u32d0',
-        '\u32ff', '\u3300',
-        '\u3377', '\u337b',
-        '\u33de', '\u33e0',
-        '\u33ff', '\u3400',
-        '\u4db6', '\u4e00',
-        '\u9fa6', '\ua000',
-        '\ua48d', '\uac00',
-        '\ud7a4', '\uf900',
-        '\ufa2e', '\ufb00',
-        '\ufb07', '\ufb13',
-        '\ufb18', '\ufb1d',
-        '\ufb1e', '\ufb1f',
-        '\ufb29', '\ufb2a',
-        '\ufb37', '\ufb38',
-        '\ufb3d', '\ufb3e',
-        '\ufb3f', '\ufb40',
-        '\ufb42', '\ufb43',
-        '\ufb45', '\ufb46',
-        '\ufbb2', '\ufbd3',
-        '\ufd3e', '\ufd50',
-        '\ufd90', '\ufd92',
-        '\ufdc8', '\ufdf0',
-        '\ufdfc', '\ufe70',
-        '\ufe73', '\ufe74',
-        '\ufe75', '\ufe76',
-        '\ufefd', '\uff21',
-        '\uff3b', '\uff41',
-        '\uff5b', '\uff66',
-        '\uffbf', '\uffc2',
-        '\uffc8', '\uffca',
-        '\uffd0', '\uffd2',
-        '\uffd8', '\uffda',
-        '\uffdd', '\uffff' // last entry is sentinel, actually never checked
+    private static int[] strongTable = {
+        0x0000, 0x0041,
+        0x005b, 0x0061,
+        0x007b, 0x00aa,
+        0x00ab, 0x00b5,
+        0x00b6, 0x00ba,
+        0x00bb, 0x00c0,
+        0x00d7, 0x00d8,
+        0x00f7, 0x00f8,
+        0x02b9, 0x02bb,
+        0x02c2, 0x02d0,
+        0x02d2, 0x02e0,
+        0x02e5, 0x02ee,
+        0x02ef, 0x0370,
+        0x0374, 0x0376,
+        0x037e, 0x0386,
+        0x0387, 0x0388,
+        0x03f6, 0x03f7,
+        0x0483, 0x048a,
+        0x058a, 0x05be,
+        0x05bf, 0x05c0,
+        0x05c1, 0x05c3,
+        0x05c4, 0x05c6,
+        0x05c7, 0x05d0,
+        0x0600, 0x0608,
+        0x0609, 0x060b,
+        0x060c, 0x060d,
+        0x060e, 0x061b,
+        0x064b, 0x066d,
+        0x0670, 0x0671,
+        0x06d6, 0x06e5,
+        0x06e7, 0x06ee,
+        0x06f0, 0x06fa,
+        0x070f, 0x0710,
+        0x0711, 0x0712,
+        0x0730, 0x074d,
+        0x07a6, 0x07b1,
+        0x07eb, 0x07f4,
+        0x07f6, 0x07fa,
+        0x0901, 0x0903,
+        0x093c, 0x093d,
+        0x0941, 0x0949,
+        0x094d, 0x0950,
+        0x0951, 0x0958,
+        0x0962, 0x0964,
+        0x0981, 0x0982,
+        0x09bc, 0x09bd,
+        0x09c1, 0x09c7,
+        0x09cd, 0x09ce,
+        0x09e2, 0x09e6,
+        0x09f2, 0x09f4,
+        0x0a01, 0x0a03,
+        0x0a3c, 0x0a3e,
+        0x0a41, 0x0a59,
+        0x0a70, 0x0a72,
+        0x0a75, 0x0a83,
+        0x0abc, 0x0abd,
+        0x0ac1, 0x0ac9,
+        0x0acd, 0x0ad0,
+        0x0ae2, 0x0ae6,
+        0x0af1, 0x0b02,
+        0x0b3c, 0x0b3d,
+        0x0b3f, 0x0b40,
+        0x0b41, 0x0b47,
+        0x0b4d, 0x0b57,
+        0x0b62, 0x0b66,
+        0x0b82, 0x0b83,
+        0x0bc0, 0x0bc1,
+        0x0bcd, 0x0bd0,
+        0x0bf3, 0x0c01,
+        0x0c3e, 0x0c41,
+        0x0c46, 0x0c58,
+        0x0c62, 0x0c66,
+        0x0c78, 0x0c7f,
+        0x0cbc, 0x0cbd,
+        0x0ccc, 0x0cd5,
+        0x0ce2, 0x0ce6,
+        0x0cf1, 0x0d02,
+        0x0d41, 0x0d46,
+        0x0d4d, 0x0d57,
+        0x0d62, 0x0d66,
+        0x0dca, 0x0dcf,
+        0x0dd2, 0x0dd8,
+        0x0e31, 0x0e32,
+        0x0e34, 0x0e40,
+        0x0e47, 0x0e4f,
+        0x0eb1, 0x0eb2,
+        0x0eb4, 0x0ebd,
+        0x0ec8, 0x0ed0,
+        0x0f18, 0x0f1a,
+        0x0f35, 0x0f36,
+        0x0f37, 0x0f38,
+        0x0f39, 0x0f3e,
+        0x0f71, 0x0f7f,
+        0x0f80, 0x0f85,
+        0x0f86, 0x0f88,
+        0x0f90, 0x0fbe,
+        0x0fc6, 0x0fc7,
+        0x102d, 0x1031,
+        0x1032, 0x1038,
+        0x1039, 0x103b,
+        0x103d, 0x103f,
+        0x1058, 0x105a,
+        0x105e, 0x1061,
+        0x1071, 0x1075,
+        0x1082, 0x1083,
+        0x1085, 0x1087,
+        0x108d, 0x108e,
+        0x135f, 0x1360,
+        0x1390, 0x13a0,
+        0x1680, 0x1681,
+        0x169b, 0x16a0,
+        0x1712, 0x1720,
+        0x1732, 0x1735,
+        0x1752, 0x1760,
+        0x1772, 0x1780,
+        0x17b7, 0x17be,
+        0x17c6, 0x17c7,
+        0x17c9, 0x17d4,
+        0x17db, 0x17dc,
+        0x17dd, 0x17e0,
+        0x17f0, 0x1810,
+        0x18a9, 0x18aa,
+        0x1920, 0x1923,
+        0x1927, 0x1929,
+        0x1932, 0x1933,
+        0x1939, 0x1946,
+        0x19de, 0x1a00,
+        0x1a17, 0x1a19,
+        0x1b00, 0x1b04,
+        0x1b34, 0x1b35,
+        0x1b36, 0x1b3b,
+        0x1b3c, 0x1b3d,
+        0x1b42, 0x1b43,
+        0x1b6b, 0x1b74,
+        0x1b80, 0x1b82,
+        0x1ba2, 0x1ba6,
+        0x1ba8, 0x1baa,
+        0x1c2c, 0x1c34,
+        0x1c36, 0x1c3b,
+        0x1dc0, 0x1e00,
+        0x1fbd, 0x1fbe,
+        0x1fbf, 0x1fc2,
+        0x1fcd, 0x1fd0,
+        0x1fdd, 0x1fe0,
+        0x1fed, 0x1ff2,
+        0x1ffd, 0x200e,
+        0x2010, 0x2071,
+        0x2074, 0x207f,
+        0x2080, 0x2090,
+        0x20a0, 0x2102,
+        0x2103, 0x2107,
+        0x2108, 0x210a,
+        0x2114, 0x2115,
+        0x2116, 0x2119,
+        0x211e, 0x2124,
+        0x2125, 0x2126,
+        0x2127, 0x2128,
+        0x2129, 0x212a,
+        0x212e, 0x212f,
+        0x213a, 0x213c,
+        0x2140, 0x2145,
+        0x214a, 0x214e,
+        0x2153, 0x2160,
+        0x2190, 0x2336,
+        0x237b, 0x2395,
+        0x2396, 0x249c,
+        0x24ea, 0x26ac,
+        0x26ad, 0x2800,
+        0x2900, 0x2c00,
+        0x2ce5, 0x2d00,
+        0x2de0, 0x3005,
+        0x3008, 0x3021,
+        0x302a, 0x3031,
+        0x3036, 0x3038,
+        0x303d, 0x3041,
+        0x3099, 0x309d,
+        0x30a0, 0x30a1,
+        0x30fb, 0x30fc,
+        0x31c0, 0x31f0,
+        0x321d, 0x3220,
+        0x3250, 0x3260,
+        0x327c, 0x327f,
+        0x32b1, 0x32c0,
+        0x32cc, 0x32d0,
+        0x3377, 0x337b,
+        0x33de, 0x33e0,
+        0x33ff, 0x3400,
+        0x4dc0, 0x4e00,
+        0xa490, 0xa500,
+        0xa60d, 0xa610,
+        0xa66f, 0xa680,
+        0xa700, 0xa722,
+        0xa788, 0xa789,
+        0xa802, 0xa803,
+        0xa806, 0xa807,
+        0xa80b, 0xa80c,
+        0xa825, 0xa827,
+        0xa828, 0xa840,
+        0xa874, 0xa880,
+        0xa8c4, 0xa8ce,
+        0xa926, 0xa92e,
+        0xa947, 0xa952,
+        0xaa29, 0xaa2f,
+        0xaa31, 0xaa33,
+        0xaa35, 0xaa40,
+        0xaa43, 0xaa44,
+        0xaa4c, 0xaa4d,
+        0xfb1e, 0xfb1f,
+        0xfb29, 0xfb2a,
+        0xfd3e, 0xfd50,
+        0xfdfd, 0xfe70,
+        0xfeff, 0xff21,
+        0xff3b, 0xff41,
+        0xff5b, 0xff66,
+        0xffe0, 0x10000,
+        0x10101, 0x10102,
+        0x10140, 0x101d0,
+        0x101fd, 0x10280,
+        0x1091f, 0x10920,
+        0x10a01, 0x10a10,
+        0x10a38, 0x10a40,
+        0x1d167, 0x1d16a,
+        0x1d173, 0x1d183,
+        0x1d185, 0x1d18c,
+        0x1d1aa, 0x1d1ae,
+        0x1d200, 0x1d360,
+        0x1d7ce, 0x20000,
+        0xe0001, 0xf0000,
+        0x10fffe, 0x10ffff // sentinel
     };
 
 
     // use a binary search with a cache
 
-    private static int stCache = 0;
+    private transient volatile int stCache = 0;
 
-    // warning, synchronize access to this as it modifies state
-    private static boolean isStrongDirectional(char c) {
-        if (c < strongTable[stCache]) {
-            stCache = search(c, strongTable, 0, stCache);
-        } else if (c >= strongTable[stCache + 1]) {
-            stCache = search(c, strongTable, stCache + 1, strongTable.length - stCache - 1);
+    private boolean isStrongDirectional(char c) {
+        int cachedIndex = stCache;
+        if (c < strongTable[cachedIndex]) {
+            cachedIndex = search(c, strongTable, 0, cachedIndex);
+        } else if (c >= strongTable[cachedIndex + 1]) {
+            cachedIndex = search(c, strongTable, cachedIndex + 1,
+                                 strongTable.length - cachedIndex - 1);
         }
-        return (stCache & 0x1) == 1;
+        boolean val = (cachedIndex & 0x1) == 1;
+        stCache = cachedIndex;
+        return val;
     }
 
-    static private int getKeyFromMask(int mask) {
+    private static int getKeyFromMask(int mask) {
         int key = 0;
         while (key < NUM_KEYS && ((mask & (1<<key)) == 0)) {
             ++key;
@@ -644,12 +812,27 @@
      * @return a non-contextual numeric shaper
      * @throws IllegalArgumentException if the range is not a single range
      */
-    static public NumericShaper getShaper(int singleRange) {
+    public static NumericShaper getShaper(int singleRange) {
         int key = getKeyFromMask(singleRange);
         return new NumericShaper(key, singleRange);
     }
 
     /**
+     * Returns a shaper for the provided Unicode
+     * range. All Latin-1 (EUROPEAN) digits are converted to the
+     * corresponding decimal digits of the specified Unicode range.
+     *
+     * @param singleRange the Unicode range given by a {@link
+     *                    NumericShaper.Range} constant.
+     * @return a non-contextual {@code NumericShaper}.
+     * @throws NullPointerException if {@code singleRange} is {@code null}
+     * @since 1.7
+     */
+    public static NumericShaper getShaper(Range singleRange) {
+        return new NumericShaper(singleRange, EnumSet.of(singleRange));
+    }
+
+    /**
      * Returns a contextual shaper for the provided unicode range(s).
      * Latin-1 (EUROPEAN) digits are converted to the decimal digits
      * corresponding to the range of the preceding text, if the
@@ -663,12 +846,34 @@
      * @param ranges the specified Unicode ranges
      * @return a shaper for the specified ranges
      */
-    static public NumericShaper getContextualShaper(int ranges) {
+    public static NumericShaper getContextualShaper(int ranges) {
         ranges |= CONTEXTUAL_MASK;
         return new NumericShaper(EUROPEAN_KEY, ranges);
     }
 
     /**
+     * Returns a contextual shaper for the provided Unicode
+     * range(s). The Latin-1 (EUROPEAN) digits are converted to the
+     * decimal digits corresponding to the range of the preceding
+     * text, if the range is one of the provided ranges.
+     *
+     * <p>The shaper assumes EUROPEAN as the starting context, that
+     * is, if EUROPEAN digits are encountered before any strong
+     * directional text in the string, the context is presumed to be
+     * EUROPEAN, and so the digits will not shape.
+     *
+     * @param ranges the specified Unicode ranges
+     * @return a contextual shaper for the specified ranges
+     * @throws NullPointerException if {@code ranges} is {@code null}.
+     * @since 1.7
+     */
+    public static NumericShaper getContextualShaper(Set<Range> ranges) {
+        NumericShaper shaper = new NumericShaper(Range.EUROPEAN, ranges);
+        shaper.mask = CONTEXTUAL_MASK;
+        return shaper;
+    }
+
+    /**
      * Returns a contextual shaper for the provided unicode range(s).
      * Latin-1 (EUROPEAN) digits will be converted to the decimal digits
      * corresponding to the range of the preceding text, if the
@@ -683,13 +888,38 @@
      * @throws IllegalArgumentException if the specified
      * <code>defaultContext</code> is not a single valid range.
      */
-    static public NumericShaper getContextualShaper(int ranges, int defaultContext) {
+    public static NumericShaper getContextualShaper(int ranges, int defaultContext) {
         int key = getKeyFromMask(defaultContext);
         ranges |= CONTEXTUAL_MASK;
         return new NumericShaper(key, ranges);
     }
 
     /**
+     * Returns a contextual shaper for the provided Unicode range(s).
+     * The Latin-1 (EUROPEAN) digits will be converted to the decimal
+     * digits corresponding to the range of the preceding text, if the
+     * range is one of the provided ranges. The shaper uses {@code
+     * defaultContext} as the starting context.
+     *
+     * @param ranges the specified Unicode ranges
+     * @param defaultContext the starting context, such as
+     *                       {@code NumericShaper.Range.EUROPEAN}
+     * @return a contextual shaper for the specified Unicode ranges.
+     * @throws NullPointerException
+     *         if {@code ranges} or {@code defaultContext} is {@code null}
+     * @since 1.7
+     */
+    public static NumericShaper getContextualShaper(Set<Range> ranges,
+                                                    Range defaultContext) {
+        if (defaultContext == null) {
+            throw new NullPointerException();
+        }
+        NumericShaper shaper = new NumericShaper(defaultContext, ranges);
+        shaper.mask = CONTEXTUAL_MASK;
+        return shaper;
+    }
+
+    /**
      * Private constructor.
      */
     private NumericShaper(int key, int mask) {
@@ -697,6 +927,11 @@
         this.mask = mask;
     }
 
+    private NumericShaper(Range defaultContext, Set<Range> ranges) {
+        this.shapingRange = defaultContext;
+        this.rangeSet = EnumSet.copyOf(ranges); // throws NPE if ranges is null.
+    }
+
     /**
      * Converts the digits in the text that occur between start and
      * start + count.
@@ -710,19 +945,13 @@
      * @throws NullPointerException if text is null
      */
     public void shape(char[] text, int start, int count) {
-        if (text == null) {
-            throw new NullPointerException("text is null");
-        }
-        if ((start < 0)
-            || (start > text.length)
-            || ((start + count) < 0)
-            || ((start + count) > text.length)) {
-            throw new IndexOutOfBoundsException(
-                "bad start or count for text of length " + text.length);
-        }
-
+        checkParams(text, start, count);
         if (isContextual()) {
-            shapeContextually(text, start, count, key);
+            if (rangeSet == null) {
+                shapeContextually(text, start, count, key);
+            } else {
+                shapeContextually(text, start, count, shapingRange);
+            }
         } else {
             shapeNonContextually(text, start, count);
         }
@@ -747,6 +976,60 @@
      * range.
      */
     public void shape(char[] text, int start, int count, int context) {
+        checkParams(text, start, count);
+        if (isContextual()) {
+            int ctxKey = getKeyFromMask(context);
+            if (rangeSet == null) {
+                shapeContextually(text, start, count, ctxKey);
+            } else {
+                shapeContextually(text, start, count, Range.values()[ctxKey]);
+            }
+        } else {
+            shapeNonContextually(text, start, count);
+        }
+    }
+
+    /**
+     * Converts the digits in the text that occur between {@code
+     * start} and {@code start + count}, using the provided {@code
+     * context}. {@code Context} is ignored if the shaper is not a
+     * contextual shaper.
+     *
+     * @param text  a {@code char} array
+     * @param start the index into {@code text} to start converting
+     * @param count the number of {@code char}s in {@code text}
+     *              to convert
+     * @param context the context to which to convert the characters,
+     *                such as {@code NumericShaper.Range.EUROPEAN}
+     * @throws IndexOutOfBoundsException
+     *         if {@code start} or {@code start + count} is out of bounds
+     * @throws NullPointerException
+     *         if {@code text} or {@code context} is null
+     * @since 1.7
+     */
+    public void shape(char[] text, int start, int count, Range context) {
+        checkParams(text, start, count);
+        if (context == null) {
+            throw new NullPointerException("context is null");
+        }
+
+        if (isContextual()) {
+            if (rangeSet != null) {
+                shapeContextually(text, start, count, context);
+            } else {
+                int key = Range.toRangeIndex(context);
+                if (key >= 0) {
+                    shapeContextually(text, start, count, key);
+                } else {
+                    shapeContextually(text, start, count, shapingRange);
+                }
+            }
+        } else {
+            shapeNonContextually(text, start, count);
+        }
+    }
+
+    private void checkParams(char[] text, int start, int count) {
         if (text == null) {
             throw new NullPointerException("text is null");
         }
@@ -757,13 +1040,6 @@
             throw new IndexOutOfBoundsException(
                 "bad start or count for text of length " + text.length);
         }
-
-        if (isContextual()) {
-            int ctxKey = getKeyFromMask(context);
-            shapeContextually(text, start, count, ctxKey);
-        } else {
-            shapeNonContextually(text, start, count);
-        }
     }
 
     /**
@@ -785,6 +1061,10 @@
      * <blockquote>
      *   <code>if ((shaper.getRanges() & shaper.ARABIC) != 0) { ... </code>
      * </blockquote>
+     *
+     * <p>Note that this method supports only the bit mask-based
+     * ranges. Call {@link #getRangeSet()} for the enum-based ranges.
+     *
      * @return the values for all the ranges to be shaped.
      */
     public int getRanges() {
@@ -792,11 +1072,34 @@
     }
 
     /**
+     * Returns a {@code Set} representing all the Unicode ranges in
+     * this {@code NumericShaper} that will be shaped.
+     *
+     * @return all the Unicode ranges to be shaped.
+     * @since 1.7
+     */
+    public Set<Range> getRangeSet() {
+        if (rangeSet != null) {
+            return EnumSet.copyOf(rangeSet);
+        }
+        return Range.maskToRangeSet(mask);
+    }
+
+    /**
      * Perform non-contextual shaping.
      */
     private void shapeNonContextually(char[] text, int start, int count) {
-        int base = bases[key];
-        char minDigit = key == TAMIL_KEY ? '\u0031' : '\u0030'; // Tamil doesn't use decimal zero
+        int base;
+        char minDigit = '0';
+        if (shapingRange != null) {
+            base = shapingRange.getDigitBase();
+            minDigit += shapingRange.getNumericBase();
+        } else {
+            base = bases[key];
+            if (key == ETHIOPIC_KEY) {
+                minDigit++; // Ethiopic doesn't use decimal zero
+            }
+        }
         for (int i = start, e = start + count; i < e; ++i) {
             char c = text[i];
             if (c >= minDigit && c <= '\u0039') {
@@ -807,7 +1110,7 @@
 
     /**
      * Perform contextual shaping.
-     * Synchronized to protect caches used in getContextKey and isStrongDirectional.
+     * Synchronized to protect caches used in getContextKey.
      */
     private synchronized void shapeContextually(char[] text, int start, int count, int ctxKey) {
 
@@ -818,29 +1121,64 @@
         int lastkey = ctxKey;
 
         int base = bases[ctxKey];
-        char minDigit = ctxKey == TAMIL_KEY ? '\u0031' : '\u0030'; // Tamil doesn't use decimal zero
+        char minDigit = ctxKey == ETHIOPIC_KEY ? '1' : '0'; // Ethiopic doesn't use decimal zero
+
+        synchronized (NumericShaper.class) {
+            for (int i = start, e = start + count; i < e; ++i) {
+                char c = text[i];
+                if (c >= minDigit && c <= '\u0039') {
+                    text[i] = (char)(c + base);
+                }
+
+                if (isStrongDirectional(c)) {
+                    int newkey = getContextKey(c);
+                    if (newkey != lastkey) {
+                        lastkey = newkey;
 
-        for (int i = start, e = start + count; i < e; ++i) {
+                        ctxKey = newkey;
+                        if (((mask & EASTERN_ARABIC) != 0) && (ctxKey == ARABIC_KEY || ctxKey == EASTERN_ARABIC_KEY)) {
+                            ctxKey = EASTERN_ARABIC_KEY;
+                        } else if ((mask & (1<<ctxKey)) == 0) {
+                            ctxKey = EUROPEAN_KEY;
+                        }
+
+                        base = bases[ctxKey];
+
+                        minDigit = ctxKey == ETHIOPIC_KEY ? '1' : '0'; // Ethiopic doesn't use decimal zero
+                    }
+                }
+            }
+        }
+    }
+
+    private void shapeContextually(char[] text, int start, int count, Range ctxKey) {
+        if (ctxKey == null) {
+            ctxKey = Range.EUROPEAN;
+        }
+
+        Range lastKey = ctxKey;
+        int base = ctxKey.getDigitBase();
+        char minDigit = (char)('0' + ctxKey.getNumericBase());
+        for (int i = start, end = start + count; i < end; ++i) {
             char c = text[i];
-            if (c >= minDigit && c <= '\u0039') {
+            if (c >= minDigit && c <= '9') {
                 text[i] = (char)(c + base);
+                continue;
             }
-
             if (isStrongDirectional(c)) {
-                int newkey = getContextKey(c);
-                if (newkey != lastkey) {
-                    lastkey = newkey;
-
-                    ctxKey = newkey;
-                    if (((mask & EASTERN_ARABIC) != 0) && (ctxKey == ARABIC_KEY || ctxKey == EASTERN_ARABIC_KEY)) {
-                        ctxKey = EASTERN_ARABIC_KEY;
-                    } else if ((mask & (1<<ctxKey)) == 0) {
-                        ctxKey = EUROPEAN_KEY;
+                Range newKey = rangeForCodePoint(c);
+                if (newKey != lastKey) {
+                    lastKey = newKey;
+                    ctxKey = newKey;
+                    if (rangeSet.contains(Range.EUROPEAN)
+                        && (ctxKey == Range.ARABIC || ctxKey == Range.EASTERN_ARABIC)) {
+                        ctxKey = Range.EASTERN_ARABIC;
+                    } else if (!rangeSet.contains(ctxKey)) {
+                        ctxKey = Range.EUROPEAN;
                     }
 
-                    base = bases[ctxKey];
-
-                    minDigit = ctxKey == TAMIL_KEY ? '\u0031' : '\u0030'; // Tamil doesn't use decimal zero
+                    base = ctxKey.getDigitBase();
+                    minDigit = (char)('0' + ctxKey.getNumericBase());
                 }
             }
         }
@@ -852,12 +1190,28 @@
      * @see java.lang.Object#hashCode
      */
     public int hashCode() {
-        return mask;
+        int hash = mask;
+        if (rangeSet != null) {
+            // Use the CONTEXTUAL_MASK bit only for the enum-based
+            // NumericShaper. A deserialized NumericShaper might have
+            // bit masks.
+            hash &= CONTEXTUAL_MASK;
+            hash ^= rangeSet.hashCode();
+        }
+        return hash;
     }
 
     /**
-     * Returns true if the specified object is an instance of
-     * <code>NumericShaper</code> and shapes identically to this one.
+     * Returns {@code true} if the specified object is an instance of
+     * <code>NumericShaper</code> and shapes identically to this one,
+     * regardless of the range representations, the bit mask or the
+     * enum. For example, the following code produces {@code "true"}.
+     * <blockquote><pre>
+     * NumericShaper ns1 = NumericShaper.getShaper(NumericShaper.ARABIC);
+     * NumericShaper ns2 = NumericShaper.getShaper(NumericShaper.Range.ARABIC);
+     * System.out.println(ns1.equals(ns2));
+     * </pre></blockquote>
+     *
      * @param o the specified object to compare to this
      *          <code>NumericShaper</code>
      * @return <code>true</code> if <code>o</code> is an instance
@@ -869,6 +1223,22 @@
         if (o != null) {
             try {
                 NumericShaper rhs = (NumericShaper)o;
+                if (rangeSet != null) {
+                    if (rhs.rangeSet != null) {
+                        return isContextual() == rhs.isContextual()
+                            && rangeSet.equals(rhs.rangeSet)
+                            && shapingRange == rhs.shapingRange;
+                    }
+                    return isContextual() == rhs.isContextual()
+                        && rangeSet.equals(Range.maskToRangeSet(rhs.mask))
+                        && shapingRange == Range.indexToRange(rhs.key);
+                } else if (rhs.rangeSet != null) {
+                    Set<Range> rset = Range.maskToRangeSet(mask);
+                    Range srange = Range.indexToRange(key);
+                    return isContextual() == rhs.isContextual()
+                        && rset.equals(rhs.rangeSet)
+                        && srange == rhs.shapingRange;
+                }
                 return rhs.mask == mask && rhs.key == key;
             }
             catch (ClassCastException e) {
@@ -885,23 +1255,29 @@
     public String toString() {
         StringBuilder buf = new StringBuilder(super.toString());
 
-        buf.append("[contextual:" + isContextual());
+        buf.append("[contextual:").append(isContextual());
 
+        String[] keyNames = null;
         if (isContextual()) {
-            buf.append(", context:" + keyNames[key]);
+            buf.append(", context:");
+            buf.append(shapingRange == null ? Range.values()[key] : shapingRange);
         }
 
-        buf.append(", range(s): ");
-        boolean first = true;
-        for (int i = 0; i < NUM_KEYS; ++i) {
-            if ((mask & (1 << i)) != 0) {
-                if (first) {
-                    first = false;
-                } else {
-                    buf.append(", ");
+        if (rangeSet == null) {
+            buf.append(", range(s): ");
+            boolean first = true;
+            for (int i = 0; i < NUM_KEYS; ++i) {
+                if ((mask & (1 << i)) != 0) {
+                    if (first) {
+                        first = false;
+                    } else {
+                        buf.append(", ");
+                    }
+                    buf.append(Range.values()[i]);
                 }
-                buf.append(keyNames[i]);
             }
+        } else {
+            buf.append(", range set: ").append(rangeSet);
         }
         buf.append(']');
 
@@ -940,7 +1316,6 @@
         }
 
         if (value >= 1 << 1) {
-            value >>= 1;
             bit += 1;
         }
 
@@ -950,7 +1325,7 @@
     /**
      * fast binary search over subrange of array.
      */
-    private static int search(char value, char[] array, int start, int length)
+    private static int search(int value, int[] array, int start, int length)
     {
         int power = 1 << getHighBit(length);
         int extra = length - power;
@@ -971,4 +1346,27 @@
 
         return index;
     }
+
+    /**
+     * Converts the {@code NumericShaper.Range} enum-based parameters,
+     * if any, to the bit mask-based counterparts and writes this
+     * object to the {@code stream}. Any enum constants that have no
+     * bit mask-based counterparts are ignored in the conversion.
+     *
+     * @param stream the output stream to write to
+     * @throws IOException if an I/O error occurs while writing to {@code stream}
+     * @since 1.7
+     */
+    private void writeObject(ObjectOutputStream stream) throws IOException {
+        if (shapingRange != null) {
+            int index = Range.toRangeIndex(shapingRange);
+            if (index >= 0) {
+                key = index;
+            }
+        }
+        if (rangeSet != null) {
+            mask |= Range.toRangeMask(rangeSet);
+        }
+        stream.defaultWriteObject();
+    }
 }
--- a/jdk/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java	Tue Dec 01 08:54:10 2009 -0800
@@ -65,7 +65,7 @@
  * PrinterStateReason PrinterStateReason} objects to an existing
  * PrinterStateReasons object and remove them again. However, like class
  *  {@link java.util.HashMap java.util.HashMap}, class PrinterStateReasons is
- * bot multiple thread safe. If a PrinterStateReasons object will be used by
+ * not multiple thread safe. If a PrinterStateReasons object will be used by
  * multiple threads, be sure to synchronize its operations (e.g., using a
  * synchronized map view obtained from class {@link java.util.Collections
  * java.util.Collections}).
--- a/jdk/src/share/classes/javax/swing/JComponent.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JComponent.java	Tue Dec 01 08:54:10 2009 -0800
@@ -795,7 +795,6 @@
      * @see java.awt.Container#paint
      */
     protected void paintChildren(Graphics g) {
-        boolean isJComponent;
         Graphics sg = g;
 
         synchronized(getTreeLock()) {
@@ -826,12 +825,21 @@
                 }
             }
             boolean printing = getFlag(IS_PRINTING);
+            final Window window = SwingUtilities.getWindowAncestor(this);
+            final boolean isWindowOpaque = window == null || window.isOpaque();
             for (; i >= 0 ; i--) {
                 Component comp = getComponent(i);
-                isJComponent = (comp instanceof JComponent);
-                if (comp != null &&
-                    (isJComponent || isLightweightComponent(comp)) &&
-                    (comp.isVisible() == true)) {
+                if (comp == null) {
+                    continue;
+                }
+
+                final boolean isJComponent = comp instanceof JComponent;
+
+                // Enable painting of heavyweights in non-opaque windows.
+                // See 6884960
+                if ((!isWindowOpaque || isJComponent ||
+                            isLightweightComponent(comp)) && comp.isVisible())
+                {
                     Rectangle cr;
 
                     cr = comp.getBounds(tmpRect);
@@ -887,6 +895,8 @@
                                     }
                                 }
                             } else {
+                                // The component is either lightweight, or
+                                // heavyweight in a non-opaque window
                                 if (!printing) {
                                     comp.paint(cg);
                                 }
@@ -4868,7 +4878,9 @@
      * @see #revalidate
      * @see java.awt.Component#invalidate
      * @see java.awt.Container#validate
-     */
+     * @see java.awt.Container#isValidateRoot
+     */
+    @Override
     public boolean isValidateRoot() {
         return false;
     }
--- a/jdk/src/share/classes/javax/swing/JEditorPane.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JEditorPane.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1330,7 +1330,7 @@
      */
     public Dimension getPreferredSize() {
         Dimension d = super.getPreferredSize();
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         if (port != null) {
             TextUI ui = getUI();
             int prefWidth = d.width;
@@ -1452,7 +1452,7 @@
      * match its own, false otherwise
      */
     public boolean getScrollableTracksViewportWidth() {
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         if (port != null) {
             TextUI ui = getUI();
             int w = port.getWidth();
@@ -1474,7 +1474,7 @@
      *          false otherwise
      */
     public boolean getScrollableTracksViewportHeight() {
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         if (port != null) {
             TextUI ui = getUI();
             int h = port.getHeight();
--- a/jdk/src/share/classes/javax/swing/JList.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JList.java	Tue Dec 01 08:54:10 2009 -0800
@@ -2722,7 +2722,7 @@
                                       getVisibleRowCount() <= 0) {
             return true;
         }
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         if (port != null) {
             return port.getWidth() > getPreferredSize().width;
         }
@@ -2748,7 +2748,7 @@
                      getVisibleRowCount() <= 0) {
             return true;
         }
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         if (port != null) {
             return port.getHeight() > getPreferredSize().height;
         }
--- a/jdk/src/share/classes/javax/swing/JRootPane.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JRootPane.java	Tue Dec 01 08:54:10 2009 -0800
@@ -725,8 +725,10 @@
      * because both classes override <code>isValidateRoot</code> to return true.
      *
      * @see JComponent#isValidateRoot
+     * @see java.awt.Container#isValidateRoot
      * @return true
      */
+    @Override
     public boolean isValidateRoot() {
         return true;
     }
--- a/jdk/src/share/classes/javax/swing/JScrollPane.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JScrollPane.java	Tue Dec 01 08:54:10 2009 -0800
@@ -453,10 +453,12 @@
      * @see java.awt.Container#validate
      * @see JComponent#revalidate
      * @see JComponent#isValidateRoot
+     * @see java.awt.Container#isValidateRoot
      *
      * @beaninfo
      *    hidden: true
      */
+    @Override
     public boolean isValidateRoot() {
         return true;
     }
--- a/jdk/src/share/classes/javax/swing/JSplitPane.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JSplitPane.java	Tue Dec 01 08:54:10 2009 -0800
@@ -947,10 +947,12 @@
      *
      * @return true
      * @see JComponent#revalidate
+     * @see java.awt.Container#isValidateRoot
      *
      * @beaninfo
      *    hidden: true
      */
+    @Override
     public boolean isValidateRoot() {
         return true;
     }
--- a/jdk/src/share/classes/javax/swing/JTable.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JTable.java	Tue Dec 01 08:54:10 2009 -0800
@@ -57,6 +57,7 @@
 import sun.swing.SwingUtilities2.Section;
 import static sun.swing.SwingUtilities2.Section.*;
 import sun.swing.PrintingStatus;
+import sun.swing.SwingLazyValue;
 
 /**
  * The <code>JTable</code> is used to display and edit regular two-dimensional tables
@@ -718,7 +719,7 @@
      * @see #addNotify
      */
     protected void configureEnclosingScrollPane() {
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         if (port != null) {
             Container gp = port.getParent();
             if (gp instanceof JScrollPane) {
@@ -727,7 +728,8 @@
                 // example, the rowHeaderView of the scrollPane -
                 // an implementor of fixed columns might do this.
                 JViewport viewport = scrollPane.getViewport();
-                if (viewport == null || viewport.getView() != this) {
+                if (viewport == null ||
+                        SwingUtilities.getUnwrappedView(viewport) != this) {
                     return;
                 }
                 scrollPane.setColumnHeaderView(getTableHeader());
@@ -750,7 +752,7 @@
      * from configureEnclosingScrollPane() and updateUI() in a safe manor.
      */
     private void configureEnclosingScrollPaneUI() {
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         if (port != null) {
             Container gp = port.getParent();
             if (gp instanceof JScrollPane) {
@@ -759,7 +761,8 @@
                 // example, the rowHeaderView of the scrollPane -
                 // an implementor of fixed columns might do this.
                 JViewport viewport = scrollPane.getViewport();
-                if (viewport == null || viewport.getView() != this) {
+                if (viewport == null ||
+                        SwingUtilities.getUnwrappedView(viewport) != this) {
                     return;
                 }
                 //  scrollPane.getViewport().setBackingStoreEnabled(true);
@@ -819,7 +822,7 @@
      * @since 1.3
      */
     protected void unconfigureEnclosingScrollPane() {
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         if (port != null) {
             Container gp = port.getParent();
             if (gp instanceof JScrollPane) {
@@ -828,7 +831,8 @@
                 // example, the rowHeaderView of the scrollPane -
                 // an implementor of fixed columns might do this.
                 JViewport viewport = scrollPane.getViewport();
-                if (viewport == null || viewport.getView() != this) {
+                if (viewport == null ||
+                        SwingUtilities.getUnwrappedView(viewport) != this) {
                     return;
                 }
                 scrollPane.setColumnHeaderView(null);
@@ -5215,7 +5219,7 @@
      * @see #getFillsViewportHeight
      */
     public boolean getScrollableTracksViewportHeight() {
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         return getFillsViewportHeight()
                && port != null
                && port.getHeight() > getPreferredSize().height;
@@ -5316,7 +5320,7 @@
     }
 
     private void setLazyValue(Hashtable h, Class c, String s) {
-        h.put(c, new UIDefaults.ProxyLazyValue(s));
+        h.put(c, new SwingLazyValue(s));
     }
 
     private void setLazyRenderer(Class c, String s) {
--- a/jdk/src/share/classes/javax/swing/JTextField.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JTextField.java	Tue Dec 01 08:54:10 2009 -0800
@@ -288,9 +288,11 @@
      *
      * @see JComponent#revalidate
      * @see JComponent#isValidateRoot
+     * @see java.awt.Container#isValidateRoot
      */
+    @Override
     public boolean isValidateRoot() {
-        return SwingUtilities2.getViewport(this) == null;
+        return SwingUtilities.getParentViewport(this) == null;
     }
 
 
--- a/jdk/src/share/classes/javax/swing/JTree.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JTree.java	Tue Dec 01 08:54:10 2009 -0800
@@ -3498,7 +3498,7 @@
      * @see Scrollable#getScrollableTracksViewportWidth
      */
     public boolean getScrollableTracksViewportWidth() {
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         if (port != null) {
             return port.getWidth() > getPreferredSize().width;
         }
@@ -3515,7 +3515,7 @@
      * @see Scrollable#getScrollableTracksViewportHeight
      */
     public boolean getScrollableTracksViewportHeight() {
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         if (port != null) {
             return port.getHeight() > getPreferredSize().height;
         }
--- a/jdk/src/share/classes/javax/swing/JViewport.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/JViewport.java	Tue Dec 01 08:54:10 2009 -0800
@@ -469,49 +469,12 @@
      * is the synchronous version of a <code>revalidate</code>.
      */
     private void validateView() {
-        Component validateRoot = null;
+        Component validateRoot = SwingUtilities.getValidateRoot(this, false);
 
-        /* Find the first JComponent ancestor of this component whose
-         * isValidateRoot() method returns true.
-         */
-        for(Component c = this; c != null; c = c.getParent()) {
-            if ((c instanceof CellRendererPane) || (c.getPeer() == null)) {
-                return;
-            }
-            if ((c instanceof JComponent) &&
-                (((JComponent)c).isValidateRoot())) {
-                validateRoot = c;
-                break;
-            }
-        }
-
-        // If no validateRoot, nothing to validate from.
         if (validateRoot == null) {
             return;
         }
 
-        // Make sure all ancestors are visible.
-        Component root = null;
-
-        for(Component c = validateRoot; c != null; c = c.getParent()) {
-            // We don't check isVisible here, otherwise if the component
-            // is contained in something like a JTabbedPane when the
-            // component is made visible again it won't have scrolled
-            // to the correct location.
-            if (c.getPeer() == null) {
-                return;
-            }
-            if ((c instanceof Window) || (c instanceof Applet)) {
-                root = c;
-                break;
-            }
-        }
-
-        // Make sure there is a Window ancestor.
-        if (root == null) {
-            return;
-        }
-
         // Validate the root.
         validateRoot.validate();
 
--- a/jdk/src/share/classes/javax/swing/RepaintManager.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/RepaintManager.java	Tue Dec 01 08:54:10 2009 -0800
@@ -310,47 +310,13 @@
             delegate.addInvalidComponent(invalidComponent);
             return;
         }
-        Component validateRoot = null;
+        Component validateRoot =
+            SwingUtilities.getValidateRoot(invalidComponent, true);
 
-        /* Find the first JComponent ancestor of this component whose
-         * isValidateRoot() method returns true.
-         */
-        for(Component c = invalidComponent; c != null; c = c.getParent()) {
-            if ((c instanceof CellRendererPane) || (c.getPeer() == null)) {
-                return;
-            }
-            if ((c instanceof JComponent) && (((JComponent)c).isValidateRoot())) {
-                validateRoot = c;
-                break;
-            }
-        }
-
-        /* There's no validateRoot to apply validate to, so we're done.
-         */
         if (validateRoot == null) {
             return;
         }
 
-        /* If the validateRoot and all of its ancestors aren't visible
-         * then we don't do anything.  While we're walking up the tree
-         * we find the root Window or Applet.
-         */
-        Component root = null;
-
-        for(Component c = validateRoot; c != null; c = c.getParent()) {
-            if (!c.isVisible() || (c.getPeer() == null)) {
-                return;
-            }
-            if ((c instanceof Window) || (c instanceof Applet)) {
-                root = c;
-                break;
-            }
-        }
-
-        if (root == null) {
-            return;
-        }
-
         /* Lazily create the invalidateComponents vector and add the
          * validateRoot if it's not there already.  If this validateRoot
          * is already in the vector, we're done.
--- a/jdk/src/share/classes/javax/swing/SwingUtilities.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/SwingUtilities.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1967,4 +1967,114 @@
             SwingUtilities.updateComponentTreeUI(component);
         }
     }
+
+    /**
+     * Looks for the first ancestor of the {@code component}
+     * which is not an instance of {@link JLayer}.
+     * If this ancestor is an instance of {@code JViewport},
+     * this {@code JViewport} is returned, otherwise returns {@code null}.
+     * The following way of obtaining the parent {@code JViewport}
+     * is not recommended any more:
+     * <pre>
+     * JViewport port = null;
+     * Container parent = component.getParent();
+     * // not recommended any more
+     * if(parent instanceof JViewport) {
+     *     port = (JViewport) parent;
+     * }
+     * </pre>
+     * Here is the way to go:
+     * <pre>
+     * // the correct way:
+     * JViewport port = SwingUtilities.getParentViewport(component);
+     * </pre>
+     * @param component {@code Component} to get the parent {@code JViewport} of.
+     * @return the {@code JViewport} instance for the {@code component}
+     * or {@code null}
+     * @throws NullPointerException if {@code component} is {@code null}
+     *
+     * @since 1.7
+     */
+    public static JViewport getParentViewport(Component component) {
+        do {
+            component = component.getParent();
+            if (component instanceof JViewport) {
+                return (JViewport) component;
+            }
+        } while(component instanceof JLayer);
+        return null;
+    }
+
+    /**
+     * Returns the first {@code JViewport}'s descendant
+     * which is not an instance of {@code JLayer} or {@code null}.
+     *
+     * If the {@code viewport}'s view component is not a {@code JLayer},
+     * this method is equal to {@link JViewport#getView()}
+     * otherwise {@link JLayer#getView()} will be recursively tested
+     *
+     * @return the first {@code JViewport}'s descendant
+     * which is not an instance of {@code JLayer} or {@code null}.
+     *
+     * @throws NullPointerException if {@code viewport} is {@code null}
+     * @see JViewport#getView()
+     * @see JLayer
+     */
+    static Component getUnwrappedView(JViewport viewport) {
+        Component view = viewport.getView();
+        while (view instanceof JLayer) {
+            view = ((JLayer)view).getView();
+        }
+        return view;
+    }
+
+   /**
+     * Retrieves the validate root of a given container.
+     *
+     * If the container is contained within a {@code CellRendererPane}, this
+     * method returns {@code null} due to the synthetic nature of the {@code
+     * CellRendererPane}.
+     * <p>
+     * The component hierarchy must be displayable up to the toplevel component
+     * (either a {@code Frame} or an {@code Applet} object.) Otherwise this
+     * method returns {@code null}.
+     * <p>
+     * If the {@code visibleOnly} argument is {@code true}, the found validate
+     * root and all its parents up to the toplevel component must also be
+     * visible. Otherwise this method returns {@code null}.
+     *
+     * @return the validate root of the given container or null
+     * @see java.awt.Component#isDisplayable()
+     * @see java.awt.Component#isVisible()
+     * @since 1.7
+     */
+    static Container getValidateRoot(Container c, boolean visibleOnly) {
+        Container root = null;
+
+        for (; c != null; c = c.getParent())
+        {
+            if (!c.isDisplayable() || c instanceof CellRendererPane) {
+                return null;
+            }
+            if (c.isValidateRoot()) {
+                root = c;
+                break;
+            }
+        }
+
+        if (root == null) {
+            return null;
+        }
+
+        for (; c != null; c = c.getParent()) {
+            if (!c.isDisplayable() || (visibleOnly && !c.isVisible())) {
+                return null;
+            }
+            if (c instanceof Window || c instanceof Applet) {
+                return root;
+            }
+        }
+
+        return null;
+    }
 }
--- a/jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java	Tue Dec 01 08:54:10 2009 -0800
@@ -33,7 +33,8 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.text.MessageFormat;
-import java.util.Vector;
+import java.util.List;
+import java.util.ArrayList;
 import java.lang.ref.WeakReference;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeEvent;
@@ -173,22 +174,27 @@
      * @since 1.4
      */
     public String getSystemDisplayName(File f) {
-        String name = null;
-        if (f != null) {
-            name = f.getName();
-            if (!name.equals("..") && !name.equals(".") &&
-                (useSystemExtensionHiding ||
-                 !isFileSystem(f) ||
-                 isFileSystemRoot(f)) &&
-                ((f instanceof ShellFolder) ||
-                 f.exists())) {
+        if (f == null) {
+            return null;
+        }
+
+        String name = f.getName();
 
+        if (!name.equals("..") && !name.equals(".") &&
+                (useSystemExtensionHiding || !isFileSystem(f) || isFileSystemRoot(f)) &&
+                (f instanceof ShellFolder || f.exists())) {
+
+            try {
                 name = getShellFolder(f).getDisplayName();
-                if (name == null || name.length() == 0) {
-                    name = f.getPath(); // e.g. "/"
-                }
+            } catch (FileNotFoundException e) {
+                return null;
+            }
+
+            if (name == null || name.length() == 0) {
+                name = f.getPath(); // e.g. "/"
             }
         }
+
         return name;
     }
 
@@ -222,16 +228,24 @@
      * @since 1.4
      */
     public Icon getSystemIcon(File f) {
-        if (f != null) {
-            ShellFolder sf = getShellFolder(f);
-            Image img = sf.getIcon(false);
-            if (img != null) {
-                return new ImageIcon(img, sf.getFolderType());
-            } else {
-                return UIManager.getIcon(f.isDirectory() ? "FileView.directoryIcon" : "FileView.fileIcon");
-            }
+        if (f == null) {
+            return null;
+        }
+
+        ShellFolder sf;
+
+        try {
+            sf = getShellFolder(f);
+        } catch (FileNotFoundException e) {
+            return null;
+        }
+
+        Image img = sf.getIcon(false);
+
+        if (img != null) {
+            return new ImageIcon(img, sf.getFolderType());
         } else {
-            return null;
+            return UIManager.getIcon(f.isDirectory() ? "FileView.directoryIcon" : "FileView.fileIcon");
         }
     }
 
@@ -446,24 +460,28 @@
      * Gets the list of shown (i.e. not hidden) files.
      */
     public File[] getFiles(File dir, boolean useFileHiding) {
-        Vector<File> files = new Vector<File>();
-
+        List<File> files = new ArrayList<File>();
 
         // add all files in dir
-        File[] names;
-            if (!(dir instanceof ShellFolder)) {
+        if (!(dir instanceof ShellFolder)) {
+            try {
                 dir = getShellFolder(dir);
+            } catch (FileNotFoundException e) {
+                return new File[0];
             }
+        }
 
-            names = ((ShellFolder)dir).listFiles(!useFileHiding);
-        File f;
+        File[] names = ((ShellFolder) dir).listFiles(!useFileHiding);
 
-        int nameCount = (names == null) ? 0 : names.length;
-        for (int i = 0; i < nameCount; i++) {
+        if (names == null) {
+            return new File[0];
+        }
+
+        for (File f : names) {
             if (Thread.currentThread().isInterrupted()) {
                 break;
             }
-            f = names[i];
+
             if (!(f instanceof ShellFolder)) {
                 if (isFileSystemRoot(f)) {
                     f = createFileSystemRoot(f);
@@ -481,7 +499,7 @@
                 }
             }
             if (!useFileHiding || !isHiddenFile(f)) {
-                files.addElement(f);
+                files.add(f);
             }
         }
 
@@ -497,42 +515,50 @@
      *   <code>null</code> if <code>dir</code> is <code>null</code>
      */
     public File getParentDirectory(File dir) {
-        if (dir != null && dir.exists()) {
-            ShellFolder sf = getShellFolder(dir);
-            File psf = sf.getParentFile();
-            if (psf != null) {
-                if (isFileSystem(psf)) {
-                    File f = psf;
-                    if (f != null && !f.exists()) {
-                        // This could be a node under "Network Neighborhood".
-                        File ppsf = psf.getParentFile();
-                        if (ppsf == null || !isFileSystem(ppsf)) {
-                            // We're mostly after the exists() override for windows below.
-                            f = createFileSystemRoot(f);
-                        }
-                    }
-                    return f;
-                } else {
-                    return psf;
+        if (dir == null || !dir.exists()) {
+            return null;
+        }
+
+        ShellFolder sf;
+
+        try {
+            sf = getShellFolder(dir);
+        } catch (FileNotFoundException e) {
+            return null;
+        }
+
+        File psf = sf.getParentFile();
+
+        if (psf == null) {
+            return null;
+        }
+
+        if (isFileSystem(psf)) {
+            File f = psf;
+            if (!f.exists()) {
+                // This could be a node under "Network Neighborhood".
+                File ppsf = psf.getParentFile();
+                if (ppsf == null || !isFileSystem(ppsf)) {
+                    // We're mostly after the exists() override for windows below.
+                    f = createFileSystemRoot(f);
                 }
             }
+            return f;
+        } else {
+            return psf;
         }
-        return null;
     }
 
-    ShellFolder getShellFolder(File f) {
-        if (!(f instanceof ShellFolder)
-            && !(f instanceof FileSystemRoot)
-            && isFileSystemRoot(f)) {
-
+    /**
+     * Throws {@code FileNotFoundException} if file not found or current thread was interrupted
+     */
+    ShellFolder getShellFolder(File f) throws FileNotFoundException {
+        if (!(f instanceof ShellFolder) && !(f instanceof FileSystemRoot) && isFileSystemRoot(f)) {
             f = createFileSystemRoot(f);
         }
+
         try {
             return ShellFolder.getShellFolder(f);
-        } catch (FileNotFoundException e) {
-            System.err.println("FileSystemView.getShellFolder: f="+f);
-            e.printStackTrace();
-            return null;
         } catch (InternalError e) {
             System.err.println("FileSystemView.getShellFolder: f="+f);
             e.printStackTrace();
@@ -596,9 +622,9 @@
         // Unix - using OpenWindows' default folder name. Can't find one for Motif/CDE.
         newFolder = createFileObject(containingDir, newFolderString);
         int i = 1;
-        while (newFolder.exists() && (i < 100)) {
+        while (newFolder.exists() && i < 100) {
             newFolder = createFileObject(containingDir, MessageFormat.format(
-                    newFolderNextString, new Object[] { new Integer(i) }));
+                    newFolderNextString, new Integer(i)));
             i++;
         }
 
@@ -612,7 +638,7 @@
     }
 
     public boolean isFileSystemRoot(File dir) {
-        return (dir != null && dir.getAbsolutePath().equals("/"));
+        return dir != null && dir.getAbsolutePath().equals("/");
     }
 
     public boolean isDrive(File dir) {
@@ -654,7 +680,7 @@
 
     public File getChild(File parent, String fileName) {
         if (fileName.startsWith("\\")
-            && !(fileName.startsWith("\\\\"))
+            && !fileName.startsWith("\\\\")
             && isFileSystem(parent)) {
 
             //Path is relative to the root of parent's drive
@@ -677,9 +703,13 @@
      * The Windows implementation gets information from the ShellFolder class.
      */
     public String getSystemTypeDescription(File f) {
-        if (f != null) {
+        if (f == null) {
+            return null;
+        }
+
+        try {
             return getShellFolder(f).getFolderType();
-        } else {
+        } catch (FileNotFoundException e) {
             return null;
         }
     }
@@ -701,9 +731,9 @@
         // Using NT's default folder name
         File newFolder = createFileObject(containingDir, newFolderString);
         int i = 2;
-        while (newFolder.exists() && (i < 100)) {
+        while (newFolder.exists() && i < 100) {
             newFolder = createFileObject(containingDir, MessageFormat.format(
-                newFolderNextString, new Object[] { new Integer(i) }));
+                newFolderNextString, new Integer(i)));
             i++;
         }
 
@@ -727,7 +757,7 @@
             }
         });
 
-        return (path != null && (path.equals("A:\\") || path.equals("B:\\")));
+        return path != null && (path.equals("A:\\") || path.equals("B:\\"));
     }
 
     /**
--- a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java	Tue Dec 01 08:54:10 2009 -0800
@@ -71,33 +71,410 @@
      * Subclasses should override this method and use
      * the specified {@code Graphics} object to
      * render the content of the component.
+     * <p/>
+     * If {@code g} is not an instance of {@code Graphics2D},
+     * this method is no-op.
      *
      * @param g the {@code Graphics} context in which to paint;
      * @param c the component being painted;
-     * it can be safely cast to the {@code JLayer<V>}
+     * it can be safely cast to {@code JLayer<? extends V>}
+     *
+     * @see #configureGraphics(Graphics2D, JLayer)
+     * @see #paintLayer(Graphics2D, JLayer)
      */
-    @Override
     public void paint(Graphics g, JComponent c) {
-        c.paint(g);
+        if (g instanceof Graphics2D) {
+            Graphics2D g2 = (Graphics2D) g.create();
+            JLayer<? extends V> l = (JLayer<? extends V>) c;
+            configureGraphics(g2, l);
+            paintLayer(g2, l);
+            g2.dispose();
+        }
+    }
+
+    /**
+     * This method is called by the {@link #paint} method prior to
+     * {@link #paintLayer} to configure the {@code Graphics2D} object.
+     * The default implementation is empty.
+     *
+     * @param g2 the {@code Graphics2D} object to configure
+     * @param l the {@code JLayer} being painted
+     *
+     * @see #paintLayer(Graphics2D, JLayer)
+     */
+    protected void configureGraphics(Graphics2D g2, JLayer<? extends V> l) {
+    }
+
+    /**
+     * Called by the {@link #paint} method,
+     * subclasses should override this method
+     * to perform any custom painting operations.
+     * <p/>
+     * The default implementation paints the passed {@code JLayer} as is.
+     *
+     * @param g2 the {@code Graphics2D} context in which to paint
+     * @param l the {@code JLayer} being painted
+     *
+     * @see #configureGraphics(Graphics2D, JLayer)
+     */
+    protected void paintLayer(Graphics2D g2, JLayer<? extends V> l) {
+        l.paint(g2);
     }
 
     /**
      * Dispatches {@code AWTEvent}s for {@code JLayer}
-     * and <b>all it subcomponents</b> to this {@code LayerUI} instance.
-     * <p>
-     * To enable the {@code AWTEvent} of the particular type,
-     * you call {@link javax.swing.JLayer#setLayerEventMask}
+     * and <b>all its subcomponents</b> to this {@code LayerUI} instance.
+     * <p/>
+     * To enable the {@code AWTEvent}s of a particular type,
+     * you call {@link JLayer#setLayerEventMask}
      * in {@link #installUI(javax.swing.JComponent)}
      * and set the layer event mask to {@code 0}
-     * in {@link #uninstallUI(javax.swing.JComponent)} after that
+     * in {@link #uninstallUI(javax.swing.JComponent)} after that.
+     * By default this  method calls the appropriate
+     * {@code process&lt;event&nbsp;type&gt;Event}
+     * method for the given class of event.
      *
      * @param e the event to be dispatched
      * @param l the layer this LayerUI is set to
      *
      * @see JLayer#setLayerEventMask(long)
-     * @see javax.swing.JLayer#getLayerEventMask()
+     * @see #installUI(javax.swing.JComponent)
+     * @see #uninstallUI(javax.swing.JComponent)
+     * @see #processComponentEvent
+     * @see #processFocusEvent
+     * @see #processKeyEvent
+     * @see #processMouseEvent
+     * @see #processMouseMotionEvent
+     * @see #processInputMethodEvent
+     * @see #processHierarchyEvent
+     * @see #processMouseWheelEvent
      */
     public void eventDispatched(AWTEvent e, JLayer<? extends V> l){
+        if (e instanceof FocusEvent) {
+            processFocusEvent((FocusEvent)e, l);
+
+        } else if (e instanceof MouseEvent) {
+            switch(e.getID()) {
+              case MouseEvent.MOUSE_PRESSED:
+              case MouseEvent.MOUSE_RELEASED:
+              case MouseEvent.MOUSE_CLICKED:
+              case MouseEvent.MOUSE_ENTERED:
+              case MouseEvent.MOUSE_EXITED:
+                  processMouseEvent((MouseEvent)e, l);
+                  break;
+              case MouseEvent.MOUSE_MOVED:
+              case MouseEvent.MOUSE_DRAGGED:
+                  processMouseMotionEvent((MouseEvent)e, l);
+                  break;
+              case MouseEvent.MOUSE_WHEEL:
+                  processMouseWheelEvent((MouseWheelEvent)e, l);
+                  break;
+            }
+        } else if (e instanceof KeyEvent) {
+            processKeyEvent((KeyEvent)e, l);
+        } else if (e instanceof ComponentEvent) {
+            processComponentEvent((ComponentEvent)e, l);
+        } else if (e instanceof InputMethodEvent) {
+            processInputMethodEvent((InputMethodEvent)e, l);
+        } else if (e instanceof HierarchyEvent) {
+            switch (e.getID()) {
+              case HierarchyEvent.HIERARCHY_CHANGED:
+                  processHierarchyEvent((HierarchyEvent)e, l);
+                  break;
+              case HierarchyEvent.ANCESTOR_MOVED:
+              case HierarchyEvent.ANCESTOR_RESIZED:
+                  processHierarchyBoundsEvent((HierarchyEvent)e, l);
+                  break;
+            }
+        }
+    }
+
+    /**
+     * Processes component events occurring on the {@link JLayer}
+     * or any of its subcomponents.
+     * <p/>
+     * This method is not called unless component events are
+     * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+     * Component events are enabled in the overridden {@link #installUI} method
+     * and should be disabled in the {@link #uninstallUI} method after that.
+     * <pre>
+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.COMPONENT_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * </pre>
+     *
+     * @param e the {@code ComponentEvent} to be processed
+     * @param l the layer this {@code LayerUI} instance is set to
+     *
+     * @see JLayer#setLayerEventMask(long)
+     * @see #installUI(javax.swing.JComponent)
+     * @see #uninstallUI(javax.swing.JComponent)
+     */
+    protected void processComponentEvent(ComponentEvent e, JLayer<? extends V> l) {
+    }
+
+    /**
+     * Processes focus events occurring on the {@link JLayer}
+     * or any of its subcomponents.
+     * <p/>
+     * This method is not called unless focus events are
+     * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+     * Focus events are enabled in the overridden {@link #installUI} method
+     * and should be disabled in the {@link #uninstallUI} method after that.
+     * <pre>
+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.FOCUS_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * </pre>
+     *
+     * @param e the {@code FocusEvent} to be processed
+     * @param l the layer this {@code LayerUI} instance is set to
+     *
+     * @see JLayer#setLayerEventMask(long)
+     * @see #installUI(javax.swing.JComponent)
+     * @see #uninstallUI(javax.swing.JComponent)
+     */
+    protected void processFocusEvent(FocusEvent e, JLayer<? extends V> l) {
+    }
+
+    /**
+     * Processes key events occurring on the {@link JLayer}
+     * or any of its subcomponents.
+     * <p/>
+     * This method is not called unless key events are
+     * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+     * Key events are enabled in the overridden {@link #installUI} method
+     * and should be disabled in the {@link #uninstallUI} method after that.
+     * <pre>
+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.KEY_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * </pre>
+     *
+     * @param e the {@code KeyEvent} to be processed
+     * @param l the layer this {@code LayerUI} instance is set to
+     *
+     * @see JLayer#setLayerEventMask(long)
+     * @see #installUI(javax.swing.JComponent)
+     * @see #uninstallUI(javax.swing.JComponent)
+     */
+    protected void processKeyEvent(KeyEvent e, JLayer<? extends V> l) {
+    }
+
+    /**
+     * Processes mouse events occurring on the {@link JLayer}
+     * or any of its subcomponents.
+     * <p/>
+     * This method is not called unless mouse events are
+     * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+     * Mouse events are enabled in the overridden {@link #installUI} method
+     * and should be disabled in the {@link #uninstallUI} method after that.
+     * <pre>
+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * </pre>
+     *
+     * @param e the {@code MouseEvent} to be processed
+     * @param l the layer this {@code LayerUI} instance is set to
+     *
+     * @see JLayer#setLayerEventMask(long)
+     * @see #installUI(javax.swing.JComponent)
+     * @see #uninstallUI(javax.swing.JComponent)
+     */
+    protected void processMouseEvent(MouseEvent e, JLayer<? extends V> l) {
+    }
+
+    /**
+     * Processes mouse motion event occurring on the {@link JLayer}
+     * or any of its subcomponents.
+     * <p/>
+     * This method is not called unless mouse motion events are
+     * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+     * Mouse motion events are enabled in the overridden {@link #installUI} method
+     * and should be disabled in the {@link #uninstallUI} method after that.
+     * <pre>
+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.MOUSE_MOTION_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * </pre>
+     *
+     * @param e the {@code MouseEvent} to be processed
+     * @param l the layer this {@code LayerUI} instance is set to
+     *
+     * @see JLayer#setLayerEventMask(long)
+     * @see #installUI(javax.swing.JComponent)
+     * @see #uninstallUI(javax.swing.JComponent)
+     */
+    protected void processMouseMotionEvent(MouseEvent e, JLayer<? extends V> l) {
+    }
+
+    /**
+     * Processes mouse wheel event occurring on the {@link JLayer}
+     * or any of its subcomponents.
+     * <p/>
+     * This method is not called unless mouse wheel events are
+     * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+     * Mouse wheel events are enabled in the overridden {@link #installUI} method
+     * and should be disabled in the {@link #uninstallUI} method after that.
+     * <pre>
+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * </pre>
+     *
+     * @param e the {@code MouseEvent} to be processed
+     * @param l the layer this {@code LayerUI} instance is set to
+     *
+     * @see JLayer#setLayerEventMask(long)
+     * @see #installUI(javax.swing.JComponent)
+     * @see #uninstallUI(javax.swing.JComponent)
+     */
+    protected void processMouseWheelEvent(MouseWheelEvent e, JLayer<? extends V> l) {
+    }
+
+    /**
+     * Processes input event occurring on the {@link JLayer}
+     * or any of its subcomponents.
+     * <p/>
+     * This method is not called unless input events are
+     * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+     * Input events are enabled in the overridden {@link #installUI} method
+     * and should be disabled in the {@link #uninstallUI} method after that.
+     * <pre>
+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.INPUT_METHOD_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * </pre>
+     *
+     * @param e the {@code InputMethodEvent} to be processed
+     * @param l the layer this {@code LayerUI} instance is set to
+     *
+     * @see JLayer#setLayerEventMask(long)
+     * @see #installUI(javax.swing.JComponent)
+     * @see #uninstallUI(javax.swing.JComponent)
+     */
+    protected void processInputMethodEvent(InputMethodEvent e, JLayer<? extends V> l) {
+    }
+
+    /**
+     * Processes hierarchy event occurring on the {@link JLayer}
+     * or any of its subcomponents.
+     * <p/>
+     * This method is not called unless hierarchy events are
+     * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+     * Hierarchy events are enabled in the overridden {@link #installUI} method
+     * and should be disabled in the {@link #uninstallUI} method after that.
+     * <pre>
+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.HIERARCHY_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * </pre>
+     *
+     * @param e the {@code HierarchyEvent} to be processed
+     * @param l the layer this {@code LayerUI} instance is set to
+     *
+     * @see JLayer#setLayerEventMask(long)
+     * @see #installUI(javax.swing.JComponent)
+     * @see #uninstallUI(javax.swing.JComponent)
+     */
+    protected void processHierarchyEvent(HierarchyEvent e, JLayer<? extends V> l) {
+    }
+
+    /**
+     * Processes hierarchy bounds event occurring on the {@link JLayer}
+     * or any of its subcomponents.
+     * <p/>
+     * This method is not called unless hierarchy bounds events are
+     * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to.
+     * Hierarchy bounds events are enabled in the overridden {@link #installUI}
+     * method and should be disabled in the {@link #uninstallUI} method after that.
+     * <pre>
+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * </pre>
+     *
+     * @param e the {@code HierarchyEvent} to be processed
+     * @param l the layer this {@code LayerUI} instance is set to
+     *
+     * @see JLayer#setLayerEventMask(long)
+     * @see #installUI(javax.swing.JComponent)
+     * @see #uninstallUI(javax.swing.JComponent)
+     */
+    protected void processHierarchyBoundsEvent(HierarchyEvent e, JLayer<? extends V> l) {
     }
 
     /**
@@ -251,13 +628,28 @@
     }
 
     /**
+     * Repaints all {@code JLayer} instances this {@code LayerUI} is set to.
+     * Call this method when the state of this {@code LayerUI} is changed
+     * and the visual appearance of its {@code JLayer} objects needs to be updated.
+     *
+     * @see Component#repaint()
+     */
+    protected void repaintLayer() {
+        firePropertyChange("dirty", null, null);
+    }
+
+    /**
      * Notifies the {@code LayerUI} when any of its property are changed
-     * and enables updating every {@code JLayer} this {@code LayerUI} instance is set to.
+     * and enables updating every {@code JLayer}
+     * this {@code LayerUI} instance is set to.
      *
      * @param evt the PropertyChangeEvent generated by this {@code LayerUI}
      * @param l the {@code JLayer} this LayerUI is set to
      */
     public void applyPropertyChange(PropertyChangeEvent evt, JLayer<? extends V> l) {
+        if ("dirty".equals(evt.getPropertyName())) {
+            l.repaint();
+        }
     }
 
     /**
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java	Tue Dec 01 08:54:10 2009 -0800
@@ -486,7 +486,7 @@
                 }
                 if (remSize > 0 && addSize == 0) {
                     fireIntervalRemoved(BasicDirectoryModel.this, remStart, remStart + remSize - 1);
-                } else if (addSize > 0 && remSize == 0 && fileCache.size() > addSize) {
+                } else if (addSize > 0 && remSize == 0 && addStart + addSize <= fileCache.size()) {
                     fireIntervalAdded(BasicDirectoryModel.this, addStart, addStart + addSize - 1);
                 } else {
                     fireContentsChanged();
--- a/jdk/src/share/classes/javax/swing/plaf/metal/OceanTheme.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/metal/OceanTheme.java	Tue Dec 01 08:54:10 2009 -0800
@@ -32,6 +32,7 @@
 import javax.swing.plaf.*;
 import sun.swing.SwingUtilities2;
 import sun.swing.PrintColorUIResource;
+import sun.swing.SwingLazyValue;
 
 /**
  * The default theme for the {@code MetalLookAndFeel}.
@@ -128,7 +129,7 @@
      * @throws NullPointerException if {@code table} is {@code null}
      */
     public void addCustomEntriesToTable(UIDefaults table) {
-        Object focusBorder = new UIDefaults.ProxyLazyValue(
+        Object focusBorder = new SwingLazyValue(
                       "javax.swing.plaf.BorderUIResource$LineBorderUIResource",
                       new Object[] {getPrimary1()});
         // .30 0 DDE8F3 white secondary2
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java	Tue Dec 01 08:54:10 2009 -0800
@@ -638,7 +638,7 @@
             if ((b == null || b instanceof UIResource
                     || component instanceof SynthBooleanTableCellRenderer)
                     && !table.isCellSelected(row, column)) {
-                if (alternateColor != null && row % 2 == 0) {
+                if (alternateColor != null && row % 2 != 0) {
                     component.setBackground(alternateColor);
                 }
             }
--- a/jdk/src/share/classes/javax/swing/table/DefaultTableCellRenderer.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/table/DefaultTableCellRenderer.java	Tue Dec 01 08:54:10 2009 -0800
@@ -214,8 +214,9 @@
                                     : table.getBackground();
             if (background == null || background instanceof javax.swing.plaf.UIResource) {
                 Color alternateColor = DefaultLookup.getColor(this, ui, "Table.alternateRowColor");
-                if (alternateColor != null && row % 2 == 0)
+                if (alternateColor != null && row % 2 != 0) {
                     background = alternateColor;
+                }
             }
             super.setForeground(unselectedForeground != null
                                     ? unselectedForeground
--- a/jdk/src/share/classes/javax/swing/text/JTextComponent.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/javax/swing/text/JTextComponent.java	Tue Dec 01 08:54:10 2009 -0800
@@ -2069,7 +2069,7 @@
      *   width to match its own
      */
     public boolean getScrollableTracksViewportWidth() {
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         if (port != null) {
             return port.getWidth() > getPreferredSize().width;
         }
@@ -2090,7 +2090,7 @@
      *   to match its own
      */
     public boolean getScrollableTracksViewportHeight() {
-        JViewport port = SwingUtilities2.getViewport(this);
+        JViewport port = SwingUtilities.getParentViewport(this);
         if (port != null) {
             return (port.getHeight() > getPreferredSize().height);
         }
--- a/jdk/src/share/classes/org/ietf/jgss/GSSContext.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/org/ietf/jgss/GSSContext.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2001 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -678,7 +678,7 @@
      * are not definitive then the method will attempt to treat all
      * available bytes as part of the token.<p>
      *
-     * Other than the possible blocking behaviour described above, this
+     * Other than the possible blocking behavior described above, this
      * method is equivalent to the byte array based {@link #unwrap(byte[],
      * int, int, MessageProp) unwrap} method.<p>
      *
@@ -826,7 +826,7 @@
      * are not definitive then the method will attempt to treat all
      * available bytes as part of the token.<p>
      *
-     * Other than the possible blocking behaviour described above, this
+     * Other than the possible blocking behavior described above, this
      * method is equivalent to the byte array based {@link #verifyMIC(byte[],
      * int, int, byte[], int, int, MessageProp) verifyMIC} method.<p>
      *
@@ -917,7 +917,7 @@
      * getMutualAuthState} method.<p>
      *
      * @param state a boolean value indicating whether mutual
-     * authentication shouls be used or not.
+     * authentication should be used or not.
      * @see #getMutualAuthState()
      *
      * @throws GSSException containing the following
@@ -928,7 +928,7 @@
 
     /**
      * Requests that replay detection be enabled for the
-     * per-message security services after context establishemnt. This
+     * per-message security services after context establishment. This
      * request can only be made on the context initiator's side and it has
      * to be done prior to the first call to
      * <code>initSecContext</code>. During context establishment replay
@@ -958,7 +958,7 @@
 
     /**
      * Requests that sequence checking be enabled for the
-     * per-message security services after context establishemnt. This
+     * per-message security services after context establishment. This
      * request can only be made on the context initiator's side and it has
      * to be done prior to the first call to
      * <code>initSecContext</code>. During context establishment sequence
--- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java	Tue Dec 01 08:54:10 2009 -0800
@@ -63,8 +63,6 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 
-import java.rmi.MarshalledObject;
-
 import java.security.AccessControlContext;
 import java.security.AccessControlException;
 import java.security.AccessController;
@@ -494,6 +492,13 @@
     }
 
     /**
+     * Returns {@code true} if the given type is a java.rmi.Remote.
+     */
+    public static boolean isRemote(Class<?> type) {
+        return RMI.isRemote(type);
+    }
+
+    /**
      * Returns an Iterator which traverses a SortedSet of Strings which are
      * a total order of the standard character sets supported by the JRE. The
      * ordering follows the same principles as DataFlavor.selectBestTextFlavor.
@@ -1360,7 +1365,7 @@
 
         // Source data is an RMI object
         } else if (flavor.isRepresentationClassRemote()) {
-            MarshalledObject mo = new MarshalledObject(obj);
+            Object mo = RMI.newMarshalledObject(obj);
             ObjectOutputStream oos = new ObjectOutputStream(bos);
             oos.writeObject(mo);
             oos.close();
@@ -1671,7 +1676,7 @@
             try {
                 byte[] ba = inputStreamToByteArray(str);
                 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(ba));
-                Object ret = ((MarshalledObject)(ois.readObject())).get();
+                Object ret = RMI.getMarshalledObject(ois.readObject());
                 ois.close();
                 str.close();
                 return ret;
@@ -2669,8 +2674,12 @@
                                               Integer.valueOf(0));
                 nonTextRepresentationsMap.put(java.io.Serializable.class,
                                               Integer.valueOf(1));
-                nonTextRepresentationsMap.put(java.rmi.Remote.class,
-                                              Integer.valueOf(2));
+
+                Class<?> remoteClass = RMI.remoteClass();
+                if (remoteClass != null) {
+                    nonTextRepresentationsMap.put(remoteClass,
+                                                  Integer.valueOf(2));
+                }
 
                 nonTextRepresentations =
                     Collections.unmodifiableMap(nonTextRepresentationsMap);
@@ -2900,4 +2909,95 @@
             }
         }
     }
+
+    /**
+     * A class that provides access to java.rmi.Remote and java.rmi.MarshalledObject
+     * without creating a static dependency.
+     */
+    private static class RMI {
+        private static final Class<?> remoteClass = getClass("java.rmi.Remote");
+        private static final Class<?> marshallObjectClass =
+            getClass("java.rmi.MarshalledObject");
+        private static final Constructor<?> marshallCtor =
+            getConstructor(marshallObjectClass, Object.class);
+        private static final Method marshallGet =
+            getMethod(marshallObjectClass, "get");
+
+        private static Class<?> getClass(String name) {
+            try {
+                return Class.forName(name, true, null);
+            } catch (ClassNotFoundException e) {
+                return null;
+            }
+        }
+
+        private static Constructor<?> getConstructor(Class<?> c, Class<?>... types) {
+            try {
+                return (c == null) ? null : c.getDeclaredConstructor(types);
+            } catch (NoSuchMethodException x) {
+                throw new AssertionError(x);
+            }
+        }
+
+        private static Method getMethod(Class<?> c, String name, Class<?>... types) {
+            try {
+                return (c == null) ? null : c.getMethod(name, types);
+            } catch (NoSuchMethodException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        /**
+         * Returns {@code true} if the given class is java.rmi.Remote.
+         */
+        static boolean isRemote(Class<?> c) {
+            return (remoteClass == null) ? null : remoteClass.isAssignableFrom(c);
+        }
+
+        /**
+         * Returns java.rmi.Remote.class if RMI is present; otherwise {@code null}.
+         */
+        static Class<?> remoteClass() {
+            return remoteClass;
+        }
+
+        /**
+         * Returns a new MarshalledObject containing the serialized representation
+         * of the given object.
+         */
+        static Object newMarshalledObject(Object obj) throws IOException {
+            try {
+                return marshallCtor.newInstance(obj);
+            } catch (InstantiationException x) {
+                throw new AssertionError(x);
+            } catch (IllegalAccessException x) {
+                throw new AssertionError(x);
+            } catch (InvocationTargetException  x) {
+                Throwable cause = x.getCause();
+                if (cause instanceof IOException)
+                    throw (IOException)cause;
+                throw new AssertionError(x);
+            }
+        }
+
+        /**
+         * Returns a new copy of the contained marshalled object.
+         */
+        static Object getMarshalledObject(Object obj)
+            throws IOException, ClassNotFoundException
+        {
+            try {
+                return marshallGet.invoke(obj);
+            } catch (IllegalAccessException x) {
+                throw new AssertionError(x);
+            } catch (InvocationTargetException x) {
+                Throwable cause = x.getCause();
+                if (cause instanceof IOException)
+                    throw (IOException)cause;
+                if (cause instanceof ClassNotFoundException)
+                    throw (ClassNotFoundException)cause;
+                throw new AssertionError(x);
+            }
+        }
+    }
 }
--- a/jdk/src/share/classes/sun/awt/im/InputMethodManager.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/awt/im/InputMethodManager.java	Tue Dec 01 08:54:10 2009 -0800
@@ -358,7 +358,9 @@
         AppContext requesterAppContext = SunToolkit.targetToAppContext(requester);
         synchronized (lock) {
             SunToolkit.postEvent(requesterAppContext, event);
-            lock.wait();
+            while (!event.isDispatched()) {
+                lock.wait();
+            }
         }
 
         Throwable eventThrowable = event.getThrowable();
--- a/jdk/src/share/classes/sun/awt/shell/ShellFolder.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/awt/shell/ShellFolder.java	Tue Dec 01 08:54:10 2009 -0800
@@ -201,6 +201,8 @@
 
     private static ShellFolderManager shellFolderManager;
 
+    private static Invoker invoker;
+
     static {
         String managerClassName = (String)Toolkit.getDefaultToolkit().
                                       getDesktopProperty("Shell.shellFolderManager");
@@ -225,6 +227,8 @@
             throw new Error ("Could not access Shell Folder Manager: "
             + managerClass.getName());
         }
+
+        invoker = shellFolderManager.createInvoker();
     }
 
     /**
@@ -486,21 +490,6 @@
         return null;
     }
 
-    private static Invoker invoker;
-
-    /**
-     * Provides the single access point to the {@link Invoker}. It is guaranteed that the value
-     * returned by this method will be always the same.
-     *
-     * @return the singleton instance of {@link Invoker}
-     */
-    public static Invoker getInvoker() {
-        if (invoker == null) {
-            invoker = shellFolderManager.createInvoker();
-        }
-        return invoker;
-    }
-
     /**
      * Invokes the {@code task} which doesn't throw checked exceptions
      * from its {@code call} method. If invokation is interrupted then Thread.currentThread().isInterrupted() will
@@ -522,7 +511,7 @@
     public static <T, E extends Throwable> T invoke(Callable<T> task, Class<E> exceptionClass)
             throws InterruptedException, E {
         try {
-            return getInvoker().invoke(task);
+            return invoker.invoke(task);
         } catch (Exception e) {
             if (e instanceof RuntimeException) {
                 // Rethrow unchecked exceptions
--- a/jdk/src/share/classes/sun/font/Font2D.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/font/Font2D.java	Tue Dec 01 08:54:10 2009 -0800
@@ -320,21 +320,6 @@
                     lastFontStrike = new SoftReference(strike);
                     StrikeCache.refStrike(strike);
                     return strike;
-                } else {
-                    /* We have found a cleared reference that has not yet
-                     * been removed by the disposer.
-                     * If we make this reference unreachable by removing it
-                     * from the map,or overwriting it with a new reference to
-                     * a new strike, then it is possible it may never be
-                     * enqueued for disposal. That is the implication of
-                     * the docs for java.lang.ref. So on finding a cleared
-                     * reference, we need to dispose the native resources,
-                     * if they haven't already been freed.
-                     * The reference object needs to have a reference to
-                     * the disposer instance for this to occur.
-                     */
-                  ((StrikeCache.DisposableStrike)strikeRef)
-                      .getDisposer().dispose();
                 }
             }
             /* When we create a new FontStrike instance, we *must*
--- a/jdk/src/share/classes/sun/font/FontDesignMetrics.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/font/FontDesignMetrics.java	Tue Dec 01 08:54:10 2009 -0800
@@ -171,7 +171,7 @@
      * out we can clear the keys from the table.
      */
     private static class KeyReference extends SoftReference
-        implements DisposerRecord {
+        implements DisposerRecord, Disposer.PollDisposable {
 
         static ReferenceQueue queue = Disposer.getQueue();
 
--- a/jdk/src/share/classes/sun/font/FontStrikeDisposer.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/font/FontStrikeDisposer.java	Tue Dec 01 08:54:10 2009 -0800
@@ -25,6 +25,7 @@
 
 package sun.font;
 
+import sun.java2d.Disposer;
 import sun.java2d.DisposerRecord;
 
 /*
@@ -49,7 +50,8 @@
  * entries would be removed much more promptly than we need.
  */
 
-class FontStrikeDisposer implements DisposerRecord {
+class FontStrikeDisposer
+    implements DisposerRecord, Disposer.PollDisposable {
 
     Font2D font2D;
     FontStrikeDesc desc;
--- a/jdk/src/share/classes/sun/font/StrikeCache.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/font/StrikeCache.java	Tue Dec 01 08:54:10 2009 -0800
@@ -254,9 +254,20 @@
         // because they may be accessed on that thread at the time of the
         // disposal (for example, when the accel. cache is invalidated)
 
-        // REMIND: this look a bit heavyweight, but should be ok
-        // because strike disposal is a relatively infrequent operation,
-        // more worrisome is the necessity of getting a GC here.
+        // Whilst this is a bit heavyweight, in most applications
+        // strike disposal is a relatively infrequent operation, so it
+        // doesn't matter. But in some tests that use vast numbers
+        // of strikes, the switching back and forth is measurable.
+        // So the "pollRemove" call is added to batch up the work.
+        // If we are polling we know we've already been called back
+        // and can directly dispose the record.
+        // Also worrisome is the necessity of getting a GC here.
+
+        if (Disposer.pollingQueue) {
+            doDispose(disposer);
+            return;
+        }
+
         RenderQueue rq = null;
         GraphicsEnvironment ge =
             GraphicsEnvironment.getLocalGraphicsEnvironment();
@@ -277,6 +288,7 @@
                 rq.flushAndInvokeNow(new Runnable() {
                     public void run() {
                         doDispose(disposer);
+                        Disposer.pollRemove();
                     }
                 });
             } finally {
--- a/jdk/src/share/classes/sun/java2d/Disposer.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/Disposer.java	Tue Dec 01 08:54:10 2009 -0800
@@ -29,6 +29,7 @@
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.PhantomReference;
 import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 import java.util.Hashtable;
 
 /**
@@ -146,6 +147,7 @@
                 rec.dispose();
                 obj = null;
                 rec = null;
+                clearDeferredRecords();
             } catch (Exception e) {
                 System.out.println("Exception while removing reference: " + e);
                 e.printStackTrace();
@@ -153,6 +155,85 @@
         }
     }
 
+    /*
+     * This is a marker interface that, if implemented, means it
+     * doesn't acquire any special locks, and is safe to
+     * be disposed in the poll loop on whatever thread
+     * which happens to be the Toolkit thread, is in use.
+     */
+    public static interface PollDisposable {
+    };
+
+    private static ArrayList<DisposerRecord> deferredRecords = null;
+
+    private static void clearDeferredRecords() {
+        if (deferredRecords == null || deferredRecords.isEmpty()) {
+            return;
+        }
+        for (int i=0;i<deferredRecords.size(); i++) {
+            try {
+                DisposerRecord rec = deferredRecords.get(i);
+                rec.dispose();
+            } catch (Exception e) {
+                System.out.println("Exception while disposing deferred rec.");
+                e.printStackTrace();
+            }
+        }
+        deferredRecords.clear();
+    }
+
+    /*
+     * Set to indicate the queue is presently being polled.
+     */
+    public static volatile boolean pollingQueue = false;
+
+    /*
+     * The pollRemove() method is called back from a dispose method
+     * that is running on the toolkit thread and wants to
+     * dispose any pending refs that are safe to be disposed
+     * on that thread.
+     */
+    public static void pollRemove() {
+
+        /* This should never be called recursively, so this check
+         * is just a safeguard against the unexpected.
+         */
+        if (pollingQueue) {
+            return;
+        }
+        Object obj;
+        pollingQueue = true;
+        int freed = 0;
+        int deferred = 0;
+        try {
+            while ((obj = queue.poll()) != null
+                   && freed < 10000 && deferred < 100) {
+                freed++;
+                ((Reference)obj).clear();
+                DisposerRecord rec = (DisposerRecord)records.remove(obj);
+                if (rec instanceof PollDisposable) {
+                    rec.dispose();
+                    obj = null;
+                    rec = null;
+                } else {
+                    if (rec == null) { // shouldn't happen, but just in case.
+                        continue;
+                    }
+                    deferred++;
+                    if (deferredRecords == null) {
+                      deferredRecords = new ArrayList<DisposerRecord>(5);
+                    }
+                    deferredRecords.add(rec);
+                }
+            }
+        } catch (Exception e) {
+            System.out.println("Exception while removing reference: " + e);
+            e.printStackTrace();
+        } finally {
+            pollingQueue = false;
+        }
+    }
+
     private static native void initIDs();
 
     /*
--- a/jdk/src/share/classes/sun/java2d/SunGraphics2D.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/SunGraphics2D.java	Tue Dec 01 08:54:10 2009 -0800
@@ -257,7 +257,6 @@
             font = defaultFont;
         }
 
-        loops = sd.getRenderLoops(this);
         setDevClip(sd.getBounds());
         invalidatePipe();
     }
@@ -367,6 +366,7 @@
         shapepipe = invalidpipe;
         textpipe = invalidpipe;
         imagepipe = invalidpipe;
+        loops = null;
     }
 
     public void validatePipe() {
--- a/jdk/src/share/classes/sun/java2d/SurfaceData.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/SurfaceData.java	Tue Dec 01 08:54:10 2009 -0800
@@ -69,6 +69,7 @@
 import sun.java2d.pipe.DrawImage;
 import sun.awt.SunHints;
 import sun.awt.image.SurfaceManager;
+import sun.java2d.pipe.LoopBasedPipe;
 
 /**
  * This class provides various pieces of information relevant to a
@@ -506,7 +507,6 @@
                     sg2d.textpipe = solidTextRenderer;
                 }
                 sg2d.shapepipe = colorPrimitives;
-                sg2d.loops = getRenderLoops(sg2d);
                 // assert(sg2d.surfaceData == this);
             }
         } else if (sg2d.compositeState == sg2d.COMP_CUSTOM) {
@@ -603,8 +603,17 @@
 
             sg2d.textpipe = getTextPipe(sg2d, false /* AA==OFF */);
             sg2d.shapepipe = colorPrimitives;
+            // assert(sg2d.surfaceData == this);
+        }
+
+        // check for loops
+        if (sg2d.textpipe  instanceof LoopBasedPipe ||
+            sg2d.shapepipe instanceof LoopBasedPipe ||
+            sg2d.fillpipe  instanceof LoopBasedPipe ||
+            sg2d.drawpipe  instanceof LoopBasedPipe ||
+            sg2d.imagepipe instanceof LoopBasedPipe)
+        {
             sg2d.loops = getRenderLoops(sg2d);
-            // assert(sg2d.surfaceData == this);
         }
     }
 
--- a/jdk/src/share/classes/sun/java2d/pipe/AATextRenderer.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/pipe/AATextRenderer.java	Tue Dec 01 08:54:10 2009 -0800
@@ -34,8 +34,9 @@
  * a solid source colour to an opaque destination.
  */
 
-public class AATextRenderer extends GlyphListLoopPipe {
-
+public class AATextRenderer extends GlyphListLoopPipe
+    implements LoopBasedPipe
+{
    protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
        sg2d.loops.drawGlyphListAALoop.DrawGlyphListAA(sg2d, sg2d.surfaceData,
                                                       gl);
--- a/jdk/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java	Tue Dec 01 08:54:10 2009 -0800
@@ -36,8 +36,9 @@
  * the installed loop may not match the glyphvector.
  */
 
-public abstract class GlyphListLoopPipe extends GlyphListPipe {
-
+public abstract class GlyphListLoopPipe extends GlyphListPipe
+    implements LoopBasedPipe
+{
     protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl,
                                  int aaHint) {
         switch (aaHint) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/java2d/pipe/LoopBasedPipe.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.java2d.pipe;
+
+/**
+ * This is a marker interface used by Pipes that need RenderLoops.
+ * RenderLoops are validated in SurfaceData when a pipe is recognised to
+ * implement this interface.
+ *
+ * @author Mario Torre <neugens@aicas.com>
+ */
+public interface LoopBasedPipe {
+
+}
--- a/jdk/src/share/classes/sun/java2d/pipe/LoopPipe.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/pipe/LoopPipe.java	Tue Dec 01 08:54:10 2009 -0800
@@ -46,7 +46,8 @@
 public class LoopPipe
     implements PixelDrawPipe,
                PixelFillPipe,
-               ShapeDrawPipe
+               ShapeDrawPipe,
+               LoopBasedPipe
 {
     final static RenderingEngine RenderEngine = RenderingEngine.getInstance();
 
--- a/jdk/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java	Tue Dec 01 08:54:10 2009 -0800
@@ -35,8 +35,9 @@
  * a solid source colour to an opaque destination.
  */
 
-public class SolidTextRenderer extends GlyphListLoopPipe {
-
+public class SolidTextRenderer extends GlyphListLoopPipe
+    implements LoopBasedPipe
+{
     protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
         sg2d.loops.drawGlyphListLoop.DrawGlyphList(sg2d, sg2d.surfaceData, gl);
     }
--- a/jdk/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java	Tue Dec 01 08:54:10 2009 -0800
@@ -65,7 +65,9 @@
         }
     }
 
-    public static class Simple extends SpanShapeRenderer {
+    public static class Simple extends SpanShapeRenderer
+        implements  LoopBasedPipe
+    {
         public Object startSequence(SunGraphics2D sg, Shape s,
                                     Rectangle devR, int[] bbox) {
             return sg;
--- a/jdk/src/share/classes/sun/java2d/pisces/Renderer.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/java2d/pisces/Renderer.java	Tue Dec 01 08:54:10 2009 -0800
@@ -775,10 +775,12 @@
 
     // Free sorting arrays if larger than maximum size
     private void crossingListFinished() {
-        if (crossings.length > DEFAULT_CROSSINGS_SIZE) {
+        if (crossings != null && crossings.length > DEFAULT_CROSSINGS_SIZE) {
             crossings = new int[DEFAULT_CROSSINGS_SIZE];
         }
-        if (crossingIndices.length > DEFAULT_INDICES_SIZE) {
+        if (crossingIndices != null &&
+            crossingIndices.length > DEFAULT_INDICES_SIZE)
+        {
             crossingIndices = new int[DEFAULT_INDICES_SIZE];
         }
     }
--- a/jdk/src/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java	Tue Dec 01 08:54:10 2009 -0800
@@ -25,6 +25,7 @@
 
 package sun.net.www.protocol.http.spnego;
 
+import com.sun.security.jgss.ExtendedGSSContext;
 import java.io.IOException;
 
 import org.ietf.jgss.GSSContext;
@@ -100,15 +101,10 @@
                                         null,
                                         GSSContext.DEFAULT_LIFETIME);
 
-        // In order to support credential delegation in HTTP/SPNEGO,
-        // we always request it before initSecContext. The current
-        // implementation will check the OK-AS-DELEGATE flag inside
-        // the service ticket of the web server, and only enable
-        // delegation when this flag is set. This check is only
-        // performed when the GSS caller is CALLER_HTTP_NEGOTIATE,
-        // so all other normal GSS-API calls are not affected.
-
-        context.requestCredDeleg(true);
+        // Always respect delegation policy in HTTP/SPNEGO.
+        if (context instanceof ExtendedGSSContext) {
+            ((ExtendedGSSContext)context).requestDelegPolicy(true);
+        }
         oneToken = context.initSecContext(new byte[0], 0, 0);
     }
 
--- a/jdk/src/share/classes/sun/security/jgss/GSSContextImpl.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/GSSContextImpl.java	Tue Dec 01 08:54:10 2009 -0800
@@ -89,7 +89,8 @@
  */
 class GSSContextImpl implements ExtendedGSSContext {
 
-    private GSSManagerImpl gssManager = null;
+    private final GSSManagerImpl gssManager;
+    private final boolean initiator;
 
     // private flags for the context state
     private static final int PRE_INIT = 1;
@@ -99,14 +100,12 @@
 
     // instance variables
     private int currentState = PRE_INIT;
-    private boolean initiator;
 
     private GSSContextSpi mechCtxt = null;
     private Oid mechOid = null;
     private ObjectIdentifier objId = null;
 
     private GSSCredentialImpl myCred = null;
-    private GSSCredentialImpl delegCred = null;
 
     private GSSNameImpl srcName = null;
     private GSSNameImpl targName = null;
@@ -121,6 +120,7 @@
     private boolean reqSequenceDetState = true;
     private boolean reqCredDelegState = false;
     private boolean reqAnonState = false;
+    private boolean reqDelegPolicyState = false;
 
     /**
      * Creates a GSSContextImp on the context initiator's side.
@@ -221,6 +221,7 @@
                 mechCtxt.requestSequenceDet(reqSequenceDetState);
                 mechCtxt.requestAnonymity(reqAnonState);
                 mechCtxt.setChannelBinding(channelBindings);
+                mechCtxt.requestDelegPolicy(reqDelegPolicyState);
 
                 objId = new ObjectIdentifier(mechOid.toString());
 
@@ -465,42 +466,42 @@
     }
 
     public void requestMutualAuth(boolean state) throws GSSException {
-        if (mechCtxt == null)
+        if (mechCtxt == null && initiator)
             reqMutualAuthState = state;
     }
 
     public void requestReplayDet(boolean state) throws GSSException {
-        if (mechCtxt == null)
+        if (mechCtxt == null && initiator)
             reqReplayDetState = state;
     }
 
     public void requestSequenceDet(boolean state) throws GSSException {
-        if (mechCtxt == null)
+        if (mechCtxt == null && initiator)
             reqSequenceDetState = state;
     }
 
     public void requestCredDeleg(boolean state) throws GSSException {
-        if (mechCtxt == null)
+        if (mechCtxt == null && initiator)
             reqCredDelegState = state;
     }
 
     public void requestAnonymity(boolean state) throws GSSException {
-        if (mechCtxt == null)
+        if (mechCtxt == null && initiator)
             reqAnonState = state;
     }
 
     public void requestConf(boolean state) throws GSSException {
-        if (mechCtxt == null)
+        if (mechCtxt == null && initiator)
             reqConfState = state;
     }
 
     public void requestInteg(boolean state) throws GSSException {
-        if (mechCtxt == null)
+        if (mechCtxt == null && initiator)
             reqIntegState = state;
     }
 
     public void requestLifetime(int lifetime) throws GSSException {
-        if (mechCtxt == null)
+        if (mechCtxt == null && initiator)
             reqLifetime = lifetime;
     }
 
@@ -630,6 +631,8 @@
         targName = null;
     }
 
+    // ExtendedGSSContext methods:
+
     @Override
     public Object inquireSecContext(InquireType type) throws GSSException {
         SecurityManager security = System.getSecurityManager();
@@ -641,4 +644,18 @@
         }
         return mechCtxt.inquireSecContext(type);
     }
+
+    @Override
+    public void requestDelegPolicy(boolean state) throws GSSException {
+        if (mechCtxt == null && initiator)
+            reqDelegPolicyState = state;
+    }
+
+    @Override
+    public boolean getDelegPolicyState() {
+        if (mechCtxt != null)
+            return mechCtxt.getDelegPolicyState();
+        else
+            return reqDelegPolicyState;
+    }
 }
--- a/jdk/src/share/classes/sun/security/jgss/krb5/InitialToken.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/InitialToken.java	Tue Dec 01 08:54:10 2009 -0800
@@ -85,34 +85,41 @@
             int size = CHECKSUM_LENGTH_SIZE + CHECKSUM_BINDINGS_SIZE +
                 CHECKSUM_FLAGS_SIZE;
 
-            if (context.getCredDelegState()) {
-                if (context.getCaller() instanceof HttpCaller &&
-                        !serviceTicket.getFlags()[Krb5.TKT_OPTS_DELEGATE]) {
-                    // When the caller is HTTP/SPNEGO and OK-AS-DELEGATE
-                    // is not present in the service ticket, delegation
-                    // is disabled.
-                    context.setCredDelegState(false);
-                } else if (!tgt.isForwardable()) {
-                    // XXX log this resetting of delegation state
-                    context.setCredDelegState(false);
+            if (!tgt.isForwardable()) {
+                context.setCredDelegState(false);
+                context.setDelegPolicyState(false);
+            } else if (context.getCredDelegState()) {
+                if (context.getDelegPolicyState()) {
+                    if (!serviceTicket.checkDelegate()) {
+                        // delegation not permitted by server policy, mark it
+                        context.setDelegPolicyState(false);
+                    }
+                }
+            } else if (context.getDelegPolicyState()) {
+                if (serviceTicket.checkDelegate()) {
+                    context.setCredDelegState(true);
                 } else {
-                    KrbCred krbCred = null;
-                    CipherHelper cipherHelper =
-                        context.getCipherHelper(serviceTicket.getSessionKey());
-                    if (useNullKey(cipherHelper)) {
-                        krbCred = new KrbCred(tgt, serviceTicket,
-                                                  EncryptionKey.NULL_KEY);
-                    } else {
-                        krbCred = new KrbCred(tgt, serviceTicket,
-                                        serviceTicket.getSessionKey());
-                    }
-                    krbCredMessage = krbCred.getMessage();
-                    size += CHECKSUM_DELEG_OPT_SIZE +
-                            CHECKSUM_DELEG_LGTH_SIZE +
-                            krbCredMessage.length;
+                    context.setDelegPolicyState(false);
                 }
             }
 
+            if (context.getCredDelegState()) {
+                KrbCred krbCred = null;
+                CipherHelper cipherHelper =
+                    context.getCipherHelper(serviceTicket.getSessionKey());
+                if (useNullKey(cipherHelper)) {
+                    krbCred = new KrbCred(tgt, serviceTicket,
+                                              EncryptionKey.NULL_KEY);
+                } else {
+                    krbCred = new KrbCred(tgt, serviceTicket,
+                                    serviceTicket.getSessionKey());
+                }
+                krbCredMessage = krbCred.getMessage();
+                size += CHECKSUM_DELEG_OPT_SIZE +
+                        CHECKSUM_DELEG_LGTH_SIZE +
+                        krbCredMessage.length;
+            }
+
             checksumBytes = new byte[size];
 
             checksumBytes[pos++] = CHECKSUM_FIRST_BYTES[0];
@@ -296,6 +303,7 @@
             return delegCreds;
         }
 
+        // Only called by acceptor
         public void setContextFlags(Krb5Context context) {
                 // default for cred delegation is false
             if ((flags & CHECKSUM_DELEG_FLAG) > 0)
--- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java	Tue Dec 01 08:54:10 2009 -0800
@@ -78,6 +78,7 @@
     private boolean sequenceDetState  = true;
     private boolean confState  = true;
     private boolean integState  = true;
+    private boolean delegPolicyState = false;
 
     private int mySeqNumber;
     private int peerSeqNumber;
@@ -299,6 +300,21 @@
         return sequenceDetState || replayDetState;
     }
 
+    /**
+     * Requests that the deleg policy be respected.
+     */
+    public final void requestDelegPolicy(boolean value) {
+        if (state == STATE_NEW && isInitiator())
+            delegPolicyState = value;
+    }
+
+    /**
+     * Is deleg policy respected?
+     */
+    public final boolean getDelegPolicyState() {
+        return delegPolicyState;
+    }
+
     /*
      * Anonymity is a little different in that after an application
      * requests anonymity it will want to know whether the mechanism
@@ -422,6 +438,10 @@
         integState = state;
     }
 
+    final void setDelegPolicyState(boolean state) {
+        delegPolicyState = state;
+    }
+
     /**
      * Sets the channel bindings to be used during context
      * establishment.
--- a/jdk/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java	Tue Dec 01 08:54:10 2009 -0800
@@ -124,6 +124,8 @@
 
     public void requestInteg(boolean state) throws GSSException;
 
+    public void requestDelegPolicy(boolean state) throws GSSException;
+
     public void setChannelBinding(ChannelBinding cb) throws GSSException;
 
     public boolean getCredDelegState();
@@ -136,6 +138,8 @@
 
     public boolean getAnonymityState();
 
+    public boolean getDelegPolicyState();
+
     public boolean isTransferable() throws GSSException;
 
     public boolean isProtReady();
--- a/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java	Tue Dec 01 08:54:10 2009 -0800
@@ -63,6 +63,7 @@
     private boolean sequenceDetState = true;
     private boolean confState = true;
     private boolean integState = true;
+    private boolean delegPolicyState = false;
 
     private GSSNameSpi peerName = null;
     private GSSNameSpi myName = null;
@@ -154,6 +155,14 @@
     }
 
     /**
+     * Requests that deleg policy be respected.
+     */
+    public final void requestDelegPolicy(boolean value) throws GSSException {
+        if (state == STATE_NEW && isInitiator())
+            delegPolicyState = value;
+    }
+
+    /**
      * Is integrity available?
      */
     public final boolean getIntegState() {
@@ -161,6 +170,19 @@
     }
 
     /**
+     * Is deleg policy respected?
+     */
+    public final boolean getDelegPolicyState() {
+        if (isInitiator() && mechContext != null &&
+                mechContext instanceof ExtendedGSSContext &&
+                (state == STATE_IN_PROCESS || state == STATE_DONE)) {
+            return ((ExtendedGSSContext)mechContext).getDelegPolicyState();
+        } else {
+            return delegPolicyState;
+        }
+    }
+
+    /**
      * Requests that credential delegation be done during context
      * establishment.
      */
@@ -173,7 +195,7 @@
      * Is credential delegation enabled?
      */
     public final boolean getCredDelegState() {
-        if (mechContext != null &&
+        if (isInitiator() && mechContext != null &&
                 (state == STATE_IN_PROCESS || state == STATE_DONE)) {
             return mechContext.getCredDelegState();
         } else {
@@ -201,30 +223,6 @@
         return mutualAuthState;
     }
 
-    final void setCredDelegState(boolean state) {
-        credDelegState = state;
-    }
-
-    final void setMutualAuthState(boolean state) {
-        mutualAuthState = state;
-    }
-
-    final void setReplayDetState(boolean state) {
-        replayDetState = state;
-    }
-
-    final void setSequenceDetState(boolean state) {
-        sequenceDetState = state;
-    }
-
-    final void setConfState(boolean state) {
-        confState = state;
-    }
-
-    final void setIntegState(boolean state) {
-        integState = state;
-    }
-
     /**
      * Returns the mechanism oid.
      *
@@ -319,14 +317,9 @@
                 mechToken = GSS_initSecContext(null);
 
                 errorCode = GSSException.DEFECTIVE_TOKEN;
-                byte[] micToken = null;
-                if (!GSSUtil.useMSInterop()) {
-                    // calculate MIC only in normal mode
-                    micToken = generateMechListMIC(DER_mechTypes);
-                }
                 // generate SPNEGO token
                 initToken = new NegTokenInit(DER_mechTypes, getContextFlags(),
-                                        mechToken, micToken);
+                                        mechToken, null);
                 if (DEBUG) {
                     System.out.println("SpNegoContext.initSecContext: " +
                                 "sending token of type = " +
@@ -585,15 +578,9 @@
                                 "negotiated result = " + negoResult);
                 }
 
-                // calculate MIC only in normal mode
-                byte[] micToken = null;
-                if (!GSSUtil.useMSInterop() && valid) {
-                    micToken = generateMechListMIC(DER_mechTypes);
-                }
-
                 // generate SPNEGO token
                 NegTokenTarg targToken = new NegTokenTarg(negoResult.ordinal(),
-                                mech_wanted, accept_token, micToken);
+                                mech_wanted, accept_token, null);
                 if (DEBUG) {
                     System.out.println("SpNegoContext.acceptSecContext: " +
                                 "sending token of type = " +
@@ -653,6 +640,10 @@
             throw gssException;
         }
 
+        if (state == STATE_DONE) {
+            // now set the context flags for acceptor
+            setContextFlags();
+        }
         return retVal;
     }
 
@@ -703,36 +694,39 @@
         return out;
     }
 
+    // Only called on acceptor side. On the initiator side, most flags
+    // are already set at request. For those that might get chanegd,
+    // state from mech below is used.
     private void setContextFlags() {
 
         if (mechContext != null) {
             // default for cred delegation is false
             if (mechContext.getCredDelegState()) {
-                setCredDelegState(true);
+                credDelegState = true;
             }
             // default for the following are true
             if (!mechContext.getMutualAuthState()) {
-                setMutualAuthState(false);
+                mutualAuthState = false;
             }
             if (!mechContext.getReplayDetState()) {
-                setReplayDetState(false);
+                replayDetState = false;
             }
             if (!mechContext.getSequenceDetState()) {
-                setSequenceDetState(false);
+                sequenceDetState = false;
             }
             if (!mechContext.getIntegState()) {
-                setIntegState(false);
+                integState = false;
             }
             if (!mechContext.getConfState()) {
-                setConfState(false);
+                confState = false;
             }
         }
     }
 
     /**
-     * generate MIC on mechList
+     * generate MIC on mechList. Not used at the moment.
      */
-    private byte[] generateMechListMIC(byte[] mechTypes)
+    /*private byte[] generateMechListMIC(byte[] mechTypes)
         throws GSSException {
 
         // sanity check the required input
@@ -769,7 +763,7 @@
             }
         }
         return mic;
-    }
+    }*/
 
     /**
      * verify MIC on MechList
@@ -837,6 +831,10 @@
             mechContext.requestMutualAuth(mutualAuthState);
             mechContext.requestReplayDet(replayDetState);
             mechContext.requestSequenceDet(sequenceDetState);
+            if (mechContext instanceof ExtendedGSSContext) {
+                ((ExtendedGSSContext)mechContext).requestDelegPolicy(
+                        delegPolicyState);
+            }
         }
 
         // pass token
@@ -1202,5 +1200,5 @@
                     "inquireSecContext not supported by underlying mech.");
         }
     }
+}
 
-}
--- a/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java	Tue Dec 01 08:54:10 2009 -0800
@@ -57,6 +57,12 @@
                         GSSName.NT_HOSTBASED_SERVICE,
                         GSSName.NT_EXPORT_NAME};
 
+    // The default underlying mech of SPNEGO, must not be SPNEGO itself.
+    private static final Oid DEFAULT_SPNEGO_MECH_OID =
+            ProviderList.DEFAULT_MECH_OID.equals(GSS_SPNEGO_MECH_OID)?
+                GSSUtil.GSS_KRB5_MECH_OID:
+                ProviderList.DEFAULT_MECH_OID;
+
     // Use an instance of a GSSManager whose provider list
     // does not include native provider
     final GSSManagerImpl manager;
@@ -100,18 +106,27 @@
                 availableMechs[j++] = mechs[i];
             }
         }
+        // Move the preferred mech to first place
+        for (int i=0; i<availableMechs.length; i++) {
+            if (availableMechs[i].equals(DEFAULT_SPNEGO_MECH_OID)) {
+                if (i != 0) {
+                    availableMechs[i] = availableMechs[0];
+                    availableMechs[0] = DEFAULT_SPNEGO_MECH_OID;
+                }
+                break;
+            }
+        }
     }
 
     public GSSNameSpi getNameElement(String nameStr, Oid nameType)
-        throws GSSException {
-        // get NameElement for the default Mechanism
-        return manager.getNameElement(nameStr, nameType, null);
+            throws GSSException {
+        return manager.getNameElement(
+                nameStr, nameType, DEFAULT_SPNEGO_MECH_OID);
     }
 
     public GSSNameSpi getNameElement(byte[] name, Oid nameType)
-        throws GSSException {
-        // get NameElement for the default Mechanism
-        return manager.getNameElement(name, nameType, null);
+            throws GSSException {
+        return manager.getNameElement(name, nameType, DEFAULT_SPNEGO_MECH_OID);
     }
 
     public GSSCredentialSpi getCredentialElement(GSSNameSpi name,
--- a/jdk/src/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java	Tue Dec 01 08:54:10 2009 -0800
@@ -549,6 +549,9 @@
     public void requestInteg(boolean state) throws GSSException {
         changeFlags(GSS_C_INTEG_FLAG, state);
     }
+    public void requestDelegPolicy(boolean state) throws GSSException {
+        // Not supported, ignore
+    }
     public void requestLifetime(int lifetime) throws GSSException {
         if (isInitiator && pContext == 0) {
             this.lifetime = lifetime;
@@ -590,6 +593,9 @@
     public boolean getIntegState() {
         return checkFlags(GSS_C_INTEG_FLAG);
     }
+    public boolean getDelegPolicyState() {
+        return false;
+    }
     public int getLifetime() {
         return cStub.getContextTime(pContext);
     }
--- a/jdk/src/share/classes/sun/security/krb5/Credentials.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/security/krb5/Credentials.java	Tue Dec 01 08:54:10 2009 -0800
@@ -234,7 +234,19 @@
      * @return true if OK-AS_DELEGATE flag is set, otherwise, return false.
      */
     public boolean checkDelegate() {
-        return (flags.get(Krb5.TKT_OPTS_DELEGATE));
+        return flags.get(Krb5.TKT_OPTS_DELEGATE);
+    }
+
+    /**
+     * Reset TKT_OPTS_DELEGATE to false, called at credentials acquirement
+     * when one of the cross-realm TGTs does not have the OK-AS-DELEGATE
+     * flag set. This info must be preservable and restorable through
+     * the Krb5Util.credsToTicket/ticketToCreds() methods so that even if
+     * the service ticket is cached it still remembers the cross-realm
+     * authentication result.
+     */
+    public void resetDelegate() {
+        flags.set(Krb5.TKT_OPTS_DELEGATE, false);
     }
 
     public Credentials renew() throws KrbException, IOException {
--- a/jdk/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Portions Copyright 2001-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Portions Copyright 2001-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -117,6 +117,7 @@
 
         // Get a list of realms to traverse
         String[] realms = Realm.getRealmsList(localRealm, serviceRealm);
+        boolean okAsDelegate = true;
 
         if (realms == null || realms.length == 0)
         {
@@ -194,6 +195,15 @@
              */
 
             newTgtRealm = newTgt.getServer().getInstanceComponent();
+            if (okAsDelegate && !newTgt.checkDelegate()) {
+                if (DEBUG)
+                {
+                    System.out.println(">>> Credentials acquireServiceCreds: " +
+                            "global OK-AS-DELEGATE turned off at " +
+                            newTgt.getServer());
+                }
+                okAsDelegate = false;
+            }
 
             if (DEBUG)
             {
@@ -283,6 +293,9 @@
                 System.out.println(">>> Credentials acquireServiceCreds: returning creds:");
                 Credentials.printDebug(theCreds);
             }
+            if (!okAsDelegate) {
+                theCreds.resetDelegate();
+            }
             return theCreds;
         }
         throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED,
--- a/jdk/src/share/classes/sun/swing/SwingLazyValue.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/swing/SwingLazyValue.java	Tue Dec 01 08:54:10 2009 -0800
@@ -26,6 +26,9 @@
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
+import java.lang.reflect.AccessibleObject;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import javax.swing.UIDefaults;
 
 /**
@@ -65,13 +68,15 @@
             if (methodName != null) {
                 Class[] types = getClassArray(args);
                 Method m = c.getMethod(methodName, types);
+                makeAccessible(m);
                 return m.invoke(c, args);
             } else {
                 Class[] types = getClassArray(args);
                 Constructor constructor = c.getConstructor(types);
+                makeAccessible(constructor);
                 return constructor.newInstance(args);
             }
-        } catch(Exception e) {
+        } catch (Exception e) {
             // Ideally we would throw an exception, unfortunately
             // often times there are errors as an initial look and
             // feel is loaded before one can be switched. Perhaps a
@@ -81,6 +86,15 @@
         return null;
     }
 
+    private void makeAccessible(final AccessibleObject object) {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                object.setAccessible(true);
+                return null;
+            }
+        });
+    }
+
     private Class[] getClassArray(Object[] args) {
         Class[] types = null;
         if (args!=null) {
--- a/jdk/src/share/classes/sun/swing/SwingUtilities2.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/swing/SwingUtilities2.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1807,22 +1807,4 @@
                                          boolean three) {
         return liesIn(rect, p, false, false, three);
     }
-
-    /**
-     * Returns the {@code JViewport} instance for the {@code component}
-     * or {@code null}.
-     *
-     * @return the {@code JViewport} instance for the {@code component}
-     * or {@code null}
-     * @throws NullPointerException if {@code component} is {@code null}
-     */
-    public static JViewport getViewport(Component component) {
-        do {
-            component = component.getParent();
-            if (component instanceof JViewport) {
-                return (JViewport) component;
-            }
-        } while(component instanceof JLayer);
-        return null;
-    }
 }
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java	Tue Dec 01 08:54:10 2009 -0800
@@ -141,6 +141,8 @@
                                      "Malaysia Summer Time", "MYST"};
         String NORONHA[] = new String[] {"Fernando de Noronha Time", "FNT",
                                          "Fernando de Noronha Summer Time", "FNST"};
+        String NOVT[] = new String[] {"Novosibirsk Time", "NOVT",
+                                      "Novosibirsk Summer Time", "NOVST"};
         String NPT[] = new String[] {"Nepal Time", "NPT",
                                      "Nepal Summer Time", "NPST"};
         String NST[] = new String[] {"Newfoundland Standard Time", "NST",
@@ -441,7 +443,8 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
-            {"Antarctica/Casey", WST_AUS},
+            {"Antarctica/Casey", new String[] {"Casey Time", "CAST",
+                                               "Casey Summer Time", "CAST"}},
             {"Antarctica/Davis", new String[] {"Davis Time", "DAVT",
                                                "Davis Summer Time", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville Time", "DDUT",
@@ -529,8 +532,8 @@
                                           "Philippines Summer Time", "PHST"}},
             {"Asia/Muscat", GST},
             {"Asia/Nicosia", EET},
-            {"Asia/Novosibirsk", new String[] {"Novosibirsk Time", "NOVT",
-                                               "Novosibirsk Summer Time", "NOVST"}},
+            {"Asia/Novokuznetsk", NOVT},
+            {"Asia/Novosibirsk", NOVT},
             {"Asia/Oral", new String[] {"Oral Time", "ORAT",
                                         "Oral Summer Time", "ORAST"}},
             {"Asia/Omsk", new String[] {"Omsk Time", "OMST",
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java	Tue Dec 01 08:54:10 2009 -0800
@@ -141,6 +141,8 @@
                                      "Malaysische Sommerzeit", "MYST"};
         String NORONHA[] = new String[] {"Fernando de Noronha Zeit", "FNT",
                                          "Fernando de Noronha Sommerzeit", "FNST"};
+        String NOVT[] = new String[] {"Nowosibirsker Zeit", "NOVT",
+                                      "Nowosibirsker Sommerzeit", "NOVST"};
         String NPT[] = new String[] {"Nepalesische Zeit", "NPT",
                                      "Nepalesische Sommerzeit", "NPST"};
         String NST[] = new String[] {"Neufundland Normalzeit", "NST",
@@ -441,7 +443,6 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
-            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"Davis Zeit", "DAVT",
                                                "Davis Sommerzeit", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville Zeit", "DDUT",
@@ -529,8 +530,8 @@
                                           "Philippinische Sommerzeit", "PHST"}},
             {"Asia/Muscat", GST},
             {"Asia/Nicosia", EET},
-            {"Asia/Novosibirsk", new String[] {"Nowosibirsker Zeit", "NOVT",
-                                               "Nowosibirsker Sommerzeit", "NOVST"}},
+            {"Asia/Novokuznetsk", NOVT},
+            {"Asia/Novosibirsk", NOVT},
             {"Asia/Oral", new String[] {"Oral Zeit", "ORAT",
                                         "Oral Sommerzeit", "ORAST"}},
             {"Asia/Omsk", new String[] {"Omsk Zeit", "OMST",
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java	Tue Dec 01 08:54:10 2009 -0800
@@ -141,6 +141,8 @@
                                      "Hora de verano de Malasia", "MYST"};
         String NORONHA[] = new String[] {"Hora de Fernando de Noronha", "FNT",
                                          "Hora de verano de Fernando de Noronha", "FNST"};
+        String NOVT[] = new String[] {"Hora de Novosibirsk", "NOVT",
+                                      "Hora de verano de Novosibirsk", "NOVST"};
         String NPT[] = new String[] {"Hora de Nepal", "NPT",
                                      "Hora de verano de Nepal", "NPST"};
         String NST[] = new String[] {"Hora est\u00e1ndar de Terranova", "NST",
@@ -441,7 +443,6 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
-            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"Hora de Davis", "DAVT",
                                                "Hora de verano de Davis", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Hora de Dumont-d'Urville", "DDUT",
@@ -529,8 +530,9 @@
                                           "Hora de verano de Filipinas", "PHST"}},
             {"Asia/Muscat", GST},
             {"Asia/Nicosia", EET},
-            {"Asia/Novosibirsk", new String[] {"Hora de Novosibirsk", "NOVT",
-                                               "Hora de verano de Novosibirsk", "NOVST"}},
+
+            {"Asia/Novokuznetsk", NOVT},
+            {"Asia/Novosibirsk", NOVT},
             {"Asia/Oral", new String[] {"Hora de Uralsk", "ORAT",
                                         "Hora de verano de Uralsk", "ORAST"}},
             {"Asia/Omsk", new String[] {"Hora de Omsk", "OMST",
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java	Tue Dec 01 08:54:10 2009 -0800
@@ -141,6 +141,8 @@
                                      "Heure d'\u00e9t\u00e9 de Malaisie", "MYST"};
         String NORONHA[] = new String[] {"Heure de Fernando de Noronha", "FNT",
                                          "Heure d'\u00e9t\u00e9 de Fernando de Noronha", "FNST"};
+        String NOVT[] = new String[] {"Heure de Novossibirsk", "NOVT",
+                                      "Heure d'\u00e9t\u00e9 de Novossibirsk", "NOVST"};
         String NPT[] = new String[] {"Heure du N\u00e9pal", "NPT",
                                      "Heure d'\u00e9t\u00e9 du N\u00e9pal", "NPST"};
         String NST[] = new String[] {"Heure normale de Terre-Neuve", "NST",
@@ -441,7 +443,6 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
-            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"Heure de Davis", "DAVT",
                                                "Heure d'\u00e9t\u00e9 de Davis", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Heure de Dumont-d'Urville", "DDUT",
@@ -529,8 +530,8 @@
                                           "Heure d'\u00e9t\u00e9 des Philippines", "PHST"}},
             {"Asia/Muscat", GST},
             {"Asia/Nicosia", EET},
-            {"Asia/Novosibirsk", new String[] {"Heure de Novossibirsk", "NOVT",
-                                               "Heure d'\u00e9t\u00e9 de Novossibirsk", "NOVST"}},
+            {"Asia/Novokuznetsk", NOVT},
+            {"Asia/Novosibirsk", NOVT},
             {"Asia/Oral", new String[] {"Heure d'Oral", "ORAT",
                                         "Heure d'\u00e9t\u00e9 d'Oral", "ORAST"}},
             {"Asia/Omsk", new String[] {"Heure d'Omsk", "OMST",
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java	Tue Dec 01 08:54:10 2009 -0800
@@ -141,6 +141,8 @@
                                      "Ora estiva della Malaysia", "MYST"};
         String NORONHA[] = new String[] {"Ora di Fernando de Noronha", "FNT",
                                          "Ora estiva di Fernando de Noronha", "FNST"};
+        String NOVT[] = new String[] {"Ora di Novosibirsk", "NOVT",
+                                      "Ora estiva di Novosibirsk", "NOVST"};
         String NPT[] = new String[] {"Ora del Nepal", "NPT",
                                      "Ora estiva del Nepal", "NPST"};
         String NST[] = new String[] {"Ora solare di Terranova", "NST",
@@ -441,7 +443,6 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
-            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"Ora di Davis", "DAVT",
                                                "Ora estiva di Davis", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Ora di Dumont-d'Urville", "DDUT",
@@ -529,8 +530,8 @@
                                           "Ora estiva delle Filippine", "PHST"}},
             {"Asia/Muscat", GST},
             {"Asia/Nicosia", EET},
-            {"Asia/Novosibirsk", new String[] {"Ora di Novosibirsk", "NOVT",
-                                               "Ora estiva di Novosibirsk", "NOVST"}},
+            {"Asia/Novokuznetsk", NOVT},
+            {"Asia/Novosibirsk", NOVT},
             {"Asia/Oral", new String[] {"Ora di Oral", "ORAT",
                                         "Ora estiva di Oral", "ORAST"}},
             {"Asia/Omsk", new String[] {"Ora di Omsk", "OMST",
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java	Tue Dec 01 08:54:10 2009 -0800
@@ -141,6 +141,8 @@
                                      "\u30de\u30ec\u30fc\u30b7\u30a2\u590f\u6642\u9593", "MYST"};
         String NORONHA[] = new String[] {"\u30d5\u30a7\u30eb\u30ca\u30f3\u30c9\u30fb\u30c7\u30fb\u30ce\u30ed\u30fc\u30cb\u30e3\u6642\u9593", "FNT",
                                          "\u30d5\u30a7\u30eb\u30ca\u30f3\u30c9\u30fb\u30c7\u30fb\u30ce\u30ed\u30fc\u30cb\u30e3\u590f\u6642\u9593", "FNST"};
+        String NOVT[] = new String[] {"\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u6642\u9593", "NOVT",
+                                      "\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u590f\u6642\u9593", "NOVST"};
         String NPT[] = new String[] {"\u30cd\u30d1\u30fc\u30eb\u6642\u9593", "NPT",
                                       "\u30cd\u30d1\u30fc\u30eb\u590f\u6642\u9593", "NPST"};
         String NST[] = new String[] {"\u30cb\u30e5\u30fc\u30d5\u30a1\u30f3\u30c9\u30e9\u30f3\u30c9\u6a19\u6e96\u6642", "NST",
@@ -441,7 +443,6 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
-            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"\u30c7\u30a4\u30d3\u30b9\u6642\u9593", "DAVT",
                                                "\u30c7\u30a4\u30d3\u30b9\u590f\u6642\u9593", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"\u30c7\u30e5\u30e2\u30f3\u30c7\u30e5\u30eb\u30f4\u30a3\u30eb\u6642\u9593", "DDUT",
@@ -529,8 +530,8 @@
                                           "\u30d5\u30a3\u30ea\u30d4\u30f3\u590f\u6642\u9593", "PHST"}},
             {"Asia/Muscat", GST},
             {"Asia/Nicosia", EET},
-            {"Asia/Novosibirsk", new String[] {"\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u6642\u9593", "NOVT",
-                                               "\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u590f\u6642\u9593", "NOVST"}},
+            {"Asia/Novokuznetsk", NOVT},
+            {"Asia/Novosibirsk", NOVT},
             {"Asia/Oral", new String[] {"\u30aa\u30e9\u30eb\u6642\u9593", "ORAT",
                                         "\u30aa\u30e9\u30eb\u590f\u6642\u9593", "ORAST"}},
             {"Asia/Omsk", new String[] {"\u30aa\u30e0\u30b9\u30af\u6642\u9593", "OMST",
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java	Tue Dec 01 08:54:10 2009 -0800
@@ -141,6 +141,8 @@
                                      "\ub9d0\ub808\uc774\uc2dc\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MYST"};
         String NORONHA[] = new String[] {"Fernando de Noronha \uc2dc\uac04", "FNT",
                                          "Fernando de Noronha \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "FNST"};
+        String NOVT[] = new String[] {"\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc2dc\uac04", "NOVT",
+                                      "\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NOVST"};
         String NPT[] = new String[] {"\ub124\ud314 \uc2dc\uac04", "NPT",
                                       "\ub124\ud314 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NPST"};
         String NST[] = new String[] {"\ub274\ud380\ub4e4\ub79c\ub4dc \ud45c\uc900\uc2dc", "NST",
@@ -441,7 +443,6 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
-            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"Davis \uc2dc\uac04", "DAVT",
                                                "Davis \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"\ub4a4\ubabd \ub4a4\ub974\ube4c \uc2dc\uac04", "DDUT",
@@ -529,8 +530,8 @@
                                           "\ud544\ub9ac\ud540 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PHST"}},
             {"Asia/Muscat", GST},
             {"Asia/Nicosia", EET},
-            {"Asia/Novosibirsk", new String[] {"\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc2dc\uac04", "NOVT",
-                                               "\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NOVST"}},
+            {"Asia/Novokuznetsk", NOVT},
+            {"Asia/Novosibirsk", NOVT},
             {"Asia/Oral", new String[] {"Oral \ud45c\uc900\uc2dc", "ORAT",
                                         "Oral \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ORAST"}},
             {"Asia/Omsk", new String[] {"Omsk \uc2dc\uac04", "OMST",
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java	Tue Dec 01 08:54:10 2009 -0800
@@ -141,6 +141,8 @@
                                      "Malaysia, sommartid", "MYST"};
         String NORONHA[] = new String[] {"Fernando de Noronha, normaltid", "FNT",
                                          "Fernando de Noronha, sommartid", "FNST"};
+        String NOVT[] = new String[] {"Novosibirsk, normaltid", "NOVT",
+                                      "Novosibirsk, sommartid", "NOVST"};
         String NPT[] = new String[] {"Nepal, normaltid", "NPT",
                                      "Nepal, sommartid", "NPST"};
         String NST[] = new String[] {"Newfoundland, normaltid", "NST",
@@ -441,7 +443,6 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
-            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"Davis, normaltid", "DAVT",
                                                "Davis, sommartid", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville, normaltid", "DDUT",
@@ -529,8 +530,8 @@
                                           "Filippinerna, sommartid", "PHST"}},
             {"Asia/Muscat", GST},
             {"Asia/Nicosia", EET},
-            {"Asia/Novosibirsk", new String[] {"Novosibirsk, normaltid", "NOVT",
-                                               "Novosibirsk, sommartid", "NOVST"}},
+            {"Asia/Novokuznetsk", NOVT},
+            {"Asia/Novosibirsk", NOVT},
             {"Asia/Oral", new String[] {"Oral, normaltid", "ORAT",
                                         "Oral, sommartid", "ORAST"}},
             {"Asia/Omsk", new String[] {"Omsk, normaltid", "OMST",
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java	Tue Dec 01 08:54:10 2009 -0800
@@ -141,6 +141,8 @@
                                      "\u9a6c\u6765\u897f\u4e9a\u590f\u4ee4\u65f6", "MYST"};
         String NORONHA[] = new String[] {"\u8d39\u5c14\u5357\u591a\u5fb7\u8bfa\u7f57\u5c3c\u4e9a\u65f6\u95f4", "FNT",
                                          "\u8d39\u5c14\u5357\u591a\u5fb7\u8bfa\u7f57\u5c3c\u4e9a\u590f\u4ee4\u65f6", "FNST"};
+        String NOVT[] = new String[] {"Novosibirsk \u65f6\u95f4", "NOVT",
+                                      "Novosibirsk \u590f\u4ee4\u65f6", "NOVST"};
         String NPT[] = new String[] {"\u5c3c\u6cca\u5c14\u65f6\u95f4", "NPT",
                                      "\u5c3c\u6cca\u5c14\u590f\u4ee4\u65f6", "NPST"};
         String NST[] = new String[] {"\u7ebd\u82ac\u5170\u6807\u51c6\u65f6\u95f4", "NST",
@@ -441,7 +443,6 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
-            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"\u6234\u7ef4\u65af\u65f6\u95f4", "DAVT",
                                                "\u6234\u7ef4\u65af\u590f\u4ee4\u65f6", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville \u65f6\u95f4", "DDUT",
@@ -529,8 +530,8 @@
                                           "\u83f2\u5f8b\u5bbe\u590f\u4ee4\u65f6", "PHST"}},
             {"Asia/Muscat", GST},
             {"Asia/Nicosia", EET},
-            {"Asia/Novosibirsk", new String[] {"Novosibirsk \u65f6\u95f4", "NOVT",
-                                               "Novosibirsk \u590f\u4ee4\u65f6", "NOVST"}},
+            {"Asia/Novokuznetsk", NOVT},
+            {"Asia/Novosibirsk", NOVT},
             {"Asia/Oral", new String[] {"Oral \u65f6\u95f4", "ORAT",
                                         "Oral \u590f\u4ee4\u65f6", "ORAST"}},
             {"Asia/Omsk", new String[] {"\u9102\u6728\u65af\u514b\u65f6\u95f4", "OMST",
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java	Tue Dec 01 08:54:10 2009 -0800
@@ -141,6 +141,8 @@
                                      "\u99ac\u4f86\u897f\u4e9e\u590f\u4ee4\u6642\u9593", "MYST"};
         String NORONHA[] = new String[] {"\u8cbb\u723e\u5357\u591a-\u8fea\u8afe\u7f85\u5c3c\u4e9e\u6642\u9593", "FNT",
                                          "\u8cbb\u723e\u5357\u591a-\u8fea\u8afe\u7f85\u5c3c\u4e9e\u590f\u4ee4\u6642\u9593", "FNST"};
+        String NOVT[] = new String[] {"Novosibirsk \u6642\u9593", "NOVT",
+                                      "Novosibirsk \u590f\u4ee4\u6642\u9593", "NOVST"};
         String NPT[] = new String[] {"\u5c3c\u6cca\u723e\u6642\u9593", "NPT",
                                      "\u5c3c\u6cca\u723e\u590f\u4ee4\u6642\u9593", "NPST"};
         String NST[] = new String[] {"\u7d10\u82ac\u862d\u6a19\u6e96\u6642\u9593", "NST",
@@ -441,7 +443,6 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
-            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"\u81fa\u7dad\u65af\u6642\u9593", "DAVT",
                                                "\u81fa\u7dad\u65af\u590f\u4ee4\u6642\u9593", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville \u6642\u9593", "DDUT",
@@ -529,8 +530,8 @@
                                           "\u83f2\u5f8b\u8cd3\u590f\u4ee4\u6642\u9593", "PHST"}},
             {"Asia/Muscat", GST},
             {"Asia/Nicosia", EET},
-            {"Asia/Novosibirsk", new String[] {"Novosibirsk \u6642\u9593", "NOVT",
-                                               "Novosibirsk \u590f\u4ee4\u6642\u9593", "NOVST"}},
+            {"Asia/Novokuznetsk", NOVT},
+            {"Asia/Novosibirsk", NOVT},
             {"Asia/Oral", new String[] {"\u6b50\u4f5b\u6642\u9593", "ORAT",
                                         "\u6b50\u4f5b\u590f\u4ee4\u6642\u9593", "ORAST"}},
             {"Asia/Omsk", new String[] {"\u6b50\u59c6\u65af\u514b (Omsk) \u6642\u9593", "OMST",
--- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Tue Dec 01 08:54:10 2009 -0800
@@ -1460,6 +1460,7 @@
         JNU_ThrowByName( env,
                          "java/lang/OutOfMemoryError",
                          "Initializing Reader");
+        free(cinfo);
         return 0;
     }
 
@@ -1496,6 +1497,7 @@
         JNU_ThrowByName(env,
                         "java/lang/OutOfMemoryError",
                         "Initializing Reader");
+        imageio_dispose((j_common_ptr)cinfo);
         return 0;
     }
     cinfo->src->bytes_in_buffer = 0;
@@ -1512,6 +1514,7 @@
         JNU_ThrowByName( env,
                          "java/lang/OutOfMemoryError",
                          "Initializing Reader");
+        imageio_dispose((j_common_ptr)cinfo);
         return 0;
     }
     return (jlong) ret;
@@ -2450,8 +2453,7 @@
         JNU_ThrowByName( env,
                          "java/lang/OutOfMemoryError",
                          "Initializing Writer");
-        free(cinfo);
-        free(jerr);
+        imageio_dispose((j_common_ptr)cinfo);
         return 0;
     }
 
@@ -2469,8 +2471,7 @@
         JNU_ThrowByName( env,
                          "java/lang/OutOfMemoryError",
                          "Initializing Writer");
-        free(cinfo);
-        free(jerr);
+        imageio_dispose((j_common_ptr)cinfo);
         return 0;
     }
     return (jlong) ret;
--- a/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c	Tue Dec 01 08:54:10 2009 -0800
@@ -960,21 +960,15 @@
     mlib_filter filter;
     unsigned int *dP;
 
-    if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
-        JNU_ThrowOutOfMemoryError(env, "Out of memory");
-        return -1;
-    }
-
-    if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
-        JNU_ThrowOutOfMemoryError(env, "Out of memory");
-        free(srcRasterP);
-        return -1;
-    }
-
     /* This function requires a lot of local refs ??? Is 64 enough ??? */
     if ((*env)->EnsureLocalCapacity(env, 64) < 0)
         return 0;
 
+    if (s_nomlib) return 0;
+    if (s_timeIt) {
+        (*start_timer)(3600);
+    }
+
     switch(interpType) {
     case java_awt_image_AffineTransformOp_TYPE_BILINEAR:
         filter = MLIB_BILINEAR;
@@ -990,9 +984,15 @@
         return -1;
     }
 
-    if (s_nomlib) return 0;
-    if (s_timeIt) {
-        (*start_timer)(3600);
+    if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
+        JNU_ThrowOutOfMemoryError(env, "Out of memory");
+        return -1;
+    }
+
+    if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) {
+        JNU_ThrowOutOfMemoryError(env, "Out of memory");
+        free(srcRasterP);
+        return -1;
     }
 
     if ((*env)->GetArrayLength(env, jmatrix) < 6) {
@@ -1215,6 +1215,9 @@
     }
 
     if (tbl == NULL || table == NULL || jtable == NULL) {
+        if (tbl != NULL) free(tbl);
+        if (table != NULL) free(table);
+        if (jtable != NULL) free(jtable);
         awt_freeParsedImage(srcImageP, TRUE);
         awt_freeParsedImage(dstImageP, TRUE);
         JNU_ThrowNullPointerException(env, "NULL LUT");
@@ -1224,6 +1227,11 @@
     for (i=0; i < jlen; i++) {
         jtable[i] = (*env)->GetObjectArrayElement(env, jtableArrays, i);
         if (jtable[i] == NULL) {
+            free(tbl);
+            free(table);
+            free(jtable);
+            awt_freeParsedImage(srcImageP, TRUE);
+            awt_freeParsedImage(dstImageP, TRUE);
             return 0;
         }
     }
@@ -1232,6 +1240,9 @@
                         FALSE, &hint);
     if (nbands < 1) {
         /* Can't handle any custom images */
+        free(tbl);
+        free(table);
+        free(jtable);
         awt_freeParsedImage(srcImageP, TRUE);
         awt_freeParsedImage(dstImageP, TRUE);
         return 0;
@@ -1240,12 +1251,18 @@
     /* Allocate the arrays */
     if (allocateArray(env, srcImageP, &src, &sdata, TRUE, FALSE, FALSE) < 0) {
         /* Must be some problem */
+        free(tbl);
+        free(table);
+        free(jtable);
         awt_freeParsedImage(srcImageP, TRUE);
         awt_freeParsedImage(dstImageP, TRUE);
         return 0;
     }
     if (allocateArray(env, dstImageP, &dst, &ddata, FALSE, FALSE, FALSE) < 0) {
         /* Must be some problem */
+        free(tbl);
+        free(table);
+        free(jtable);
         freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
         awt_freeParsedImage(srcImageP, TRUE);
         awt_freeParsedImage(dstImageP, TRUE);
@@ -1284,6 +1301,9 @@
                                                       (jbyte *) table[j],
                                                       JNI_ABORT);
             }
+            free(tbl);
+            free(table);
+            free(jtable);
             freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL);
             awt_freeParsedImage(srcImageP, TRUE);
             awt_freeParsedImage(dstImageP, TRUE);
@@ -1413,12 +1433,15 @@
 
     /* Parse the source raster - reject custom images */
     if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) {
+        free(srcRasterP);
+        free(dstRasterP);
         return 0;
     }
 
     /* Parse the destination image - reject custom images */
     if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) {
         awt_freeParsedRaster(srcRasterP, TRUE);
+        free(dstRasterP);
         return 0;
     }
 
--- a/jdk/src/share/native/sun/font/freetypeScaler.c	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/share/native/sun/font/freetypeScaler.c	Tue Dec 01 08:54:10 2009 -0800
@@ -102,9 +102,21 @@
 }
 
 static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) {
+    void *stream;
+
     if (scalerInfo == NULL)
         return;
 
+    //apparently Done_Face will only close the stream
+    // but will not relase the memory of stream structure.
+    // We need to free it explicitly to avoid leak.
+    //Direct access to the stream field might be not ideal solution as
+    // it is considred to be "private".
+    //Alternatively we could have stored pointer to the structure
+    // in the scalerInfo but this will increase size of the structure
+    // for no good reason
+    stream = scalerInfo->face->stream;
+
     FT_Done_Face(scalerInfo->face);
     FT_Done_FreeType(scalerInfo->library);
 
@@ -116,6 +128,10 @@
         free(scalerInfo->fontData);
     }
 
+   if (stream != NULL) {
+        free(stream);
+   }
+
     free(scalerInfo);
 }
 
--- a/jdk/src/solaris/bin/java_md.c	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/solaris/bin/java_md.c	Tue Dec 01 08:54:10 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,9 +51,9 @@
  * two data models and cohabitation of jre/jdk bits with both data
  * models is supported, then DUAL_MODE is defined.  When DUAL_MODE is
  * defined, the architecture names for the narrow and wide version of
- * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME.  Currently
- * only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE; linux
- * i586/amd64 could be defined as DUAL_MODE but that is not the
+ * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME.
+ * Currently  only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE;
+ * linux i586/amd64 could be defined as DUAL_MODE but that is not the
  * current policy.
  */
 
@@ -103,49 +103,56 @@
  * platform independent routine SelectVersion.  This may result in
  * the exec of the specified launcher version.
  *
- * Typically, the launcher execs at least once to ensure a suitable
- * LD_LIBRARY_PATH is in effect for the process.  The first exec
- * screens out all the data model options; leaving the choice of data
- * model implicit in the binary selected to run.  However, in case no
- * exec is done, the data model options are screened out before the vm
- * is invoked.
+ * Previously the launcher modified the LD_LIBRARY_PATH appropriately for the
+ * desired data model path, regardless if data models matched or not. The
+ * launcher subsequently exec'ed the desired executable, in order to make the
+ * LD_LIBRARY_PATH path available for the runtime linker. This is no longer the
+ * case, the launcher dlopens the target libjvm.so. All other required
+ * libraries are loaded by the runtime linker, by virtue of the $ORIGIN paths
+ * baked into the shared libraries, by the build infrastructure at compile time.
  *
- *  incoming argv ------------------------------
- *  |                                          |
- * \|/                                         |
- * CheckJVMType                                |
- * (removes -client, -server, etc.)            |
- *                                            \|/
- *                                            CreateExecutionEnvironment
- *                                            (removes -d32 and -d64,
- *                                             determines desired data model,
- *                                             sets up LD_LIBRARY_PATH,
- *                                             and exec's)
- *                                             |
- *  --------------------------------------------
+ *  Main
+ *  (incoming argv)
+ *  |
+ * \|/
+ * SelectVersion
+ * (selects the JRE version, note: not data model)
+ *  |
+ * \|/
+ * CreateExecutionEnvironment
+ * (determines desired data model)
+ *  |
  *  |
  * \|/
- * exec child 1 incoming argv -----------------
+ *  Have Desired Model ? --> NO --> Is Dual-Mode ? --> NO --> Exit(with error)
+ *  |                                          |
  *  |                                          |
- * \|/                                         |
- * CheckJVMType                                |
- * (removes -client, -server, etc.)            |
+ *  |                                         \|/
+ *  |                                         YES
+ *  |                                          |
+ *  |                                          |
  *  |                                         \|/
- *  |                                          CreateExecutionEnvironment
- *  |                                          (verifies desired data model
- *  |                                           is running and acceptable
- *  |                                           LD_LIBRARY_PATH;
- *  |                                           no-op in child)
+ *  |                                CheckJvmType
+ *  |                               (removes -client, -server etc.)
+ *  |                                          |
+ *  |                                          |
+ * \|/                                        \|/
+ * YES                              (find the desired executable and exec child)
+ *  |                                          |
+ *  |                                          |
+ * \|/                                        \|/
+ * CheckJvmType                                Main
+ * (removes -client, -server, etc.)
+ *  |
  *  |
  * \|/
  * TranslateDashJArgs...
  * (Prepare to pass args to vm)
  *  |
  *  |
- *  |
  * \|/
  * ParseArguments
- * (ignores -d32 and -d64,
+ * (removes -d32 and -d64 if any,
  *  processes version options,
  *  creates argument list for vm,
  *  etc.)
@@ -199,17 +206,13 @@
     /* Compute/set the name of the executable */
     SetExecname(*_argvp);
 
-    /* Set the LD_LIBRARY_PATH environment variable, check data model
-       flags, and exec process, if needed */
+    /* Check data model flags, and exec process, if needed */
     {
       char *arch        = (char *)GetArch(); /* like sparc or sparcv9 */
       char * jvmtype    = NULL;
       int argc          = *_argcp;
       char **argv       = original_argv;
 
-      char *runpath     = NULL; /* existing effective LD_LIBRARY_PATH
-                                   setting */
-
       int running       = CURRENT_DATA_MODEL;
 
       int wanted        = running;      /* What data mode is being
@@ -217,18 +220,8 @@
                                            fine unless another model
                                            is asked for */
 
-      char* new_runpath = NULL; /* desired new LD_LIBRARY_PATH string */
-      char* newpath     = NULL; /* path on new LD_LIBRARY_PATH */
-      char* lastslash   = NULL;
-
-      char** newenvp    = NULL; /* current environment */
-
       char** newargv    = NULL;
       int    newargc    = 0;
-#ifdef __solaris__
-      char*  dmpath     = NULL;  /* data model specific LD_LIBRARY_PATH,
-                                    Solaris only */
-#endif
 
       /*
        * Starting in 1.5, all unix platforms accept the -d32 and -d64
@@ -306,6 +299,11 @@
           JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath);
           exit(4);
         }
+        /*
+         * we seem to have everything we need, so without further ado
+         * we return back.
+         */
+        return;
       } else {  /* do the same speculatively or exit */
 #ifdef DUAL_MODE
         if (running != wanted) {
@@ -335,190 +333,6 @@
 #endif
       }
 
-      /*
-       * We will set the LD_LIBRARY_PATH as follows:
-       *
-       *     o          $JVMPATH (directory portion only)
-       *     o          $JRE/lib/$LIBARCHNAME
-       *     o          $JRE/../lib/$LIBARCHNAME
-       *
-       * followed by the user's previous effective LD_LIBRARY_PATH, if
-       * any.
-       */
-
-#ifdef __solaris__
-      /*
-       * Starting in Solaris 7, ld.so.1 supports three LD_LIBRARY_PATH
-       * variables:
-       *
-       * 1. LD_LIBRARY_PATH -- used for 32 and 64 bit searches if
-       * data-model specific variables are not set.
-       *
-       * 2. LD_LIBRARY_PATH_64 -- overrides and replaces LD_LIBRARY_PATH
-       * for 64-bit binaries.
-       *
-       * 3. LD_LIBRARY_PATH_32 -- overrides and replaces LD_LIBRARY_PATH
-       * for 32-bit binaries.
-       *
-       * The vm uses LD_LIBRARY_PATH to set the java.library.path system
-       * property.  To shield the vm from the complication of multiple
-       * LD_LIBRARY_PATH variables, if the appropriate data model
-       * specific variable is set, we will act as if LD_LIBRARY_PATH had
-       * the value of the data model specific variant and the data model
-       * specific variant will be unset.  Note that the variable for the
-       * *wanted* data model must be used (if it is set), not simply the
-       * current running data model.
-       */
-
-      switch(wanted) {
-      case 0:
-        if(running == 32) {
-          dmpath = getenv("LD_LIBRARY_PATH_32");
-          wanted = 32;
-        }
-        else {
-          dmpath = getenv("LD_LIBRARY_PATH_64");
-          wanted = 64;
-        }
-        break;
-
-      case 32:
-        dmpath = getenv("LD_LIBRARY_PATH_32");
-        break;
-
-      case 64:
-        dmpath = getenv("LD_LIBRARY_PATH_64");
-        break;
-
-      default:
-        JLI_ReportErrorMessage(JRE_ERROR3, __LINE__);
-        exit(1); /* unknown value in wanted */
-        break;
-      }
-
-      /*
-       * If dmpath is NULL, the relevant data model specific variable is
-       * not set and normal LD_LIBRARY_PATH should be used.
-       */
-      if( dmpath == NULL) {
-        runpath = getenv("LD_LIBRARY_PATH");
-      }
-      else {
-        runpath = dmpath;
-      }
-#else
-      /*
-       * If not on Solaris, assume only a single LD_LIBRARY_PATH
-       * variable.
-       */
-      runpath = getenv("LD_LIBRARY_PATH");
-#endif /* __solaris__ */
-
-#ifdef __linux
-      /*
-       * On linux, if a binary is running as sgid or suid, glibc sets
-       * LD_LIBRARY_PATH to the empty string for security purposes.  (In
-       * contrast, on Solaris the LD_LIBRARY_PATH variable for a
-       * privileged binary does not lose its settings; but the dynamic
-       * linker does apply more scrutiny to the path.) The launcher uses
-       * the value of LD_LIBRARY_PATH to prevent an exec loop.
-       * Therefore, if we are running sgid or suid, this function's
-       * setting of LD_LIBRARY_PATH will be ineffective and we should
-       * return from the function now.  Getting the right libraries to
-       * be found must be handled through other mechanisms.
-       */
-      if((getgid() != getegid()) || (getuid() != geteuid()) ) {
-        return;
-      }
-#endif
-
-      /* runpath contains current effective LD_LIBRARY_PATH setting */
-
-      jvmpath = JLI_StringDup(jvmpath);
-      new_runpath = JLI_MemAlloc( ((runpath!=NULL)?JLI_StrLen(runpath):0) +
-                              2*JLI_StrLen(jrepath) + 2*JLI_StrLen(arch) +
-                              JLI_StrLen(jvmpath) + 52);
-      newpath = new_runpath + JLI_StrLen("LD_LIBRARY_PATH=");
-
-
-      /*
-       * Create desired LD_LIBRARY_PATH value for target data model.
-       */
-      {
-        /* remove the name of the .so from the JVM path */
-        lastslash = JLI_StrRChr(jvmpath, '/');
-        if (lastslash)
-          *lastslash = '\0';
-
-
-        /* jvmpath, ((running != wanted)?((wanted==64)?"/"LIBARCH64NAME:"/.."):""), */
-
-        sprintf(new_runpath, "LD_LIBRARY_PATH="
-                "%s:"
-                "%s/lib/%s:"
-                "%s/../lib/%s",
-                jvmpath,
-#ifdef DUAL_MODE
-                jrepath, GetArchPath(wanted),
-                jrepath, GetArchPath(wanted)
-#else
-                jrepath, arch,
-                jrepath, arch
-#endif
-                );
-
-
-        /*
-         * Check to make sure that the prefix of the current path is the
-         * desired environment variable setting.
-         */
-        if (runpath != NULL &&
-            JLI_StrNCmp(newpath, runpath, JLI_StrLen(newpath))==0 &&
-            (runpath[JLI_StrLen(newpath)] == 0 || runpath[JLI_StrLen(newpath)] == ':') &&
-            (running == wanted) /* data model does not have to be changed */
-#ifdef __solaris__
-            && (dmpath == NULL)    /* data model specific variables not set  */
-#endif
-            ) {
-
-          return;
-
-        }
-      }
-
-      /*
-       * Place the desired environment setting onto the prefix of
-       * LD_LIBRARY_PATH.  Note that this prevents any possible infinite
-       * loop of execv() because we test for the prefix, above.
-       */
-      if (runpath != 0) {
-        JLI_StrCat(new_runpath, ":");
-        JLI_StrCat(new_runpath, runpath);
-      }
-
-      if( putenv(new_runpath) != 0) {
-        exit(1); /* problem allocating memory; LD_LIBRARY_PATH not set
-                    properly */
-      }
-
-      /*
-       * Unix systems document that they look at LD_LIBRARY_PATH only
-       * once at startup, so we have to re-exec the current executable
-       * to get the changed environment variable to have an effect.
-       */
-
-#ifdef __solaris__
-      /*
-       * If dmpath is not NULL, remove the data model specific string
-       * in the environment for the exec'ed child.
-       */
-
-      if( dmpath != NULL)
-        (void)UnsetEnv((wanted==32)?"LD_LIBRARY_PATH_32":"LD_LIBRARY_PATH_64");
-#endif
-
-      newenvp = environ;
-
       {
         char *newexec = execname;
 #ifdef DUAL_MODE
@@ -549,17 +363,16 @@
           argv[0] = newexec;
         }
 #endif
-
+        JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
         (void)fflush(stdout);
         (void)fflush(stderr);
-        execve(newexec, argv, newenvp);
+        execv(newexec, argv);
         JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
 
 #ifdef DUAL_MODE
         if (running != wanted) {
           JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
 #  ifdef __solaris__
-
 #    ifdef __sparc
           JLI_ReportErrorMessage(JRE_ERROR6);
 #    else
@@ -570,13 +383,11 @@
 #endif
 
       }
-
       exit(1);
     }
 
 }
 
-
 /*
  * On Solaris VM choosing is done by the launcher (java.c).
  */
@@ -1123,6 +934,7 @@
             printf(" %s", argv[i]);
         printf("\n");
     }
+    JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
     (void)fflush(stdout);
     (void)fflush(stderr);
     execv(wanted, argv);
--- a/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java	Tue Dec 01 08:54:10 2009 -0800
@@ -534,71 +534,71 @@
         return entry.getSite(x, y);
     }
 
+    /*
+     * Note: this method should be called under AWT lock.
+     */
     public void registerDropSite(long window) {
+        assert XToolkit.isAWTLockHeldByCurrentThread();
+
         if (window == 0) {
             throw new IllegalArgumentException();
         }
 
         XDropTargetEventProcessor.activate();
 
-        XToolkit.awtLock();
-        try {
-            long toplevel = getToplevelWindow(window);
+        long toplevel = getToplevelWindow(window);
 
-            /*
-             * No window with WM_STATE property is found.
-             * Since the window can be a plugin window reparented to the browser
-             * toplevel, we cannot determine which window will eventually have
-             * WM_STATE property set. So we schedule a timer callback that will
-             * periodically attempt to find an ancestor with WM_STATE and
-             * register the drop site appropriately.
-             */
-            if (toplevel == 0) {
-                addDelayedRegistrationEntry(window);
-                return;
+        /*
+         * No window with WM_STATE property is found.
+         * Since the window can be a plugin window reparented to the browser
+         * toplevel, we cannot determine which window will eventually have
+         * WM_STATE property set. So we schedule a timer callback that will
+         * periodically attempt to find an ancestor with WM_STATE and
+         * register the drop site appropriately.
+         */
+        if (toplevel == 0) {
+            addDelayedRegistrationEntry(window);
+            return;
+        }
+
+        if (toplevel == window) {
+            Iterator dropTargetProtocols =
+                XDragAndDropProtocols.getDropTargetProtocols();
+
+            while (dropTargetProtocols.hasNext()) {
+                XDropTargetProtocol dropTargetProtocol =
+                    (XDropTargetProtocol)dropTargetProtocols.next();
+                dropTargetProtocol.registerDropTarget(toplevel);
             }
-
-            if (toplevel == window) {
-                Iterator dropTargetProtocols =
-                    XDragAndDropProtocols.getDropTargetProtocols();
-
-                while (dropTargetProtocols.hasNext()) {
-                    XDropTargetProtocol dropTargetProtocol =
-                        (XDropTargetProtocol)dropTargetProtocols.next();
-                    dropTargetProtocol.registerDropTarget(toplevel);
-                }
-            } else {
-                registerEmbeddedDropSite(toplevel, window);
-            }
-        } finally {
-            XToolkit.awtUnlock();
+        } else {
+            registerEmbeddedDropSite(toplevel, window);
         }
     }
 
+    /*
+     * Note: this method should be called under AWT lock.
+     */
     public void unregisterDropSite(long window) {
+        assert XToolkit.isAWTLockHeldByCurrentThread();
+
         if (window == 0) {
             throw new IllegalArgumentException();
         }
 
-        XToolkit.awtLock();
-        try {
-            long toplevel = getToplevelWindow(window);
+        long toplevel = getToplevelWindow(window);
 
-            if (toplevel == window) {
-                Iterator dropProtocols =
-                    XDragAndDropProtocols.getDropTargetProtocols();
-
-                removeDelayedRegistrationEntry(window);
+        if (toplevel == window) {
+            Iterator dropProtocols =
+                XDragAndDropProtocols.getDropTargetProtocols();
 
-                while (dropProtocols.hasNext()) {
-                    XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next();
-                    dropProtocol.unregisterDropTarget(window);
-                }
-            } else {
-                unregisterEmbeddedDropSite(toplevel, window);
+            removeDelayedRegistrationEntry(window);
+
+            while (dropProtocols.hasNext()) {
+                XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next();
+                dropProtocol.unregisterDropTarget(window);
             }
-        } finally {
-            XToolkit.awtUnlock();
+        } else {
+            unregisterEmbeddedDropSite(toplevel, window);
         }
     }
 
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1509,4 +1509,24 @@
         return new XAtomList();
     }
 
+    /**
+     * Indicates if the window is currently in the FSEM.
+     * Synchronization: state lock.
+     */
+    private boolean fullScreenExclusiveModeState = false;
+
+    // Implementation of the X11ComponentPeer
+    @Override
+    public void setFullScreenExclusiveModeState(boolean state) {
+        synchronized (getStateLock()) {
+            fullScreenExclusiveModeState = state;
+        }
+    }
+
+    public final boolean isFullScreenExclusiveMode() {
+        synchronized (getStateLock()) {
+            return fullScreenExclusiveModeState;
+        }
+    }
+
 }
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1079,31 +1079,39 @@
         updateSecurityWarningVisibility();
     }
 
+    @Override
+    public void setFullScreenExclusiveModeState(boolean state) {
+        super.setFullScreenExclusiveModeState(state);
+        updateSecurityWarningVisibility();
+    }
+
     public void updateSecurityWarningVisibility() {
         if (warningWindow == null) {
             return;
         }
 
-        boolean show = false;
-
-        int state = getWMState();
-
         if (!isVisible()) {
             return; // The warning window should already be hidden.
         }
 
-        // getWMState() always returns 0 (Withdrawn) for simple windows. Hence
-        // we ignore the state for such windows.
-        if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) {
-            if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() ==
-                    getTarget())
-            {
-                show = true;
-            }
+        boolean show = false;
+
+        if (!isFullScreenExclusiveMode()) {
+            int state = getWMState();
 
-            if (isMouseAbove() || warningWindow.isMouseAbove())
-            {
-                show = true;
+            // getWMState() always returns 0 (Withdrawn) for simple windows. Hence
+            // we ignore the state for such windows.
+            if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) {
+                if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() ==
+                        getTarget())
+                {
+                    show = true;
+                }
+
+                if (isMouseAbove() || warningWindow.isMouseAbove())
+                {
+                    show = true;
+                }
             }
         }
 
@@ -1756,25 +1764,36 @@
         }
     }
 
+    // should be synchronized on awtLock
     private int dropTargetCount = 0;
 
-    public synchronized void addDropTarget() {
-        if (dropTargetCount == 0) {
-            long window = getWindow();
-            if (window != 0) {
-                XDropTargetRegistry.getRegistry().registerDropSite(window);
+    public void addDropTarget() {
+        XToolkit.awtLock();
+        try {
+            if (dropTargetCount == 0) {
+                long window = getWindow();
+                if (window != 0) {
+                    XDropTargetRegistry.getRegistry().registerDropSite(window);
+                }
             }
+            dropTargetCount++;
+        } finally {
+            XToolkit.awtUnlock();
         }
-        dropTargetCount++;
     }
 
-    public synchronized void removeDropTarget() {
-        dropTargetCount--;
-        if (dropTargetCount == 0) {
-            long window = getWindow();
-            if (window != 0) {
-                XDropTargetRegistry.getRegistry().unregisterDropSite(window);
+    public void removeDropTarget() {
+        XToolkit.awtLock();
+        try {
+            dropTargetCount--;
+            if (dropTargetCount == 0) {
+                long window = getWindow();
+                if (window != 0) {
+                    XDropTargetRegistry.getRegistry().unregisterDropSite(window);
+                }
             }
+        } finally {
+            XToolkit.awtUnlock();
         }
     }
     void addRootPropertyEventDispatcher() {
@@ -1837,13 +1856,18 @@
         }
     }
 
-    protected synchronized void updateDropTarget() {
-        if (dropTargetCount > 0) {
-            long window = getWindow();
-            if (window != 0) {
-                XDropTargetRegistry.getRegistry().unregisterDropSite(window);
-                XDropTargetRegistry.getRegistry().registerDropSite(window);
+    protected void updateDropTarget() {
+        XToolkit.awtLock();
+        try {
+            if (dropTargetCount > 0) {
+                long window = getWindow();
+                if (window != 0) {
+                    XDropTargetRegistry.getRegistry().unregisterDropSite(window);
+                    XDropTargetRegistry.getRegistry().registerDropSite(window);
+                }
             }
+        } finally {
+            XToolkit.awtUnlock();
         }
     }
 
--- a/jdk/src/solaris/classes/sun/awt/X11ComponentPeer.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11ComponentPeer.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,4 +39,5 @@
     Rectangle getBounds();
     Graphics getGraphics();
     Object getTarget();
+    void setFullScreenExclusiveModeState(boolean state);
 }
--- a/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Tue Dec 01 08:54:10 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -306,12 +306,14 @@
         X11ComponentPeer peer = (X11ComponentPeer)w.getPeer();
         if (peer != null) {
             enterFullScreenExclusive(peer.getContentWindow());
+            peer.setFullScreenExclusiveModeState(true);
         }
     }
 
     private static void exitFullScreenExclusive(Window w) {
         X11ComponentPeer peer = (X11ComponentPeer)w.getPeer();
         if (peer != null) {
+            peer.setFullScreenExclusiveModeState(false);
             exitFullScreenExclusive(peer.getContentWindow());
         }
     }
--- a/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java	Tue Dec 01 08:54:10 2009 -0800
@@ -388,7 +388,10 @@
             // if a GlyphVector overrides the AA setting.
             // We use getRenderLoops() rather than setting solidloops
             // directly so that we get the appropriate loops in XOR mode.
-            sg2d.loops = getRenderLoops(sg2d);
+            if (sg2d.loops == null) {
+                // assert(some pipe will always be a LoopBasedPipe)
+                sg2d.loops = getRenderLoops(sg2d);
+            }
         } else {
             super.validatePipe(sg2d);
         }
--- a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c	Tue Dec 01 08:54:10 2009 -0800
@@ -1654,6 +1654,7 @@
 #ifndef HEADLESS
 
 #define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI
+#define REFRESH_RATE_UNKNOWN java_awt_DisplayMode_REFRESH_RATE_UNKNOWN
 
 typedef Status
     (*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp);
@@ -1680,6 +1681,9 @@
                                      Rotation rotation,
                                      short rate,
                                      Time timestamp);
+typedef Rotation
+    (*XRRConfigRotationsType)(XRRScreenConfiguration *config,
+                              Rotation *current_rotation);
 
 static XRRQueryVersionType               awt_XRRQueryVersion;
 static XRRGetScreenInfoType              awt_XRRGetScreenInfo;
@@ -1689,6 +1693,7 @@
 static XRRConfigSizesType                awt_XRRConfigSizes;
 static XRRConfigCurrentConfigurationType awt_XRRConfigCurrentConfiguration;
 static XRRSetScreenConfigAndRateType     awt_XRRSetScreenConfigAndRate;
+static XRRConfigRotationsType            awt_XRRConfigRotations;
 
 #define LOAD_XRANDR_FUNC(f) \
     do { \
@@ -1755,6 +1760,7 @@
     LOAD_XRANDR_FUNC(XRRConfigSizes);
     LOAD_XRANDR_FUNC(XRRConfigCurrentConfiguration);
     LOAD_XRANDR_FUNC(XRRSetScreenConfigAndRate);
+    LOAD_XRANDR_FUNC(XRRConfigRotations);
 
     return JNI_TRUE;
 }
@@ -1765,6 +1771,7 @@
 {
     jclass displayModeClass;
     jmethodID cid;
+    jint validRefreshRate = refreshRate;
 
     displayModeClass = (*env)->FindClass(env, "java/awt/DisplayMode");
     if (JNU_IsNull(env, displayModeClass)) {
@@ -1780,8 +1787,13 @@
         return NULL;
     }
 
+    // early versions of xrandr may report "empty" rates (6880694)
+    if (validRefreshRate <= 0) {
+        validRefreshRate = REFRESH_RATE_UNKNOWN;
+    }
+
     return (*env)->NewObject(env, displayModeClass, cid,
-                             width, height, bitDepth, refreshRate);
+                             width, height, bitDepth, validRefreshRate);
 }
 
 static void
@@ -1926,8 +1938,7 @@
         curRate = awt_XRRConfigCurrentRate(config);
 
         if ((sizes != NULL) &&
-            (curSizeIndex < nsizes) &&
-            (curRate > 0))
+            (curSizeIndex < nsizes))
         {
             XRRScreenSize curSize = sizes[curSizeIndex];
             displayMode = X11GD_CreateDisplayMode(env,
@@ -2004,6 +2015,7 @@
     jboolean success = JNI_FALSE;
     XRRScreenConfiguration *config;
     Drawable root;
+    Rotation currentRotation = RR_Rotate_0;
 
     AWT_LOCK();
 
@@ -2015,6 +2027,7 @@
         short chosenRate = -1;
         int nsizes;
         XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes);
+        awt_XRRConfigRotations(config, &currentRotation);
 
         if (sizes != NULL) {
             int i, j;
@@ -2048,7 +2061,7 @@
             Status status =
                 awt_XRRSetScreenConfigAndRate(awt_display, config, root,
                                               chosenSizeIndex,
-                                              RR_Rotate_0,
+                                              currentRotation,
                                               chosenRate,
                                               CurrentTime);
 
--- a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.h	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.h	Tue Dec 01 08:54:10 2009 -0800
@@ -42,6 +42,10 @@
 #include <sys/ipc.h>
 #include <sys/shm.h>
 #include <X11/extensions/XShm.h>
+#ifndef X_ShmAttach
+#include <X11/Xmd.h>
+#include <X11/extensions/shmproto.h>
+#endif
 
 extern int XShmQueryExtension();
 
--- a/jdk/src/solaris/native/sun/awt/gtk2_interface.c	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.c	Tue Dec 01 08:54:10 2009 -0800
@@ -637,13 +637,13 @@
     if (gtk_modules_env && strstr (gtk_modules_env, "atk-bridge") ||
         gtk_modules_env && strstr (gtk_modules_env, "gail"))
     {
-        gchar *tmp_env = strdup (gtk_modules_env);
         /* the new env will be smaller than the old one */
         gchar *s, *new_env = malloc (sizeof(ENV_PREFIX)+strlen (gtk_modules_env));
 
         if (new_env != NULL )
         {
             /* careful, strtok modifies its args */
+            gchar *tmp_env = strdup (gtk_modules_env);
             strcpy(new_env, ENV_PREFIX);
 
             /* strip out 'atk-bridge' and 'gail' */
--- a/jdk/src/solaris/native/sun/xawt/XToolkit.c	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/solaris/native/sun/xawt/XToolkit.c	Tue Dec 01 08:54:10 2009 -0800
@@ -677,7 +677,7 @@
     jstring ret = NULL;
 
     keystr = JNU_GetStringPlatformChars(env, key, NULL);
-    if (key) {
+    if (keystr) {
         ptr = getenv(keystr);
         if (ptr) {
             ret = JNU_NewStringPlatform(env, (const char *) ptr);
--- a/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/windows/classes/sun/awt/Win32GraphicsDevice.java	Tue Dec 01 08:54:10 2009 -0800
@@ -353,6 +353,7 @@
             }
             WWindowPeer peer = (WWindowPeer)old.getPeer();
             if (peer != null) {
+                peer.setFullScreenExclusiveModeState(false);
                 // we used to destroy the buffers on exiting fs mode, this
                 // is no longer needed since fs change will cause a surface
                 // data replacement
@@ -370,12 +371,15 @@
             addFSWindowListener(w);
             // Enter full screen exclusive mode.
             WWindowPeer peer = (WWindowPeer)w.getPeer();
-            synchronized(peer) {
-                enterFullScreenExclusive(screen, peer);
-                // Note: removed replaceSurfaceData() call because
-                // changing the window size or making it visible
-                // will cause this anyway, and both of these events happen
-                // as part of switching into fullscreen mode.
+            if (peer != null) {
+                synchronized(peer) {
+                    enterFullScreenExclusive(screen, peer);
+                    // Note: removed replaceSurfaceData() call because
+                    // changing the window size or making it visible
+                    // will cause this anyway, and both of these events happen
+                    // as part of switching into fullscreen mode.
+                }
+                peer.setFullScreenExclusiveModeState(true);
             }
 
             // fix for 4868278
--- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java	Tue Dec 01 08:54:10 2009 -0800
@@ -524,7 +524,7 @@
     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
     private static native int compareIDs(long pParentIShellFolder, long pidl1, long pidl2);
 
-    private Boolean cachedIsFileSystem;
+    private volatile Boolean cachedIsFileSystem;
 
     /**
      * @return Whether this is a file system shell folder
@@ -693,29 +693,32 @@
                     ArrayList<Win32ShellFolder2> list = new ArrayList<Win32ShellFolder2>();
                     long pEnumObjects = getEnumObjects(includeHiddenFiles);
                     if (pEnumObjects != 0) {
-                        long childPIDL;
-                        int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
-                        do {
-                            childPIDL = getNextChild(pEnumObjects);
-                            boolean releasePIDL = true;
-                            if (childPIDL != 0 &&
-                                    (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) {
-                                Win32ShellFolder2 childFolder;
-                                if (Win32ShellFolder2.this.equals(desktop)
-                                        && personal != null
-                                        && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
-                                    childFolder = personal;
-                                } else {
-                                    childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
-                                    releasePIDL = false;
+                        try {
+                            long childPIDL;
+                            int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
+                            do {
+                                childPIDL = getNextChild(pEnumObjects);
+                                boolean releasePIDL = true;
+                                if (childPIDL != 0 &&
+                                        (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) {
+                                    Win32ShellFolder2 childFolder;
+                                    if (Win32ShellFolder2.this.equals(desktop)
+                                            && personal != null
+                                            && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
+                                        childFolder = personal;
+                                    } else {
+                                        childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
+                                        releasePIDL = false;
+                                    }
+                                    list.add(childFolder);
                                 }
-                                list.add(childFolder);
-                            }
-                            if (releasePIDL) {
-                                releasePIDL(childPIDL);
-                            }
-                        } while (childPIDL != 0 && !Thread.currentThread().isInterrupted());
-                        releaseEnumObjects(pEnumObjects);
+                                if (releasePIDL) {
+                                    releasePIDL(childPIDL);
+                                }
+                            } while (childPIDL != 0 && !Thread.currentThread().isInterrupted());
+                        } finally {
+                            releaseEnumObjects(pEnumObjects);
+                        }
                     }
                     return Thread.currentThread().isInterrupted()
                         ? new File[0]
@@ -759,7 +762,7 @@
         }, InterruptedException.class);
     }
 
-    private Boolean cachedIsLink;
+    private volatile Boolean cachedIsLink;
 
     /**
      * @return Whether this shell folder is a link
--- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Tue Dec 01 08:54:10 2009 -0800
@@ -79,9 +79,12 @@
             // Shouldn't happen but watch for it anyway
             throw new FileNotFoundException("File " + file.getAbsolutePath() + " not found");
         }
-        Win32ShellFolder2 folder = createShellFolderFromRelativePIDL(parent, pIDL);
-        Win32ShellFolder2.releasePIDL(pIDL);
-        return folder;
+
+        try {
+            return createShellFolderFromRelativePIDL(parent, pIDL);
+        } finally {
+            Win32ShellFolder2.releasePIDL(pIDL);
+        }
     }
 
     static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long pIDL)
@@ -269,7 +272,7 @@
                 Arrays.sort(secondLevelFolders);
                 for (File secondLevelFolder : secondLevelFolders) {
                     Win32ShellFolder2 folder = (Win32ShellFolder2) secondLevelFolder;
-                    if (!folder.isFileSystem() || folder.isDirectory()) {
+                    if (!folder.isFileSystem() || (folder.isDirectory() && !folder.isLink())) {
                         folders.add(folder);
                         // Add third level for "My Computer"
                         if (folder.equals(drives)) {
--- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java	Tue Dec 01 08:54:10 2009 -0800
@@ -550,8 +550,34 @@
     final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
 
     public Graphics getGraphics() {
+        if (isDisposed()) {
+            return null;
+        }
+
+        Component target = (Component)getTarget();
+        Window window = SunToolkit.getContainingWindow(target);
+        if (window != null && !window.isOpaque()) {
+            // Non-opaque windows do not support heavyweight children.
+            // Redirect all painting to the Window's Graphics instead.
+            // The caller is responsible for calling the
+            // WindowPeer.updateWindow() after painting has finished.
+            int x = 0, y = 0;
+            for (Component c = target; c != window; c = c.getParent()) {
+                x += c.getX();
+                y += c.getY();
+            }
+
+            Graphics g =
+                ((WWindowPeer)window.getPeer()).getTranslucentGraphics();
+
+            g.translate(x, y);
+            g.clipRect(0, 0, target.getWidth(), target.getHeight());
+
+            return g;
+        }
+
         SurfaceData surfaceData = this.surfaceData;
-        if (!isDisposed() && surfaceData != null) {
+        if (surfaceData != null) {
             /* Fix for bug 4746122. Color and Font shouldn't be null */
             Color bgColor = background;
             if (bgColor == null) {
--- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java	Tue Dec 01 08:54:10 2009 -0800
@@ -510,6 +510,9 @@
 
     private native int getScreenImOn();
 
+    // Used in Win32GraphicsDevice.
+    public final native void setFullScreenExclusiveModeState(boolean state);
+
 /*
  * ----END DISPLAY CHANGE SUPPORT----
  */
@@ -575,11 +578,17 @@
         }
     }
 
+    public final Graphics getTranslucentGraphics() {
+        synchronized (getStateLock()) {
+            return isOpaque ? null : painter.getBackBuffer(false).getGraphics();
+        }
+    }
+
     @Override
     public Graphics getGraphics() {
         synchronized (getStateLock()) {
             if (!isOpaque) {
-                return painter.getBackBuffer(false).getGraphics();
+                return getTranslucentGraphics();
             }
         }
         return super.getGraphics();
--- a/jdk/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java	Tue Dec 01 08:54:10 2009 -0800
@@ -210,7 +210,10 @@
             // if a GlyphVector overrides the AA setting.
             // We use getRenderLoops() rather than setting solidloops
             // directly so that we get the appropriate loops in XOR mode.
-            sg2d.loops = getRenderLoops(sg2d);
+            if (sg2d.loops == null) {
+                // assert(some pipe will always be a LoopBasedPipe)
+                sg2d.loops = getRenderLoops(sg2d);
+            }
         } else {
             super.validatePipe(sg2d);
         }
--- a/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp	Tue Dec 01 08:54:10 2009 -0800
@@ -687,7 +687,7 @@
     // Now, set-up the struct for the real calls to ::PrintDlg and ::CreateDC
 
     pd.hwndOwner = hwndOwner;
-    pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC;
+    pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE;
     pd.lpfnPrintHook = (LPPRINTHOOKPROC)PrintDlgHook;
 
     if (env->CallBooleanMethod(printCtrl, AwtPrintControl::getCollateID)) {
--- a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp	Tue Dec 01 08:54:10 2009 -0800
@@ -59,7 +59,7 @@
 };
 
 typedef struct tagBitmapheader  {
-    BITMAPINFOHEADER bmiHeader;
+    BITMAPV5HEADER bmiHeader;
     DWORD            dwMasks[256];
 } Bitmapheader, *LPBITMAPHEADER;
 
@@ -638,12 +638,12 @@
 
 HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH)
 {
-    Bitmapheader    bmhHeader;
+    Bitmapheader    bmhHeader = {0};
     HDC             hDC;
     char            *ptrImageData;
     HBITMAP         hbmpBitmap;
     HBITMAP         hBitmap;
-    int             nNumChannels    = 3;
+    int             nNumChannels    = 4;
 
     if (!hW) {
         hW = ::GetDesktopWindow();
@@ -653,14 +653,20 @@
         return NULL;
     }
 
-    memset(&bmhHeader, 0, sizeof(Bitmapheader));
-    bmhHeader.bmiHeader.biSize              = sizeof(BITMAPINFOHEADER);
-    bmhHeader.bmiHeader.biWidth             = nW;
-    bmhHeader.bmiHeader.biHeight            = -nH;
-    bmhHeader.bmiHeader.biPlanes            = 1;
+    bmhHeader.bmiHeader.bV5Size              = sizeof(BITMAPV5HEADER);
+    bmhHeader.bmiHeader.bV5Width             = nW;
+    bmhHeader.bmiHeader.bV5Height            = -nH;
+    bmhHeader.bmiHeader.bV5Planes            = 1;
 
-    bmhHeader.bmiHeader.biBitCount          = 24;
-    bmhHeader.bmiHeader.biCompression       = BI_RGB;
+    bmhHeader.bmiHeader.bV5BitCount          = 32;
+    bmhHeader.bmiHeader.bV5Compression       = BI_BITFIELDS;
+
+    // The following mask specification specifies a supported 32 BPP
+    // alpha format for Windows XP.
+    bmhHeader.bmiHeader.bV5RedMask   =  0x00FF0000;
+    bmhHeader.bmiHeader.bV5GreenMask =  0x0000FF00;
+    bmhHeader.bmiHeader.bV5BlueMask  =  0x000000FF;
+    bmhHeader.bmiHeader.bV5AlphaMask =  0xFF000000;
 
     hbmpBitmap = ::CreateDIBSection(hDC, (BITMAPINFO*)&(bmhHeader),
                                     DIB_RGB_COLORS,
@@ -674,6 +680,7 @@
     }
     for (int nOutern = 0; nOutern < nH; nOutern++) {
         for (int nInner = 0; nInner < nSS; nInner++) {
+            dstPtr[3] = (*srcPtr >> 0x18) & 0xFF;
             dstPtr[2] = (*srcPtr >> 0x10) & 0xFF;
             dstPtr[1] = (*srcPtr >> 0x08) & 0xFF;
             dstPtr[0] = *srcPtr & 0xFF;
--- a/jdk/src/windows/native/sun/windows/awt_Window.cpp	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp	Tue Dec 01 08:54:10 2009 -0800
@@ -143,6 +143,11 @@
     jobject window;
 };
 
+struct SetFullScreenExclusiveModeStateStruct {
+    jobject window;
+    jboolean isFSEMState;
+};
+
 
 /************************************************************************
  * AwtWindow fields
@@ -915,7 +920,9 @@
 
     bool show = false;
 
-    if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED) {
+    if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED &&
+            !isFullScreenExclusiveMode())
+    {
         if (AwtComponent::GetFocusedWindow() == GetHWnd()) {
             show = true;
         }
@@ -2954,6 +2961,25 @@
     delete uws;
 }
 
+void AwtWindow::_SetFullScreenExclusiveModeState(void *param)
+{
+    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+    SetFullScreenExclusiveModeStateStruct * data =
+        (SetFullScreenExclusiveModeStateStruct*)param;
+    jobject self = data->window;
+    jboolean state = data->isFSEMState;
+
+    PDATA pData;
+    JNI_CHECK_PEER_GOTO(self, ret);
+    AwtWindow *window = (AwtWindow *)pData;
+
+    window->setFullScreenExclusiveModeState(state != 0);
+
+  ret:
+    env->DeleteGlobalRef(self);
+    delete data;
+}
 
 extern "C" {
 
@@ -3335,6 +3361,29 @@
 
 /*
  * Class:     sun_awt_windows_WWindowPeer
+ * Method:    setFullScreenExclusiveModeState
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_windows_WWindowPeer_setFullScreenExclusiveModeState(JNIEnv *env,
+        jobject self, jboolean state)
+{
+    TRY;
+
+    SetFullScreenExclusiveModeStateStruct *data =
+        new SetFullScreenExclusiveModeStateStruct;
+    data->window = env->NewGlobalRef(self);
+    data->isFSEMState = state;
+
+    AwtToolkit::GetInstance().SyncCall(
+            AwtWindow::_SetFullScreenExclusiveModeState, data);
+    // global ref and data are deleted in the invoked method
+
+    CATCH_BAD_ALLOC;
+}
+
+/*
+ * Class:     sun_awt_windows_WWindowPeer
  * Method:    modalDisable
  * Signature: (J)V
  */
--- a/jdk/src/windows/native/sun/windows/awt_Window.h	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/src/windows/native/sun/windows/awt_Window.h	Tue Dec 01 08:54:10 2009 -0800
@@ -229,6 +229,7 @@
     static void _SetOpaque(void* param);
     static void _UpdateWindow(void* param);
     static void _RepositionSecurityWarning(void* param);
+    static void _SetFullScreenExclusiveModeState(void* param);
 
     inline static BOOL IsResizing() {
         return sm_resizing;
@@ -331,6 +332,16 @@
     static void SetLayered(HWND window, bool layered);
     static bool IsLayered(HWND window);
 
+    BOOL fullScreenExclusiveModeState;
+    inline void setFullScreenExclusiveModeState(BOOL isEntered) {
+        fullScreenExclusiveModeState = isEntered;
+        UpdateSecurityWarningVisibility();
+    }
+    inline BOOL isFullScreenExclusiveMode() {
+        return fullScreenExclusiveModeState;
+    }
+
+
 public:
     void UpdateSecurityWarningVisibility();
     static bool IsWarningWindow(HWND hWnd);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Container/ValidateRoot/InvalidateMustRespectValidateRoots.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+  @test
+  @bug 6852592
+  @summary invalidate() must stop when it encounters a validate root
+  @author anthony.petrov@sun.com
+  @run main InvalidateMustRespectValidateRoots
+*/
+
+import javax.swing.*;
+import java.awt.event.*;
+
+public class InvalidateMustRespectValidateRoots {
+    private static volatile JRootPane rootPane;
+
+    public static void main(String args[]) throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                // The JRootPane is a validate root. We'll check if
+                // invalidate() stops on the root pane, or goes further
+                // up to the frame.
+                JFrame frame = new JFrame();
+                final JButton button = new JButton();
+
+                frame.add(button);
+
+                // To enable running the test manually: use the Ctrl-Shift-F1
+                // to print the component hierarchy to the console
+                button.addActionListener(new ActionListener() {
+                    public void actionPerformed(ActionEvent ev) {
+                        if (button.isValid()) {
+                            button.invalidate();
+                        } else {
+                            button.revalidate();
+                        }
+                    }
+                });
+
+                rootPane = frame.getRootPane();
+
+                // Now the component hierarchy looks like:
+                // frame
+                // --> rootPane
+                //     --> layered pane
+                //         --> content pane
+                //             --> button
+
+                // Make all components valid first via showing the frame
+                // We have to make the frame visible. Otherwise revalidate() is
+                // useless (see RepaintManager.addInvalidComponent()).
+                frame.pack(); // To enable running this test manually
+                frame.setVisible(true);
+
+                if (!frame.isValid()) {
+                    throw new RuntimeException(
+                            "setVisible(true) failed to validate the frame");
+                }
+
+                // Now invalidate the button
+                button.invalidate();
+
+                // Check if the 'valid' status is what we expect it to be
+                if (rootPane.isValid()) {
+                    throw new RuntimeException(
+                            "invalidate() failed to invalidate the root pane");
+                }
+
+                if (!frame.isValid()) {
+                    throw new RuntimeException(
+                            "invalidate() invalidated the frame");
+                }
+
+                // Now validate the hierarchy again
+                button.revalidate();
+
+                // Now let the validation happen on the EDT
+            }
+        });
+
+        Thread.sleep(1000);
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                // Check if the root pane finally became valid
+                if (!rootPane.isValid()) {
+                    throw new RuntimeException(
+                            "revalidate() failed to validate the hierarchy");
+                }
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/InvocationEvent/InvocationEventTest.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+  @test
+  @bug 6852111
+  @summary Unhandled 'spurious wakeup' in java.awt.EventQueue.invokeAndWait()
+  @author dmitry.cherepanov@sun.com: area=awt.event
+  @run main InvocationEventTest
+*/
+
+/**
+ * InvocationEventTest.java
+ *
+ * summary: Tests new isDispatched method of the InvocationEvent class
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class InvocationEventTest
+{
+    public static void main(String []s) throws Exception
+    {
+        Toolkit tk = Toolkit.getDefaultToolkit();
+        Runnable runnable = new Runnable() {
+            public void run() {
+            }
+        };
+        Object lock = new Object();
+        InvocationEvent event = new InvocationEvent(tk, runnable, lock, true);
+
+        if (event.isDispatched()) {
+            throw new RuntimeException(" Initially, the event shouldn't be dispatched ");
+        }
+
+        synchronized(lock) {
+            tk.getSystemEventQueue().postEvent(event);
+            while(!event.isDispatched()) {
+                lock.wait();
+            }
+        }
+
+        if(!event.isDispatched()) {
+            throw new RuntimeException(" Finally, the event should be dispatched ");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/NumericShaper/EqualsTest.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6842557
+ * @summary confirm that an instance which is created with new Enum ranges is
+ * equivalent to another instance which is created with equivalent traditional
+ * ranges or the same Enum ranges.
+ */
+
+import java.awt.font.NumericShaper;
+import java.util.EnumSet;
+import static java.awt.font.NumericShaper.*;
+
+public class EqualsTest {
+    public static void main(String[] args) {
+        NumericShaper ns1 = getContextualShaper(ARABIC | TAMIL, TAMIL);
+        NumericShaper ns2 = getContextualShaper(
+                                EnumSet.of(Range.ARABIC, Range.TAMIL),
+                                Range.TAMIL);
+        NumericShaper ns3 = getContextualShaper(
+                                EnumSet.of(Range.ARABIC, Range.TAMIL),
+                                Range.TAMIL);
+        NumericShaper ns4 = getContextualShaper(
+                                EnumSet.of(Range.ARABIC, Range.TAMIL),
+                                Range.ARABIC);
+
+        if (!ns1.equals(ns2)) {
+            throw new RuntimeException("ns1 != ns2: ns1=" + ns1 + ", ns2=" + ns2);
+        }
+        if (!ns2.equals(ns1)) {
+            throw new RuntimeException("ns2 != ns1: ns1=" + ns1 + ", ns2=" + ns2);
+        }
+        if (!ns2.equals(ns3)) {
+            throw new RuntimeException("ns2 != ns3: ns2=" + ns2 + ", ns3=" + ns3);
+        }
+        if (ns1.equals(ns4)) {
+            throw new RuntimeException("ns1 == ns4: ns1=" + ns1 + ", ns4=" + ns4);
+        }
+        if (ns2.equals(ns4)) {
+            throw new RuntimeException("ns2 == ns4: ns2=" + ns2 + ", ns4=" + ns4);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/NumericShaper/MTTest.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6843181
+ * @summary Confirm that NumericShaper is thread-safe.
+ * @run main/timeout=300/othervm MTTest
+ */
+
+import java.awt.font.NumericShaper;
+import java.util.Arrays;
+import java.util.EnumSet;
+import static java.awt.font.NumericShaper.*;
+
+public class MTTest {
+    static volatile boolean runrun = true;
+    static volatile boolean err = false;
+
+    final static String text = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -789 (Thai) \u0e01\u0e33 01.23";
+    static char[] t1, t2;
+    static NumericShaper ns1, ns2, ns3, ns4;
+
+    public static void main(String[] args) {
+        System.out.println("   original: " + text);
+        ns1 = getContextualShaper(EnumSet.of(Range.ARABIC), Range.ARABIC);
+        t1 = text.toCharArray();
+        ns1.shape(t1, 0, t1.length);
+        System.out.println("expected t1: " + String.valueOf(t1));
+
+        ns2 = getContextualShaper(EnumSet.of(Range.THAI), Range.THAI);
+        t2 = text.toCharArray();
+        ns2.shape(t2, 0, t2.length);
+        System.out.println("expected t2: " + String.valueOf(t2));
+
+        ns3 = getContextualShaper(ARABIC, ARABIC);
+        ns4 = getContextualShaper(THAI, THAI);
+
+        Thread th1 = new Thread(new Work(ns1, t1));
+        Thread th2 = new Thread(new Work(ns2, t2));
+        Thread th3 = new Thread(new Work(ns1, t1));
+        Thread th4 = new Thread(new Work(ns2, t2));
+        Thread th5 = new Thread(new Work(ns3, t1));
+        Thread th6 = new Thread(new Work(ns4, t2));
+        Thread th7 = new Thread(new Work(ns3, t1));
+        Thread th8 = new Thread(new Work(ns4, t2));
+
+        th1.start();
+        th2.start();
+        th3.start();
+        th4.start();
+        th5.start();
+        th6.start();
+        th7.start();
+        th8.start();
+
+        try {
+            for (int i = 0; runrun && i < 180; i++) {
+                Thread.sleep(1000); // 1 seconds
+            }
+            runrun = false;
+            th1.join();
+            th2.join();
+            th3.join();
+            th4.join();
+            th5.join();
+            th6.join();
+            th7.join();
+            th8.join();
+        }
+        catch (InterruptedException e) {
+        }
+
+        if (err) {
+            throw new RuntimeException("Thread-safe test failed.");
+        }
+    }
+
+    private static class Work implements Runnable {
+        NumericShaper ns;
+        char[] expectedText;
+
+        Work(NumericShaper ns, char[] expectedText) {
+            this.ns = ns;
+            this.expectedText = expectedText;
+
+        }
+
+        public void run() {
+            int count = 0;
+            while (runrun) {
+                char[] t = text.toCharArray();
+                try {
+                    count++;
+                    ns.shape(t, 0, t.length);
+                } catch (Exception e) {
+                    System.err.println("Error: Unexpected exception: " + e);
+                    runrun = false;
+                    err = true;
+                    return;
+                }
+                if (!Arrays.equals(t, expectedText)) {
+                    System.err.println("Error: shape() returned unexpected value: ");
+                    System.err.println("count = " + count);
+                    System.err.println("   expected: " + String.valueOf(expectedText));
+                    System.err.println("        got: " + String.valueOf(t));
+                    runrun = false;
+                    err = true;
+                    return;
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/NumericShaper/ShapingTest.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6842557
+ * @summary confirm that shaping works as expected. (Mainly for new characters which were added in Unicode 5)
+ * used where appropriate.
+ */
+
+import java.awt.font.NumericShaper;
+import java.util.EnumSet;
+import static java.awt.font.NumericShaper.*;
+
+public class ShapingTest {
+    public static void main(String[] args) {
+        NumericShaper ns_old = getContextualShaper(ARABIC | TAMIL | ETHIOPIC,
+                                   EUROPEAN);
+        NumericShaper ns_new = getContextualShaper(EnumSet.of(
+                                   Range.ARABIC, Range.TAMIL, Range.ETHIOPIC),
+                                   Range.EUROPEAN);
+
+        boolean err = false;
+
+        String[][] data = {
+           // Arabic "October 10"
+          {"\u0623\u0643\u062a\u0648\u0628\u0631 10",
+           "\u0623\u0643\u062a\u0648\u0628\u0631 \u0661\u0660"},
+
+           // Tamil "Year 2009"
+          {"\u0b86\u0ba3\u0bcd\u0b9f\u0bc1 2009",
+           "\u0b86\u0ba3\u0bcd\u0b9f\u0bc1 \u0be8\u0be6\u0be6\u0bef"},
+           // "\u0be800\u0bef is returned by pre-JDK7 because Tamil zero was not
+           //  included in Unicode 4.0.0.
+
+           // Ethiopic "Syllable<HA> 2009"
+          {"\u1200 2009",
+           "\u1200 \u136a00\u1371"},
+           // Ethiopic zero doesn't exist even in Unicode 5.1.0.
+        };
+
+        for (int i = 0; i < data.length; i++) {
+            String expected = data[i][1];
+
+            char[] text = data[i][0].toCharArray();
+            ns_old.shape(text, 0, text.length);
+            String got = new String(text);
+
+            if (!expected.equals(got)) {
+                err = true;
+                System.err.println("Error with traditional range.");
+                System.err.println("  text = " + data[i][0]);
+                System.err.println("  got = " + got);
+                System.err.println("  expected = " + expected);
+            } else {
+                System.err.println("OK with traditional range.");
+                System.err.println("  text = " + data[i][0]);
+                System.err.println("  got = " + got);
+                System.err.println("  expected = " + expected);
+            }
+
+            text = data[i][0].toCharArray();
+            ns_new.shape(text, 0, text.length);
+            got = new String(text);
+
+            if (!expected.equals(got)) {
+                err = true;
+                System.err.println("Error with new Enum range.");
+                System.err.println("  text = " + data[i][0]);
+                System.err.println("  got = " + got);
+                System.err.println("  expected = " + expected);
+            } else {
+                System.err.println("OK with new Enum range.");
+                System.err.println("  text = " + data[i][0]);
+                System.err.println("  got = " + got);
+                System.err.println("  expected = " + expected);
+            }
+        }
+
+        if (err) {
+            throw new RuntimeException("shape() returned unexpected value.");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFileChooser/6550546/bug6550546.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @bug 6550546
+   @summary Win LAF: JFileChooser -> Look in Drop down should not display any shortcuts created on desktop
+   @author Pavel Porvatov
+   @run main bug6550546
+*/
+
+import sun.awt.OSInfo;
+import sun.awt.shell.ShellFolder;
+
+import javax.swing.*;
+import java.io.File;
+
+public class bug6550546 {
+    public static void main(String[] args) throws Exception {
+        if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
+            System.out.println("The test is suitable only for Windows, skipped.");
+
+            return;
+        }
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                File[] files = (File[]) ShellFolder.get("fileChooserComboBoxFolders");
+
+                for (File file : files) {
+                    if (file instanceof ShellFolder && ((ShellFolder) file).isLink()) {
+                        throw new RuntimeException("Link shouldn't be in FileChooser combobox, " + file.getPath());
+                    }
+                }
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFileChooser/6741890/bug6741890.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @bug 6741890
+   @summary Deadlock in Win32ShellFolderManager2
+   @author Pavel Porvatov
+   @run main bug6741890
+*/
+
+import sun.awt.shell.ShellFolder;
+import sun.awt.OSInfo;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.util.concurrent.Callable;
+
+public class bug6741890 {
+    /**
+     * This mux is used to prevent NPE in the isLink and isFileSystem methods
+     */
+    private static final Object mux = new Object();
+
+    private static final int COUNT = 100000;
+
+    public static void main(String[] args) throws Exception {
+        if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
+            System.out.println("The test is applicable only for Windows. Skipped.");
+
+            return;
+        }
+
+        String tmpDir = System.getProperty("java.io.tmpdir");
+
+        if (tmpDir.length() == 0) { //'java.io.tmpdir' isn't guaranteed to be defined
+            tmpDir = System.getProperty("user.home");
+        }
+
+        final ShellFolder tmpFile = ShellFolder.getShellFolder(new File(tmpDir));
+
+        System.out.println("Temp directory: " + tmpDir);
+
+        System.out.println("Stress test was run");
+
+        Thread thread = new Thread() {
+            public void run() {
+                while (!isInterrupted()) {
+                    ShellFolder.invoke(new Callable<Void>() {
+                        public Void call() throws Exception {
+                            synchronized (mux) {
+                                tmpFile.isFileSystem();
+                                tmpFile.isLink();
+                            }
+
+                            return null;
+                        }
+                    });
+                }
+            }
+        };
+
+        thread.start();
+
+        for (int i = 0; i < COUNT; i++) {
+            synchronized (mux) {
+                clearField(tmpFile, "cachedIsLink");
+                clearField(tmpFile, "cachedIsFileSystem");
+            }
+
+            tmpFile.isFileSystem();
+            tmpFile.isLink();
+        }
+
+        thread.interrupt();
+        thread.join();
+
+        System.out.println("Test passed successfully");
+    }
+
+    private static void clearField(Object o, String fieldName) throws Exception {
+        Field field = o.getClass().getDeclaredField(fieldName);
+
+        field.setAccessible(true);
+
+        field.set(o, null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFileChooser/6868611/bug6868611.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @bug 6868611
+   @summary FileSystemView throws NullPointerException
+   @author Pavel Porvatov
+   @run main bug6868611
+*/
+
+import javax.swing.*;
+import javax.swing.filechooser.FileSystemView;
+import java.io.File;
+
+public class bug6868611 {
+    private static final int COUNT = 1000;
+
+    public static void main(String[] args) throws Exception {
+        String tempDirProp = System.getProperty("java.io.tmpdir");
+
+        final String tempDir = tempDirProp == null || !new File(tempDirProp).isDirectory() ?
+            System.getProperty("user.home") : tempDirProp;
+
+        System.out.println("Temp directory: " + tempDir);
+
+        // Create 1000 files
+        for (int i = 0; i < 1000; i++) {
+            new File(tempDir, "temp" + i).createNewFile();
+        }
+
+        // Init default FileSystemView
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                FileSystemView.getFileSystemView().getFiles(new File(tempDir), false);
+            }
+        });
+
+        for (int i = 0; i < COUNT; i++) {
+            Thread thread = new MyThread(tempDir);
+
+            thread.start();
+
+            Thread.sleep((long) (Math.random() * 100));
+
+            thread.interrupt();
+
+            if (i % 100 == 0) {
+                System.out.print("*");
+            }
+        }
+
+        System.out.println();
+
+        // Remove 1000 files
+        for (int i = 0; i < 1000; i++) {
+            new File(tempDir, "temp" + i).delete();
+        }
+    }
+
+    private static class MyThread extends Thread {
+        private final String dir;
+
+        private MyThread(String dir) {
+            this.dir = dir;
+        }
+
+        public void run() {
+            FileSystemView fileSystemView = FileSystemView.getFileSystemView();
+
+            fileSystemView.getFiles(new File(dir), false);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/UIDefaults/6795356/SwingLazyValueTest.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6795356
+ * @summary Checks that SwingLazyValue class correclty works
+ * @author Alexander Potochkin
+ * @run main SwingLazyValueTest
+ */
+
+import sun.swing.SwingLazyValue;
+
+import javax.swing.*;
+
+public class SwingLazyValueTest {
+
+    public static void main(String[] args) throws Exception {
+        if(new SwingLazyValue("javax.swing.JTable$DoubleRenderer").
+                createValue(null) == null) {
+            throw new RuntimeException("SwingLazyValue doesn't work");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/UIDefaults/6795356/TableTest.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6795356
+ * @summary Checks that SwingLazyValue class correclty works
+ * @author Alexander Potochkin
+ * @run main/othervm TableTest
+ */
+
+import sun.applet.AppletSecurity;
+
+import javax.swing.*;
+import javax.swing.table.TableCellEditor;
+import java.awt.*;
+
+public class TableTest {
+
+    public static void main(String[] args) throws Exception {
+
+        KeyboardFocusManager.getCurrentKeyboardFocusManager();
+        System.setSecurityManager(new AppletSecurity());
+
+        JTable table = new JTable();
+        TableCellEditor de = table.getDefaultEditor(Double.class);
+        if (de == null) {
+            throw new RuntimeException("Table default editor is null");
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/UIDefaults/6795356/bug6795356.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6795356
+ * @summary Leak caused by javax.swing.UIDefaults.ProxyLazyValue.acc
+ * @author Alexander Potochkin
+ * @run main bug6795356
+ */
+
+import java.lang.ref.WeakReference;
+import java.security.ProtectionDomain;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.AccessControlContext;
+import java.util.LinkedList;
+import java.util.List;
+import javax.swing.*;
+
+public class bug6795356 {
+    volatile static WeakReference<ProtectionDomain> weakRef;
+
+    public static void main(String[] args) throws Exception {
+
+        ProtectionDomain domain = new ProtectionDomain(null, null);
+
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            public Object run() {
+
+                // this initialize ProxyLazyValues
+                UIManager.getLookAndFeel();
+
+                return null;
+            }
+        }, new AccessControlContext(new ProtectionDomain[]{domain}));
+
+        weakRef = new WeakReference<ProtectionDomain>(domain);
+        domain = null;
+
+        // Generate OutOfMemory and check the weak ref
+        generateOOME();
+
+        if (weakRef.get() != null) {
+            throw new RuntimeException("Memory leak found!");
+        }
+        System.out.println("Test passed");
+    }
+
+    static void generateOOME() {
+        List<Object> bigLeak = new LinkedList<Object>();
+        boolean oome = false;
+        System.out.print("Filling the heap");
+        try {
+            for(int i = 0; true ; i++) {
+                // Now, use up all RAM
+                bigLeak.add(new byte[1024 * 1024]);
+                System.out.print(".");
+
+                // Give the GC a change at that weakref
+                if (i % 10 == 0) {
+                    System.gc();
+                    try {
+                        Thread.sleep(100);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        } catch (OutOfMemoryError e) {
+            bigLeak = null;
+            oome = true;
+        }
+        System.out.println("");
+        if (!oome) {
+            throw new RuntimeException("Problem with test case - never got OOME");
+        }
+        System.out.println("Got OOME");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/java2d/pisces/Renderer/TestNPE.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug     6887494
+ *
+ * @summary Verifies that no NullPointerException is thrown in Pisces Renderer
+ *          under certain circumstances.
+ *
+ * @run     main TestNPE
+ */
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.image.BufferedImage;
+
+public class TestNPE {
+
+    private static void paint(Graphics g) {
+        Graphics2D g2d = (Graphics2D) g;
+        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                             RenderingHints.VALUE_ANTIALIAS_ON);
+        g2d.setClip(0, 0, 0, 0);
+        g2d.setTransform(
+               new AffineTransform(4.0f, 0.0f, 0.0f, 4.0f, -1248.0f, -744.0f));
+        g2d.draw(new Line2D.Float(131.21428571428572f, 33.0f,
+                                  131.21428571428572f, 201.0f));
+    }
+
+    public static void main(String[] args) {
+        BufferedImage im = new BufferedImage(100, 100,
+                                             BufferedImage.TYPE_INT_ARGB);
+
+        // Trigger exception in main thread.
+        Graphics g = im.getGraphics();
+        paint(g);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/jgss/spnego/NoSpnegoAsDefMech.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6770883
+ * @summary Infinite loop if SPNEGO specified as sun.security.jgss.mechanism
+ */
+
+import org.ietf.jgss.*;
+import sun.security.jgss.*;
+
+public class NoSpnegoAsDefMech {
+
+    public static void main(String[] argv) throws Exception {
+        System.setProperty("sun.security.jgss.mechanism", GSSUtil.GSS_SPNEGO_MECH_OID.toString());
+        try {
+            GSSManager.getInstance().createName("service@host", GSSName.NT_HOSTBASED_SERVICE, new Oid("1.3.6.1.5.5.2"));
+        } catch (GSSException e) {
+            // This is OK, for example, krb5.conf is missing or other problems
+        }
+    }
+}
--- a/jdk/test/sun/security/krb5/auto/Context.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/test/sun/security/krb5/auto/Context.java	Tue Dec 01 08:54:10 2009 -0800
@@ -72,7 +72,7 @@
 public class Context {
 
     private Subject s;
-    private GSSContext x;
+    private ExtendedGSSContext x;
     private boolean f;      // context established?
     private String name;
     private GSSCredential cred;     // see static method delegated().
@@ -147,8 +147,8 @@
             @Override
             public byte[] run(Context me, byte[] dummy) throws Exception {
                 GSSManager m = GSSManager.getInstance();
-                me.x = m.createContext(
-                        target.indexOf('@') < 0 ?
+                me.x = (ExtendedGSSContext)m.createContext(
+                          target.indexOf('@') < 0 ?
                             m.createName(target, null) :
                             m.createName(target, GSSName.NT_HOSTBASED_SERVICE),
                         mech,
@@ -170,7 +170,7 @@
             @Override
             public byte[] run(Context me, byte[] dummy) throws Exception {
                 GSSManager m = GSSManager.getInstance();
-                me.x = m.createContext(m.createCredential(
+                me.x = (ExtendedGSSContext)m.createContext(m.createCredential(
                         null,
                         GSSCredential.INDEFINITE_LIFETIME,
                         mech,
@@ -193,7 +193,7 @@
      *
      * @return the GSSContext object
      */
-    public GSSContext x() {
+    public ExtendedGSSContext x() {
         return x;
     }
 
@@ -255,6 +255,11 @@
             if (x.getSequenceDetState()) {
                 sb.append("seq det, ");
             }
+            if (x instanceof ExtendedGSSContext) {
+                if (((ExtendedGSSContext)x).getDelegPolicyState()) {
+                    sb.append("deleg policy, ");
+                }
+            }
             System.out.println("Context status of " + name + ": " + sb.toString());
             System.out.println(x.getSrcName() + " -> " + x.getTargName());
         } catch (Exception e) {
--- a/jdk/test/sun/security/krb5/auto/KDC.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/test/sun/security/krb5/auto/KDC.java	Tue Dec 01 08:54:10 2009 -0800
@@ -63,6 +63,14 @@
  * settings after calling a KDC method, call <code>Config.refresh()</code> to
  * make sure your changes are reflected in the <code>Config</code> object.
  * </ol>
+ * System properties recognized:
+ * <ul>
+ * <li>test.kdc.save.ccache
+ * </ul>
+ * Support policies:
+ * <ul>
+ * <li>ok-as-delegate
+ * </ul>
  * Issues and TODOs:
  * <ol>
  * <li> Generates krb5.conf to be used on another machine, currently the kdc is
@@ -151,7 +159,7 @@
      * A standalone KDC server.
      */
     public static void main(String[] args) throws Exception {
-        KDC kdc = create("RABBIT.HOLE", "kdc.rabbit,hole", 0, false);
+        KDC kdc = create("RABBIT.HOLE", "kdc.rabbit.hole", 0, false);
         kdc.addPrincipal("dummy", "bogus".toCharArray());
         kdc.addPrincipal("foo", "bar".toCharArray());
         kdc.addPrincipalRandKey("krbtgt/RABBIT.HOLE");
@@ -426,14 +434,17 @@
      * @throws sun.security.krb5.KrbException when the principal is not inside
      *         the database.
      */
-    private char[] getPassword(PrincipalName p) throws KrbException {
+    private char[] getPassword(PrincipalName p, boolean server)
+            throws KrbException {
         String pn = p.toString();
         if (p.getRealmString() == null) {
             pn = pn + "@" + getRealm();
         }
         char[] pass = passwords.get(pn);
         if (pass == null) {
-            throw new KrbException(Krb5.KDC_ERR_C_PRINCIPAL_UNKNOWN);
+            throw new KrbException(server?
+                Krb5.KDC_ERR_S_PRINCIPAL_UNKNOWN:
+                Krb5.KDC_ERR_C_PRINCIPAL_UNKNOWN);
         }
         return pass;
     }
@@ -457,10 +468,12 @@
      * Returns the key for a given principal of the given encryption type
      * @param p the principal
      * @param etype the encryption type
+     * @param server looking for a server principal?
      * @return the key
      * @throws sun.security.krb5.KrbException for unknown/unsupported etype
      */
-    private EncryptionKey keyForUser(PrincipalName p, int etype) throws KrbException {
+    private EncryptionKey keyForUser(PrincipalName p, int etype, boolean server)
+            throws KrbException {
         try {
             // Do not call EncryptionKey.acquireSecretKeys(), otherwise
             // the krb5.conf config file would be loaded.
@@ -469,22 +482,71 @@
             Integer kvno = null;
             // For service whose password ending with a number, use it as kvno
             if (p.toString().indexOf('/') >= 0) {
-                char[] pass = getPassword(p);
+                char[] pass = getPassword(p, server);
                 if (Character.isDigit(pass[pass.length-1])) {
                     kvno = pass[pass.length-1] - '0';
                 }
             }
             return new EncryptionKey((byte[]) stringToKey.invoke(
-                    null, getPassword(p), getSalt(p), null, etype),
+                    null, getPassword(p, server), getSalt(p), null, etype),
                     etype, kvno);
         } catch (InvocationTargetException ex) {
             KrbException ke = (KrbException)ex.getCause();
             throw ke;
+        } catch (KrbException ke) {
+            throw ke;
         } catch (Exception e) {
             throw new RuntimeException(e);  // should not happen
         }
     }
 
+    private Map<String,String> policies = new HashMap<String,String>();
+
+    public void setPolicy(String rule, String value) {
+        if (value == null) {
+            policies.remove(rule);
+        } else {
+            policies.put(rule, value);
+        }
+    }
+    /**
+     * If the provided client/server pair matches a rule
+     *
+     * A system property named test.kdc.policy.RULE will be consulted.
+     * If it's unset, returns false. If its value is "", any pair is
+     * matched. Otherwise, it should contains the server name matched.
+     *
+     * TODO: client name is not used currently.
+     *
+     * @param c client name
+     * @param s server name
+     * @param rule rule name
+     * @return if a match is found
+     */
+    private boolean configMatch(String c, String s, String rule) {
+        String policy = policies.get(rule);
+        boolean result = false;
+        if (policy == null) {
+            result = false;
+        } else if (policy.length() == 0) {
+            result = true;
+        } else {
+            String[] names = policy.split("\\s+");
+            for (String name: names) {
+                if (name.equals(s)) {
+                    result = true;
+                    break;
+                }
+            }
+        }
+        if (result) {
+            System.out.printf(">>>> Policy match result (%s vs %s on %s) %b\n",
+                    c, s, rule, result);
+        }
+        return result;
+    }
+
+
     /**
      * Processes an incoming request and generates a response.
      * @param in the request
@@ -530,7 +592,7 @@
                         tkt = apReq.ticket;
                         etype = tkt.encPart.getEType();
                         tkt.sname.setRealm(tkt.realm);
-                        EncryptionKey kkey = keyForUser(tkt.sname, etype);
+                        EncryptionKey kkey = keyForUser(tkt.sname, etype, true);
                         byte[] bb = tkt.encPart.decrypt(kkey, KeyUsage.KU_TICKET);
                         DerInputStream derIn = new DerInputStream(bb);
                         DerValue der = derIn.getDerValue();
@@ -541,7 +603,7 @@
                     throw new KrbException(Krb5.KDC_ERR_PADATA_TYPE_NOSUPP);
                 }
             }
-            EncryptionKey skey = keyForUser(body.sname, etype);
+            EncryptionKey skey = keyForUser(body.sname, etype, true);
             if (skey == null) {
                 throw new KrbException(Krb5.KDC_ERR_SUMTYPE_NOSUPP); // TODO
             }
@@ -581,6 +643,10 @@
             if (body.kdcOptions.get(KDCOptions.ALLOW_POSTDATE)) {
                 bFlags[Krb5.TKT_OPTS_MAY_POSTDATE] = true;
             }
+
+            if (configMatch("", body.sname.getNameString(), "ok-as-delegate")) {
+                bFlags[Krb5.TKT_OPTS_DELEGATE] = true;
+            }
             bFlags[Krb5.TKT_OPTS_INITIAL] = true;
 
             TicketFlags tFlags = new TicketFlags(bFlags);
@@ -671,8 +737,8 @@
             eTypes = (int[])f.get(body);
             int eType = eTypes[0];
 
-            EncryptionKey ckey = keyForUser(body.cname, eType);
-            EncryptionKey skey = keyForUser(body.sname, eType);
+            EncryptionKey ckey = keyForUser(body.cname, eType, false);
+            EncryptionKey skey = keyForUser(body.sname, eType, true);
             if (ckey == null) {
                 throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP);
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/OkAsDelegate.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import com.sun.security.jgss.ExtendedGSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.Oid;
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.Config;
+
+public class OkAsDelegate {
+
+    public static void main(String[] args)
+            throws Exception {
+        OkAsDelegate ok = new OkAsDelegate();
+        ok.go(
+                Boolean.valueOf(args[0]),   // FORWARDABLE in krb5.conf on?
+                Boolean.valueOf(args[1]),   // requestDelegState
+                Boolean.valueOf(args[2]),   // requestDelegPolicyState
+                Boolean.valueOf(args[3]),   // DelegState in response
+                Boolean.valueOf(args[4]),   // DelegPolicyState in response
+                Boolean.valueOf(args[5])    // getDelegCred OK?
+                );
+    }
+
+    void go(
+            boolean forwardable,
+            boolean requestDelegState,
+            boolean requestDelegPolicyState,
+            boolean delegState,
+            boolean delegPolicyState,
+            boolean delegated
+            ) throws Exception {
+        OneKDC kdc = new OneKDC(null);
+        kdc.setPolicy("ok-as-delegate",
+                System.getProperty("test.kdc.policy.ok-as-delegate"));
+        kdc.writeJAASConf();
+        if (!forwardable) {
+            // The default OneKDC always includes "forwardable = true"
+            // in krb5.conf, override it.
+            KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
+                    "default_keytab_name = " + OneKDC.KTAB);
+            Config.refresh();
+        }
+
+        Context c, s;
+        c = Context.fromJAAS("client");
+        s = Context.fromJAAS("server");
+
+        Oid mech = GSSUtil.GSS_KRB5_MECH_OID;
+        if (System.getProperty("test.spnego") != null) {
+            mech = GSSUtil.GSS_SPNEGO_MECH_OID;
+        }
+        c.startAsClient(OneKDC.SERVER, mech);
+        ExtendedGSSContext cx = (ExtendedGSSContext)c.x();
+        cx.requestCredDeleg(requestDelegState);
+        cx.requestDelegPolicy(requestDelegPolicyState);
+        s.startAsServer(mech);
+        ExtendedGSSContext sx = (ExtendedGSSContext)s.x();
+
+        Context.handshake(c, s);
+
+        if (cx.getCredDelegState() != delegState) {
+            throw new Exception("Initiator cred state error");
+        }
+        if (sx.getCredDelegState() != delegState) {
+            throw new Exception("Acceptor cred state error");
+        }
+        if (cx.getDelegPolicyState() != delegPolicyState) {
+            throw new Exception("Initiator cred policy state error");
+        }
+
+        GSSCredential cred = null;
+        try {
+            cred = s.x().getDelegCred();
+        } catch (GSSException e) {
+            // leave cred as null
+        }
+
+        if (delegated != (cred != null)) {
+            throw new Exception("get cred error");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/OkAsDelegateXRealm.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import com.sun.security.jgss.ExtendedGSSContext;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.Security;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.Config;
+
+public class OkAsDelegateXRealm implements CallbackHandler {
+
+    /**
+     * @param args boolean if the program should succeed
+     */
+    public static void main(String[] args)
+            throws Exception {
+
+        // Create and start the KDCs. Here we have 3 realms: R1, R2 and R3.
+        // R1 is trusted by R2, and R2 trusted by R3.
+        KDC kdc1 = KDC.create("R1");
+        kdc1.setPolicy("ok-as-delegate",
+                System.getProperty("test.kdc.policy.ok-as-delegate"));
+        kdc1.addPrincipal("dummy", "bogus".toCharArray());
+        kdc1.addPrincipalRandKey("krbtgt/R1");
+        kdc1.addPrincipal("krbtgt/R2@R1", "r1->r2".toCharArray());
+
+        KDC kdc2 = KDC.create("R2");
+        kdc2.setPolicy("ok-as-delegate",
+                System.getProperty("test.kdc.policy.ok-as-delegate"));
+        kdc2.addPrincipalRandKey("krbtgt/R2");
+        kdc2.addPrincipal("krbtgt/R2@R1", "r1->r2".toCharArray());
+        kdc2.addPrincipal("krbtgt/R3@R2", "r2->r3".toCharArray());
+
+        KDC kdc3 = KDC.create("R3");
+        kdc3.setPolicy("ok-as-delegate",
+                System.getProperty("test.kdc.policy.ok-as-delegate"));
+        kdc3.addPrincipalRandKey("krbtgt/R3");
+        kdc3.addPrincipal("krbtgt/R3@R2", "r2->r3".toCharArray());
+        kdc3.addPrincipalRandKey("host/host.r3.local");
+
+        KDC.saveConfig("krb5-localkdc.conf", kdc1, kdc2, kdc3,
+                "forwardable=true",
+                "[capaths]",
+                "R1 = {",
+                "    R2 = .",
+                "    R3 = R2",
+                "}",
+                "[domain_realm]",
+                ".r3.local=R3"
+                );
+
+        System.setProperty("java.security.krb5.conf", "krb5-localkdc.conf");
+        kdc3.writeKtab("localkdc.ktab");
+
+        FileOutputStream fos = new FileOutputStream("jaas-localkdc.conf");
+
+        // Defines the client and server on R1 and R3 respectively.
+        fos.write(("com.sun.security.jgss.krb5.initiate {\n" +
+                "    com.sun.security.auth.module.Krb5LoginModule\n" +
+                "    required\n" +
+                "    principal=dummy\n" +
+                "    doNotPrompt=false\n" +
+                "    useTicketCache=false\n" +
+                "    ;\n};\n" +
+                "com.sun.security.jgss.krb5.accept {\n" +
+                "    com.sun.security.auth.module.Krb5LoginModule required\n" +
+                "    principal=\"host/host.r3.local@R3\"\n" +
+                "    useKeyTab=true\n" +
+                "    keyTab=localkdc.ktab\n" +
+                "    isInitiator=false\n" +
+                "    storeKey=true;\n};\n" +
+                "\n").getBytes());
+        fos.close();
+
+        Security.setProperty("auth.login.defaultCallbackHandler",
+                "OkAsDelegateXRealm");
+
+        System.setProperty("java.security.auth.login.config", "jaas-localkdc.conf");
+
+        new File("krb5-localkdc.conf").deleteOnExit();
+        new File("localkdc.ktab").deleteOnExit();
+        new File("jaas-localkdc.conf").deleteOnExit();
+        Config.refresh();
+
+        Context c = Context.fromJAAS("com.sun.security.jgss.krb5.initiate");
+        Context s = Context.fromJAAS("com.sun.security.jgss.krb5.accept");
+
+        // Test twice. The frist time the whole cross realm process is tried,
+        // the second time the cached service ticket is used. This is to make sure
+        // the behaviors are the same, especailly for the case when one of the
+        // cross-realm TGTs does not have OK-AS-DELEGATE on.
+
+        for (int i=0; i<2; i++) {
+            c.startAsClient("host@host.r3.local", GSSUtil.GSS_KRB5_MECH_OID);
+            s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+            c.x().requestDelegPolicy(true);
+
+            Context.handshake(c, s);
+            boolean succeed = true;
+            try {
+                s.x().getDelegCred();
+            } catch (GSSException gsse) {
+                succeed = false;
+            }
+            if (succeed != Boolean.parseBoolean(args[0])) {
+                throw new Exception("Test fail at round #" + i);
+            }
+        }
+    }
+
+    @Override
+    public void handle(Callback[] callbacks)
+            throws IOException, UnsupportedCallbackException {
+        for (Callback callback : callbacks) {
+            if (callback instanceof NameCallback) {
+                ((NameCallback) callback).setName("dummy");
+            }
+            if (callback instanceof PasswordCallback) {
+                ((PasswordCallback) callback).setPassword("bogus".toCharArray());
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/ok-as-delegate-xrealm.sh	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,79 @@
+#
+# Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6853328
+# @summary Support OK-AS-DELEGATE flag
+# @run shell/timeout=600 ok-as-delegate-xrealm.sh
+#
+
+if [ "${TESTSRC}" = "" ] ; then
+  TESTSRC=`dirname $0`
+fi
+
+if [ "${TESTJAVA}" = "" ] ; then
+  JAVAC_CMD=`which javac`
+  TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  Windows_* )
+    FS="\\"
+    SEP=";"
+    ;;
+  CYGWIN* )
+    FS="/"
+    SEP=";"
+    ;;
+  * )
+    FS="/"
+    SEP=":"
+    ;;
+esac
+
+${TESTJAVA}${FS}bin${FS}javac -XDignore.symbol.file -d . \
+    ${TESTSRC}${FS}OkAsDelegateXRealm.java \
+    ${TESTSRC}${FS}KDC.java \
+    ${TESTSRC}${FS}OneKDC.java \
+    ${TESTSRC}${FS}Action.java \
+    ${TESTSRC}${FS}Context.java \
+    || exit 10
+
+# Add $TESTSRC to classpath so that customized nameservice can be used
+J="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}."
+
+# KDC no OK-AS-DELEGATE, fail
+$J OkAsDelegateXRealm false || exit 1
+
+# KDC set OK-AS-DELEGATE for all, succeed
+$J -Dtest.kdc.policy.ok-as-delegate OkAsDelegateXRealm true || exit 2
+
+# KDC set OK-AS-DELEGATE for host/host.r3.local only, fail
+$J -Dtest.kdc.policy.ok-as-delegate=host/host.r3.local OkAsDelegateXRealm false || exit 3
+
+# KDC set OK-AS-DELEGATE for all, succeed
+$J "-Dtest.kdc.policy.ok-as-delegate=host/host.r3.local krbtgt/R2 krbtgt/R3" OkAsDelegateXRealm true || exit 4
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/ok-as-delegate.sh	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,118 @@
+#
+# Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6853328
+# @summary Support OK-AS-DELEGATE flag
+# @run shell/timeout=600 ok-as-delegate.sh
+#
+
+if [ "${TESTSRC}" = "" ] ; then
+  TESTSRC=`dirname $0`
+fi
+
+if [ "${TESTJAVA}" = "" ] ; then
+  JAVAC_CMD=`which javac`
+  TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  Windows_* )
+    FS="\\"
+    SEP=";"
+    ;;
+  CYGWIN* )
+    FS="/"
+    SEP=";"
+    ;;
+  * )
+    FS="/"
+    SEP=":"
+    ;;
+esac
+
+${TESTJAVA}${FS}bin${FS}javac -XDignore.symbol.file -d . \
+    ${TESTSRC}${FS}OkAsDelegate.java \
+    ${TESTSRC}${FS}KDC.java \
+    ${TESTSRC}${FS}OneKDC.java \
+    ${TESTSRC}${FS}Action.java \
+    ${TESTSRC}${FS}Context.java \
+    || exit 10
+
+# Testing Kerberos 5
+
+# Add $TESTSRC to classpath so that customized nameservice can be used
+J="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. OkAsDelegate"
+JOK="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. -Dtest.kdc.policy.ok-as-delegate OkAsDelegate"
+
+# FORWARDABLE ticket not allowed, always fail
+$J false true true false false false || exit 1
+
+# Service ticket no OK-AS-DELEGATE
+
+# Request nothing, gain nothing
+$J true false false false false false || exit 2
+# Request deleg policy, gain nothing
+$J true false true false false false || exit 3
+# Request deleg, granted
+$J true true false true false true || exit 4
+# Request deleg and deleg policy, granted, with info not by policy
+$J true true true true false true || exit 5
+
+# Service ticket has OK-AS-DELEGATE
+
+# Request deleg policy, granted
+$JOK true false true true true true || exit 6
+# Request deleg and deleg policy, granted, with info by policy
+$JOK true true true true true true || exit 7
+
+# Testing SPNEGO
+
+# Add $TESTSRC to classpath so that customized nameservice can be used
+J="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. -Dtest.spnego OkAsDelegate"
+JOK="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. -Dtest.spnego -Dtest.kdc.policy.ok-as-delegate OkAsDelegate"
+
+# FORWARDABLE ticket not allowed, always fail
+$J false true true false false false || exit 11
+
+# Service ticket no OK-AS-DELEGATE
+
+# Request nothing, gain nothing
+$J true false false false false false || exit 12
+# Request deleg policy, gain nothing
+$J true false true false false false || exit 13
+# Request deleg, granted
+$J true true false true false true || exit 14
+# Request deleg and deleg policy, granted, with info not by policy
+$J true true true true false true || exit 15
+
+# Service ticket has OK-AS-DELEGATE
+
+# Request deleg policy, granted
+$JOK true false true true true true || exit 16
+# Request deleg and deleg policy, granted, with info by policy
+$JOK true true true true true true || exit 17
+
+exit 0
--- a/jdk/test/tools/launcher/Arrrghs.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/test/tools/launcher/Arrrghs.java	Tue Dec 01 08:54:10 2009 -0800
@@ -25,7 +25,7 @@
  * @test
  * @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881
  * @summary Argument parsing validation.
- * @compile Arrrghs.java TestHelper.java
+ * @compile -XDignore.symbol.file Arrrghs.java TestHelper.java
  * @run main Arrrghs
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/ExecutionEnvironment.java	Tue Dec 01 08:54:10 2009 -0800
@@ -0,0 +1,358 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4780570 4731671 6354700 6367077 6670965 4882974
+ * @summary Checks for LD_LIBRARY_PATH and execution  on *nixes
+ * @compile -XDignore.symbol.file ExecutionEnvironment.java TestHelper.java
+ * @run main ExecutionEnvironment
+ */
+
+/*
+ * This test tests for various things as follows:
+ * Ensures that:
+ *   1. uneccessary execs do not occur
+ *   2. the environment is pristine,  users environment variable wrt.
+ *      LD_LIBRARY_PATH if set are not modified in any way.
+ *   3. the correct vm is chosen with -server and -client options
+ *   4. the VM on Solaris correctly interprets the LD_LIBRARY_PATH32
+ *      and LD_LIBRARY_PATH64 variables if set by the user, ie.
+ *      i. on 32 bit systems:
+ *         a. if LD_LIBRARY_PATH32 is set it will override LD_LIBRARY_PATH
+ *         b. LD_LIBRARY_PATH64 is ignored if set
+ *      ii. on 64 bit systems:
+ *            a. if LD_LIBRARY_PATH64 is set it will override LD_LIBRARY_PATH
+ *            b. LD_LIBRARY_PATH32 is ignored if set
+ *   5. no extra symlink exists on Solaris ie.
+ *      jre/lib/$arch/libjvm.so -> client/libjvm.so
+ * TODO:
+ *      a. perhaps we need to add a test to audit all environment variables are
+ *         in pristine condition after the launch, there may be a few that the
+ *         launcher may add as implementation details.
+ *      b. add a pldd for solaris to ensure only one libjvm.so is linked
+ */
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+public class ExecutionEnvironment {
+    static final String LD_LIBRARY_PATH    = "LD_LIBRARY_PATH";
+    static final String LD_LIBRARY_PATH_32 = LD_LIBRARY_PATH + "_32";
+    static final String LD_LIBRARY_PATH_64 = LD_LIBRARY_PATH + "_64";
+
+    // Note: these paths need not exist on the filesytem
+    static final String LD_LIBRARY_PATH_VALUE    = "/Bridge/On/The/River/Kwai";
+    static final String LD_LIBRARY_PATH_32_VALUE = "/Lawrence/Of/Arabia";
+    static final String LD_LIBRARY_PATH_64_VALUE = "/A/Passage/To/India";
+
+    static final String JLDEBUG_KEY = "_JAVA_LAUNCHER_DEBUG";
+    static final String EXPECTED_MARKER = "TRACER_MARKER:About to EXEC";
+
+    static final String[] LD_PATH_STRINGS = {
+        LD_LIBRARY_PATH + "=" + LD_LIBRARY_PATH_VALUE,
+        LD_LIBRARY_PATH_32 + "=" + LD_LIBRARY_PATH_32_VALUE,
+        LD_LIBRARY_PATH_64 + "=" + LD_LIBRARY_PATH_64_VALUE
+    };
+
+    static final File testJarFile = new File("EcoFriendly.jar");
+
+    static int errors = 0;
+    static int passes = 0;
+
+    private static void createTestJar() {
+        try {
+            List<String> codeList = new ArrayList<String>();
+            codeList.add("static void printValue(String name, boolean property) {\n");
+            codeList.add("    String value = (property) ? System.getProperty(name) : System.getenv(name);\n");
+            codeList.add("    System.out.println(name + \"=\" + value);\n");
+            codeList.add("}\n");
+            codeList.add("public static void main(String... args) {\n");
+            codeList.add("    System.out.println(\"Execute test:\");\n");
+            codeList.add("    printValue(\"os.name\", true);\n");
+            codeList.add("    printValue(\"os.arch\", true);\n");
+            codeList.add("    printValue(\"os.version\", true);\n");
+            codeList.add("    printValue(\"sun.arch.data.model\", true);\n");
+            codeList.add("    printValue(\"java.library.path\", true);\n");
+            codeList.add("    printValue(\"" + LD_LIBRARY_PATH + "\", false);\n");
+            codeList.add("    printValue(\"" + LD_LIBRARY_PATH_32 + "\", false);\n");
+            codeList.add("    printValue(\"" + LD_LIBRARY_PATH_64 + "\", false);\n");
+            codeList.add("}\n");
+            String[] clist = new String[codeList.size()];
+            TestHelper.createJar(testJarFile, codeList.toArray(clist));
+        } catch (FileNotFoundException fnfe) {
+            throw new RuntimeException(fnfe);
+        }
+    }
+
+    /*
+     * tests if the launcher pollutes the LD_LIBRARY_PATH variables ie. there
+     * should not be any new variables or pollution/mutations of any kind, the
+     * environment should be pristine.
+     */
+    private static void ensureEcoFriendly() {
+        TestHelper.TestResult tr = null;
+
+        Map<String, String> env = new HashMap<String, String>();
+        for (String x : LD_PATH_STRINGS) {
+            String pairs[] = x.split("=");
+            env.put(pairs[0], pairs[1]);
+        }
+
+        tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+                testJarFile.getAbsolutePath());
+
+        if (!tr.isNotZeroOutput()) {
+            throw new RuntimeException("Error: No output at all. Did the test execute ?");
+        }
+
+        for (String x : LD_PATH_STRINGS) {
+            if (!tr.contains(x)) {
+                System.out.println("FAIL: did not get <" + x + ">");
+                System.out.println(tr);
+                errors++;
+            } else {
+                passes++;
+            }
+        }
+    }
+
+    /*
+     * ensures that there are no execs as long as we are in the same
+     * data model
+     */
+    static void ensureNoExec() {
+        Map<String, String> env = new HashMap<String, String>();
+        env.put(JLDEBUG_KEY, "true");
+        TestHelper.TestResult tr =
+                TestHelper.doExec(env, TestHelper.javaCmd, "-version");
+        if (tr.testOutput.contains(EXPECTED_MARKER)) {
+            System.out.println("FAIL: EnsureNoExecs: found expected warning <" +
+                    EXPECTED_MARKER +
+                    "> the process execing ?");
+            errors++;
+        } else {
+            passes++;
+        }
+        return;
+    }
+
+    /*
+     * This test ensures that LD_LIBRARY_PATH* values are interpreted by the VM
+     * and the expected java.library.path behaviour.
+     * For Generic platforms (All *nixes):
+     *    * All LD_LIBRARY_PATH variable should be on java.library.path
+     * For Solaris 32-bit
+     *    * The LD_LIBRARY_PATH_32 should override LD_LIBRARY_PATH if specified
+     * For Solaris 64-bit
+     *    * The LD_LIBRARY_PATH_64 should override LD_LIBRARY_PATH if specified
+     */
+
+    static void verifyJavaLibraryPath() {
+        TestHelper.TestResult tr = null;
+
+        Map<String, String> env = new HashMap<String, String>();
+
+
+        if (TestHelper.isLinux) {
+            for (String x : LD_PATH_STRINGS) {
+                String pairs[] = x.split("=");
+                env.put(pairs[0], pairs[1]);
+            }
+
+            tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+                    testJarFile.getAbsolutePath());
+            verifyJavaLibraryPathGeneric(tr);
+        } else {
+            // no override
+            env.clear();
+            env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE);
+            tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+                    testJarFile.getAbsolutePath());
+            verifyJavaLibraryPathGeneric(tr);
+
+            env.clear();
+            for (String x : LD_PATH_STRINGS) {
+                String pairs[] = x.split("=");
+                env.put(pairs[0], pairs[1]);
+            }
+
+            // verify the override occurs, since we know the invocation always
+            // uses by default is 32-bit, therefore we also set the test
+            // expectation to be the same.
+            tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+                    testJarFile.getAbsolutePath());
+            verifyJavaLibraryPathOverride(tr, true);
+
+            // try changing the model from 32 to 64 bit
+            if (TestHelper.java64Cmd != null && TestHelper.is32Bit) {
+                // verify the override occurs
+                env.clear();
+                for (String x : LD_PATH_STRINGS) {
+                    String pairs[] = x.split("=");
+                    env.put(pairs[0], pairs[1]);
+                }
+                tr = TestHelper.doExec(env, TestHelper.javaCmd, "-d64", "-jar",
+                    testJarFile.getAbsolutePath());
+                verifyJavaLibraryPathOverride(tr, false);
+
+                // no override
+                env.clear();
+                env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE);
+                tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar",
+                        testJarFile.getAbsolutePath());
+                verifyJavaLibraryPathGeneric(tr);
+            }
+
+            // try changing the model from 64 to 32 bit
+            if (TestHelper.java64Cmd != null && TestHelper.is64Bit) {
+                // verify the override occurs
+                env.clear();
+                for (String x : LD_PATH_STRINGS) {
+                    String pairs[] = x.split("=");
+                    env.put(pairs[0], pairs[1]);
+                }
+                tr = TestHelper.doExec(env, TestHelper.java64Cmd, "-d32", "-jar",
+                    testJarFile.getAbsolutePath());
+                verifyJavaLibraryPathOverride(tr, true);
+
+                // no override
+                env.clear();
+                env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE);
+                tr = TestHelper.doExec(env, TestHelper.java64Cmd, "-d32", "-jar",
+                        testJarFile.getAbsolutePath());
+                verifyJavaLibraryPathGeneric(tr);
+            }
+        }
+    }
+
+    private static void verifyJavaLibraryPathGeneric(TestHelper.TestResult tr) {
+        if (!tr.matches("java.library.path=.*" + LD_LIBRARY_PATH_VALUE + ".*")) {
+            System.out.print("FAIL: verifyJavaLibraryPath: ");
+            System.out.println(" java.library.path does not contain " +
+                    LD_LIBRARY_PATH_VALUE);
+            System.out.println(tr);
+            errors++;
+        } else {
+            passes++;
+        }
+    }
+
+    private static void verifyJavaLibraryPathOverride(TestHelper.TestResult tr,
+            boolean is32Bit) {
+        // make sure the 32/64 bit value exists
+        if (!tr.matches("java.library.path=.*" +
+                (is32Bit ? LD_LIBRARY_PATH_32_VALUE : LD_LIBRARY_PATH_64_VALUE) + ".*")) {
+            System.out.print("FAIL: verifyJavaLibraryPathOverride: ");
+            System.out.println(" java.library.path does not contain " +
+                    (is32Bit ? LD_LIBRARY_PATH_32_VALUE : LD_LIBRARY_PATH_64_VALUE));
+            System.out.println(tr);
+            errors++;
+        } else {
+            passes++;
+        }
+        // make sure the generic value is absent
+        if (tr.matches("java.library.path=.*" + LD_LIBRARY_PATH_VALUE + ".*")) {
+            System.out.print("FAIL: verifyJavaLibraryPathOverride: ");
+            System.out.println(" java.library.path contains " +
+                    LD_LIBRARY_PATH_VALUE);
+            System.out.println(tr);
+            errors++;
+        } else {
+            passes++;
+        }
+    }
+
+    /*
+     * ensures we have indeed exec'ed the correct vm of choice, all VMs support
+     * -server, however 32-bit VMs support -client and -server.
+     */
+    static void verifyVmSelection() {
+
+        TestHelper.TestResult tr = null;
+
+        if (TestHelper.is32Bit) {
+            tr = TestHelper.doExec(TestHelper.javaCmd, "-client", "-version");
+            if (!tr.matches("Java.*Client VM.*")) {
+                System.out.println("FAIL: the expected vm -client did launch");
+                System.out.println(tr);
+                errors++;
+            } else {
+                passes++;
+            }
+        }
+        tr = TestHelper.doExec(TestHelper.javaCmd, "-server", "-version");
+        if (!tr.matches("Java.*Server VM.*")) {
+            System.out.println("FAIL: the expected vm -server did launch");
+            System.out.println(tr);
+            errors++;
+        } else {
+            passes++;
+        }
+    }
+
+    /*
+     * checks to see there is no extra libjvm.so than needed
+     */
+    static void verifyNoSymLink() {
+        if (TestHelper.is64Bit) {
+            return;
+        }
+
+        File symLink = null;
+        String libPathPrefix = TestHelper.isSDK ? "jre/lib" : "/lib";
+        symLink = new File(TestHelper.JAVAHOME, libPathPrefix +
+                TestHelper.getJreArch() + "/libjvm.so");
+        if (symLink.exists()) {
+            System.out.println("FAIL: The symlink exists " +
+                    symLink.getAbsolutePath());
+            errors++;
+        } else {
+            passes++;
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        if (TestHelper.isWindows) {
+            System.out.println("Warning: noop on windows");
+            return;
+        }
+        // create our test jar first
+        createTestJar();
+        ensureNoExec();
+        verifyVmSelection();
+        ensureEcoFriendly();
+        verifyJavaLibraryPath();
+        verifyNoSymLink();
+        if (errors > 0) {
+            throw new Exception("ExecutionEnvironment: FAIL: with " +
+                    errors + " errors and passes " + passes );
+        } else {
+            System.out.println("ExecutionEnvironment: PASS " + passes);
+        }
+    }
+}
--- a/jdk/test/tools/launcher/SolarisDataModel.sh	Tue Dec 01 08:51:16 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,219 +0,0 @@
-# Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-
-# @test
-# @bug 4780570
-# @run shell SolarisDataModel.sh
-# @summary Verify Solaris SPARC -d32 and -d64 options work with preset LD_LIBRARY_PATH
-# @author Joseph D. Darcy
-
-# Test to see if presetting LD_LIBRARY_PATH affects the treatment of
-# -d32 and -d64 options; also checks that -d<n> options result in the
-# desired data model.
-
-# If the test is not being run on a Solaris SPARC box SPARC the test
-# succeeds immediately.
-
-OS=`uname -s`;
-
-case "$OS" in
-	SunOS )
-		# ARCH should be sparc or i386
-		ARCH=`uname -p`
-		case "$ARCH" in 
-			sparc)
-			PATHSEP=":"
-			;;
-
-			* )
-			echo "Non-SPARC Solaris environment; test vacuously succeeds."
-			exit 0
-		esac
-	;;
-
-	* )
-	echo "Not a Solaris SPARC environment; test vacuously succeeds."
-	exit 0;
-	;;
-esac
-
-
-# Verify directory context variables are set
-if [ "${TESTJAVA}" = "" ]
-then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-
-if [ "${TESTSRC}" = "" ]
-then
-  echo "TESTSRC not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-
-
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-
-
-JAVAC="$TESTJAVA/bin/javac"
-
-# Create our little Java tests on the fly
-( printf "public class GetDataModel {"
-  printf "   public static void main(String argv[]) {"
-  printf "      System.out.println(System.getProperty(\"sun.arch.data.model\", \"none\"));"
-  printf "   }"
-  printf "}"
-) > GetDataModel.java
-
-$JAVAC  GetDataModel.java
-
-( printf "public class GetLdLibraryPath {"
-  printf "   public static void main(String argv[]) {"
-  printf "      System.out.println(System.getProperty(\"java.library.path\"));"
-  printf "   }"
-  printf "}"
-) > GetLdLibraryPath.java
-
-$JAVAC  GetLdLibraryPath.java
-
-
-
-# All preconditions are met; run the tests
-
-
-# Construct path to 32-bit Java executable
-JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES${PATHSEP}."
-
-
-# Construct path to 64-bit Java executable, might not exist
-JAVA64="$TESTJAVA/bin/sparcv9/java -classpath $TESTCLASSES${PATHSEP}."
-JAVA64FILE="$TESTJAVA/bin/sparcv9/java"
-
-
-# java -d32 tests
-
-LD_LIBRARY_PATH=""
-export LD_LIBRARY_PATH
-
-DM=`$JAVA -d32 GetDataModel`
-case "$DM" in
-        32 )
-        ;;
-
-        * )
-	echo "The combination \"java -d32\" failed."
-	echo $DM
-        exit 1
-esac
-
-# Rerun test with LD_LIBRARY_PATH preset
-LD_LIBRARY_PATH=`$JAVA GetLdLibraryPath`;
-DM=`$JAVA -d32 GetDataModel`
-case "$DM" in
-        32 )
-        ;;
-
-        * )
-	echo "The combination \"java -d32\" failed with preset LD_LIBRARY_PATH."
-	echo $DM
-        exit 1
-esac
-
-# Reset LD_LIBRARY_PATH
-LD_LIBRARY_PATH=
-
-
-# Test for 64-bit executable
-
-if [ -f $JAVA64FILE ]; then
-
-	DM=`$JAVA -d64 GetDataModel`
-	case "$DM" in
-        	64 )
-        	;;
-
-        	* )
-		echo "The combination \"java -d64\" failed."
-        	exit 1
-	esac
-
-	DM=`$JAVA64 -d32 GetDataModel`
-	case "$DM" in
-        	32 )
-        	;;
-
-        	* )
-		echo "The combination \"sparcv9/java -d32\" failed."
-        	exit 1
-	esac
-
-	DM=`$JAVA64 -d64 GetDataModel`
-	case "$DM" in
-        	64 )
-        	;;
-
-        	* )
-		echo "The combination \"sparcv9/java -d64\" failed."
-        	exit 1
-	esac
-
-	# Rerun tests with LD_LIBRARY_PATH preset
-	LD_LIBRARY_PATH=`$JAVA GetLdLibraryPath`;
-	echo "Presetting LD_LIBRARY_PATH"
-
-	DM=`$JAVA -d64 GetDataModel`
-	case "$DM" in
-        	64 )
-        	;;
-
-        	* )
-		echo "The combination \"java -d64\" failed with preset LD_LIBRARY_PATH."
-        	exit 1
-	esac
-
-	DM=`$JAVA64 -d32 GetDataModel`
-	case "$DM" in
-        	32 )
-        	;;
-
-        	* )
-		echo "The combination \"sparcv9/java -d32\" failed with preset LD_LIBRARY_PATH."
-        	exit 1
-	esac
-
-	DM=`$JAVA64 -d64 GetDataModel`
-	case "$DM" in
-        	64 )
-        	;;
-
-        	* )
-		echo "The combination \"sparcv9/java -d64\" failed with preset LD_LIBRARY_PATH."
-        	exit 1
-	esac
-
-else
-  echo "Warning: no 64-bit components found; only java -d32 tests have been run."
-fi
-exit 0;
--- a/jdk/test/tools/launcher/SolarisRunpath.sh	Tue Dec 01 08:51:16 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-# Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-
-
-# @test
-# @bug 4731671
-# @build libraryCaller
-# @run shell SolarisRunpath.sh
-# @summary Verify that Solaris LD_LIBRARY_PATH rules are followed
-# @author Joseph D. Darcy
-
-# The launcher has been updated to properly take account of Solaris
-# LD_LIBRARY_PATH rules when constructing the runpath for the Java
-# executable.  That is, data model dependent LD_LIBRARY_PATH variables
-# are tested for and override LD_LIBRARY_PATH if present.  The current
-# launcher design relies on LD_LIBRARY_PATH settings to ensure the
-# proper jre/jdk libraries are opening during program execution.  In
-# the future, this dependence might be removed by having the vm
-# explicitly dlopen the needed files.  If that change occurs, this
-# test will be harmless but no long relevant.
-
-# A more robust test for Solaris SPARC would set the different
-# LD_LIBRARY_PATH variables while also varying the -d[32|64] options
-# to make sure the LD_LIBRARY_PATH of the *target* data model were
-# being respected.  That is "java -d64" should use the 64-bit
-# LD_LIBRARY_PATH while "java -d32" should use the 32-bit
-# LD_LIBRARY_PATH regardless of the data model of the "java" binary.
-# However, by default builds do not contain both 32 and 64 bit
-# components so such a test would often not be applicable.
-
-
-# If the test is not being run on a Solaris box, SPARC or x86, the
-# test succeeds immediately.
-
-OS=`uname -s`;
-
-case "$OS" in
-	SunOS )
-	PATHSEP=":"
-	;;
-
-	* )
-	echo "Not a Solaris environment; test vacuously succeeds."
-	exit 0;
-	;;
-esac
-
-# Verify directory context variables are set
-if [ "${TESTJAVA}" = "" ]
-then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-
-if [ "${TESTSRC}" = "" ]
-then
-  echo "TESTSRC not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-
-
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-
-# Construct paths to default Java executables
-JAVAC="$TESTJAVA/bin/javac"
-
-
-# Create our little Java test on the fly
-( printf "public class GetDataModel {"
-  printf "   public static void main(String argv[]) {"
-  printf "      System.out.println(System.getProperty(\"sun.arch.data.model\", \"none\"));"
-  printf "   }"
-  printf "}"
-) > GetDataModel.java
-
-$JAVAC GetDataModel.java
-
-
-# ARCH should be sparc or i386
-ARCH=`uname -p`
-case "$ARCH" in 
-	sparc | i386 )
-	;;
-
-	* )
-	echo "Unrecognized architecture; test fails."
-	exit 1
-esac
-
-# The following construction may not work as desired in a
-# 64-bit build.
-JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES${PATHSEP}."
-
-# Determine data model
-DM=`$JAVA GetDataModel`
-
-# verify DM is 32 or 64
-case "$DM" in 
-	32 )
-	ODM=64;
-	;;
-	
-	64 )
-	ODM=32;
-	;;
-
-	* )
-	echo "Unknown data model \"$DM\"; test fails."
-	exit 1
-esac
-
-# -------------------- Test 1 --------------------
-
-LD_LIBRARY_PATH=$TESTSRC/lib/$ARCH/lib$DM
-export LD_LIBRARY_PATH
-unset LD_LIBRARY_PATH_32
-unset LD_LIBRARY_PATH_64
-	
-# With plain LD_LIBRARY_PATH, result should always be 0
-RESULT=`$JAVA libraryCaller`
-if [ "${RESULT}" != "0" ]; 
-then
-	echo "Not using LD_LIBRARY_PATH; test fails."
-	exit 1
-fi
-
-# The following two tests sets both data model dependent
-# LD_LIBRARY_PATH variables individually.
-
-# -------------------- Test 2 --------------------
-
-# Set opposite data model variable; should return same result
-# as plain LD_LIBRARY_PATH.
-
-if [ "${DM}" = "32"  ]; then
-	LD_LIBRARY_PATH_64=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
-	export LD_LIBRARY_PATH_64
-else
-	LD_LIBRARY_PATH_32=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
-	export LD_LIBRARY_PATH_32
-fi
-
-RESULT=`$JAVA libraryCaller`
-if [ "${RESULT}" != "0" ]; 
-then
-	echo "Using LD_LIBRARY_PATH_$ODM for $DM binary;"
-	echo "test fails."
-	exit 1
-fi
-
-unset LD_LIBRARY_PATH_32
-unset LD_LIBRARY_PATH_64
-
-# -------------------- Test 3 --------------------
-
-# Set appropriate data model variable; result should match
-# data model.
-if [ "${DM}" = "32"  ]; then
-	LD_LIBRARY_PATH_32=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
-	export LD_LIBRARY_PATH_32
-else
-	LD_LIBRARY_PATH_64=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
-	export LD_LIBRARY_PATH_64
-fi
-
-RESULT=`$JAVA libraryCaller`
-if [ "${RESULT}" != "$DM" ]; 
-then
-	echo "Data model dependent LD_LIBRARY_PATH_$DM"
-	echo "not overriding LD_LIBRARY_PATH; test fails."
-	exit 1
-fi
-
-unset LD_LIBRARY_PATH
-unset LD_LIBRARY_PATH_32
-unset LD_LIBRARY_PATH_64
-
-# -------------------- Test 4 --------------------
-
-# Have only data model dependent LD_LIBRARY_PATH set; result
-# should match data model.
-
-if [ "${DM}" = "32"  ]; then
-	LD_LIBRARY_PATH_32=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
-	export LD_LIBRARY_PATH_32
-else
-	LD_LIBRARY_PATH_64=$TESTSRC/lib/$ARCH/lib$DM/lib$DM
-	export LD_LIBRARY_PATH_64
-fi
-
-RESULT=`$JAVA libraryCaller`
-if [ "${RESULT}" != "$DM" ]; 
-then
-	echo "Not using data-model dependent LD_LIBRARY_PATH; test fails."
-	exit 1
-fi
-
-# All tests have passed
-exit 0
--- a/jdk/test/tools/launcher/TestHelper.java	Tue Dec 01 08:51:16 2009 -0800
+++ b/jdk/test/tools/launcher/TestHelper.java	Tue Dec 01 08:54:10 2009 -0800
@@ -39,18 +39,36 @@
  */
 public enum TestHelper {
     INSTANCE;
-    static final String JAVAHOME = System.getProperty("java.home", ".");
+    static final String JAVAHOME = System.getProperty("java.home");
     static final boolean isSDK = JAVAHOME.endsWith("jre");
     static final String javaCmd;
+    static final String java64Cmd;
     static final String javacCmd;
     static final JavaCompiler compiler;
 
-    static final boolean debug = Boolean.getBoolean("Arrrghs.Debug");
+    static final boolean debug = Boolean.getBoolean("TestHelper.Debug");
     static final boolean isWindows =
             System.getProperty("os.name", "unknown").startsWith("Windows");
+    static final boolean is64Bit =
+            System.getProperty("sun.arch.data.model").equals("64");
+    static final boolean is32Bit =
+            System.getProperty("sun.arch.data.model").equals("32");
+    static final boolean isSolaris =
+            System.getProperty("os.name", "unknown").startsWith("SunOS");
+    static final boolean isLinux =
+            System.getProperty("os.name", "unknown").startsWith("Linux");
+    static final boolean isDualMode = isSolaris;
+    static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc");
+
     static int testExitValue = 0;
 
     static {
+        if (is64Bit && is32Bit) {
+            throw new RuntimeException("arch model cannot be both 32 and 64 bit");
+        }
+        if (!is64Bit && !is32Bit) {
+            throw new RuntimeException("arch model is not 32 or 64 bit ?");
+        }
         compiler = ToolProvider.getSystemJavaCompiler();
         File binDir = (isSDK) ? new File((new File(JAVAHOME)).getParentFile(), "bin")
             : new File(JAVAHOME, "bin");
@@ -69,6 +87,33 @@
         if (!javacCmdFile.canExecute()) {
             throw new RuntimeException("java <" + javacCmd + "> must exist");
         }
+        if (isSolaris) {
+            File sparc64BinDir = new File(binDir,isSparc ? "sparcv9" : "amd64");
+            File java64CmdFile= new File(sparc64BinDir, "java");
+            if (java64CmdFile.exists() && java64CmdFile.canExecute()) {
+                java64Cmd = java64CmdFile.getAbsolutePath();
+            } else {
+                java64Cmd = null;
+            }
+        } else {
+            java64Cmd = null;
+        }
+    }
+
+    /*
+     * usually the jre/lib/arch-name is the same as os.arch, except for x86.
+     */
+    static String getJreArch() {
+        String arch = System.getProperty("os.arch");
+        return arch.equals("x86") ? "i386" : arch;
+    }
+
+    /*
+     * A convenience method to create a jar with jar file name and defs
+     */
+    static void createJar(File jarName, String... mainDefs)
+            throws FileNotFoundException{
+        createJar(null, jarName, new File("Foo"), mainDefs);
     }
 
     /*
@@ -123,16 +168,23 @@
         }
     }
 
+    static TestResult doExec(String...cmds) {
+        return doExec(null, cmds);
+    }
+
     /*
      * A method which executes a java cmd and returns the results in a container
      */
-    static TestResult doExec(String...cmds) {
+    static TestResult doExec(Map<String, String> envToSet, String...cmds) {
         String cmdStr = "";
         for (String x : cmds) {
             cmdStr = cmdStr.concat(x + " ");
         }
         ProcessBuilder pb = new ProcessBuilder(cmds);
         Map<String, String> env = pb.environment();
+        if (envToSet != null) {
+            env.putAll(envToSet);
+        }
         BufferedReader rdr = null;
         try {
             List<String> outputList = new ArrayList<String>();
@@ -163,21 +215,25 @@
         List<String> testOutput;
 
         public TestResult(String str, int rv, List<String> oList) {
-            status = new StringBuilder(str);
+            status = new StringBuilder("Executed command: " + str + "\n");
             exitValue = rv;
             testOutput = oList;
         }
 
+        void appendStatus(String x) {
+            status = status.append("  " + x + "\n");
+        }
+
         void checkNegative() {
             if (exitValue == 0) {
-                status = status.append("  Error: test must not return 0 exit value");
+                appendStatus("Error: test must not return 0 exit value");
                 testExitValue++;
             }
         }
 
         void checkPositive() {
             if (exitValue != 0) {
-                status = status.append("  Error: test did not return 0 exit value");
+                appendStatus("Error: test did not return 0 exit value");
                 testExitValue++;
             }
         }
@@ -188,7 +244,7 @@
 
         boolean isZeroOutput() {
             if (!testOutput.isEmpty()) {
-                status = status.append("  Error: No message from cmd please");
+                appendStatus("Error: No message from cmd please");
                 testExitValue++;
                 return false;
             }
@@ -197,19 +253,20 @@
 
         boolean isNotZeroOutput() {
             if (testOutput.isEmpty()) {
-                status = status.append("  Error: Missing message");
+                appendStatus("Error: Missing message");
                 testExitValue++;
                 return false;
             }
             return true;
         }
 
+        @Override
         public String toString() {
-            if (debug) {
-                for (String x : testOutput) {
-                    status = status.append(x + "\n");
-                }
+            status = status.append("++++Test Output Begin++++\n");
+            for (String x : testOutput) {
+                appendStatus(x);
             }
+            status = status.append("++++Test Output End++++\n");
             return status.toString();
         }
 
@@ -219,7 +276,18 @@
                     return true;
                 }
             }
-            status = status.append("   Error: string <" + str + "> not found ");
+            appendStatus("Error: string <" + str + "> not found");
+            testExitValue++;
+            return false;
+        }
+
+        boolean matches(String stringToMatch) {
+          for (String x : testOutput) {
+                if (x.matches(stringToMatch)) {
+                    return true;
+                }
+            }
+            appendStatus("Error: string <" + stringToMatch + "> not found");
             testExitValue++;
             return false;
         }
--- a/jdk/test/tools/launcher/libraryCaller.c	Tue Dec 01 08:51:16 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-/*
- *
- *
- * Indictly used by SolarisRunpath.sh; this file is used to generate
- * the shared objects:
- *
- * ./lib/sparc/lib32/liblibrary.so
- * ./lib/sparc/lib32/lib32/liblibrary.so
- *
- * ./lib/sparc/lib64/liblibrary.so
- * ./lib/sparc/lib64/lib64/liblibrary.so
- *
- * ./lib/i386/lib32/liblibrary.so
- * ./lib/i386/lib32/lib32/liblibrary.so
- *
- * The function defined below returns either 0 or the size of an
- * integer in the data model used to compile the file (32 for ILP; 64
- * for LP).  The libraries in ./lib/$ARCH/lib$DM return 0; those in
- * ./lib/$ARCH/lib$DM/lib$DM return 32 or 64.
- */
-
-
-#include <jni.h>
-#include "libraryCaller.h"
-
-#ifndef RETURN_VALUE
-#define RETURN_VALUE 0
-#endif
-
-JNIEXPORT jint JNICALL Java_libraryCaller_number
-(JNIEnv *je, jclass jc) {
-  return RETURN_VALUE;
-}
--- a/jdk/test/tools/launcher/libraryCaller.h	Tue Dec 01 08:51:16 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-/* DO NOT EDIT THIS FILE - it is machine generated */
-
-#include <jni.h>
-/* Header for class libraryCaller */
-
-#ifndef _Included_libraryCaller
-#define _Included_libraryCaller
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     libraryCaller
- * Method:    number
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_libraryCaller_number
-  (JNIEnv *, jclass);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
--- a/jdk/test/tools/launcher/libraryCaller.java	Tue Dec 01 08:51:16 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-
-/*
- *
- *
- * Used by SolarisRunpath.sh to help test if the launcher fully
- * respects Solaris LD_LIBRARY_PATH semantics.  The ./lib directory is
- * structured so that the results of the dynamically linked number
- * method varies depending on the value the data model dependent
- * LD_LIBRARY_PATH variable.
- */
-
-
-
-class libraryCaller {
-    static {
-        System.loadLibrary("library");
-    }
-    static native int number();
-
-    public static void main(String argv[]) {
-        System.out.println(number());
-    }
-}