changeset 2687:043d2736d44c

Merge
author lana
date Sun, 29 Aug 2010 22:41:28 -0700
parents 17a5d84b7561 62d37c19c213
children 80a8742483bf df049d0b973f 448387146bb8 d4012b86a6e9 7f8a9157544a 8af4eca2e2be 72136d9a079f 48f0b94573c8
files src/share/classes/sun/java2d/pisces/PiscesMath.java src/share/classes/sun/java2d/pisces/Transform4.java test/tools/pack200/Pack200Simple.sh test/tools/pack200/SegmentLimit.java
diffstat 99 files changed, 13052 insertions(+), 2732 deletions(-) [+]
line wrap: on
line diff
--- a/make/common/shared/Defs-windows.gmk	Thu Aug 26 16:17:02 2010 -0700
+++ b/make/common/shared/Defs-windows.gmk	Sun Aug 29 22:41:28 2010 -0700
@@ -89,7 +89,7 @@
 $(shell $(CYGPATH_CMD) $1 2> $(DEV_NULL))
 endef
 define OptFullPath
-$(shell if [ "$1" != "" -a -d "$1" ]; then $(CYGPATH_CMD) "$1"; else echo "$1"; fi)
+$(shell if [ "$1" != "" -a -d "$1" ]; then $(CYGPATH_CMD) "$1" 2> $(DEV_NULL); else echo "$1"; fi)
 endef
 else
 # Temporary until we upgrade to MKS 8.7, MKS pwd returns mixed mode path
--- a/make/common/shared/Defs.gmk	Thu Aug 26 16:17:02 2010 -0700
+++ b/make/common/shared/Defs.gmk	Sun Aug 29 22:41:28 2010 -0700
@@ -136,15 +136,20 @@
 $(shell echo $1 | sed -e 's@[^0-9]*\([0-9][0-9]*\.[0-9][.0-9]*\).*@\1@' )
 endef
 
+# Return one part of the version numbers, watch out for non digits.
+define VersionWord # Number Version
+$(word $1,$(subst ., ,$(subst -, ,$2)))
+endef
+
 # Given a major.minor.micro version, return the major, minor, or micro number
 define MajorVersion
-$(if $(word 1, $(subst ., ,$1)),$(word 1, $(subst ., ,$1)),0)
+$(if $(call VersionWord,1,$1),$(call VersionWord,1,$1),0)
 endef
 define MinorVersion
-$(if $(word 2, $(subst ., ,$1)),$(word 2, $(subst ., ,$1)),0)
+$(if $(call VersionWord,2,$1),$(call VersionWord,2,$1),0)
 endef
 define MicroVersion
-$(if $(word 3, $(subst ., ,$1)),$(word 3, $(subst ., ,$1)),0)
+$(if $(call VersionWord,3,$1),$(call VersionWord,3,$1),0)
 endef
 
 # Macro that returns missing, same, newer, or older $1=version $2=required
--- a/make/jdk_generic_profile.sh	Thu Aug 26 16:17:02 2010 -0700
+++ b/make/jdk_generic_profile.sh	Sun Aug 29 22:41:28 2010 -0700
@@ -340,6 +340,10 @@
 export PATH
 
 # Export variables required for Zero
+if [ "${SHARK_BUILD}" = true ] ; then
+  ZERO_BUILD=true
+  export ZERO_BUILD
+fi
 if [ "${ZERO_BUILD}" = true ] ; then
   # ZERO_LIBARCH is the name of the architecture-specific
   # subdirectory under $JAVA_HOME/jre/lib
@@ -417,4 +421,55 @@
   fi
   export LIBFFI_CFLAGS
   export LIBFFI_LIBS
+
+  # LLVM_CFLAGS, LLVM_LDFLAGS and LLVM_LIBS tell the compiler how to
+  # compile and link against LLVM
+  if [ "${SHARK_BUILD}" = true ] ; then
+    if [ "${LLVM_CONFIG}" = "" ] ; then
+      LLVM_CONFIG=$(which llvm-config 2>/dev/null)
+    fi
+    if [ ! -x "${LLVM_CONFIG}" ] ; then
+      echo "ERROR: Unable to locate llvm-config"
+      exit 1
+    fi
+    llvm_components="jit engine nativecodegen"
+
+    unset LLVM_CFLAGS
+    for flag in $("${LLVM_CONFIG}" --cxxflags $llvm_components); do
+      if echo "${flag}" | grep -q '^-[ID]'; then
+        if [ "${flag}" != "-D_DEBUG" ] ; then
+          if [ "${LLVM_CFLAGS}" != "" ] ; then
+            LLVM_CFLAGS="${LLVM_CFLAGS} "
+          fi
+          LLVM_CFLAGS="${LLVM_CFLAGS}${flag}"
+        fi
+      fi
+    done
+    llvm_version=$("${LLVM_CONFIG}" --version | sed 's/\.//; s/svn.*//')
+    LLVM_CFLAGS="${LLVM_CFLAGS} -DSHARK_LLVM_VERSION=${llvm_version}"
+
+    unset LLVM_LDFLAGS
+    for flag in $("${LLVM_CONFIG}" --ldflags $llvm_components); do
+      if echo "${flag}" | grep -q '^-L'; then
+        if [ "${LLVM_LDFLAGS}" != "" ] ; then
+          LLVM_LDFLAGS="${LLVM_LDFLAGS} "
+        fi
+        LLVM_LDFLAGS="${LLVM_LDFLAGS}${flag}"
+      fi
+    done
+
+    unset LLVM_LIBS
+    for flag in $("${LLVM_CONFIG}" --libs $llvm_components); do
+      if echo "${flag}" | grep -q '^-l'; then
+        if [ "${LLVM_LIBS}" != "" ] ; then
+          LLVM_LIBS="${LLVM_LIBS} "
+        fi
+        LLVM_LIBS="${LLVM_LIBS}${flag}"
+      fi
+    done
+
+    export LLVM_CFLAGS
+    export LLVM_LDFLAGS
+    export LLVM_LIBS
+  fi
 fi
--- a/make/sun/javazic/tzdata/VERSION	Thu Aug 26 16:17:02 2010 -0700
+++ b/make/sun/javazic/tzdata/VERSION	Sun Aug 29 22:41:28 2010 -0700
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2010i
+tzdata2010l
--- a/make/sun/javazic/tzdata/africa	Thu Aug 26 16:17:02 2010 -0700
+++ b/make/sun/javazic/tzdata/africa	Sun Aug 29 22:41:28 2010 -0700
@@ -316,8 +316,25 @@
 # and can be found by searching for "winter" in their search engine
 # (at least today).
 
+# From Alexander Krivenyshev (2010-07-20):
+# According to News from Egypt -  Al-Masry Al-Youm Egypt's cabinet has
+# decided that Daylight Saving Time will not be used in Egypt during
+# Ramadan.
+#
+# Arabic translation:
+# "Clocks to go back during Ramadan--and then forward again"
+# <a href="http://www.almasryalyoum.com/en/news/clocks-go-back-during-ramadan-and-then-forward-again">
+# http://www.almasryalyoum.com/en/news/clocks-go-back-during-ramadan-and-then-forward-again
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_egypt02.html">
+# http://www.worldtimezone.com/dst_news/dst_news_egypt02.html
+# </a>
+
 Rule	Egypt	2008	only	-	Aug	lastThu	23:00s	0	-
 Rule	Egypt	2009	only	-	Aug	20	23:00s	0	-
+Rule	Egypt	2010	only	-	Aug	11	0:00	0	-
+Rule	Egypt	2010	only	-	Sep	10	0:00	1:00	S
 Rule	Egypt	2010	max	-	Sep	lastThu	23:00s	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
--- a/make/sun/javazic/tzdata/asia	Thu Aug 26 16:17:02 2010 -0700
+++ b/make/sun/javazic/tzdata/asia	Sun Aug 29 22:41:28 2010 -0700
@@ -2200,6 +2200,18 @@
 # "At 12:01am Friday, clocks in Israel and the West Bank will change to
 # 1:01am, while Gaza clocks will change at 12:01am Saturday morning."
 
+# From Steffen Thorsen (2010-08-11):
+# According to several sources, including
+# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=306795">
+# http://www.maannews.net/eng/ViewDetails.aspx?ID=306795
+# </a>
+# the clocks were set back one hour at 2010-08-11 00:00:00 local time in 
+# Gaza and the West Bank.
+# Some more background info:
+# <a href="http://www.timeanddate.com/news/time/westbank-gaza-end-dst-2010.html">
+# http://www.timeanddate.com/news/time/westbank-gaza-end-dst-2010.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
@@ -2220,6 +2232,7 @@
 Rule Palestine	2009	only	-	Mar	lastFri	0:00	1:00	S
 Rule Palestine	2010	max	-	Mar	lastSat	0:01	1:00	S
 Rule Palestine	2009	max	-	Sep	Fri>=1	2:00	0	-
+Rule Palestine	2010	only	-	Aug	11	0:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
--- a/make/sun/javazic/tzdata/australasia	Thu Aug 26 16:17:02 2010 -0700
+++ b/make/sun/javazic/tzdata/australasia	Sun Aug 29 22:41:28 2010 -0700
@@ -368,10 +368,10 @@
 
 # Micronesia
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Truk	10:07:08 -	LMT	1901
-			10:00	-	TRUT			# Truk Time
-Zone Pacific/Ponape	10:32:52 -	LMT	1901		# Kolonia
-			11:00	-	PONT			# Ponape Time
+Zone Pacific/Chuuk	10:07:08 -	LMT	1901
+			10:00	-	CHUT			# Chuuk Time
+Zone Pacific/Pohnpei	10:32:52 -	LMT	1901		# Kolonia
+			11:00	-	PONT			# Pohnpei Time
 Zone Pacific/Kosrae	10:51:56 -	LMT	1901
 			11:00	-	KOST	1969 Oct	# Kosrae Time
 			12:00	-	KOST	1999
--- a/make/sun/javazic/tzdata/backward	Thu Aug 26 16:17:02 2010 -0700
+++ b/make/sun/javazic/tzdata/backward	Sun Aug 29 22:41:28 2010 -0700
@@ -112,7 +112,9 @@
 Link	America/Denver		Navajo
 Link	Asia/Shanghai		PRC
 Link	Pacific/Pago_Pago	Pacific/Samoa
-Link	Pacific/Truk		Pacific/Yap
+Link	Pacific/Chuuk		Pacific/Yap
+Link	Pacific/Chuuk		Pacific/Truk
+Link	Pacific/Pohnpei		Pacific/Ponape
 Link	Europe/Warsaw		Poland
 Link	Europe/Lisbon		Portugal
 Link	Asia/Taipei		ROC
--- a/make/sun/javazic/tzdata/europe	Thu Aug 26 16:17:02 2010 -0700
+++ b/make/sun/javazic/tzdata/europe	Sun Aug 29 22:41:28 2010 -0700
@@ -1035,22 +1035,47 @@
 			2:00	EU	EE%sT
 
 # Finland
-#
+
 # From Hannu Strang (1994-09-25 06:03:37 UTC):
 # Well, here in Helsinki we're just changing from summer time to regular one,
 # and it's supposed to change at 4am...
+
+# From Janne Snabb (2010-0715):
 #
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger say Finland has switched at 02:00 standard time
-# since 1981.  Go with Strang instead.
+# I noticed that the Finland data is not accurate for years 1981 and 1982.
+# During these two first trial years the DST adjustment was made one hour
+# earlier than in forthcoming years. Starting 1983 the adjustment was made
+# according to the central European standards.
 #
+# This is documented in Heikki Oja: Aikakirja 2007, published by The Almanac
+# Office of University of Helsinki, ISBN 952-10-3221-9, available online (in
+# Finnish) at
+#
+# <a href="http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf">
+# http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf
+# </a>
+#
+# Page 105 (56 in PDF version) has a handy table of all past daylight savings
+# transitions. It is easy enough to interpret without Finnish skills.
+#
+# This is also confirmed by Finnish Broadcasting Company's archive at:
+#
+# <a href="http://www.yle.fi/elavaarkisto/?s=s&g=1&ag=5&t=&a=3401">
+# http://www.yle.fi/elavaarkisto/?s=s&g=1&ag=5&t=&a=3401
+# </a>
+#
+# The news clip from 1981 says that "the time between 2 and 3 o'clock does not
+# exist tonight."
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Finland	1942	only	-	Apr	3	0:00	1:00	S
 Rule	Finland	1942	only	-	Oct	3	0:00	0	-
+Rule	Finland	1981	1982	-	Mar	lastSun	2:00	1:00	S
+Rule	Finland	1981	1982	-	Sep	lastSun	3:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Europe/Helsinki	1:39:52 -	LMT	1878 May 31
 			1:39:52	-	HMT	1921 May    # Helsinki Mean Time
-			2:00	Finland	EE%sT	1981 Mar 29 2:00
+			2:00	Finland	EE%sT	1983
 			2:00	EU	EE%sT
 
 # Aaland Is
--- a/make/sun/javazic/tzdata/leapseconds	Thu Aug 26 16:17:02 2010 -0700
+++ b/make/sun/javazic/tzdata/leapseconds	Sun Aug 29 22:41:28 2010 -0700
@@ -82,9 +82,9 @@
 # FAX       : 33 (0) 1 40 51 22 91
 # Internet  : services.iers@obspm.fr
 #
-# Paris, 4 July 2009
+# Paris, 14 July 2010
 #
-# Bulletin C 38
+# Bulletin C 40
 #
 # To authorities responsible
 # for the measurement and
@@ -92,9 +92,9 @@
 #
 # INFORMATION ON UTC - TAI
 #
-# NO positive leap second will be introduced at the end of December 2009.
+# NO positive leap second will be introduced at the end of December 2010.
 # The difference between Coordinated Universal Time UTC and the
-# International Atomic Time TAI is :		
+# International Atomic Time TAI is :
 #
 # from 2009 January 1, 0h UTC, until further notice : UTC-TAI = -34 s
 #
@@ -104,6 +104,6 @@
 # will be no time step at the next possible date.
 #
 # Daniel GAMBIS
-# Director			
+# Director
 # Earth Orientation Center of IERS
 # Observatoire de Paris, France
--- a/make/sun/javazic/tzdata/northamerica	Thu Aug 26 16:17:02 2010 -0700
+++ b/make/sun/javazic/tzdata/northamerica	Sun Aug 29 22:41:28 2010 -0700
@@ -1346,6 +1346,83 @@
 # entry since our cutoff date of 1970, so we can move
 # America/Coral_Harbour to the 'backward' file.
 
+# From Mark Brader (2010-03-06):
+#
+# Currently the database has:
+#
+# # Ontario
+#
+# # From Paul Eggert (2006-07-09):
+# # Shanks & Pottenger write that since 1970 most of Ontario has been like
+# # Toronto.
+# # Thunder Bay skipped DST in 1973.
+# # Many smaller locales did not observe peacetime DST until 1974;
+# # Nipigon (EST) and Rainy River (CST) are the largest that we know of.
+#
+# In the (Toronto) Globe and Mail for Saturday, 1955-09-24, in the bottom
+# right corner of page 1, it says that Toronto will return to standard
+# time at 2 am Sunday morning (which agrees with the database), and that:
+#
+#     The one-hour setback will go into effect throughout most of Ontario,
+#     except in areas like Windsor which remains on standard time all year.
+#
+# Windsor is, of course, a lot larger than Nipigon.
+#
+# I only came across this incidentally.  I don't know if Windsor began
+# observing DST when Detroit did, or in 1974, or on some other date.
+#
+# By the way, the article continues by noting that:
+#
+#     Some cities in the United States have pushed the deadline back
+#     three weeks and will change over from daylight saving in October.
+
+# From Arthur David Olson (2010-07-17):
+#
+# "Standard Time and Time Zones in Canada" appeared in
+# The Journal of The Royal Astronomical Society of Canada,
+# volume 26, number 2 (February 1932) and, as of 2010-07-17,
+# was available at
+# <a href="http://adsabs.harvard.edu/full/1932JRASC..26...49S">
+# http://adsabs.harvard.edu/full/1932JRASC..26...49S
+# </a>
+#
+# It includes the text below (starting on page 57):
+#
+#   A list of the places in Canada using daylight saving time would
+# require yearly revision. From information kindly furnished by
+# the provincial governments and by the postmasters in many cities
+# and towns, it is found that the following places used daylight sav-
+# ing in 1930. The information for the province of Quebec is definite,
+# for the other provinces only approximate:
+#
+# 	Province	Daylight saving time used
+# Prince Edward Island	Not used.
+# Nova Scotia		In Halifax only.
+# New Brunswick		In St. John only.
+# Quebec		In the following places:
+# 			Montreal	Lachine
+# 			Quebec		Mont-Royal
+# 			Levis		Iberville
+# 			St. Lambert	Cap de la Madeleine
+# 			Verdun		Loretteville
+# 			Westmount	Richmond
+# 			Outremont	St. Jerome
+# 			Longueuil	Greenfield Park
+# 			Arvida		Waterloo
+# 			Chambly-Canton	Beaulieu
+# 			Melbourne	La Tuque
+# 			St. Theophile	Buckingham
+# Ontario		Used generally in the cities and towns along
+# 			the southerly part of the province. Not
+# 			used in the northwesterlhy part.
+# Manitoba		Not used.
+# Saskatchewan		In Regina only.
+# Alberta		Not used.
+# British Columbia	Not used.
+#
+#   With some exceptions, the use of daylight saving may be said to be limited
+# to those cities and towns lying between Quebec city and Windsor, Ont.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Toronto	1919	only	-	Mar	30	23:30	1:00	D
 Rule	Toronto	1919	only	-	Oct	26	0:00	0	S
@@ -2111,7 +2188,44 @@
 			-8:00	-	PST	1970
 			-7:00	Mexico	M%sT	1999
 			-7:00	-	MST
+
+# From Alexander Krivenyshev (2010-04-21):
+# According to news, Bah&iacute;a de Banderas (Mexican state of Nayarit)
+# changed time zone UTC-7 to new time zone UTC-6 on April 4, 2010 (to
+# share the same time zone as nearby city Puerto Vallarta, Jalisco).
+#
+# (Spanish)
+# Bah&iacute;a de Banderas homologa su horario al del centro del
+# pa&iacute;s, a partir de este domingo
+# <a href="http://www.nayarit.gob.mx/notes.asp?id=20748">
+# http://www.nayarit.gob.mx/notes.asp?id=20748
+# </a>
+#
+# Bah&iacute;a de Banderas homologa su horario con el del Centro del
+# Pa&iacute;s
+# <a href="http://www.bahiadebanderas.gob.mx/principal/index.php?option=com_content&view=article&id=261:bahia-de-banderas-homologa-su-horario-con-el-del-centro-del-pais&catid=42:comunicacion-social&Itemid=50">
+# http://www.bahiadebanderas.gob.mx/principal/index.php?option=com_content&view=article&id=261:bahia-de-banderas-homologa-su-horario-con-el-del-centro-del-pais&catid=42:comunicacion-social&Itemid=50"
+# </a>
+#
+# (English)
+# Puerto Vallarta and Bah&iacute;a de Banderas: One Time Zone
+# <a href="http://virtualvallarta.com/puertovallarta/puertovallarta/localnews/2009-12-03-Puerto-Vallarta-and-Bahia-de-Banderas-One-Time-Zone.shtml">
+# http://virtualvallarta.com/puertovallarta/puertovallarta/localnews/2009-12-03-Puerto-Vallarta-and-Bahia-de-Banderas-One-Time-Zone.shtml
+# </a>
+#
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_mexico08.html">
+# http://www.worldtimezone.com/dst_news/dst_news_mexico08.html
+# </a>
+#
+# "Mexico's Senate approved the amendments to the Mexican Schedule System that
+# will allow Bah&iacute;a de Banderas and Puerto Vallarta to share the same time
+# zone ..."
 # Baja California Sur, Nayarit, Sinaloa
+
+# From Arthur David Olson (2010-05-01):
+# Use "Bahia_Banderas" to keep the name to fourteen characters.
+
 Zone America/Mazatlan	-7:05:40 -	LMT	1921 Dec 31 23:54:20
 			-7:00	-	MST	1927 Jun 10 23:00
 			-6:00	-	CST	1930 Nov 15
@@ -2122,6 +2236,19 @@
 			-7:00	-	MST	1949 Jan 14
 			-8:00	-	PST	1970
 			-7:00	Mexico	M%sT
+
+Zone America/Bahia_Banderas	-7:01:00 -	LMT	1921 Dec 31 23:59:00
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1942 Apr 24
+			-7:00	-	MST	1949 Jan 14
+			-8:00	-	PST	1970
+			-7:00	Mexico	M%sT	2010 Apr 4 2:00
+			-6:00	Mexico	C%sT
+
 # Baja California (near US border)
 Zone America/Tijuana	-7:48:04 -	LMT	1922 Jan  1  0:11:56
 			-7:00	-	MST	1924
--- a/make/sun/javazic/tzdata/zone.tab	Thu Aug 26 16:17:02 2010 -0700
+++ b/make/sun/javazic/tzdata/zone.tab	Sun Aug 29 22:41:28 2010 -0700
@@ -199,8 +199,8 @@
 FI	+6010+02458	Europe/Helsinki
 FJ	-1808+17825	Pacific/Fiji
 FK	-5142-05751	Atlantic/Stanley
-FM	+0725+15147	Pacific/Truk	Truk (Chuuk) and Yap
-FM	+0658+15813	Pacific/Ponape	Ponape (Pohnpei)
+FM	+0725+15147	Pacific/Chuuk	Chuuk (Truk) and Yap
+FM	+0658+15813	Pacific/Pohnpei	Pohnpei (Ponape)
 FM	+0519+16259	Pacific/Kosrae	Kosrae
 FO	+6201-00646	Atlantic/Faroe
 FR	+4852+00220	Europe/Paris
@@ -310,6 +310,7 @@
 MX	+2904-11058	America/Hermosillo	Mountain Standard Time - Sonora
 MX	+3232-11701	America/Tijuana	US Pacific Time - Baja California near US border
 MX	+3018-11452	America/Santa_Isabel	Mexican Pacific Time - Baja California away from US border
+MX	+2048-10515	America/Bahia_Banderas	Mexican Central Time - Bahia de Banderas
 MY	+0310+10142	Asia/Kuala_Lumpur	peninsular Malaysia
 MY	+0133+11020	Asia/Kuching	Sabah & Sarawak
 MZ	-2558+03235	Africa/Maputo
--- a/src/share/classes/com/sun/java/util/jar/pack/Attribute.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/com/sun/java/util/jar/pack/Attribute.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
 
 import java.io.*;
 import java.util.*;
-import com.sun.java.util.jar.pack.Package.Class;
 import com.sun.java.util.jar.pack.ConstantPool.*;
 
 /**
@@ -96,20 +95,20 @@
         return this.def.compareTo(that.def);
     }
 
-    static private final byte[] noBytes = {};
-    static private final HashMap canonLists = new HashMap();
-    static private final HashMap attributes = new HashMap();
-    static private final HashMap standardDefs = new HashMap();
+    private static final byte[] noBytes = {};
+    private static final Map<List<Attribute>, List<Attribute>> canonLists = new HashMap<>();
+    private static final Map<Layout, Attribute> attributes = new HashMap<>();
+    private static final Map<Layout, Attribute> standardDefs = new HashMap<>();
 
     // Canonicalized lists of trivial attrs (Deprecated, etc.)
     // are used by trimToSize, in order to reduce footprint
     // of some common cases.  (Note that Code attributes are
     // always zero size.)
-    public static List getCanonList(List al) {
+    public static List getCanonList(List<Attribute> al) {
         synchronized (canonLists) {
-            List cl = (List) canonLists.get(al);
+            List<Attribute> cl = canonLists.get(al);
             if (cl == null) {
-                cl = new ArrayList(al.size());
+                cl = new ArrayList<>(al.size());
                 cl.addAll(al);
                 cl = Collections.unmodifiableList(cl);
                 canonLists.put(al, cl);
@@ -122,7 +121,7 @@
     public static Attribute find(int ctype, String name, String layout) {
         Layout key = Layout.makeKey(ctype, name, layout);
         synchronized (attributes) {
-            Attribute a = (Attribute) attributes.get(key);
+            Attribute a = attributes.get(key);
             if (a == null) {
                 a = new Layout(ctype, name, layout).canonicalInstance();
                 attributes.put(key, a);
@@ -131,24 +130,29 @@
         }
     }
 
-    public static Object keyForLookup(int ctype, String name) {
+    public static Layout keyForLookup(int ctype, String name) {
         return Layout.makeKey(ctype, name);
     }
 
     // Find canonical empty attribute with given ctype and name,
     // and with the standard layout.
-    public static Attribute lookup(Map defs, int ctype, String name) {
-        if (defs == null)  defs = standardDefs;
-        return (Attribute) defs.get(Layout.makeKey(ctype, name));
+    public static Attribute lookup(Map<Layout, Attribute> defs, int ctype,
+            String name) {
+        if (defs == null) {
+            defs = standardDefs;
+        }
+        return defs.get(Layout.makeKey(ctype, name));
     }
-    public static Attribute define(Map defs, int ctype, String name, String layout) {
+
+    public static Attribute define(Map<Layout, Attribute> defs, int ctype,
+            String name, String layout) {
         Attribute a = find(ctype, name, layout);
         defs.put(Layout.makeKey(ctype, name), a);
         return a;
     }
 
     static {
-        Map sd = standardDefs;
+        Map<Layout, Attribute> sd = standardDefs;
         define(sd, ATTR_CONTEXT_CLASS, "Signature", "RSH");
         define(sd, ATTR_CONTEXT_CLASS, "Synthetic", "");
         define(sd, ATTR_CONTEXT_CLASS, "Deprecated", "");
@@ -244,7 +248,7 @@
              +"\n    ()[] ]"
              )
         };
-        Map sd = standardDefs;
+        Map<Layout, Attribute> sd = standardDefs;
         String defaultLayout     = mdLayouts[2];
         String annotationsLayout = mdLayouts[1] + mdLayouts[2];
         String paramsLayout      = mdLayouts[0] + annotationsLayout;
@@ -275,10 +279,6 @@
         return null;
     }
 
-    public static Map getStandardDefs() {
-        return new HashMap(standardDefs);
-    }
-
     /** Base class for any attributed object (Class, Field, Method, Code).
      *  Flags are included because they are used to help transmit the
      *  presence of attributes.  That is, flags are a mix of modifier
@@ -291,7 +291,7 @@
         protected abstract Entry[] getCPMap();
 
         protected int flags;             // defined here for convenience
-        protected List attributes;
+        protected List<Attribute> attributes;
 
         public int attributeSize() {
             return (attributes == null) ? 0 : attributes.size();
@@ -301,16 +301,15 @@
             if (attributes == null) {
                 return;
             }
-            if (attributes.size() == 0) {
+            if (attributes.isEmpty()) {
                 attributes = null;
                 return;
             }
             if (attributes instanceof ArrayList) {
-                ArrayList al = (ArrayList) attributes;
+                ArrayList<Attribute> al = (ArrayList<Attribute>)attributes;
                 al.trimToSize();
                 boolean allCanon = true;
-                for (Iterator i = al.iterator(); i.hasNext(); ) {
-                    Attribute a = (Attribute) i.next();
+                for (Attribute a : al) {
                     if (!a.isCanonical()) {
                         allCanon = false;
                     }
@@ -330,9 +329,9 @@
 
         public void addAttribute(Attribute a) {
             if (attributes == null)
-                attributes = new ArrayList(3);
+                attributes = new ArrayList<>(3);
             else if (!(attributes instanceof ArrayList))
-                attributes = new ArrayList(attributes);  // unfreeze it
+                attributes = new ArrayList<>(attributes);  // unfreeze it
             attributes.add(a);
         }
 
@@ -340,32 +339,31 @@
             if (attributes == null)       return null;
             if (!attributes.contains(a))  return null;
             if (!(attributes instanceof ArrayList))
-                attributes = new ArrayList(attributes);  // unfreeze it
+                attributes = new ArrayList<>(attributes);  // unfreeze it
             attributes.remove(a);
             return a;
         }
 
         public Attribute getAttribute(int n) {
-            return (Attribute) attributes.get(n);
+            return attributes.get(n);
         }
 
-        protected void visitRefs(int mode, Collection refs) {
+        protected void visitRefs(int mode, Collection<Entry> refs) {
             if (attributes == null)  return;
-            for (Iterator i = attributes.iterator(); i.hasNext(); ) {
-                Attribute a = (Attribute) i.next();
+            for (Attribute a : attributes) {
                 a.visitRefs(this, mode, refs);
             }
         }
 
-        static final List noAttributes = Arrays.asList(new Object[0]);
+        static final List<Attribute> noAttributes = Arrays.asList(new Attribute[0]);
 
-        public List getAttributes() {
+        public List<Attribute> getAttributes() {
             if (attributes == null)
                 return noAttributes;
             return attributes;
         }
 
-        public void setAttributes(List attrList) {
+        public void setAttributes(List<Attribute> attrList) {
             if (attrList.isEmpty())
                 attributes = null;
             else
@@ -374,8 +372,7 @@
 
         public Attribute getAttribute(String attrName) {
             if (attributes == null)  return null;
-            for (Iterator i = attributes.iterator(); i.hasNext(); ) {
-                Attribute a = (Attribute) i.next();
+            for (Attribute a : attributes) {
                 if (a.name().equals(attrName))
                     return a;
             }
@@ -384,8 +381,7 @@
 
         public Attribute getAttribute(Layout attrDef) {
             if (attributes == null)  return null;
-            for (Iterator i = attributes.iterator(); i.hasNext(); ) {
-                Attribute a = (Attribute) i.next();
+            for (Attribute a : attributes) {
                 if (a.layout() == attrDef)
                     return a;
             }
@@ -457,14 +453,8 @@
         public String layout() { return layout; }
         public Attribute canonicalInstance() { return canon; }
 
-        // Cache of name reference.
-        private Entry nameRef;   // name, for use by visitRefs
         public Entry getNameRef() {
-            Entry nameRef = this.nameRef;
-            if (nameRef == null) {
-                this.nameRef = nameRef = ConstantPool.getUtf8Entry(name());
-            }
-            return nameRef;
+            return ConstantPool.getUtf8Entry(name());
         }
 
         public boolean isEmpty() { return layout == ""; }
@@ -834,14 +824,14 @@
     */
     static //private
     Layout.Element[] tokenizeLayout(Layout self, int curCble, String layout) {
-        ArrayList col = new ArrayList(layout.length());
+        ArrayList<Layout.Element> col = new ArrayList<>(layout.length());
         tokenizeLayout(self, curCble, layout, col);
         Layout.Element[] res = new Layout.Element[col.size()];
         col.toArray(res);
         return res;
     }
     static //private
-    void tokenizeLayout(Layout self, int curCble, String layout, ArrayList col) {
+    void tokenizeLayout(Layout self, int curCble, String layout, ArrayList<Layout.Element> col) {
         boolean prevBCI = false;
         for (int len = layout.length(), i = 0; i < len; ) {
             int start = i;
@@ -899,7 +889,7 @@
             case 'T': // union: 'T' any_int union_case* '(' ')' '[' body ']'
                 kind = EK_UN;
                 i = tokenizeSInt(e, layout, i);
-                ArrayList cases = new ArrayList();
+                ArrayList<Layout.Element> cases = new ArrayList<>();
                 for (;;) {
                     // Keep parsing cases until we hit the default case.
                     if (layout.charAt(i++) != '(')
@@ -1053,7 +1043,7 @@
     }
     static //private
     String[] splitBodies(String layout) {
-        ArrayList bodies = new ArrayList();
+        ArrayList<String> bodies = new ArrayList<>();
         // Parse several independent layout bodies:  "[foo][bar]...[baz]"
         for (int i = 0; i < layout.length(); i++) {
             if (layout.charAt(i++) != '[')
@@ -1132,7 +1122,9 @@
     int parseIntBefore(String layout, int dash) {
         int end = dash;
         int beg = end;
-        while (beg > 0 && isDigit(layout.charAt(beg-1)))  --beg;
+        while (beg > 0 && isDigit(layout.charAt(beg-1))) {
+            --beg;
+        }
         if (beg == end)  return Integer.parseInt("empty");
         // skip backward over a sign
         if (beg >= 1 && layout.charAt(beg-1) == '-')  --beg;
@@ -1145,7 +1137,9 @@
         int end = beg;
         int limit = layout.length();
         if (end < limit && layout.charAt(end) == '-')  ++end;
-        while (end < limit && isDigit(layout.charAt(end)))  ++end;
+        while (end < limit && isDigit(layout.charAt(end))) {
+            ++end;
+        }
         if (beg == end)  return Integer.parseInt("empty");
         return Integer.parseInt(layout.substring(beg, end));
     }
--- a/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
 
 package com.sun.java.util.jar.pack;
 
-import java.io.*;
 import java.util.*;
 
 /**
@@ -40,20 +39,13 @@
         return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
     }
 
-    // Uniquification tables for factory methods:
-    private static final HashMap utf8Entries       = new HashMap();
-    private static final HashMap classEntries      = new HashMap();
-    private static final HashMap literalEntries    = new HashMap();
-    private static final HashMap signatureEntries  = new HashMap();
-    private static final HashMap descriptorEntries = new HashMap();
-    private static final HashMap memberEntries     = new HashMap();
-
     /** Factory for Utf8 string constants.
      *  Used for well-known strings like "SourceFile", "<init>", etc.
      *  Also used to back up more complex constant pool entries, like Class.
      */
     public static synchronized Utf8Entry getUtf8Entry(String value) {
-        Utf8Entry e = (Utf8Entry) utf8Entries.get(value);
+        Map<String, Utf8Entry> utf8Entries  = Utils.getUtf8Entries();
+        Utf8Entry e = utf8Entries.get(value);
         if (e == null) {
             e = new Utf8Entry(value);
             utf8Entries.put(e.stringValue(), e);
@@ -62,9 +54,10 @@
     }
     /** Factory for Class constants. */
     public static synchronized ClassEntry getClassEntry(String name) {
-        ClassEntry e = (ClassEntry) classEntries.get(name);
+        Map<String, ClassEntry> classEntries = Utils.getClassEntries();
+        ClassEntry e = classEntries.get(name);
         if (e == null) {
-            e = (ClassEntry) new ClassEntry(getUtf8Entry(name));
+            e = new ClassEntry(getUtf8Entry(name));
             assert(name.equals(e.stringValue()));
             classEntries.put(e.stringValue(), e);
         }
@@ -72,7 +65,8 @@
     }
     /** Factory for literal constants (String, Integer, etc.). */
     public static synchronized LiteralEntry getLiteralEntry(Comparable value) {
-        LiteralEntry e = (LiteralEntry) literalEntries.get(value);
+        Map<Object, LiteralEntry> literalEntries = Utils.getLiteralEntries();
+        LiteralEntry e = literalEntries.get(value);
         if (e == null) {
             if (value instanceof String)
                 e = new StringEntry(getUtf8Entry((String)value));
@@ -89,7 +83,8 @@
 
     /** Factory for signature (type) constants. */
     public static synchronized SignatureEntry getSignatureEntry(String type) {
-        SignatureEntry e = (SignatureEntry) signatureEntries.get(type);
+        Map<String, SignatureEntry> signatureEntries = Utils.getSignatureEntries();
+        SignatureEntry e = signatureEntries.get(type);
         if (e == null) {
             e = new SignatureEntry(type);
             assert(e.stringValue().equals(type));
@@ -104,8 +99,9 @@
 
     /** Factory for descriptor (name-and-type) constants. */
     public static synchronized DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, SignatureEntry typeRef) {
+        Map<String, DescriptorEntry> descriptorEntries = Utils.getDescriptorEntries();
         String key = DescriptorEntry.stringValueOf(nameRef, typeRef);
-        DescriptorEntry e = (DescriptorEntry) descriptorEntries.get(key);
+        DescriptorEntry e = descriptorEntries.get(key);
         if (e == null) {
             e = new DescriptorEntry(nameRef, typeRef);
             assert(e.stringValue().equals(key))
@@ -121,8 +117,9 @@
 
     /** Factory for member reference constants. */
     public static synchronized MemberEntry getMemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) {
+        Map<String, MemberEntry> memberEntries = Utils.getMemberEntries();
         String key = MemberEntry.stringValueOf(tag, classRef, descRef);
-        MemberEntry e = (MemberEntry) memberEntries.get(key);
+        MemberEntry e = memberEntries.get(key);
         if (e == null) {
             e = new MemberEntry(tag, classRef, descRef);
             assert(e.stringValue().equals(key))
@@ -489,8 +486,9 @@
             String[] parts = structureSignature(value);
             formRef = getUtf8Entry(parts[0]);
             classRefs = new ClassEntry[parts.length-1];
-            for (int i = 1; i < parts.length; i++)
-                classRefs[i-1] = getClassEntry(parts[i]);
+            for (int i = 1; i < parts.length; i++) {
+                classRefs[i - 1] = getClassEntry(parts[i]);
+            }
             hashCode();  // force computation of valueHash
         }
         protected int computeValueHash() {
@@ -527,8 +525,9 @@
         String stringValueOf(Utf8Entry formRef, ClassEntry[] classRefs) {
             String[] parts = new String[1+classRefs.length];
             parts[0] = formRef.stringValue();
-            for (int i = 1; i < parts.length; i++)
-                parts[i] = classRefs[i-1].stringValue();
+            for (int i = 1; i < parts.length; i++) {
+                parts[i] = classRefs[i - 1].stringValue();
+            }
             return flattenSignature(parts).intern();
         }
 
@@ -543,19 +542,23 @@
             int size = 0;
             for (int i = min; i < max; i++) {
                 switch (form.charAt(i)) {
-                case 'D':
-                case 'J':
-                    if (countDoublesTwice) size++;
-                    break;
-                case '[':
-                    // Skip rest of array info.
-                    while (form.charAt(i) == '[') ++i;
-                    break;
-                case ';':
-                    continue;
-                default:
-                    assert(0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i)));
-                    break;
+                    case 'D':
+                    case 'J':
+                        if (countDoublesTwice) {
+                            size++;
+                        }
+                        break;
+                    case '[':
+                        // Skip rest of array info.
+                        while (form.charAt(i) == '[') {
+                            ++i;
+                        }
+                        break;
+                    case ';':
+                        continue;
+                    default:
+                        assert (0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i)));
+                        break;
                 }
                 size++;
             }
@@ -586,8 +589,9 @@
                 s = "/" + formRef.stringValue();
             }
             int i;
-            while ((i = s.indexOf(';')) >= 0)
-                s = s.substring(0,i) + s.substring(i+1);
+            while ((i = s.indexOf(';')) >= 0) {
+                s = s.substring(0, i) + s.substring(i + 1);
+            }
             return s;
         }
     }
@@ -732,11 +736,11 @@
             clearIndex();
             this.cpMap = cpMap;
         }
-        protected Index(String debugName, Collection cpMapList) {
+        protected Index(String debugName, Collection<Entry> cpMapList) {
             this(debugName);
             setMap(cpMapList);
         }
-        protected void setMap(Collection cpMapList) {
+        protected void setMap(Collection<Entry> cpMapList) {
             cpMap = new Entry[cpMapList.size()];
             cpMapList.toArray(cpMap);
             setMap(cpMap);
@@ -756,11 +760,13 @@
         //
         // As a special hack, if flattenSigs, signatures are
         // treated as equivalent entries of cpMap.  This is wrong
-        // fron a Collection point of view, because contains()
+        // from a Collection point of view, because contains()
         // reports true for signatures, but the iterator()
         // never produces them!
         private int findIndexOf(Entry e) {
-            if (indexKey == null)  initializeIndex();
+            if (indexKey == null) {
+                initializeIndex();
+            }
             int probe = findIndexLocation(e);
             if (indexKey[probe] != e) {
                 if (flattenSigs && e.tag == CONSTANT_Signature) {
@@ -832,7 +838,9 @@
                 System.out.println("initialize Index "+debugName+" ["+size()+"]");
             int hsize0 = (int)((cpMap.length + 10) * 1.5);
             int hsize = 1;
-            while (hsize < hsize0)  hsize <<= 1;
+            while (hsize < hsize0) {
+                hsize <<= 1;
+            }
             indexKey   = new Entry[hsize];
             indexValue = new int[hsize];
             for (int i = 0; i < cpMap.length; i++) {
@@ -855,7 +863,7 @@
             return toArray(new Entry[size()]);
         }
         public Object clone() {
-            return new Index(debugName, (Entry[]) cpMap.clone());
+            return new Index(debugName, cpMap.clone());
         }
         public String toString() {
             return "Index "+debugName+" ["+size()+"]";
@@ -901,22 +909,24 @@
     public static
     Index[] partition(Index ix, int[] keys) {
         // %%% Should move this into class Index.
-        ArrayList parts = new ArrayList();
+        ArrayList<List<Entry>> parts = new ArrayList<>();
         Entry[] cpMap = ix.cpMap;
         assert(keys.length == cpMap.length);
         for (int i = 0; i < keys.length; i++) {
             int key = keys[i];
             if (key < 0)  continue;
-            while (key >= parts.size())  parts.add(null);
-            ArrayList part = (ArrayList) parts.get(key);
+            while (key >= parts.size()) {
+                parts.add(null);
+            }
+            List<Entry> part = parts.get(key);
             if (part == null) {
-                parts.set(key, part = new ArrayList());
+                parts.set(key, part = new ArrayList<>());
             }
             part.add(cpMap[i]);
         }
         Index[] indexes = new Index[parts.size()];
         for (int key = 0; key < indexes.length; key++) {
-            ArrayList part = (ArrayList) parts.get(key);
+            List<Entry> part = parts.get(key);
             if (part == null)  continue;
             indexes[key] = new Index(ix.debugName+"/part#"+key, part);
             assert(indexes[key].indexOf(part.get(0)) == 0);
@@ -1048,9 +1058,10 @@
                     whichClasses[i] = whichClass;
                 }
                 perClassIndexes = partition(allMembers, whichClasses);
-                for (int i = 0; i < perClassIndexes.length; i++)
-                    assert(perClassIndexes[i]==null
-                            || perClassIndexes[i].assertIsSorted());
+                for (int i = 0; i < perClassIndexes.length; i++) {
+                    assert (perClassIndexes[i] == null ||
+                            perClassIndexes[i].assertIsSorted());
+                }
                 indexByTagAndClass[tag] = perClassIndexes;
             }
             int whichClass = allClasses.indexOf(classRef);
@@ -1113,7 +1124,7 @@
      *  Also, discard null from cpRefs.
      */
     public static
-    void completeReferencesIn(Set cpRefs, boolean flattenSigs) {
+    void completeReferencesIn(Set<Entry> cpRefs, boolean flattenSigs) {
         cpRefs.remove(null);
         for (ListIterator work =
                  new ArrayList(cpRefs).listIterator(cpRefs.size());
--- a/src/share/classes/com/sun/java/util/jar/pack/Driver.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/com/sun/java/util/jar/pack/Driver.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
 
 package com.sun.java.util.jar.pack;
 
-import java.lang.Error;
 import java.io.*;
 import java.text.MessageFormat;
 import java.util.*;
@@ -35,10 +34,11 @@
 /** Command line interface for Pack200.
  */
 class Driver {
-        private static final ResourceBundle RESOURCE= ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource");
+        private static final ResourceBundle RESOURCE =
+                ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource");
 
     public static void main(String[] ava) throws IOException {
-        ArrayList<String> av = new ArrayList<String>(Arrays.asList(ava));
+        ArrayList<String> av = new ArrayList<>(Arrays.asList(ava));
 
         boolean doPack   = true;
         boolean doUnpack = false;
@@ -61,7 +61,7 @@
         }
 
         // Collect engine properties here:
-        HashMap<String,String> engProps = new HashMap<String,String>();
+        HashMap<String,String> engProps = new HashMap<>();
         engProps.put(verboseProp, System.getProperty(verboseProp));
 
         String optionMap;
@@ -75,7 +75,7 @@
         }
 
         // Collect argument properties here:
-        HashMap<String,String> avProps = new HashMap<String,String>();
+        HashMap<String,String> avProps = new HashMap<>();
         try {
             for (;;) {
                 String state = parseCommandOptions(av, optionMap, avProps);
@@ -133,8 +133,9 @@
                     if (engProps.get(verboseProp) != null)
                         fileProps.list(System.out);
                     propIn.close();
-                    for (Map.Entry<Object,Object> me : fileProps.entrySet())
-                        engProps.put((String)me.getKey(), (String)me.getValue());
+                    for (Map.Entry<Object,Object> me : fileProps.entrySet()) {
+                        engProps.put((String) me.getKey(), (String) me.getValue());
+                    }
                 } else if (state == "--version") {
                         System.out.println(MessageFormat.format(RESOURCE.getString(DriverResource.VERSION), Driver.class.getName(), "1.31, 07/05/05"));
                     return;
@@ -493,7 +494,7 @@
         String resultString = null;
 
         // Convert options string into optLines dictionary.
-        TreeMap<String,String[]> optmap = new TreeMap<String,String[]>();
+        TreeMap<String,String[]> optmap = new TreeMap<>();
     loadOptmap:
         for (String optline : options.split("\n")) {
             String[] words = optline.split("\\p{Space}+");
@@ -687,7 +688,9 @@
         // Report number of arguments consumed.
         args.subList(0, argp.nextIndex()).clear();
         // Report any unconsumed partial argument.
-        while (pbp.hasPrevious())  args.add(0, pbp.previous());
+        while (pbp.hasPrevious()) {
+            args.add(0, pbp.previous());
+        }
         //System.out.println(args+" // "+properties+" -> "+resultString);
         return resultString;
     }
--- a/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,13 +28,8 @@
 
 import java.nio.*;
 import java.io.*;
-import java.nio.channels.*;
-import java.util.Date;
 import java.util.jar.*;
 import java.util.zip.*;
-import java.util.*;
-//import com.sun.java.util.jar.pack.Pack200;
-
 
 class NativeUnpack {
     // Pointer to the native unpacker obj
@@ -91,13 +86,13 @@
     NativeUnpack(UnpackerImpl p200) {
         super();
         _p200  = p200;
-        _props = p200._props;
+        _props = p200.props;
         p200._nunp = this;
     }
 
     // for JNI callbacks
     static private Object currentInstance() {
-        UnpackerImpl p200 = (UnpackerImpl) Utils.currentInstance.get();
+        UnpackerImpl p200 = (UnpackerImpl) Utils.getTLGlobals();
         return (p200 == null)? null: p200._nunp;
     }
 
@@ -216,10 +211,10 @@
                 ++_fileCount;
                 updateProgress();
             }
+            presetInput = getUnusedInput();
             long consumed = finish();
             if (_verbose > 0)
                 Utils.log.info("bytes consumed = "+consumed);
-            presetInput = getUnusedInput();
             if (presetInput == null &&
                 !Utils.isPackMagic(Utils.readMagic(in))) {
                 break;
--- a/src/share/classes/com/sun/java/util/jar/pack/Package.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/com/sun/java/util/jar/pack/Package.java	Sun Aug 29 22:41:28 2010 -0700
@@ -25,9 +25,9 @@
 
 package com.sun.java.util.jar.pack;
 
+import com.sun.java.util.jar.pack.Attribute.Layout;
 import java.lang.reflect.Modifier;
 import java.util.*;
-import java.util.zip.*;
 import java.util.jar.*;
 import java.io.*;
 import com.sun.java.util.jar.pack.ConstantPool.*;
@@ -77,10 +77,11 @@
         cp = new ConstantPool.IndexGroup();
         classes.clear();
         files.clear();
+        BandStructure.nextSeqForDebug = 0;
     }
 
     int getPackageVersion() {
-        return (package_majver << 16) + (int)package_minver;
+        return (package_majver << 16) + package_minver;
     }
 
     // Special empty versions of Code and InnerClasses, used for markers.
@@ -89,7 +90,7 @@
     public static final Attribute.Layout attrSourceFileSpecial;
     public static final Map attrDefs;
     static {
-        HashMap ad = new HashMap(2);
+        HashMap<Layout, Attribute> ad = new HashMap<>(3);
         attrCodeEmpty = Attribute.define(ad, ATTR_CONTEXT_METHOD,
                                          "Code", "").layout();
         attrInnerClassesEmpty = Attribute.define(ad, ATTR_CONTEXT_CLASS,
@@ -159,9 +160,9 @@
         }
     }
 
-    ArrayList classes = new ArrayList();
+    ArrayList<Package.Class> classes = new ArrayList<>();
 
-    public List getClasses() {
+    public List<Package.Class> getClasses() {
         return classes;
     }
 
@@ -186,11 +187,11 @@
         ClassEntry[] interfaces;
 
         // Class parts
-        ArrayList fields;
-        ArrayList methods;
+        ArrayList<Field> fields;
+        ArrayList<Method> methods;
         //ArrayList attributes;  // in Attribute.Holder.this.attributes
         // Note that InnerClasses may be collected at the package level.
-        ArrayList innerClasses;
+        ArrayList<InnerClass> innerClasses;
 
         Class(int flags, ClassEntry thisClass, ClassEntry superClass, ClassEntry[] interfaces) {
             this.magic      = JAVA_MAGIC;
@@ -270,7 +271,7 @@
             if (a != olda) {
                 if (verbose > 2)
                     Utils.log.fine("recoding obvious SourceFile="+obvious);
-                List newAttrs = new ArrayList(getAttributes());
+                List<Attribute> newAttrs = new ArrayList<>(getAttributes());
                 int where = newAttrs.indexOf(olda);
                 newAttrs.set(where, a);
                 setAttributes(newAttrs);
@@ -295,12 +296,12 @@
         boolean hasInnerClasses() {
             return innerClasses != null;
         }
-        List getInnerClasses() {
+        List<InnerClass> getInnerClasses() {
             return innerClasses;
         }
 
-        public void setInnerClasses(Collection ics) {
-            innerClasses = (ics == null) ? null : new ArrayList(ics);
+        public void setInnerClasses(Collection<InnerClass> ics) {
+            innerClasses = (ics == null) ? null : new ArrayList<InnerClass>(ics);
             // Edit the attribute list, if necessary.
             Attribute a = getAttribute(attrInnerClassesEmpty);
             if (innerClasses != null && a == null)
@@ -318,19 +319,18 @@
          *  The order of the resulting list is consistent
          *  with that of Package.this.allInnerClasses.
          */
-        public List computeGloballyImpliedICs() {
-            HashSet cpRefs = new HashSet();
+        public List<InnerClass> computeGloballyImpliedICs() {
+            HashSet<Entry> cpRefs = new HashSet<>();
             {   // This block temporarily displaces this.innerClasses.
-                ArrayList innerClassesSaved = innerClasses;
+                ArrayList<InnerClass> innerClassesSaved = innerClasses;
                 innerClasses = null;  // ignore for the moment
                 visitRefs(VRM_CLASSIC, cpRefs);
                 innerClasses = innerClassesSaved;
             }
             ConstantPool.completeReferencesIn(cpRefs, true);
 
-            HashSet icRefs = new HashSet();
-            for (Iterator i = cpRefs.iterator(); i.hasNext(); ) {
-                Entry e = (Entry) i.next();
+            HashSet<Entry> icRefs = new HashSet<>();
+            for (Entry e : cpRefs) {
                 // Restrict cpRefs to InnerClasses entries only.
                 if (!(e instanceof ClassEntry))  continue;
                 // For every IC reference, add its outers also.
@@ -345,9 +345,8 @@
             // This loop is structured this way so as to accumulate
             // entries into impliedICs in an order which reflects
             // the order of allInnerClasses.
-            ArrayList impliedICs = new ArrayList();
-            for (Iterator i = allInnerClasses.iterator(); i.hasNext(); ) {
-                InnerClass ic = (InnerClass) i.next();
+            ArrayList<InnerClass> impliedICs = new ArrayList<>();
+            for (InnerClass ic : allInnerClasses) {
                 // This one is locally relevant if it describes
                 // a member of the current class, or if the current
                 // class uses it somehow.  In the particular case
@@ -366,10 +365,11 @@
 
         // Helper for both minimizing and expanding.
         // Computes a symmetric difference.
-        private List computeICdiff() {
-            List impliedICs = computeGloballyImpliedICs();
-            List actualICs  = getInnerClasses();
-            if (actualICs == null)  actualICs = Collections.EMPTY_LIST;
+        private List<InnerClass> computeICdiff() {
+            List<InnerClass> impliedICs = computeGloballyImpliedICs();
+            List<InnerClass> actualICs  = getInnerClasses();
+            if (actualICs == null)
+                actualICs = Collections.EMPTY_LIST;
 
             // Symmetric difference is calculated from I, A like this:
             //  diff = (I+A) - (I*A)
@@ -388,8 +388,8 @@
                 // Diff is A since I is empty.
             }
             // (I*A) is non-trivial
-            HashSet center = new HashSet(actualICs);
-            center.retainAll(new HashSet(impliedICs));
+            HashSet<InnerClass> center = new HashSet<>(actualICs);
+            center.retainAll(new HashSet<>(impliedICs));
             impliedICs.addAll(actualICs);
             impliedICs.removeAll(center);
             // Diff is now I^A = (I+A)-(I*A).
@@ -407,9 +407,9 @@
          *  to use the globally implied ICs changed.
          */
         void minimizeLocalICs() {
-            List diff = computeICdiff();
-            List actualICs = innerClasses;
-            List localICs;  // will be the diff, modulo edge cases
+            List<InnerClass> diff = computeICdiff();
+            List<InnerClass> actualICs = innerClasses;
+            List<InnerClass> localICs;  // will be the diff, modulo edge cases
             if (diff.isEmpty()) {
                 // No diff, so transmit no attribute.
                 localICs = null;
@@ -439,12 +439,12 @@
          *  Otherwise, return positive if any IC tuples were added.
          */
         int expandLocalICs() {
-            List localICs = innerClasses;
-            List actualICs;
+            List<InnerClass> localICs = innerClasses;
+            List<InnerClass> actualICs;
             int changed;
             if (localICs == null) {
                 // Diff was empty.  (Common case.)
-                List impliedICs = computeGloballyImpliedICs();
+                List<InnerClass> impliedICs = computeGloballyImpliedICs();
                 if (impliedICs.isEmpty()) {
                     actualICs = null;
                     changed = 0;
@@ -490,7 +490,7 @@
             protected Entry[] getCPMap() {
                 return cpMap;
             }
-            protected void visitRefs(int mode, Collection refs) {
+            protected void visitRefs(int mode, Collection<Entry> refs) {
                 if (verbose > 2)  Utils.log.fine("visitRefs "+this);
                 // Careful:  The descriptor is used by the package,
                 // but the classfile breaks it into component refs.
@@ -518,7 +518,7 @@
                 super(flags, descriptor);
                 assert(!descriptor.isMethod());
                 if (fields == null)
-                    fields = new ArrayList();
+                    fields = new ArrayList<>();
                 boolean added = fields.add(this);
                 assert(added);
                 order = fields.size();
@@ -543,7 +543,7 @@
                 super(flags, descriptor);
                 assert(descriptor.isMethod());
                 if (methods == null)
-                    methods = new ArrayList();
+                    methods = new ArrayList<>();
                 boolean added = methods.add(this);
                 assert(added);
             }
@@ -573,7 +573,7 @@
                     code.strip(attrName);
                 super.strip(attrName);
             }
-            protected void visitRefs(int mode, Collection refs) {
+            protected void visitRefs(int mode, Collection<Entry> refs) {
                 super.visitRefs(mode, refs);
                 if (code != null) {
                     if (mode == VRM_CLASSIC) {
@@ -614,7 +614,7 @@
             super.strip(attrName);
         }
 
-        protected void visitRefs(int mode, Collection refs) {
+        protected void visitRefs(int mode, Collection<Entry> refs) {
             if (verbose > 2)  Utils.log.fine("visitRefs "+this);
             refs.add(thisClass);
             refs.add(superClass);
@@ -641,7 +641,7 @@
             super.visitRefs(mode, refs);
         }
 
-        protected void visitInnerClassRefs(int mode, Collection refs) {
+        protected void visitInnerClassRefs(int mode, Collection<Entry> refs) {
             Package.visitInnerClassRefs(innerClasses, mode, refs);
         }
 
@@ -713,16 +713,15 @@
     }
 
     // What non-class files are in this unit?
-    ArrayList files = new ArrayList();
+    ArrayList<File> files = new ArrayList<>();
 
-    public List getFiles() {
+    public List<File> getFiles() {
         return files;
     }
 
-    public List getClassStubs() {
-        ArrayList classStubs = new ArrayList(classes.size());
-        for (Iterator i = classes.iterator(); i.hasNext(); ) {
-            Class cls = (Class) i.next();
+    public List<File> getClassStubs() {
+        ArrayList<File> classStubs = new ArrayList<>(classes.size());
+        for (Class cls : classes) {
             assert(cls.file.isClassStub());
             classStubs.add(cls.file);
         }
@@ -840,7 +839,7 @@
         public InputStream getInputStream() {
             InputStream in = new ByteArrayInputStream(append.toByteArray());
             if (prepend.size() == 0)  return in;
-            ArrayList isa = new ArrayList(prepend.size()+1);
+            ArrayList<InputStream> isa = new ArrayList<>(prepend.size()+1);
             for (Iterator i = prepend.iterator(); i.hasNext(); ) {
                 byte[] bytes = (byte[]) i.next();
                 isa.add(new ByteArrayInputStream(bytes));
@@ -849,7 +848,7 @@
             return new SequenceInputStream(Collections.enumeration(isa));
         }
 
-        protected void visitRefs(int mode, Collection refs) {
+        protected void visitRefs(int mode, Collection<Entry> refs) {
             assert(name != null);
             refs.add(name);
         }
@@ -877,8 +876,8 @@
     }
 
     // Is there a globally declared table of inner classes?
-    ArrayList allInnerClasses = new ArrayList();
-    HashMap   allInnerClassesByThis;
+    ArrayList<InnerClass> allInnerClasses = new ArrayList<>();
+    HashMap<ClassEntry, InnerClass>   allInnerClassesByThis;
 
     public
     List getAllInnerClasses() {
@@ -886,15 +885,14 @@
     }
 
     public
-    void setAllInnerClasses(Collection ics) {
+    void setAllInnerClasses(Collection<InnerClass> ics) {
         assert(ics != allInnerClasses);
         allInnerClasses.clear();
         allInnerClasses.addAll(ics);
 
         // Make an index:
-        allInnerClassesByThis = new HashMap(allInnerClasses.size());
-        for (Iterator i = allInnerClasses.iterator(); i.hasNext(); ) {
-            InnerClass ic = (InnerClass) i.next();
+        allInnerClassesByThis = new HashMap<>(allInnerClasses.size());
+        for (InnerClass ic : allInnerClasses) {
             Object pic = allInnerClassesByThis.put(ic.thisClass, ic);
             assert(pic == null);  // caller must ensure key uniqueness!
         }
@@ -904,7 +902,7 @@
     public
     InnerClass getGlobalInnerClass(Entry thisClass) {
         assert(thisClass instanceof ClassEntry);
-        return (InnerClass) allInnerClassesByThis.get(thisClass);
+        return allInnerClassesByThis.get(thisClass);
     }
 
     static
@@ -963,7 +961,7 @@
             return this.thisClass.compareTo(that.thisClass);
         }
 
-        protected void visitRefs(int mode, Collection refs) {
+        protected void visitRefs(int mode, Collection<Entry> refs) {
             refs.add(thisClass);
             if (mode == VRM_CLASSIC || !predictable) {
                 // If the name can be demangled, the package omits
@@ -980,7 +978,7 @@
 
     // Helper for building InnerClasses attributes.
     static private
-    void visitInnerClassRefs(Collection innerClasses, int mode, Collection refs) {
+    void visitInnerClassRefs(Collection innerClasses, int mode, Collection<Entry> refs) {
         if (innerClasses == null) {
             return;  // no attribute; nothing to do
         }
@@ -1165,9 +1163,8 @@
         }
     }
 
-    protected void visitRefs(int mode, Collection refs) {
-        for (Iterator i = classes.iterator(); i.hasNext(); ) {
-            Class c = (Class)i.next();
+    protected void visitRefs(int mode, Collection<Entry> refs) {
+        for ( Class c : classes) {
             c.visitRefs(mode, refs);
         }
         if (mode != VRM_CLASSIC) {
@@ -1259,7 +1256,7 @@
     }
 
     // Use this before writing the package file.
-    void buildGlobalConstantPool(Set requiredEntries) {
+    void buildGlobalConstantPool(Set<Entry> requiredEntries) {
         if (verbose > 1)
             Utils.log.fine("Checking for unused CP entries");
         requiredEntries.add(getRefString(""));  // uconditionally present
@@ -1291,9 +1288,8 @@
 
     // Use this before writing the class files.
     void ensureAllClassFiles() {
-        HashSet fileSet = new HashSet(files);
-        for (Iterator i = classes.iterator(); i.hasNext(); ) {
-            Class cls = (Class) i.next();
+        HashSet<File> fileSet = new HashSet<>(files);
+        for (Class cls : classes) {
             // Add to the end of ths list:
             if (!fileSet.contains(cls.file))
                 files.add(cls.file);
--- a/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,11 @@
 
 package com.sun.java.util.jar.pack;
 
+import com.sun.java.util.jar.pack.Attribute.Layout;
 import java.util.*;
 import java.util.jar.*;
-import java.util.zip.*;
 import java.io.*;
 import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeEvent;
 
 
 /*
@@ -41,31 +40,22 @@
  */
 
 
-public class PackerImpl implements Pack200.Packer {
+public class PackerImpl  extends TLGlobals implements Pack200.Packer {
 
     /**
      * Constructs a Packer object and sets the initial state of
      * the packer engines.
      */
-    public PackerImpl() {
-        _props = new PropMap();
-        //_props.getProperty() consults defaultProps invisibly.
-        //_props.putAll(defaultProps);
-    }
-
-
-    // Private stuff.
-    final PropMap _props;
+    public PackerImpl() {}
 
     /**
      * Get the set of options for the pack and unpack engines.
      * @return A sorted association of option key strings to option values.
      */
-    public SortedMap properties() {
-        return _props;
+    public SortedMap<String, String> properties() {
+        return props;
     }
 
-
     //Driver routines
 
     /**
@@ -78,21 +68,22 @@
      */
     public void pack(JarFile in, OutputStream out) throws IOException {
         assert(Utils.currentInstance.get() == null);
-        TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
-            TimeZone.getDefault();
+        TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
+                      ? null
+                      : TimeZone.getDefault();
         try {
             Utils.currentInstance.set(this);
             if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
 
-            if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) {
+            if ("0".equals(props.getProperty(Pack200.Packer.EFFORT))) {
                 Utils.copyJarFile(in, out);
             } else {
                 (new DoPack()).run(in, out);
-                in.close();
             }
         } finally {
             Utils.currentInstance.set(null);
             if (tz != null) TimeZone.setDefault(tz);
+            in.close();
         }
     }
 
@@ -112,21 +103,20 @@
      */
     public void pack(JarInputStream in, OutputStream out) throws IOException {
         assert(Utils.currentInstance.get() == null);
-        TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
+        TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
             TimeZone.getDefault();
         try {
             Utils.currentInstance.set(this);
             if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
-            if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) {
+            if ("0".equals(props.getProperty(Pack200.Packer.EFFORT))) {
                 Utils.copyJarFile(in, out);
             } else {
                 (new DoPack()).run(in, out);
-                in.close();
             }
         } finally {
             Utils.currentInstance.set(null);
             if (tz != null) TimeZone.setDefault(tz);
-
+            in.close();
         }
     }
     /**
@@ -134,7 +124,7 @@
      * @param listener  An object to be invoked when a property is changed.
      */
     public void addPropertyChangeListener(PropertyChangeListener listener) {
-        _props.addListener(listener);
+        props.addListener(listener);
     }
 
     /**
@@ -142,7 +132,7 @@
      * @param listener  The PropertyChange listener to be removed.
      */
     public void removePropertyChangeListener(PropertyChangeListener listener) {
-        _props.removeListener(listener);
+        props.removeListener(listener);
     }
 
 
@@ -151,11 +141,11 @@
 
     // The packer worker.
     private class DoPack {
-        final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
+        final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
 
         {
-            _props.setInteger(Pack200.Packer.PROGRESS, 0);
-            if (verbose > 0) Utils.log.info(_props.toString());
+            props.setInteger(Pack200.Packer.PROGRESS, 0);
+            if (verbose > 0) Utils.log.info(props.toString());
         }
 
         // Here's where the bits are collected before getting packed:
@@ -163,7 +153,7 @@
 
         final String unknownAttrCommand;
         {
-            String uaMode = _props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS);
+            String uaMode = props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS);
             if (!(Pack200.Packer.STRIP.equals(uaMode) ||
                   Pack200.Packer.PASS.equals(uaMode) ||
                   Pack200.Packer.ERROR.equals(uaMode))) {
@@ -191,13 +181,12 @@
             };
             for (int i = 0; i < ctypes.length; i++) {
                 String pfx = keys[i];
-                Map map = _props.prefixMap(pfx);
-                for (Iterator j = map.keySet().iterator(); j.hasNext(); ) {
-                    String key = (String) j.next();
+                Map<String, String> map = props.prefixMap(pfx);
+                for (String key : map.keySet()) {
                     assert(key.startsWith(pfx));
                     String name = key.substring(pfx.length());
-                    String layout = _props.getProperty(key);
-                    Object lkey = Attribute.keyForLookup(ctypes[i], name);
+                    String layout = props.getProperty(key);
+                    Layout lkey = Attribute.keyForLookup(ctypes[i], name);
                     if (Pack200.Packer.STRIP.equals(layout) ||
                         Pack200.Packer.PASS.equals(layout) ||
                         Pack200.Packer.ERROR.equals(layout)) {
@@ -222,25 +211,25 @@
         }
 
         final boolean keepFileOrder
-            = _props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER);
+            = props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER);
         final boolean keepClassOrder
-            = _props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER);
+            = props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER);
 
         final boolean keepModtime
-            = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME));
+            = Pack200.Packer.KEEP.equals(props.getProperty(Pack200.Packer.MODIFICATION_TIME));
         final boolean latestModtime
-            = Pack200.Packer.LATEST.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME));
+            = Pack200.Packer.LATEST.equals(props.getProperty(Pack200.Packer.MODIFICATION_TIME));
         final boolean keepDeflateHint
-            = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.DEFLATE_HINT));
+            = Pack200.Packer.KEEP.equals(props.getProperty(Pack200.Packer.DEFLATE_HINT));
         {
             if (!keepModtime && !latestModtime) {
-                int modtime = _props.getTime(Pack200.Packer.MODIFICATION_TIME);
+                int modtime = props.getTime(Pack200.Packer.MODIFICATION_TIME);
                 if (modtime != Constants.NO_MODTIME) {
                     pkg.default_modtime = modtime;
                 }
             }
             if (!keepDeflateHint) {
-                boolean deflate_hint = _props.getBoolean(Pack200.Packer.DEFLATE_HINT);
+                boolean deflate_hint = props.getBoolean(Pack200.Packer.DEFLATE_HINT);
                 if (deflate_hint) {
                     pkg.default_options |= Constants.AO_DEFLATE_HINT;
                 }
@@ -254,10 +243,10 @@
         final long segmentLimit;
         {
             long limit;
-            if (_props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals(""))
+            if (props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals(""))
                 limit = -1;
             else
-                limit = _props.getLong(Pack200.Packer.SEGMENT_LIMIT);
+                limit = props.getLong(Pack200.Packer.SEGMENT_LIMIT);
             limit = Math.min(Integer.MAX_VALUE, limit);
             limit = Math.max(-1, limit);
             if (limit == -1)
@@ -265,10 +254,10 @@
             segmentLimit = limit;
         }
 
-        final List passFiles;  // parsed pack.pass.file options
+        final List<String> passFiles;  // parsed pack.pass.file options
         {
             // Which class files will be passed through?
-            passFiles = _props.getProperties(Pack200.Packer.PASS_FILE_PFX);
+            passFiles = props.getProperties(Pack200.Packer.PASS_FILE_PFX);
             for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) {
                 String file = (String) i.next();
                 if (file == null) { i.remove(); continue; }
@@ -283,28 +272,28 @@
         {
             // Fill in permitted range of major/minor version numbers.
             int ver;
-            if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0)
+            if ((ver = props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0)
                 pkg.min_class_majver = (short) ver;
-            if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0)
+            if ((ver = props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0)
                 pkg.min_class_minver = (short) ver;
-            if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0)
+            if ((ver = props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0)
                 pkg.max_class_majver = (short) ver;
-            if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0)
+            if ((ver = props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0)
                 pkg.max_class_minver = (short) ver;
-            if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0)
+            if ((ver = props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0)
                 pkg.package_minver = (short) ver;
-            if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0)
+            if ((ver = props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0)
                 pkg.package_majver = (short) ver;
         }
 
         {
             // Hook for testing:  Forces use of special archive modes.
-            int opt = _props.getInteger(Utils.COM_PREFIX+"archive.options");
+            int opt = props.getInteger(Utils.COM_PREFIX+"archive.options");
             if (opt != 0)
                 pkg.default_options |= opt;
         }
 
-        // (Done collecting options from _props.)
+        // (Done collecting options from props.)
 
         boolean isClassFile(String name) {
             if (!name.endsWith(".class"))  return false;
@@ -423,16 +412,18 @@
                 Package.File file = null;
                 // (5078608) : discount the resource files in META-INF
                 // from segment computation.
-                long inflen = (isMetaInfFile(name)) ?  0L :
-                                inFile.getInputLength();
+                long inflen = (isMetaInfFile(name))
+                              ? 0L
+                              : inFile.getInputLength();
 
                 if ((segmentSize += inflen) > segmentLimit) {
                     segmentSize -= inflen;
                     int nextCount = -1;  // don't know; it's a stream
                     flushPartial(out, nextCount);
                 }
-                if (verbose > 1)
+                if (verbose > 1) {
                     Utils.log.fine("Reading " + name);
+                }
 
                 assert(je.isDirectory() == name.endsWith("/"));
 
@@ -450,18 +441,18 @@
         }
 
         void run(JarFile in, OutputStream out) throws IOException {
-            List inFiles = scanJar(in);
+            List<InFile> inFiles = scanJar(in);
 
             if (verbose > 0)
                 Utils.log.info("Reading " + inFiles.size() + " files...");
 
             int numDone = 0;
-            for (Iterator i = inFiles.iterator(); i.hasNext(); ) {
-                InFile inFile = (InFile) i.next();
+            for (InFile inFile : inFiles) {
                 String name      = inFile.name;
                 // (5078608) : discount the resource files completely from segmenting
-                long inflen = (isMetaInfFile(name)) ? 0L :
-                                inFile.getInputLength() ;
+                long inflen = (isMetaInfFile(name))
+                               ? 0L
+                               : inFile.getInputLength() ;
                 if ((segmentSize += inflen) > segmentLimit) {
                     segmentSize -= inflen;
                     // Estimate number of remaining segments:
@@ -530,11 +521,11 @@
         }
 
         void flushPartial(OutputStream out, int nextCount) throws IOException {
-            if (pkg.files.size() == 0 && pkg.classes.size() == 0) {
+            if (pkg.files.isEmpty() && pkg.classes.isEmpty()) {
                 return;  // do not flush an empty segment
             }
             flushPackage(out, Math.max(1, nextCount));
-            _props.setInteger(Pack200.Packer.PROGRESS, 25);
+            props.setInteger(Pack200.Packer.PROGRESS, 25);
             // In case there will be another segment:
             makeNextPackage();
             segmentCount += 1;
@@ -543,10 +534,10 @@
         }
 
         void flushAll(OutputStream out) throws IOException {
-            _props.setInteger(Pack200.Packer.PROGRESS, 50);
+            props.setInteger(Pack200.Packer.PROGRESS, 50);
             flushPackage(out, 0);
             out.flush();
-            _props.setInteger(Pack200.Packer.PROGRESS, 100);
+            props.setInteger(Pack200.Packer.PROGRESS, 100);
             segmentCount += 1;
             segmentTotalSize += segmentSize;
             segmentSize = 0;
@@ -582,11 +573,11 @@
             pkg.trimStubs();
 
             // Do some stripping, maybe.
-            if (_props.getBoolean(Utils.COM_PREFIX+"strip.debug"))        pkg.stripAttributeKind("Debug");
-            if (_props.getBoolean(Utils.COM_PREFIX+"strip.compile"))      pkg.stripAttributeKind("Compile");
-            if (_props.getBoolean(Utils.COM_PREFIX+"strip.constants"))    pkg.stripAttributeKind("Constant");
-            if (_props.getBoolean(Utils.COM_PREFIX+"strip.exceptions"))   pkg.stripAttributeKind("Exceptions");
-            if (_props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses");
+            if (props.getBoolean(Utils.COM_PREFIX+"strip.debug"))        pkg.stripAttributeKind("Debug");
+            if (props.getBoolean(Utils.COM_PREFIX+"strip.compile"))      pkg.stripAttributeKind("Compile");
+            if (props.getBoolean(Utils.COM_PREFIX+"strip.constants"))    pkg.stripAttributeKind("Constant");
+            if (props.getBoolean(Utils.COM_PREFIX+"strip.exceptions"))   pkg.stripAttributeKind("Exceptions");
+            if (props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses");
 
             // Must choose an archive version; PackageWriter does not.
             if (pkg.package_majver <= 0)  pkg.choosePackageVersion();
@@ -606,11 +597,10 @@
             }
         }
 
-        List scanJar(JarFile jf) throws IOException {
+        List<InFile> scanJar(JarFile jf) throws IOException {
             // Collect jar entries, preserving order.
-            List inFiles = new ArrayList();
-            for (Enumeration e = jf.entries(); e.hasMoreElements(); ) {
-                JarEntry je = (JarEntry) e.nextElement();
+            List<InFile> inFiles = new ArrayList<>();
+            for (JarEntry je : Collections.list(jf.entries())) {
                 InFile inFile = new InFile(jf, je);
                 assert(je.isDirectory() == inFile.name.endsWith("/"));
                 inFiles.add(inFile);
--- a/src/share/classes/com/sun/java/util/jar/pack/PropMap.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/com/sun/java/util/jar/pack/PropMap.java	Sun Aug 29 22:41:28 2010 -0700
@@ -91,7 +91,7 @@
                   String.valueOf(Boolean.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)));
 
         // The segment size is unlimited
-        props.put(Pack200.Packer.SEGMENT_LIMIT, "");
+        props.put(Pack200.Packer.SEGMENT_LIMIT, "-1");
 
         // Preserve file ordering by default.
         props.put(Pack200.Packer.KEEP_FILE_ORDER, Pack200.Packer.TRUE);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/java/util/jar/pack/TLGlobals.java	Sun Aug 29 22:41:28 2010 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.java.util.jar.pack;
+
+import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
+import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
+import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry;
+import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
+import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
+import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedMap;
+
+/*
+ * @author ksrini
+ */
+
+/*
+ * This class provides a container to hold the global variables, for packer
+ * and unpacker instances. This is typically stashed away in a ThreadLocal,
+ * and the storage is destroyed upon completion. Therefore any local
+ * references to these members must be eliminated appropriately to prevent a
+ * memory leak.
+ */
+class TLGlobals {
+    // Global environment
+    final PropMap props;
+
+    // Needed by ConstantPool.java
+    private final Map<String, Utf8Entry> utf8Entries;
+    private final Map<String, ClassEntry> classEntries;
+    private final Map<Object, LiteralEntry> literalEntries;
+    private final Map<String, SignatureEntry> signatureEntries;
+    private final Map<String, DescriptorEntry> descriptorEntries;
+    private final Map<String, MemberEntry> memberEntries;
+
+    TLGlobals() {
+        utf8Entries = new HashMap<>();
+        classEntries = new HashMap<>();
+        literalEntries = new HashMap<>();
+        signatureEntries = new HashMap<>();
+        descriptorEntries = new HashMap<>();
+        memberEntries = new HashMap<>();
+        props = new PropMap();
+    }
+
+    SortedMap<Object, Object> getPropMap() {
+        return props;
+    }
+
+    Map<String, Utf8Entry> getUtf8Entries() {
+        return utf8Entries;
+    }
+
+    Map<String, ClassEntry> getClassEntries() {
+        return classEntries;
+    }
+
+    Map<Object, LiteralEntry> getLiteralEntries() {
+        return literalEntries;
+    }
+
+    Map<String, DescriptorEntry> getDescriptorEntries() {
+         return descriptorEntries;
+    }
+
+    Map<String, SignatureEntry> getSignatureEntries() {
+        return signatureEntries;
+    }
+
+    Map<String, MemberEntry> getMemberEntries() {
+        return memberEntries;
+    }
+}
--- a/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,6 @@
 import java.util.zip.*;
 import java.io.*;
 import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeEvent;
 
 /*
  * Implementation of the Pack provider.
@@ -40,7 +39,7 @@
  */
 
 
-public class UnpackerImpl implements Pack200.Unpacker {
+public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
 
 
     /**
@@ -48,7 +47,7 @@
      * @param listener  An object to be invoked when a property is changed.
      */
     public void addPropertyChangeListener(PropertyChangeListener listener) {
-        _props.addListener(listener);
+        props.addListener(listener);
     }
 
 
@@ -57,25 +56,19 @@
      * @param listener  The PropertyChange listener to be removed.
      */
     public void removePropertyChangeListener(PropertyChangeListener listener) {
-        _props.removeListener(listener);
+        props.removeListener(listener);
     }
 
-    public UnpackerImpl() {
-        _props = new PropMap();
-        //_props.getProperty() consults defaultProps invisibly.
-        //_props.putAll(defaultProps);
-    }
+    public UnpackerImpl() {}
 
-    // Private stuff.
-    final PropMap _props;
 
 
     /**
      * Get the set of options for the pack and unpack engines.
      * @return A sorted association of option key strings to option values.
      */
-    public SortedMap properties() {
-        return _props;
+    public SortedMap<String, String> properties() {
+        return props;
     }
 
     // Back-pointer to NativeUnpacker, when active.
@@ -101,19 +94,20 @@
      */
     public void unpack(InputStream in0, JarOutputStream out) throws IOException {
         assert(Utils.currentInstance.get() == null);
-        TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
-            TimeZone.getDefault();
+        TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
+                      ? null
+                      : TimeZone.getDefault();
 
         try {
             Utils.currentInstance.set(this);
             if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
-            final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
+            final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
             BufferedInputStream in = new BufferedInputStream(in0);
             if (Utils.isJarMagic(Utils.readMagic(in))) {
                 if (verbose > 0)
                     Utils.log.info("Copying unpacked JAR file...");
                 Utils.copyJarFile(new JarInputStream(in), out);
-            } else if (_props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) {
+            } else if (props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) {
                 (new DoUnpack()).run(in, out);
                 in.close();
                 Utils.markJarFile(out);
@@ -142,36 +136,38 @@
         // %%% Reconsider if native unpacker learns to memory-map the file.
         FileInputStream instr = new FileInputStream(in);
         unpack(instr, out);
-        if (_props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
+        if (props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
             in.delete();
         }
     }
 
     private class DoUnpack {
-        final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
+        final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
 
         {
-            _props.setInteger(Pack200.Unpacker.PROGRESS, 0);
+            props.setInteger(Pack200.Unpacker.PROGRESS, 0);
         }
 
         // Here's where the bits are read from disk:
         final Package pkg = new Package();
 
         final boolean keepModtime
-            = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP));
+            = Pack200.Packer.KEEP.equals(
+              props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP));
         final boolean keepDeflateHint
-            = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP));
+            = Pack200.Packer.KEEP.equals(
+              props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP));
         final int modtime;
         final boolean deflateHint;
         {
             if (!keepModtime) {
-                modtime = _props.getTime(Utils.UNPACK_MODIFICATION_TIME);
+                modtime = props.getTime(Utils.UNPACK_MODIFICATION_TIME);
             } else {
                 modtime = pkg.default_modtime;
             }
 
             deflateHint = (keepDeflateHint) ? false :
-                _props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT);
+                props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT);
         }
 
         // Checksum apparatus.
@@ -181,7 +177,7 @@
 
         public void run(BufferedInputStream in, JarOutputStream out) throws IOException {
             if (verbose > 0) {
-                _props.list(System.out);
+                props.list(System.out);
             }
             for (int seg = 1; ; seg++) {
                 unpackSegment(in, out);
@@ -194,25 +190,26 @@
         }
 
         private void unpackSegment(InputStream in, JarOutputStream out) throws IOException {
-            _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0");
+            props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0");
             // Process the output directory or jar output.
             new PackageReader(pkg, in).read();
 
-            if (_props.getBoolean("unpack.strip.debug"))    pkg.stripAttributeKind("Debug");
-            if (_props.getBoolean("unpack.strip.compile"))  pkg.stripAttributeKind("Compile");
-            _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50");
+            if (props.getBoolean("unpack.strip.debug"))    pkg.stripAttributeKind("Debug");
+            if (props.getBoolean("unpack.strip.compile"))  pkg.stripAttributeKind("Compile");
+            props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50");
             pkg.ensureAllClassFiles();
             // Now write out the files.
-            HashSet classesToWrite = new HashSet(pkg.getClasses());
+            HashSet<Package.Class> classesToWrite = new HashSet<>(pkg.getClasses());
             for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) {
                 Package.File file = (Package.File) i.next();
                 String name = file.nameString;
                 JarEntry je = new JarEntry(Utils.getJarEntryName(name));
                 boolean deflate;
 
-                deflate = (keepDeflateHint) ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) ||
-                                                   ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0)) :
-                    deflateHint;
+                deflate = (keepDeflateHint)
+                          ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) ||
+                            ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0))
+                          : deflateHint;
 
                 boolean needCRC = !deflate;  // STORE mode requires CRC
 
@@ -250,7 +247,7 @@
                     Utils.log.info("Writing "+Utils.zeString((ZipEntry)je));
             }
             assert(classesToWrite.isEmpty());
-            _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100");
+            props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100");
             pkg.reset();  // reset for the next segment, if any
         }
     }
--- a/src/share/classes/com/sun/java/util/jar/pack/Utils.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/com/sun/java/util/jar/pack/Utils.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,13 @@
 
 package com.sun.java.util.jar.pack;
 
+import com.sun.java.util.jar.pack.Attribute.Layout;
+import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
+import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
+import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry;
+import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
+import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
+import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
 import java.util.*;
 import java.util.jar.*;
 import java.util.zip.*;
@@ -113,17 +120,46 @@
      */
     static final String PACK_ZIP_ARCHIVE_MARKER_COMMENT = "PACK200";
 
-   // Keep a TLS point to the current Packer or Unpacker.
-   // This makes it simpler to supply environmental options
+    // Keep a TLS point to the global data and environment.
+    // This makes it simpler to supply environmental options
     // to the engine code, especially the native code.
-    static final ThreadLocal currentInstance = new ThreadLocal();
+    static final ThreadLocal<TLGlobals> currentInstance = new ThreadLocal<>();
+
+    // convenience methods to access the TL globals
+    static TLGlobals getTLGlobals() {
+        return currentInstance.get();
+    }
+
+    static Map<String, Utf8Entry> getUtf8Entries() {
+        return getTLGlobals().getUtf8Entries();
+    }
+
+    static Map<String, ClassEntry> getClassEntries() {
+        return getTLGlobals().getClassEntries();
+    }
+
+    static Map<Object, LiteralEntry> getLiteralEntries() {
+        return getTLGlobals().getLiteralEntries();
+    }
+
+    static Map<String, DescriptorEntry> getDescriptorEntries() {
+         return getTLGlobals().getDescriptorEntries();
+    }
+
+    static Map<String, SignatureEntry> getSignatureEntries() {
+        return getTLGlobals().getSignatureEntries();
+    }
+
+    static Map<String, MemberEntry> getMemberEntries() {
+        return getTLGlobals().getMemberEntries();
+    }
 
     static PropMap currentPropMap() {
         Object obj = currentInstance.get();
         if (obj instanceof PackerImpl)
-            return ((PackerImpl)obj)._props;
+            return ((PackerImpl)obj).props;
         if (obj instanceof UnpackerImpl)
-            return ((UnpackerImpl)obj)._props;
+            return ((UnpackerImpl)obj).props;
         return null;
     }
 
--- a/src/share/classes/com/sun/jndi/ldap/Connection.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/com/sun/jndi/ldap/Connection.java	Sun Aug 29 22:41:28 2010 -0700
@@ -813,7 +813,8 @@
         try {
             while (true) {
                 try {
-                    inbuf = new byte[10];
+                    // type and length (at most 128 octets for long form)
+                    inbuf = new byte[129];
 
                     offset = 0;
                     seqlen = 0;
--- a/src/share/classes/java/lang/AbstractStringBuilder.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/java/lang/AbstractStringBuilder.java	Sun Aug 29 22:41:28 2010 -0700
@@ -470,7 +470,7 @@
     public AbstractStringBuilder append(CharSequence s, int start, int end) {
         if (s == null)
             s = "null";
-        if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
+        if ((start < 0) || (start > end) || (end > s.length()))
             throw new IndexOutOfBoundsException(
                 "start " + start + ", end " + end + ", s.length() "
                 + s.length());
@@ -529,7 +529,8 @@
      *         or {@code offset+len > str.length}
      */
     public AbstractStringBuilder append(char str[], int offset, int len) {
-        ensureCapacityInternal(count + len);
+        if (len > 0)                // let arraycopy report AIOOBE for len < 0
+            ensureCapacityInternal(count + len);
         System.arraycopy(str, offset, value, count, len);
         count += len;
         return this;
--- a/src/share/classes/java/lang/Thread.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/java/lang/Thread.java	Sun Aug 29 22:41:28 2010 -0700
@@ -414,6 +414,18 @@
     }
 
     /**
+     * Throws CloneNotSupportedException as a Thread can not be meaningfully
+     * cloned. Construct a new Thread instead.
+     *
+     * @throws  CloneNotSupportedException
+     *          always
+     */
+    @Override
+    protected Object clone() throws CloneNotSupportedException {
+        throw new CloneNotSupportedException();
+    }
+
+    /**
      * Allocates a new {@code Thread} object. This constructor has the same
      * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
      * {@code (null, null, gname)}, where {@code gname} is a newly generated
--- a/src/share/classes/java/lang/Throwable.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/java/lang/Throwable.java	Sun Aug 29 22:41:28 2010 -0700
@@ -200,7 +200,16 @@
      * @serial
      * @since 1.7
      */
-    private List<Throwable> suppressedExceptions = Collections.emptyList();
+    private List<Throwable> suppressedExceptions = null;
+    /*
+     * This field is lazily initialized when the first suppressed
+     * exception is added.
+     *
+     * OutOfMemoryError is preallocated in the VM for better OOM
+     * diagnosability during VM initialization. Constructor can't
+     * be not invoked. If a new field to be added in the future must
+     * be initialized to non-null, it requires a synchronized VM change.
+     */
 
     /** Message for trying to suppress a null exception. */
     private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
@@ -329,7 +338,7 @@
      *          cause is nonexistent or unknown.
      * @since 1.4
      */
-    public Throwable getCause() {
+    public synchronized Throwable getCause() {
         return (cause==this ? null : cause);
     }
 
@@ -563,7 +572,7 @@
                 s.println("\tat " + traceElement);
 
             // Print suppressed exceptions, if any
-            for (Throwable se : suppressedExceptions)
+            for (Throwable se : getSuppressedExceptions())
                 se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
 
             // Print cause, if any
@@ -604,7 +613,7 @@
                 s.println(prefix + "\t... " + framesInCommon + " more");
 
             // Print suppressed exceptions, if any
-            for (Throwable se : suppressedExceptions)
+            for (Throwable se : getSuppressedExceptions())
                 se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
                                            prefix +"\t", dejaVu);
 
@@ -747,7 +756,9 @@
             if (defensiveCopy[i] == null)
                 throw new NullPointerException("stackTrace[" + i + "]");
 
-        this.stackTrace = defensiveCopy;
+        synchronized (this) {
+            this.stackTrace = defensiveCopy;
+        }
     }
 
     /**
@@ -772,11 +783,11 @@
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
         s.defaultReadObject();     // read in all fields
-        List<Throwable> suppressed = Collections.emptyList();
+        List<Throwable> suppressed = null;
         if (suppressedExceptions != null &&
             !suppressedExceptions.isEmpty()) { // Copy Throwables to new list
             suppressed = new ArrayList<Throwable>();
-            for(Throwable t : suppressedExceptions) {
+            for (Throwable t : suppressedExceptions) {
                 if (t == null)
                     throw new NullPointerException(NULL_CAUSE_MESSAGE);
                 suppressed.add(t);
@@ -819,7 +830,7 @@
         if (exception == this)
             throw new IllegalArgumentException("Self-suppression not permitted");
 
-        if (suppressedExceptions.size() == 0)
+        if (suppressedExceptions == null)
             suppressedExceptions = new ArrayList<Throwable>();
         suppressedExceptions.add(exception);
     }
@@ -835,7 +846,10 @@
      *         suppressed to deliver this exception.
      * @since 1.7
      */
-    public Throwable[] getSuppressedExceptions() {
-        return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
+    public synchronized Throwable[] getSuppressedExceptions() {
+        if (suppressedExceptions == null)
+            return EMPTY_THROWABLE_ARRAY;
+        else
+            return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
     }
 }
--- a/src/share/classes/java/net/HttpCookie.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/java/net/HttpCookie.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1093,14 +1093,8 @@
         return sb.toString();
     }
 
-    private static SimpleDateFormat[] cDateFormats = null;
-    static {
-            cDateFormats = new SimpleDateFormat[COOKIE_DATE_FORMATS.length];
-            for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) {
-                cDateFormats[i] = new SimpleDateFormat(COOKIE_DATE_FORMATS[i], Locale.US);
-                cDateFormats[i].setTimeZone(TimeZone.getTimeZone("GMT"));
-            }
-    }
+    static final TimeZone GMT = TimeZone.getTimeZone("GMT");
+
     /*
      * @param dateString        a date string in one of the formats
      *                          defined in Netscape cookie spec
@@ -1109,12 +1103,14 @@
      *                          time and the time specified by dateString
      */
     private long expiryDate2DeltaSeconds(String dateString) {
-        for (SimpleDateFormat df : cDateFormats) {
+        for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) {
+            SimpleDateFormat df = new SimpleDateFormat(COOKIE_DATE_FORMATS[i], Locale.US);
+            df.setTimeZone(GMT);
             try {
                 Date date = df.parse(dateString);
                 return (date.getTime() - whenCreated) / 1000;
             } catch (Exception e) {
-
+                // Ignore, try the next date format
             }
         }
         return 0;
--- a/src/share/classes/java/net/URI.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/java/net/URI.java	Sun Aug 29 22:41:28 2010 -0700
@@ -856,9 +856,7 @@
         try {
             return new URI(str);
         } catch (URISyntaxException x) {
-            IllegalArgumentException y = new IllegalArgumentException();
-            y.initCause(x);
-            throw y;
+            throw new IllegalArgumentException(x.getMessage(), x);
         }
     }
 
--- a/src/share/classes/java/security/KeyStore.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/java/security/KeyStore.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -131,17 +131,19 @@
  * to read existing entries from the keystore, or to write new entries
  * into the keystore:
  * <pre>
+ *    KeyStore.ProtectionParameter protParam =
+ *        new KeyStore.PasswordProtection(password);
+ *
  *    // get my private key
  *    KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
- *        ks.getEntry("privateKeyAlias", password);
+ *        ks.getEntry("privateKeyAlias", protParam);
  *    PrivateKey myPrivateKey = pkEntry.getPrivateKey();
  *
  *    // save my secret key
  *    javax.crypto.SecretKey mySecretKey;
  *    KeyStore.SecretKeyEntry skEntry =
  *        new KeyStore.SecretKeyEntry(mySecretKey);
- *    ks.setEntry("secretKeyAlias", skEntry,
- *        new KeyStore.PasswordProtection(password));
+ *    ks.setEntry("secretKeyAlias", skEntry, protParam);
  *
  *    // store away the keystore
  *    java.io.FileOutputStream fos = null;
--- a/src/share/classes/java/sql/Date.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/java/sql/Date.java	Sun Aug 29 22:41:28 2010 -0700
@@ -103,27 +103,46 @@
      *         JDBC date escape format (yyyy-mm-dd)
      */
     public static Date valueOf(String s) {
-        int year;
-        int month;
-        int day;
+        final int YEAR_LENGTH = 4;
+        final int MONTH_LENGTH = 2;
+        final int DAY_LENGTH = 2;
+        final int MAX_MONTH = 12;
+        final int MAX_DAY = 31;
         int firstDash;
         int secondDash;
+        Date d = null;
 
-        if (s == null) throw new java.lang.IllegalArgumentException();
-
-        firstDash = s.indexOf('-');
-        secondDash = s.indexOf('-', firstDash+1);
-        if ((firstDash > 0) & (secondDash > 0) & (secondDash < s.length()-1)) {
-            year = Integer.parseInt(s.substring(0, firstDash)) - 1900;
-            month = Integer.parseInt(s.substring(firstDash+1, secondDash)) - 1;
-            day = Integer.parseInt(s.substring(secondDash+1));
-        } else {
+        if (s == null) {
             throw new java.lang.IllegalArgumentException();
         }
 
-        return new Date(year, month, day);
+        firstDash = s.indexOf('-');
+        secondDash = s.indexOf('-', firstDash + 1);
+
+        if ((firstDash > 0) && (secondDash > 0) && (secondDash < s.length() - 1)) {
+            String yyyy = s.substring(0, firstDash);
+            String mm = s.substring(firstDash + 1, secondDash);
+            String dd = s.substring(secondDash + 1);
+            if (yyyy.length() == YEAR_LENGTH && mm.length() == MONTH_LENGTH &&
+                    dd.length() == DAY_LENGTH) {
+                int year = Integer.parseInt(yyyy);
+                int month = Integer.parseInt(mm);
+                int day = Integer.parseInt(dd);
+
+                if ((month >= 1 && month <= MAX_MONTH) && (day >= 1 && day <= MAX_DAY)) {
+                    d = new Date(year - 1900, month - 1, day);
+                }
+            }
+        }
+        if (d == null) {
+            throw new java.lang.IllegalArgumentException();
+        }
+
+        return d;
+
     }
 
+
     /**
      * Formats a date in the date escape format yyyy-mm-dd.
      * <P>
--- a/src/share/classes/javax/swing/JTable.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/javax/swing/JTable.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -946,7 +946,6 @@
 
     /**
      * Returns the height of a table row, in pixels.
-     * The default row height is 16.0.
      *
      * @return  the height in pixels of a table row
      * @see     #setRowHeight
--- a/src/share/classes/sun/java2d/pisces/Dasher.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/java2d/pisces/Dasher.java	Sun Aug 29 22:41:28 2010 -0700
@@ -36,117 +36,71 @@
  * semantics are unclear.
  *
  */
-public class Dasher extends LineSink {
+public class Dasher implements LineSink {
+    private final LineSink output;
+    private final float[] dash;
+    private final float startPhase;
+    private final boolean startDashOn;
+    private final int startIdx;
 
-    LineSink output;
-    int[] dash;
-    int startPhase;
-    boolean startDashOn;
-    int startIdx;
+    private final float m00, m10, m01, m11;
+    private final float det;
 
-    int idx;
-    boolean dashOn;
-    int phase;
+    private boolean firstDashOn;
+    private boolean starting;
 
-    int sx, sy;
-    int x0, y0;
+    private int idx;
+    private boolean dashOn;
+    private float phase;
 
-    int m00, m01;
-    int m10, m11;
+    private float sx, sy;
+    private float x0, y0;
+    private float sx1, sy1;
 
-    Transform4 transform;
-
-    boolean symmetric;
-    long ldet;
-
-    boolean firstDashOn;
-    boolean starting;
-    int sx1, sy1;
-
-    /**
-     * Empty constructor.  <code>setOutput</code> and
-     * <code>setParameters</code> must be called prior to calling any
-     * other methods.
-     */
-    public Dasher() {}
 
     /**
      * Constructs a <code>Dasher</code>.
      *
      * @param output an output <code>LineSink</code>.
-     * @param dash an array of <code>int</code>s containing the dash
-     * pattern in S15.16 format.
-     * @param phase an <code>int</code> containing the dash phase in
-     * S15.16 format.
+     * @param dash an array of <code>int</code>s containing the dash pattern
+     * @param phase an <code>int</code> containing the dash phase
      * @param transform a <code>Transform4</code> object indicating
      * the transform that has been previously applied to all incoming
      * coordinates.  This is required in order to compute dash lengths
      * properly.
      */
     public Dasher(LineSink output,
-                  int[] dash, int phase,
-                  Transform4 transform) {
-        setOutput(output);
-        setParameters(dash, phase, transform);
-    }
-
-    /**
-     * Sets the output <code>LineSink</code> of this
-     * <code>Dasher</code>.
-     *
-     * @param output an output <code>LineSink</code>.
-     */
-    public void setOutput(LineSink output) {
-        this.output = output;
-    }
-
-    /**
-     * Sets the parameters of this <code>Dasher</code>.
-     *
-     * @param dash an array of <code>int</code>s containing the dash
-     * pattern in S15.16 format.
-     * @param phase an <code>int</code> containing the dash phase in
-     * S15.16 format.
-     * @param transform a <code>Transform4</code> object indicating
-     * the transform that has been previously applied to all incoming
-     * coordinates.  This is required in order to compute dash lengths
-     * properly.
-     */
-    public void setParameters(int[] dash, int phase,
-                              Transform4 transform) {
+                  float[] dash, float phase,
+                  float a00, float a01, float a10, float a11) {
         if (phase < 0) {
             throw new IllegalArgumentException("phase < 0 !");
         }
 
+        this.output = output;
+
         // Normalize so 0 <= phase < dash[0]
         int idx = 0;
         dashOn = true;
-        int d;
+        float d;
         while (phase >= (d = dash[idx])) {
             phase -= d;
             idx = (idx + 1) % dash.length;
             dashOn = !dashOn;
         }
 
-        this.dash = new int[dash.length];
-        for (int i = 0; i < dash.length; i++) {
-            this.dash[i] = dash[i];
-        }
+        this.dash = dash;
         this.startPhase = this.phase = phase;
         this.startDashOn = dashOn;
         this.startIdx = idx;
 
-        this.transform = transform;
-
-        this.m00 = transform.m00;
-        this.m01 = transform.m01;
-        this.m10 = transform.m10;
-        this.m11 = transform.m11;
-        this.ldet = ((long)m00*m11 - (long)m01*m10) >> 16;
-        this.symmetric = (m00 == m11 && m10 == -m01);
+        m00 = a00;
+        m01 = a01;
+        m10 = a10;
+        m11 = a11;
+        det = m00 * m11 - m01 * m10;
     }
 
-    public void moveTo(int x0, int y0) {
+    public void moveTo(float x0, float y0) {
         output.moveTo(x0, y0);
         this.idx = startIdx;
         this.dashOn = this.startDashOn;
@@ -160,7 +114,7 @@
         output.lineJoin();
     }
 
-    private void goTo(int x1, int y1) {
+    private void goTo(float x1, float y1) {
         if (dashOn) {
             if (starting) {
                 this.sx1 = x1;
@@ -180,52 +134,64 @@
         this.y0 = y1;
     }
 
-    public void lineTo(int x1, int y1) {
+    public void lineTo(float x1, float y1) {
+        // The widened line is squished to a 0 width one, so no drawing is done
+        if (det == 0) {
+            goTo(x1, y1);
+            return;
+        }
+        float dx = x1 - x0;
+        float dy = y1 - y0;
+
+
+        // Compute segment length in the untransformed
+        // coordinate system
+
+        float la = (dy*m00 - dx*m10)/det;
+        float lb = (dy*m01 - dx*m11)/det;
+        float origLen = (float) Math.hypot(la, lb);
+
+        if (origLen == 0) {
+            // Let the output LineSink deal with cases where dx, dy are 0.
+            goTo(x1, y1);
+            return;
+        }
+
+        // The scaling factors needed to get the dx and dy of the
+        // transformed dash segments.
+        float cx = dx / origLen;
+        float cy = dy / origLen;
+
         while (true) {
-            int d = dash[idx] - phase;
-            int lx = x1 - x0;
-            int ly = y1 - y0;
-
-            // Compute segment length in the untransformed
-            // coordinate system
-            // IMPL NOTE - use fixed point
-
-            int l;
-            if (symmetric) {
-                l = (int)((PiscesMath.hypot(lx, ly)*65536L)/ldet);
-            } else{
-                long la = ((long)ly*m00 - (long)lx*m10)/ldet;
-                long lb = ((long)ly*m01 - (long)lx*m11)/ldet;
-                l = (int)PiscesMath.hypot(la, lb);
-            }
-
-            if (l < d) {
+            float leftInThisDashSegment = dash[idx] - phase;
+            if (origLen < leftInThisDashSegment) {
                 goTo(x1, y1);
                 // Advance phase within current dash segment
-                phase += l;
+                phase += origLen;
+                return;
+            } else if (origLen == leftInThisDashSegment) {
+                goTo(x1, y1);
+                phase = 0f;
+                idx = (idx + 1) % dash.length;
+                dashOn = !dashOn;
                 return;
             }
 
-            long t;
-            int xsplit, ysplit;
-//             // For zero length dashses, SE appears to move 1/8 unit
-//             // in device space
-//             if (d == 0) {
-//                 double dlx = lx/65536.0;
-//                 double dly = ly/65536.0;
-//                 len = PiscesMath.hypot(dlx, dly);
-//                 double dt = 1.0/(8*len);
-//                 double dxsplit = (x0/65536.0) + dt*dlx;
-//                 double dysplit = (y0/65536.0) + dt*dly;
-//                 xsplit = (int)(dxsplit*65536.0);
-//                 ysplit = (int)(dysplit*65536.0);
-//             } else {
-                t = ((long)d << 16)/l;
-                xsplit = x0 + (int)(t*(x1 - x0) >> 16);
-                ysplit = y0 + (int)(t*(y1 - y0) >> 16);
-//             }
-            goTo(xsplit, ysplit);
+            float dashx, dashy;
+            float dashdx = dash[idx] * cx;
+            float dashdy = dash[idx] * cy;
+            if (phase == 0) {
+                dashx = x0 + dashdx;
+                dashy = y0 + dashdy;
+            } else {
+                float p = (leftInThisDashSegment) / dash[idx];
+                dashx = x0 + p * dashdx;
+                dashy = y0 + p * dashdy;
+            }
 
+            goTo(dashx, dashy);
+
+            origLen -= (dash[idx] - phase);
             // Advance to next dash segment
             idx = (idx + 1) % dash.length;
             dashOn = !dashOn;
@@ -233,6 +199,7 @@
         }
     }
 
+
     public void close() {
         lineTo(sx, sy);
         if (firstDashOn) {
--- a/src/share/classes/sun/java2d/pisces/LineSink.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/java2d/pisces/LineSink.java	Sun Aug 29 22:41:28 2010 -0700
@@ -39,16 +39,16 @@
  * <code>LineSink</code> interface.
  *
  */
-public abstract class LineSink {
+public interface LineSink {
 
     /**
      * Moves the current drawing position to the point <code>(x0,
      * y0)</code>.
      *
-     * @param x0 the X coordinate in S15.16 format
-     * @param y0 the Y coordinate in S15.16 format
+     * @param x0 the X coordinate
+     * @param y0 the Y coordinate
      */
-    public abstract void moveTo(int x0, int y0);
+    public void moveTo(float x0, float y0);
 
     /**
      * Provides a hint that the current segment should be joined to
@@ -65,29 +65,29 @@
      * <p> Other <code>LineSink</code> classes should simply pass this
      * hint to their output sink as needed.
      */
-    public abstract void lineJoin();
+    public void lineJoin();
 
     /**
      * Draws a line from the current drawing position to the point
      * <code>(x1, y1)</code> and sets the current drawing position to
      * <code>(x1, y1)</code>.
      *
-     * @param x1 the X coordinate in S15.16 format
-     * @param y1 the Y coordinate in S15.16 format
+     * @param x1 the X coordinate
+     * @param y1 the Y coordinate
      */
-    public abstract void lineTo(int x1, int y1);
+    public void lineTo(float x1, float y1);
 
     /**
      * Closes the current path by drawing a line from the current
      * drawing position to the point specified by the moset recent
      * <code>moveTo</code> command.
      */
-    public abstract void close();
+    public void close();
 
     /**
      * Ends the current path.  It may be necessary to end a path in
      * order to allow end caps to be drawn.
      */
-    public abstract void end();
+    public void end();
 
 }
--- a/src/share/classes/sun/java2d/pisces/PiscesMath.java	Thu Aug 26 16:17:02 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.java2d.pisces;
-
-public class PiscesMath {
-
-    private PiscesMath() {}
-
-    private static final int SINTAB_LG_ENTRIES = 10;
-    private static final int SINTAB_ENTRIES = 1 << SINTAB_LG_ENTRIES;
-    private static int[] sintab;
-
-    public static final int PI = (int)(Math.PI*65536.0);
-    public static final int TWO_PI = (int)(2.0*Math.PI*65536.0);
-    public static final int PI_OVER_TWO = (int)((Math.PI/2.0)*65536.0);
-    public static final int SQRT_TWO = (int)(Math.sqrt(2.0)*65536.0);
-
-    static {
-        sintab = new int[SINTAB_ENTRIES + 1];
-        for (int i = 0; i < SINTAB_ENTRIES + 1; i++) {
-            double theta = i*(Math.PI/2.0)/SINTAB_ENTRIES;
-            sintab[i] = (int)(Math.sin(theta)*65536.0);
-        }
-    }
-
-    public static int sin(int theta) {
-        int sign = 1;
-        if (theta < 0) {
-            theta = -theta;
-            sign = -1;
-        }
-        // 0 <= theta
-        while (theta >= TWO_PI) {
-            theta -= TWO_PI;
-        }
-        // 0 <= theta < 2*PI
-        if (theta >= PI) {
-            theta = TWO_PI - theta;
-            sign = -sign;
-        }
-        // 0 <= theta < PI
-        if (theta > PI_OVER_TWO) {
-            theta = PI - theta;
-        }
-        // 0 <= theta <= PI/2
-        int itheta = (int)((long)theta*SINTAB_ENTRIES/(PI_OVER_TWO));
-        return sign*sintab[itheta];
-    }
-
-    public static int cos(int theta) {
-        return sin(PI_OVER_TWO - theta);
-    }
-
-//     public static double sqrt(double x) {
-//         double dsqrt = Math.sqrt(x);
-//         int ix = (int)(x*65536.0);
-//         Int Isqrt = Isqrt(Ix);
-
-//         Long Lx = (Long)(X*65536.0);
-//         Long Lsqrt = Lsqrt(Lx);
-
-//         System.Out.Println();
-//         System.Out.Println("X = " + X);
-//         System.Out.Println("Dsqrt = " + Dsqrt);
-
-//         System.Out.Println("Ix = " + Ix);
-//         System.Out.Println("Isqrt = " + Isqrt/65536.0);
-
-//         System.Out.Println("Lx = " + Lx);
-//         System.Out.Println("Lsqrt = " + Lsqrt/65536.0);
-
-//         Return Dsqrt;
-//     }
-
-    // From Ken Turkowski, _Fixed-Point Square Root_, In Graphics Gems V
-    public static int isqrt(int x) {
-        int fracbits = 16;
-
-        int root = 0;
-        int remHi = 0;
-        int remLo = x;
-        int count = 15 + fracbits/2;
-
-        do {
-            remHi = (remHi << 2) | (remLo >>> 30); // N.B. - unsigned shift R
-            remLo <<= 2;
-            root <<= 1;
-            int testdiv = (root << 1) + 1;
-            if (remHi >= testdiv) {
-                remHi -= testdiv;
-                root++;
-            }
-        } while (count-- != 0);
-
-        return root;
-    }
-
-    public static long lsqrt(long x) {
-        int fracbits = 16;
-
-        long root = 0;
-        long remHi = 0;
-        long remLo = x;
-        int count = 31 + fracbits/2;
-
-        do {
-            remHi = (remHi << 2) | (remLo >>> 62); // N.B. - unsigned shift R
-            remLo <<= 2;
-            root <<= 1;
-            long testDiv = (root << 1) + 1;
-            if (remHi >= testDiv) {
-                remHi -= testDiv;
-                root++;
-            }
-        } while (count-- != 0);
-
-        return root;
-    }
-
-    public static double hypot(double x, double y) {
-        // new RuntimeException().printStackTrace();
-        return Math.sqrt(x*x + y*y);
-    }
-
-    public static int hypot(int x, int y) {
-        return (int)((lsqrt((long)x*x + (long)y*y) + 128) >> 8);
-    }
-
-    public static long hypot(long x, long y) {
-        return (lsqrt(x*x + y*y) + 128) >> 8;
-    }
-}
--- a/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java	Sun Aug 29 22:41:28 2010 -0700
@@ -27,6 +27,7 @@
 
 import java.awt.Shape;
 import java.awt.BasicStroke;
+import java.awt.geom.FlatteningPathIterator;
 import java.awt.geom.Path2D;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.PathIterator;
@@ -37,23 +38,9 @@
 import sun.java2d.pipe.AATileGenerator;
 
 public class PiscesRenderingEngine extends RenderingEngine {
-    public static Transform4 IdentT4 = new Transform4();
     public static double defaultFlat = 0.1;
 
-    static int FloatToS15_16(float flt) {
-        flt = flt * 65536f + 0.5f;
-        if (flt <= -(65536f * 65536f)) {
-            return Integer.MIN_VALUE;
-        } else if (flt >= (65536f * 65536f)) {
-            return Integer.MAX_VALUE;
-        } else {
-            return (int) Math.floor(flt);
-        }
-    }
-
-    static float S15_16ToFloat(int fix) {
-        return (fix / 65536f);
-    }
+    private static enum NormMode {OFF, ON_NO_AA, ON_WITH_AA}
 
     /**
      * Create a widened path as specified by the parameters.
@@ -85,18 +72,19 @@
         strokeTo(src,
                  null,
                  width,
+                 NormMode.OFF,
                  caps,
                  join,
                  miterlimit,
                  dashes,
                  dashphase,
                  new LineSink() {
-                     public void moveTo(int x0, int y0) {
-                         p2d.moveTo(S15_16ToFloat(x0), S15_16ToFloat(y0));
+                     public void moveTo(float x0, float y0) {
+                         p2d.moveTo(x0, y0);
                      }
                      public void lineJoin() {}
-                     public void lineTo(int x1, int y1) {
-                         p2d.lineTo(S15_16ToFloat(x1), S15_16ToFloat(y1));
+                     public void lineTo(float x1, float y1) {
+                         p2d.lineTo(x1, y1);
                      }
                      public void close() {
                          p2d.closePath();
@@ -142,14 +130,17 @@
                          boolean antialias,
                          final PathConsumer2D consumer)
     {
-        strokeTo(src, at, bs, thin, normalize, antialias,
+        NormMode norm = (normalize) ?
+                ((antialias) ? NormMode.ON_WITH_AA : NormMode.ON_NO_AA)
+                : NormMode.OFF;
+        strokeTo(src, at, bs, thin, norm, antialias,
                  new LineSink() {
-                     public void moveTo(int x0, int y0) {
-                         consumer.moveTo(S15_16ToFloat(x0), S15_16ToFloat(y0));
+                     public void moveTo(float x0, float y0) {
+                         consumer.moveTo(x0, y0);
                      }
                      public void lineJoin() {}
-                     public void lineTo(int x1, int y1) {
-                         consumer.lineTo(S15_16ToFloat(x1), S15_16ToFloat(y1));
+                     public void lineTo(float x1, float y1) {
+                         consumer.lineTo(x1, y1);
                      }
                      public void close() {
                          consumer.closePath();
@@ -164,7 +155,7 @@
                   AffineTransform at,
                   BasicStroke bs,
                   boolean thin,
-                  boolean normalize,
+                  NormMode normalize,
                   boolean antialias,
                   LineSink lsink)
     {
@@ -181,6 +172,7 @@
         strokeTo(src,
                  at,
                  lw,
+                 normalize,
                  bs.getEndCap(),
                  bs.getLineJoin(),
                  bs.getMiterLimit(),
@@ -258,6 +250,7 @@
     void strokeTo(Shape src,
                   AffineTransform at,
                   float width,
+                  NormMode normalize,
                   int caps,
                   int join,
                   float miterlimit,
@@ -265,36 +258,139 @@
                   float dashphase,
                   LineSink lsink)
     {
-        Transform4 t4;
+        float a00 = 1f, a01 = 0f, a10 = 0f, a11 = 1f;
+        if (at != null && !at.isIdentity()) {
+            a00 = (float)at.getScaleX();
+            a01 = (float)at.getShearX();
+            a10 = (float)at.getShearY();
+            a11 = (float)at.getScaleY();
+        }
+        lsink = new Stroker(lsink, width, caps, join, miterlimit, a00, a01, a10, a11);
+        if (dashes != null) {
+            lsink = new Dasher(lsink, dashes, dashphase, a00, a01, a10, a11);
+        }
+        PathIterator pi;
+        if (normalize != NormMode.OFF) {
+            pi = new FlatteningPathIterator(
+                    new NormalizingPathIterator(src.getPathIterator(at), normalize),
+                    defaultFlat);
+        } else {
+            pi = src.getPathIterator(at, defaultFlat);
+        }
+        pathTo(pi, lsink);
+    }
 
-        if (at == null || at.isIdentity()) {
-            t4 = IdentT4;
-        } else {
-            t4 = new Transform4(FloatToS15_16((float) at.getScaleX()),
-                                FloatToS15_16((float) at.getShearX()),
-                                FloatToS15_16((float) at.getShearY()),
-                                FloatToS15_16((float) at.getScaleY()));
+    private static class NormalizingPathIterator implements PathIterator {
+
+        private final PathIterator src;
+
+        // the adjustment applied to the current position.
+        private float curx_adjust, cury_adjust;
+        // the adjustment applied to the last moveTo position.
+        private float movx_adjust, movy_adjust;
+
+        // constants used in normalization computations
+        private final float lval, rval;
+
+        NormalizingPathIterator(PathIterator src, NormMode mode) {
+            this.src = src;
+            switch (mode) {
+            case ON_NO_AA:
+                // round to nearest (0.25, 0.25) pixel
+                lval = rval = 0.25f;
+                break;
+            case ON_WITH_AA:
+                // round to nearest pixel center
+                lval = 0f;
+                rval = 0.5f;
+                break;
+            case OFF:
+                throw new InternalError("A NormalizingPathIterator should " +
+                         "not be created if no normalization is being done");
+            default:
+                throw new InternalError("Unrecognized normalization mode");
+            }
         }
 
-        lsink = new Stroker(lsink,
-                            FloatToS15_16(width),
-                            caps,
-                            join,
-                            FloatToS15_16(miterlimit),
-                            t4);
-        if (dashes != null) {
-            int fdashes[] = new int[dashes.length];
-            for (int i = 0; i < dashes.length; i++) {
-                fdashes[i] = FloatToS15_16(dashes[i]);
+        public int currentSegment(float[] coords) {
+            int type = src.currentSegment(coords);
+
+            int lastCoord;
+            switch(type) {
+            case PathIterator.SEG_CUBICTO:
+                lastCoord = 4;
+                break;
+            case PathIterator.SEG_QUADTO:
+                lastCoord = 2;
+                break;
+            case PathIterator.SEG_LINETO:
+            case PathIterator.SEG_MOVETO:
+                lastCoord = 0;
+                break;
+            case PathIterator.SEG_CLOSE:
+                // we don't want to deal with this case later. We just exit now
+                curx_adjust = movx_adjust;
+                cury_adjust = movy_adjust;
+                return type;
+            default:
+                throw new InternalError("Unrecognized curve type");
             }
-            lsink = new Dasher(lsink,
-                               fdashes,
-                               FloatToS15_16(dashphase),
-                               t4);
+
+            // normalize endpoint
+            float x_adjust = (float)Math.floor(coords[lastCoord] + lval) + rval -
+                         coords[lastCoord];
+            float y_adjust = (float)Math.floor(coords[lastCoord+1] + lval) + rval -
+                         coords[lastCoord + 1];
+
+            coords[lastCoord    ] += x_adjust;
+            coords[lastCoord + 1] += y_adjust;
+
+            // now that the end points are done, normalize the control points
+            switch(type) {
+            case PathIterator.SEG_CUBICTO:
+                coords[0] += curx_adjust;
+                coords[1] += cury_adjust;
+                coords[2] += x_adjust;
+                coords[3] += y_adjust;
+                break;
+            case PathIterator.SEG_QUADTO:
+                coords[0] += (curx_adjust + x_adjust) / 2;
+                coords[1] += (cury_adjust + y_adjust) / 2;
+                break;
+            case PathIterator.SEG_LINETO:
+                break;
+            case PathIterator.SEG_MOVETO:
+                movx_adjust = x_adjust;
+                movy_adjust = y_adjust;
+                break;
+            case PathIterator.SEG_CLOSE:
+                throw new InternalError("This should be handled earlier.");
+            }
+            curx_adjust = x_adjust;
+            cury_adjust = y_adjust;
+            return type;
         }
 
-        PathIterator pi = src.getPathIterator(at, defaultFlat);
-        pathTo(pi, lsink);
+        public int currentSegment(double[] coords) {
+            float[] tmp = new float[6];
+            int type = this.currentSegment(tmp);
+            for (int i = 0; i < 6; i++) {
+                coords[i] = (float) tmp[i];
+            }
+            return type;
+        }
+
+        public int getWindingRule() {
+            return src.getWindingRule();
+        }
+
+        public boolean isDone() {
+            return src.isDone();
+        }
+
+        public void next() {
+            src.next();
+        }
     }
 
     void pathTo(PathIterator pi, LineSink lsink) {
@@ -302,13 +398,11 @@
         while (!pi.isDone()) {
             switch (pi.currentSegment(coords)) {
             case PathIterator.SEG_MOVETO:
-                lsink.moveTo(FloatToS15_16(coords[0]),
-                             FloatToS15_16(coords[1]));
+                lsink.moveTo(coords[0], coords[1]);
                 break;
             case PathIterator.SEG_LINETO:
                 lsink.lineJoin();
-                lsink.lineTo(FloatToS15_16(coords[0]),
-                             FloatToS15_16(coords[1]));
+                lsink.lineTo(coords[0], coords[1]);
                 break;
             case PathIterator.SEG_CLOSE:
                 lsink.lineJoin();
@@ -378,18 +472,28 @@
                                               int bbox[])
     {
         PiscesCache pc = PiscesCache.createInstance();
-        Renderer r = new Renderer();
-        r.setCache(pc);
-        r.setAntialiasing(3, 3);
-        r.beginRendering(clip.getLoX(), clip.getLoY(),
-                         clip.getWidth(), clip.getHeight());
+        Renderer r;
+        NormMode norm = (normalize) ? NormMode.ON_WITH_AA : NormMode.OFF;
         if (bs == null) {
-            PathIterator pi = s.getPathIterator(at, defaultFlat);
-            r.setWindingRule(pi.getWindingRule());
+            PathIterator pi;
+            if (normalize) {
+                pi = new FlatteningPathIterator(
+                        new NormalizingPathIterator(s.getPathIterator(at), norm),
+                        defaultFlat);
+            } else {
+                pi = s.getPathIterator(at, defaultFlat);
+            }
+            r = new Renderer(3, 3,
+                             clip.getLoX(), clip.getLoY(),
+                             clip.getWidth(), clip.getHeight(),
+                             pi.getWindingRule(), pc);
             pathTo(pi, r);
         } else {
-            r.setWindingRule(PathIterator.WIND_NON_ZERO);
-            strokeTo(s, at, bs, thin, normalize, true, r);
+            r = new Renderer(3, 3,
+                             clip.getLoX(), clip.getLoY(),
+                             clip.getWidth(), clip.getHeight(),
+                             PathIterator.WIND_NON_ZERO, pc);
+            strokeTo(s, at, bs, thin, norm, true, r);
         }
         r.endRendering();
         PiscesTileGenerator ptg = new PiscesTileGenerator(pc, r.MAX_AA_ALPHA);
@@ -420,3 +524,4 @@
         }
     }
 }
+
--- a/src/share/classes/sun/java2d/pisces/Renderer.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/java2d/pisces/Renderer.java	Sun Aug 29 22:41:28 2010 -0700
@@ -25,446 +25,440 @@
 
 package sun.java2d.pisces;
 
-public class Renderer extends LineSink {
+import java.util.Arrays;
+
+public class Renderer implements LineSink {
+
+///////////////////////////////////////////////////////////////////////////////
+// Scan line iterator and edge crossing data.
+//////////////////////////////////////////////////////////////////////////////
+
+    private int[] crossings;
+
+    // This is an array of indices into the edge array. It is initialized to
+    // [i * SIZEOF_STRUCT_EDGE for i in range(0, edgesSize/SIZEOF_STRUCT_EDGE)]
+    // (where range(i, j) is i,i+1,...,j-1 -- just like in python).
+    // The reason for keeping this is because we need the edges array sorted
+    // by y0, but we don't want to move all that data around, so instead we
+    // sort the indices into the edge array, and use edgeIndices to access
+    // the edges array. This is meant to simulate a pointer array (hence the name)
+    private int[] edgePtrs;
+
+    // crossing bounds. The bounds are not necessarily tight (the scan line
+    // at minY, for example, might have no crossings). The x bounds will
+    // be accumulated as crossings are computed.
+    private int minY, maxY;
+    private int minX, maxX;
+    private int nextY;
+
+    // indices into the edge pointer list. They indicate the "active" sublist in
+    // the edge list (the portion of the list that contains all the edges that
+    // cross the next scan line).
+    private int lo, hi;
+
+    private static final int INIT_CROSSINGS_SIZE = 50;
+    private void ScanLineItInitialize() {
+        crossings = new int[INIT_CROSSINGS_SIZE];
+        edgePtrs = new int[edgesSize / SIZEOF_STRUCT_EDGE];
+        for (int i = 0; i < edgePtrs.length; i++) {
+            edgePtrs[i] = i * SIZEOF_STRUCT_EDGE;
+        }
+
+        qsort(0, edgePtrs.length - 1);
+
+        // We don't care if we clip some of the line off with ceil, since
+        // no scan line crossings will be eliminated (in fact, the ceil is
+        // the y of the first scan line crossing).
+        nextY = minY = Math.max(boundsMinY, (int)Math.ceil(edgeMinY));
+        maxY = Math.min(boundsMaxY, (int)Math.ceil(edgeMaxY));
+
+        for (lo = 0; lo < edgePtrs.length && edges[edgePtrs[lo]+Y1] <= nextY; lo++)
+            ;
+        for (hi = lo; hi < edgePtrs.length && edges[edgePtrs[hi]+CURY] <= nextY; hi++)
+            ; // the active list is *edgePtrs[lo] (inclusive) *edgePtrs[hi] (exclusive)
+        for (int i = lo; i < hi; i++) {
+            setCurY(edgePtrs[i], nextY);
+        }
+
+        // We accumulate X in the iterator because accumulating it in addEdge
+        // like we do with Y does not do much good: if there's an edge
+        // (0,0)->(1000,10000), and if y gets clipped to 1000, then the x
+        // bound should be 100, but the accumulator from addEdge would say 1000,
+        // so we'd still have to accumulate the X bounds as we add crossings.
+        minX = boundsMinX;
+        maxX = boundsMaxX;
+    }
+
+    private int ScanLineItCurrentY() {
+        return nextY - 1;
+    }
+
+    private int ScanLineItGoToNextYAndComputeCrossings() {
+        // we go through the active list and remove the ones that don't cross
+        // the nextY scanline.
+        int crossingIdx = 0;
+        for (int i = lo; i < hi; i++) {
+            if (edges[edgePtrs[i]+Y1] <= nextY) {
+                edgePtrs[i] = edgePtrs[lo++];
+            }
+        }
+        if (hi - lo > crossings.length) {
+            int newSize = Math.max(hi - lo, crossings.length * 2);
+            crossings = Arrays.copyOf(crossings, newSize);
+        }
+        // Now every edge between lo and hi crosses nextY. Compute it's
+        // crossing and put it in the crossings array.
+        for (int i = lo; i < hi; i++) {
+            addCrossing(nextY, getCurCrossing(edgePtrs[i]), (int)edges[edgePtrs[i]+OR], crossingIdx);
+            gotoNextY(edgePtrs[i]);
+            crossingIdx++;
+        }
+
+        nextY++;
+        // Expand active list to include new edges.
+        for (; hi < edgePtrs.length && edges[edgePtrs[hi]+CURY] <= nextY; hi++) {
+            setCurY(edgePtrs[hi], nextY);
+        }
+
+        Arrays.sort(crossings, 0, crossingIdx);
+        return crossingIdx;
+    }
+
+    private boolean ScanLineItHasNext() {
+        return nextY < maxY;
+    }
+
+    private void addCrossing(int y, int x, int or, int idx) {
+        if (x < minX) {
+            minX = x;
+        }
+        if (x > maxX) {
+            maxX = x;
+        }
+        x <<= 1;
+        crossings[idx] = ((or == 1) ? (x | 0x1) : x);
+    }
+
+
+    // quicksort implementation for sorting the edge indices ("pointers")
+    // by increasing y0. first, last are indices into the "pointer" array
+    // It sorts the pointer array from first (inclusive) to last (inclusive)
+    private void qsort(int first, int last) {
+        if (last > first) {
+            int p = partition(first, last);
+            if (first < p - 1) {
+                qsort(first, p - 1);
+            }
+            if (p < last) {
+                qsort(p, last);
+            }
+        }
+    }
+
+    // i, j are indices into edgePtrs.
+    private int partition(int i, int j) {
+        int pivotVal = edgePtrs[i];
+        while (i <= j) {
+            // edges[edgePtrs[i]+1] is equivalent to (*(edgePtrs[i])).y0 in C
+            while (edges[edgePtrs[i]+CURY] < edges[pivotVal+CURY]) { i++; }
+            while (edges[edgePtrs[j]+CURY] > edges[pivotVal+CURY]) { j--; }
+            if (i <= j) {
+                int tmp = edgePtrs[i];
+                edgePtrs[i] = edgePtrs[j];
+                edgePtrs[j] = tmp;
+                i++;
+                j--;
+            }
+        }
+        return i;
+    }
+
+//============================================================================
+
+
+//////////////////////////////////////////////////////////////////////////////
+//  EDGE LIST
+//////////////////////////////////////////////////////////////////////////////
+
+    private static final int INIT_NUM_EDGES = 1000;
+    private static final int SIZEOF_STRUCT_EDGE = 5;
+
+    // The following array is a poor man's struct array:
+    // it simulates a struct array by having
+    // edges[SIZEOF_STRUCT_EDGE * i + j] be the jth field in the ith element
+    // of an array of edge structs.
+    private float[] edges;
+    private int edgesSize; // size of the edge list.
+    private static final int Y1    = 0;
+    private static final int SLOPE = 1;
+    private static final int OR    = 2; // the orientation. This can be -1 or 1.
+                                     // -1 means up, 1 means down.
+    private static final int CURY  = 3; // j = 5 corresponds to the "current Y".
+                             // Each edge keeps track of the last scanline
+                             // crossing it computed, and this is the y coord of
+                             // that scanline.
+    private static final int CURX = 4; //the x coord of the current crossing.
+
+    // Note that while the array is declared as a float[] not all of it's
+    // elements should be floats. currentY and Orientation should be ints (or int and
+    // byte respectively), but they all need to be the same type. This isn't
+    // really a problem because floats can represent exactly all 23 bit integers,
+    // which should be more than enough.
+    // Note, also, that we only need x1 for slope computation, so we don't need
+    // to store it. x0, y0 don't need to be stored either. They can be put into
+    // curx, cury, and it's ok if they're lost when curx and cury are changed.
+    // We take this undeniably ugly and error prone approach (instead of simply
+    // making an Edge class) for performance reasons. Also, it would probably be nicer
+    // to have one array for each field, but that would defeat the purpose because
+    // it would make poor use of the processor cache, since we tend to access
+    // all the fields for one edge at a time.
+
+    private float edgeMinY;
+    private float edgeMaxY;
+
+
+    private void addEdge(float x0, float y0, float x1, float y1) {
+        float or = (y0 < y1) ? 1f : -1f; // orientation: 1 = UP; -1 = DOWN
+        if (or == -1) {
+            float tmp = y0;
+            y0 = y1;
+            y1 = tmp;
+            tmp = x0;
+            x0 = x1;
+            x1 = tmp;
+        }
+        // skip edges that don't cross a scanline
+        if (Math.ceil(y0) >= Math.ceil(y1)) {
+            return;
+        }
+
+        int newSize = edgesSize + SIZEOF_STRUCT_EDGE;
+        if (edges.length < newSize) {
+            edges = Arrays.copyOf(edges, newSize * 2);
+        }
+        edges[edgesSize+CURX] = x0;
+        edges[edgesSize+CURY] = y0;
+        edges[edgesSize+Y1] = y1;
+        edges[edgesSize+SLOPE] = (x1 - x0) / (y1 - y0);
+        edges[edgesSize+OR] = or;
+        // the crossing values can't be initialized meaningfully yet. This
+        // will have to wait until setCurY is called
+        edgesSize += SIZEOF_STRUCT_EDGE;
+
+        // Accumulate edgeMinY and edgeMaxY
+        if (y0 < edgeMinY) { edgeMinY = y0; }
+        if (y1 > edgeMaxY) { edgeMaxY = y1; }
+    }
+
+    // As far as the following methods care, this edges extends to infinity.
+    // They can compute the x intersect of any horizontal line.
+    // precondition: idx is the index to the start of the desired edge.
+    // So, if the ith edge is wanted, idx should be SIZEOF_STRUCT_EDGE * i
+    private void setCurY(int idx, int y) {
+        // compute the x crossing of edge at idx and horizontal line y
+        // currentXCrossing = (y - y0)*slope + x0
+        edges[idx + CURX] = (y - edges[idx + CURY]) * edges[idx + SLOPE] + edges[idx+CURX];
+        edges[idx + CURY] = (float)y;
+    }
+
+    private void gotoNextY(int idx) {
+        edges[idx + CURY] += 1f; // i.e. curY += 1
+        edges[idx + CURX] += edges[idx + SLOPE]; // i.e. curXCrossing += slope
+    }
+
+    private int getCurCrossing(int idx) {
+        return (int)edges[idx + CURX];
+    }
+//====================================================================================
+
     public static final int WIND_EVEN_ODD = 0;
     public static final int WIND_NON_ZERO = 1;
 
-    // Initial edge list size
-    // IMPL_NOTE - restore size after growth
-    public static final int INITIAL_EDGES = 1000;
-
-    // Recommended maximum scratchpad sizes.  The arrays will grow
-    // larger if needed, but when finished() is called they will be released
-    // if they have grown larger than these sizes.
-    public static final int DEFAULT_INDICES_SIZE = 8192;
-    public static final int DEFAULT_CROSSINGS_SIZE = 32*1024;
-
     // Antialiasing
-    private int SUBPIXEL_LG_POSITIONS_X;
-    private int SUBPIXEL_LG_POSITIONS_Y;
-    private int SUBPIXEL_MASK_X;
-    private int SUBPIXEL_MASK_Y;
-    private int SUBPIXEL_POSITIONS_X;
-    private int SUBPIXEL_POSITIONS_Y;
-    int MAX_AA_ALPHA;
-    private int MAX_AA_ALPHA_DENOM;
-    private int HALF_MAX_AA_ALPHA_DENOM;
-    private int XSHIFT;
-    private int YSHIFT;
-    private int YSTEP;
-    private int HYSTEP;
-    private int YMASK;
-
-    private static final int MIN_QUAD_OPT_WIDTH = 100 << 16;
+    final private int SUBPIXEL_LG_POSITIONS_X;
+    final private int SUBPIXEL_LG_POSITIONS_Y;
+    final private int SUBPIXEL_POSITIONS_X;
+    final private int SUBPIXEL_POSITIONS_Y;
+    final private int SUBPIXEL_MASK_X;
+    final private int SUBPIXEL_MASK_Y;
+    final int MAX_AA_ALPHA;
 
     // Cache to store RLE-encoded coverage mask of the current primitive
-    PiscesCache cache;
+    final PiscesCache cache;
 
-    // Bounds of the drawing region, at S15.16 precsion
-    private int boundsMinX, boundsMinY, boundsMaxX, boundsMaxY;
-
-    // Bounds of the current primitive, at subsample precision
-    private int rasterMinX, rasterMaxX, rasterMinY, rasterMaxY;
+    // Bounds of the drawing region, at subpixel precision.
+    final private int boundsMinX, boundsMinY, boundsMaxX, boundsMaxY;
 
     // Pixel bounding box for current primitive
-    private int bboxX0, bboxY0, bboxX1, bboxY1;
+    private int pix_bboxX0, pix_bboxY0, pix_bboxX1, pix_bboxY1;
 
     // Current winding rule
-    private int windingRule;
+    final private int windingRule;
 
     // Current drawing position, i.e., final point of last segment
-    private int x0, y0;
+    private float x0, y0;
 
     // Position of most recent 'moveTo' command
-    private int sx0, sy0;
+    private float pix_sx0, pix_sy0;
 
-    // Buffer to be filled with one row's worth of alpha values
-    private byte[] rowAA; // needs to be short if 16x16 subsampling
+    public Renderer(int subpixelLgPositionsX, int subpixelLgPositionsY,
+                    int pix_boundsX, int pix_boundsY,
+                    int pix_boundsWidth, int pix_boundsHeight,
+                    int windingRule,
+                    PiscesCache cache) {
+        this.SUBPIXEL_LG_POSITIONS_X = subpixelLgPositionsX;
+        this.SUBPIXEL_LG_POSITIONS_Y = subpixelLgPositionsY;
+        this.SUBPIXEL_MASK_X = (1 << (SUBPIXEL_LG_POSITIONS_X)) - 1;
+        this.SUBPIXEL_MASK_Y = (1 << (SUBPIXEL_LG_POSITIONS_Y)) - 1;
+        this.SUBPIXEL_POSITIONS_X = 1 << (SUBPIXEL_LG_POSITIONS_X);
+        this.SUBPIXEL_POSITIONS_Y = 1 << (SUBPIXEL_LG_POSITIONS_Y);
+        this.MAX_AA_ALPHA = (SUBPIXEL_POSITIONS_X * SUBPIXEL_POSITIONS_Y);
 
-    // Track the number of vertical extrema of the incoming edge list
-    // in order to determine the maximum number of crossings of a
-    // scanline
-    private int firstOrientation;
-    private int lastOrientation;
-    private int flips;
+        this.edges = new float[SIZEOF_STRUCT_EDGE * INIT_NUM_EDGES];
+        edgeMinY = Float.POSITIVE_INFINITY;
+        edgeMaxY = Float.NEGATIVE_INFINITY;
+        edgesSize = 0;
 
-    // Parameters for emitRow
-    private int alphaWidth;
+        this.windingRule = windingRule;
+        this.cache = cache;
 
-    public Renderer() {
+        this.boundsMinX = pix_boundsX * SUBPIXEL_POSITIONS_X;
+        this.boundsMinY = pix_boundsY * SUBPIXEL_POSITIONS_Y;
+        this.boundsMaxX = (pix_boundsX + pix_boundsWidth) * SUBPIXEL_POSITIONS_X;
+        this.boundsMaxY = (pix_boundsY + pix_boundsHeight) * SUBPIXEL_POSITIONS_Y;
+
+        this.pix_bboxX0 = pix_boundsX;
+        this.pix_bboxY0 = pix_boundsY;
+        this.pix_bboxX1 = pix_boundsX + pix_boundsWidth;
+        this.pix_bboxY1 = pix_boundsY + pix_boundsHeight;
     }
 
-    public void setAntialiasing(int subpixelLgPositionsX,
-                                int subpixelLgPositionsY) {
-        this.SUBPIXEL_LG_POSITIONS_X = subpixelLgPositionsX;
-        this.SUBPIXEL_LG_POSITIONS_Y = subpixelLgPositionsY;
-
-        this.SUBPIXEL_MASK_X =
-            (1 << (SUBPIXEL_LG_POSITIONS_X)) - 1;
-        this.SUBPIXEL_MASK_Y =
-            (1 << (SUBPIXEL_LG_POSITIONS_Y)) - 1;
-        this.SUBPIXEL_POSITIONS_X =
-            1 << (SUBPIXEL_LG_POSITIONS_X);
-        this.SUBPIXEL_POSITIONS_Y =
-            1 << (SUBPIXEL_LG_POSITIONS_Y);
-        this.MAX_AA_ALPHA =
-            (SUBPIXEL_POSITIONS_X*SUBPIXEL_POSITIONS_Y);
-        this.MAX_AA_ALPHA_DENOM = 255*MAX_AA_ALPHA;
-        this.HALF_MAX_AA_ALPHA_DENOM = MAX_AA_ALPHA_DENOM/2;
-        this.XSHIFT = 16 - SUBPIXEL_LG_POSITIONS_X;
-        this.YSHIFT = 16 - SUBPIXEL_LG_POSITIONS_Y;
-        this.YSTEP = 1 << YSHIFT;
-        this.HYSTEP = 1 << (YSHIFT - 1);
-        this.YMASK = ~(YSTEP - 1);
+    private float tosubpixx(float pix_x) {
+        return pix_x * SUBPIXEL_POSITIONS_X;
+    }
+    private float tosubpixy(float pix_y) {
+        return pix_y * SUBPIXEL_POSITIONS_Y;
     }
 
-    public int getSubpixelLgPositionsX() {
-        return SUBPIXEL_LG_POSITIONS_X;
+    public void moveTo(float pix_x0, float pix_y0) {
+        close();
+        this.pix_sx0 = pix_x0;
+        this.pix_sy0 = pix_y0;
+        this.y0 = tosubpixy(pix_y0);
+        this.x0 = tosubpixx(pix_x0);
     }
 
-    public int getSubpixelLgPositionsY() {
-        return SUBPIXEL_LG_POSITIONS_Y;
-    }
+    public void lineJoin() { /* do nothing */ }
 
-    public void setWindingRule(int windingRule) {
-        this.windingRule = windingRule;
-    }
-
-    public int getWindingRule() {
-        return windingRule;
-    }
-
-    public void beginRendering(int boundsX, int boundsY,
-                               int boundsWidth, int boundsHeight) {
-        lastOrientation = 0;
-        flips = 0;
-
-        resetEdges();
-
-        this.boundsMinX = boundsX << 16;
-        this.boundsMinY = boundsY << 16;
-        this.boundsMaxX = (boundsX + boundsWidth) << 16;
-        this.boundsMaxY = (boundsY + boundsHeight) << 16;
-
-        this.bboxX0 = boundsX;
-        this.bboxY0 = boundsY;
-        this.bboxX1 = boundsX + boundsWidth;
-        this.bboxY1 = boundsY + boundsHeight;
-    }
-
-    public void moveTo(int x0, int y0) {
-        // System.out.println("Renderer: moveTo " + x0/65536.0 + " " + y0/65536.0);
-        close();
-        this.sx0 = this.x0 = x0;
-        this.sy0 = this.y0 = y0;
-        this.lastOrientation = 0;
-    }
-
-    public void lineJoin() {
-        // System.out.println("Renderer: lineJoin");
-        // do nothing
-    }
-
-    public void lineTo(int x1, int y1) {
-        // System.out.println("Renderer: lineTo " + x1/65536.0 + " " + y1/65536.0);
+    public void lineTo(float pix_x1, float pix_y1) {
+        float x1 = tosubpixx(pix_x1);
+        float y1 = tosubpixy(pix_y1);
 
         // Ignore horizontal lines
-        // Next line will count flip
         if (y0 == y1) {
             this.x0 = x1;
             return;
         }
 
-        int orientation = (y0 < y1) ? 1 : -1;
-        if (lastOrientation == 0) {
-            firstOrientation = orientation;
-        } else if (orientation != lastOrientation) {
-            ++flips;
-        }
-        lastOrientation = orientation;
-
-        // Bias Y by 1 ULP so endpoints never lie on a scanline
-        addEdge(x0, y0 | 0x1, x1, y1 | 0x1);
+        addEdge(x0, y0, x1, y1);
 
         this.x0 = x1;
         this.y0 = y1;
     }
 
     public void close() {
-        // System.out.println("Renderer: close");
-
-        int orientation = lastOrientation;
-        if (y0 != sy0) {
-            orientation = (y0 < sy0) ? 1 : -1;
-        }
-        if (orientation != firstOrientation) {
-            ++flips;
-        }
-        lineTo(sx0, sy0);
+        // lineTo expects its input in pixel coordinates.
+        lineTo(pix_sx0, pix_sy0);
     }
 
     public void end() {
         close();
-        // System.out.println("Renderer: end");
-        // do nothing
-    }
-
-    // Scan convert a single edge
-    private void computeCrossingsForEdge(int index,
-                                         int boundsMinY, int boundsMaxY) {
-        int iy0 = edges[index + 1];
-        int iy1 = edges[index + 3];
-
-        // Clip to valid Y range
-        int clipy0 = (iy0 > boundsMinY) ? iy0 : boundsMinY;
-        int clipy1 = (iy1 < boundsMaxY) ? iy1 : boundsMaxY;
-
-        int minY = ((clipy0 + HYSTEP) & YMASK) + HYSTEP;
-        int maxY = ((clipy1 - HYSTEP) & YMASK) + HYSTEP;
-
-        // IMPL_NOTE - If line falls outside the valid X range, could
-        // draw a vertical line instead
-
-        // Exit if no scanlines are crossed
-        if (minY > maxY) {
-            return;
-        }
-
-        // Scan convert line using a DDA approach
-
-        int ix0 = edges[index];
-        int ix1 = edges[index + 2];
-        long dx = ((long) ix1) - ix0;
-        long dy = ((long) iy1) - iy0;
-
-        // Compute first crossing point at y = minY
-        int orientation = edges[index + 4];
-        int y = minY;
-        long lx = (((long) y) - iy0)*dx/dy + ix0;
-        addCrossing(y >> YSHIFT, (int)(lx >> XSHIFT), orientation);
-
-        // Advance y to next scanline, exit if past endpoint
-        y += YSTEP;
-        if (y > maxY) {
-            return;
-        }
-
-        // Compute xstep only if additional scanlines are crossed
-        // For each scanline, add xstep to lx and YSTEP to y and
-        // emit the new crossing
-        long xstep = ((long)YSTEP*dx)/dy;
-        for (; y <= maxY; y += YSTEP) {
-            lx += xstep;
-            addCrossing(y >> YSHIFT, (int)(lx >> XSHIFT), orientation);
-        }
-    }
-
-    private void computeBounds() {
-        rasterMinX = crossingMinX & ~SUBPIXEL_MASK_X;
-        rasterMaxX = crossingMaxX | SUBPIXEL_MASK_X;
-        rasterMinY = crossingMinY & ~SUBPIXEL_MASK_Y;
-        rasterMaxY = crossingMaxY | SUBPIXEL_MASK_Y;
-
-        // If nothing was drawn, we have:
-        // minX = Integer.MAX_VALUE and maxX = Integer.MIN_VALUE
-        // so nothing to render
-        if (rasterMinX > rasterMaxX || rasterMinY > rasterMaxY) {
-            rasterMinX = 0;
-            rasterMaxX = -1;
-            rasterMinY = 0;
-            rasterMaxY = -1;
-            return;
-        }
-
-        if (rasterMinX < boundsMinX >> XSHIFT) {
-            rasterMinX = boundsMinX >> XSHIFT;
-        }
-        if (rasterMinY < boundsMinY >> YSHIFT) {
-            rasterMinY = boundsMinY >> YSHIFT;
-        }
-        if (rasterMaxX > boundsMaxX >> XSHIFT) {
-            rasterMaxX = boundsMaxX >> XSHIFT;
-        }
-        if (rasterMaxY > boundsMaxY >> YSHIFT) {
-            rasterMaxY = boundsMaxY >> YSHIFT;
-        }
-    }
-
-    private int clamp(int x, int min, int max) {
-        if (x < min) {
-            return min;
-        } else if (x > max) {
-            return max;
-        }
-        return x;
     }
 
     private void _endRendering() {
-        if (flips == 0) {
-            bboxX0 = bboxY0 = 0;
-            bboxX1 = bboxY1 = -1;
-            return;
+        // Mask to determine the relevant bit of the crossing sum
+        // 0x1 if EVEN_ODD, all bits if NON_ZERO
+        int mask = (windingRule == WIND_EVEN_ODD) ? 0x1 : ~0x0;
+
+        // add 1 to better deal with the last pixel in a pixel row.
+        int width = ((boundsMaxX - boundsMinX) >> SUBPIXEL_LG_POSITIONS_X) + 1;
+        byte[] alpha = new byte[width+1];
+
+        // Now we iterate through the scanlines. We must tell emitRow the coord
+        // of the first non-transparent pixel, so we must keep accumulators for
+        // the first and last pixels of the section of the current pixel row
+        // that we will emit.
+        // We also need to accumulate pix_bbox*, but the iterator does it
+        // for us. We will just get the values from it once this loop is done
+        int pix_maxX = Integer.MIN_VALUE;
+        int pix_minX = Integer.MAX_VALUE;
+
+        int y = boundsMinY; // needs to be declared here so we emit the last row properly.
+        ScanLineItInitialize();
+        for ( ; ScanLineItHasNext(); ) {
+            int numCrossings = ScanLineItGoToNextYAndComputeCrossings();
+            y = ScanLineItCurrentY();
+
+            if (numCrossings > 0) {
+                int lowx = crossings[0] >> 1;
+                int highx = crossings[numCrossings - 1] >> 1;
+                int x0 = Math.max(lowx, boundsMinX);
+                int x1 = Math.min(highx, boundsMaxX);
+
+                pix_minX = Math.min(pix_minX, x0 >> SUBPIXEL_LG_POSITIONS_X);
+                pix_maxX = Math.max(pix_maxX, x1 >> SUBPIXEL_LG_POSITIONS_X);
+            }
+
+            int sum = 0;
+            int prev = boundsMinX;
+            for (int i = 0; i < numCrossings; i++) {
+                int curxo = crossings[i];
+                int curx = curxo >> 1;
+                int crorientation = ((curxo & 0x1) == 0x1) ? 1 : -1;
+                if ((sum & mask) != 0) {
+                    int x0 = Math.max(prev, boundsMinX);
+                    int x1 = Math.min(curx, boundsMaxX);
+                    if (x0 < x1) {
+                        x0 -= boundsMinX; // turn x0, x1 from coords to indeces
+                        x1 -= boundsMinX; // in the alpha array.
+
+                        int pix_x = x0 >> SUBPIXEL_LG_POSITIONS_X;
+                        int pix_xmaxm1 = (x1 - 1) >> SUBPIXEL_LG_POSITIONS_X;
+
+                        if (pix_x == pix_xmaxm1) {
+                            // Start and end in same pixel
+                            alpha[pix_x] += (x1 - x0);
+                            alpha[pix_x+1] -= (x1 - x0);
+                        } else {
+                            int pix_xmax = x1 >> SUBPIXEL_LG_POSITIONS_X;
+                            alpha[pix_x] += SUBPIXEL_POSITIONS_X - (x0 & SUBPIXEL_MASK_X);
+                            alpha[pix_x+1] += (x0 & SUBPIXEL_MASK_X);
+                            alpha[pix_xmax] -= SUBPIXEL_POSITIONS_X - (x1 & SUBPIXEL_MASK_X);
+                            alpha[pix_xmax+1] -= (x1 & SUBPIXEL_MASK_X);
+                        }
+                    }
+                }
+                sum += crorientation;
+                prev = curx;
+            }
+
+            if ((y & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) {
+                emitRow(alpha, y >> SUBPIXEL_LG_POSITIONS_Y, pix_minX, pix_maxX);
+                pix_minX = Integer.MAX_VALUE;
+                pix_maxX = Integer.MIN_VALUE;
+            }
         }
 
-        // Special case for filling a single rect with a flat, opaque color
-        // REMIND: This special case was not originally written to fill a
-        // cache object and called directly to a Blit - it needs some code
-        // to fill the cache instead to be useful for this usage...
-        if (false /* Does not work with cache (yet?) */ &&
-            edgeIdx == 10 &&
-            edges[0] == edges[2] &&
-            edges[1] == edges[6] &&
-            edges[3] == edges[8] &&
-            edges[5] == edges[7] &&
-            Math.abs(edges[0] - edges[5]) > MIN_QUAD_OPT_WIDTH)
-        {
+        // Emit final row
+        if (pix_maxX >= pix_minX) {
+            emitRow(alpha, y >> SUBPIXEL_LG_POSITIONS_Y, pix_minX, pix_maxX);
+        }
+        pix_bboxX0 = minX >> SUBPIXEL_LG_POSITIONS_X;
+        pix_bboxX1 = maxX >> SUBPIXEL_LG_POSITIONS_X;
+        pix_bboxY0 = minY >> SUBPIXEL_LG_POSITIONS_Y;
+        pix_bboxY1 = maxY >> SUBPIXEL_LG_POSITIONS_Y;
+    }
 
-            int x0 = edges[0] >> XSHIFT;
-            int y0 = edges[1] >> YSHIFT;
-            int x1 = edges[5] >> XSHIFT;
-            int y1 = edges[3] >> YSHIFT;
-
-            if (x0 > x1) {
-                int tmp = x0;
-                x0 = x1;
-                x1 = tmp;
-            }
-            if (y0 > y1) {
-                int tmp = y0;
-                y0 = y1;
-                y1 = tmp;
-            }
-
-            int bMinX = this.boundsMinX >> XSHIFT;
-            int bMinY = this.boundsMinY >> YSHIFT;
-            int bMaxX = this.boundsMaxX >> XSHIFT;
-            int bMaxY = this.boundsMaxY >> YSHIFT;
-
-            // Clip to image bounds in supersampled coordinates
-            x0 = clamp(x0, bMinX, bMaxX);
-            x1 = clamp(x1, bMinX, bMaxX);
-            y0 = clamp(y0, bMinY, bMaxY);
-            y1 = clamp(y1, bMinY, bMaxY);
-
-            /*
-             * REMIND: Need to fill the cache here instead...
-            Blit.fillRectSrcOver(this,
-                                 imageData, imageType,
-                                 imageOffset,
-                                 imageScanlineStride, imagePixelStride,
-                                 width, height,
-                                 x0, y0, x1, y1,
-                                 cred, cgreen, cblue);
-            */
-
-            bboxX0 = x0 >> SUBPIXEL_LG_POSITIONS_X;
-            bboxY0 = y0 >> SUBPIXEL_LG_POSITIONS_Y;
-            bboxX1 = (x1 + SUBPIXEL_POSITIONS_X - 1)
-                >> SUBPIXEL_LG_POSITIONS_X;
-            bboxY1 = (y1 + SUBPIXEL_POSITIONS_Y - 1)
-                >> SUBPIXEL_LG_POSITIONS_Y;
-
-            return;
-        }
-
-        int minY = (edgeMinY > boundsMinY) ? edgeMinY : boundsMinY;
-        int maxY = (edgeMaxY < boundsMaxY) ? edgeMaxY : boundsMaxY;
-
-        // Check for empty intersection of primitive with the drawing area
-        if (minY > maxY) {
-            bboxX0 = bboxY0 = 0;
-            bboxX1 = bboxY1 = -1;
-            return;
-        }
-
-        // Compute Y extent in subpixel coordinates
-        int iminY = (minY >> YSHIFT) & ~SUBPIXEL_MASK_Y;
-        int imaxY = (maxY >> YSHIFT) | SUBPIXEL_MASK_Y;
-        int yextent = (imaxY - iminY) + 1;
-
-        // Maximum number of crossings
-        int size = flips*yextent;
-
-        int bmax = (boundsMaxY >> YSHIFT) - 1;
-        if (imaxY > bmax) {
-            imaxY = bmax;
-        }
-
-        // Initialize X bounds, will be refined for each strip
-        bboxX0 = Integer.MAX_VALUE;
-        bboxX1 = Integer.MIN_VALUE;
-
-        // Set Y bounds
-        bboxY0 = iminY >> SUBPIXEL_LG_POSITIONS_Y;
-        bboxY1 = (imaxY + SUBPIXEL_POSITIONS_Y - 1) >> SUBPIXEL_LG_POSITIONS_Y;
-
-        // Compute number of rows that can be processing using
-        // a crossings table no larger than DEFAULT_CROSSINGS_SIZE.
-        // However, we must process at least one row, so we grow the table
-        // temporarily if needed.  This would require an object with a
-        // huge number of flips.
-        int rows = DEFAULT_CROSSINGS_SIZE/(flips*SUBPIXEL_POSITIONS_Y);
-        rows = Math.min(rows, yextent);
-        rows = Math.max(rows, 1);
-        for (int i = iminY; i <= imaxY; i += rows*SUBPIXEL_POSITIONS_Y) {
-            // Compute index of last scanline to be processed in this pass
-            int last = Math.min(i + rows*SUBPIXEL_POSITIONS_Y - 1, imaxY);
-            setCrossingsExtents(i, last, flips);
-
-            int bminY = i << YSHIFT;
-            int bmaxY = (last << YSHIFT) | ~YMASK;
-
-            // Process edges from the edge list
-            int maxIdx = edgeIdx;
-            for (int index = 0; index < maxIdx; index += 5) {
-                // Test y1 < min:
-                //
-                // If edge lies entirely above current strip,
-                // discard it
-                if (edges[index + 3] < bminY) {
-                    // Overwrite the edge with the last edge
-                    edgeIdx -= 5;
-                    int fidx = edgeIdx;
-                    int tidx = index;
-                    edges[tidx++] = edges[fidx++];
-                    edges[tidx++] = edges[fidx++];
-                    edges[tidx++] = edges[fidx++];
-                    edges[tidx++] = edges[fidx++];
-                    edges[tidx  ] = edges[fidx  ];
-
-                    maxIdx -= 5;
-                    index -= 5;
-                    continue;
-                }
-
-                // Test y0 > max:
-                //
-                // If edge lies entirely below current strip,
-                // skip it for now
-                if (edges[index + 1] > bmaxY) {
-                    continue;
-                }
-
-                computeCrossingsForEdge(index, bminY, bmaxY);
-            }
-
-            computeBounds();
-            if (rasterMaxX < rasterMinX) {
-                continue;
-            }
-
-            bboxX0 = Math.min(bboxX0,
-                              rasterMinX >> SUBPIXEL_LG_POSITIONS_X);
-            bboxX1 = Math.max(bboxX1,
-                              (rasterMaxX + SUBPIXEL_POSITIONS_X - 1)
-                              >> SUBPIXEL_LG_POSITIONS_X);
-            renderStrip();
-        }
-
-        // Free up any unusually large scratchpad memory used by the
-        // preceding primitive
-        crossingListFinished();
-    }
 
     public void endRendering() {
         // Set up the cache to accumulate the bounding box
@@ -478,176 +472,31 @@
         _endRendering();
     }
 
-    public void getBoundingBox(int[] bbox) {
-        bbox[0] = bboxX0;
-        bbox[1] = bboxY0;
-        bbox[2] = bboxX1 - bboxX0;
-        bbox[3] = bboxY1 - bboxY0;
+    public void getBoundingBox(int[] pix_bbox) {
+        pix_bbox[0] = pix_bboxX0;
+        pix_bbox[1] = pix_bboxY0;
+        pix_bbox[2] = pix_bboxX1 - pix_bboxX0;
+        pix_bbox[3] = pix_bboxY1 - pix_bboxY0;
     }
 
-    private void renderStrip() {
-        // Grow rowAA according to the raster width
-        int width = (rasterMaxX - rasterMinX + 1) >> SUBPIXEL_LG_POSITIONS_X;
-        alphaWidth = width;
-
-        // Allocate one extra entry in rowAA to avoid a conditional in
-        // the rendering loop
-        int bufLen = width + 1;
-        if (this.rowAA == null || this.rowAA.length < bufLen) {
-            this.rowAA = new byte[bufLen];
-        }
-
-        // Mask to determine the relevant bit of the crossing sum
-        // 0x1 if EVEN_ODD, all bits if NON_ZERO
-        int mask = (windingRule == WIND_EVEN_ODD) ? 0x1 : ~0x0;
-
-        int y = 0;
-        int prevY = rasterMinY - 1;
-
-        int minX = Integer.MAX_VALUE;
-        int maxX = Integer.MIN_VALUE;
-
-        iterateCrossings();
-        while (hasMoreCrossingRows()) {
-            y = crossingY;
-
-            // Emit any skipped rows
-            for (int j = prevY + 1; j < y; j++) {
-                if (((j & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) ||
-                    (j == rasterMaxY)) {
-                    emitRow(j >> SUBPIXEL_LG_POSITIONS_Y, 0, -1);
-                }
-            }
-            prevY = y;
-
-            if (crossingRowIndex < crossingRowCount) {
-                int lx = crossings[crossingRowOffset + crossingRowIndex];
-                lx >>= 1;
-                int hx = crossings[crossingRowOffset + crossingRowCount - 1];
-                hx >>= 1;
-                int x0 = lx > rasterMinX ? lx : rasterMinX;
-                int x1 = hx < rasterMaxX ? hx : rasterMaxX;
-                x0 -= rasterMinX;
-                x1 -= rasterMinX;
-
-                minX = Math.min(minX, x0 >> SUBPIXEL_LG_POSITIONS_X);
-                maxX = Math.max(maxX, x1 >> SUBPIXEL_LG_POSITIONS_X);
-            }
-
-            int sum = 0;
-            int prev = rasterMinX;
-            while (crossingRowIndex < crossingRowCount) {
-                int crxo = crossings[crossingRowOffset + crossingRowIndex];
-                crossingRowIndex++;
-
-                int crx = crxo >> 1;
-                int crorientation = ((crxo & 0x1) == 0x1) ? 1 : -1;
-
-                if ((sum & mask) != 0) {
-                    // Clip to active X range, if x1 < x0 loop will
-                    // have no effect
-                    int x0 = prev > rasterMinX ? prev : rasterMinX;
-                    int x1 =  crx < rasterMaxX ?  crx : rasterMaxX;
-
-                    // Empty spans
-                    if (x1 > x0) {
-                        x0 -= rasterMinX;
-                        x1 -= rasterMinX;
-
-                        // Accumulate alpha, equivalent to:
-                        //   for (int x = x0; x < x1; x++) {
-                        //       ++rowAA[x >> SUBPIXEL_LG_POSITIONS_X];
-                        //   }
-                        //
-                        // In the middle of the span, we can update a full
-                        // pixel at a time (i.e., SUBPIXEL_POSITIONS_X
-                        // subpixels)
-
-                        int x = x0 >> SUBPIXEL_LG_POSITIONS_X;
-                        int xmaxm1 = (x1 - 1) >> SUBPIXEL_LG_POSITIONS_X;
-                        if (x == xmaxm1) {
-                            // Start and end in same pixel
-                            rowAA[x] += x1 - x0;
-                        } else {
-                            // Start and end in different pixels
-                            rowAA[x++] += SUBPIXEL_POSITIONS_X -
-                                (x0 & SUBPIXEL_MASK_X);
-                            int xmax = x1 >> SUBPIXEL_LG_POSITIONS_X;
-                            while (x < xmax) {
-                                rowAA[x++] += SUBPIXEL_POSITIONS_X;
-                            }
-                            // Note - at this point it is possible that
-                            // x == width, which implies that
-                            // x1 & SUBPIXEL_MASK_X == 0.  We allocate
-                            // one extra entry in rowAA so this
-                            // assignment will be harmless.  The alternative
-                            // is an extra conditional here, or some other
-                            // scheme to deal with the last pixel better.
-                            rowAA[x] += x1 & SUBPIXEL_MASK_X;
-                        }
-                    }
-                }
-                sum += crorientation;
-                prev = crx;
-            }
-
-            // Every SUBPIXEL_POSITIONS rows, output an antialiased row
-            if (((y & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) ||
-                (y == rasterMaxY)) {
-                emitRow(y >> SUBPIXEL_LG_POSITIONS_Y, minX, maxX);
-                minX = Integer.MAX_VALUE;
-                maxX = Integer.MIN_VALUE;
-            }
-        }
-
-        // Emit final row
-        for (int j = prevY + 1; j <= rasterMaxY; j++) {
-            if (((j & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) ||
-                (j == rasterMaxY)) {
-                emitRow(j >> SUBPIXEL_LG_POSITIONS_Y, minX, maxX);
-                minX = Integer.MAX_VALUE;
-                maxX = Integer.MIN_VALUE;
-            }
-        }
-    }
-
-    private void clearAlpha(byte[] alpha,
-                            int width,
-                            int minX, int maxX) {
-        if (maxX >= minX) {
-            int w = maxX - minX + 1;
-            if (w + minX > width) {
-                w = width - minX;
-            }
-
-            int aidx = minX;
-            for (int i = 0; i < w; i++, aidx++) {
-                alpha[aidx] = (byte)0;
-            }
-        }
-    }
-
-    private void emitRow(int y, int minX, int maxX) {
+    private void emitRow(byte[] alphaRow, int pix_y, int pix_from, int pix_to) {
         // Copy rowAA data into the cache if one is present
         if (cache != null) {
-            if (maxX >= minX) {
-                int x0 = minX + (rasterMinX >> SUBPIXEL_LG_POSITIONS_X);
-                int x1 = maxX + (rasterMinX >> SUBPIXEL_LG_POSITIONS_X);
+            if (pix_to >= pix_from) {
+                cache.startRow(pix_y, pix_from, pix_to);
 
-                cache.startRow(y, x0, x1);
-                int srcIdx = minX;
+                // Perform run-length encoding and store results in the cache
+                int from = pix_from - (boundsMinX >> SUBPIXEL_LG_POSITIONS_X);
+                int to = pix_to - (boundsMinX >> SUBPIXEL_LG_POSITIONS_X);
 
-                // Perform run-length encoding
-                // and store results in the cache
-                byte startVal = rowAA[srcIdx++];
                 int runLen = 1;
-                while (srcIdx <= maxX) {
-                    byte nextVal = rowAA[srcIdx++];
+                byte startVal = alphaRow[from];
+                for (int i = from + 1; i <= to; i++) {
+                    byte nextVal = (byte)(startVal + alphaRow[i]);
                     if (nextVal == startVal && runLen < 255) {
-                        ++runLen;
+                        runLen++;
                     } else {
                         cache.addRLERun(startVal, runLen);
-
                         runLen = 1;
                         startVal = nextVal;
                     }
@@ -656,190 +505,6 @@
                 cache.addRLERun((byte)0, 0);
             }
         }
-
-        clearAlpha(rowAA,
-                   alphaWidth,
-                   minX, maxX);
-    }
-
-    public void setCache(PiscesCache cache) {
-        this.cache = cache;
-    }
-
-    // Edge list data
-
-    private int[] edges = new int[5*INITIAL_EDGES];
-    private int edgeIdx = 0;
-    private int edgeMinY = Integer.MAX_VALUE;
-    private int edgeMaxY = Integer.MIN_VALUE;
-
-    private void addEdge(int x0, int y0, int x1, int y1) {
-        int newLen = edgeIdx + 5;
-        if (edges.length < newLen) {
-            int[] tmp = new int[Math.max(11*edges.length/10, newLen)];
-            System.arraycopy(edges, 0, tmp, 0, edgeIdx);
-            this.edges = tmp;
-        }
-
-        int orientation = 1;
-        if (y0 > y1) {
-            int tmp = y0;
-            y0 = y1;
-            y1 = tmp;
-
-            orientation = -1;
-        }
-
-        // Skip edges that don't cross a subsampled scanline
-        int eminY = ((y0 + HYSTEP) & YMASK);
-        int emaxY = ((y1 - HYSTEP) & YMASK);
-        if (eminY > emaxY) {
-            return;
-        }
-
-        if (orientation == -1) {
-            int tmp = x0;
-            x0 = x1;
-            x1 = tmp;
-        }
-
-        edges[edgeIdx++] = x0;
-        edges[edgeIdx++] = y0;
-        edges[edgeIdx++] = x1;
-        edges[edgeIdx++] = y1;
-        edges[edgeIdx++] = orientation;
-
-        // Update Y bounds of primitive
-        if (y0 < edgeMinY) {
-            edgeMinY = y0;
-        }
-        if (y1 > edgeMaxY) {
-            edgeMaxY = y1;
-        }
-    }
-
-    private void resetEdges() {
-        this.edgeIdx = 0;
-        this.edgeMinY = Integer.MAX_VALUE;
-        this.edgeMaxY = Integer.MIN_VALUE;
-    }
-
-    // Crossing list data
-
-    private int[] crossingIndices;
-    private int[] crossings;
-    private int crossingMinY;
-    private int crossingMaxY;
-    private int crossingMinX = Integer.MAX_VALUE;
-    private int crossingMaxX = Integer.MIN_VALUE;
-    private int crossingMaxXEntries;
-    private int numCrossings = 0;
-    private boolean crossingsSorted = false;
-
-    private int crossingY;
-    private int crossingRowCount;
-    private int crossingRowOffset;
-    private int crossingRowIndex;
-
-    private void setCrossingsExtents(int minY, int maxY, int maxXEntries) {
-        int yextent = maxY - minY + 1;
-
-        // Grow indices array as needed
-        if (crossingIndices == null || crossingIndices.length < yextent) {
-            this.crossingIndices =
-                new int[Math.max(yextent, DEFAULT_INDICES_SIZE)];
-        }
-        // Grow crossings array as needed
-        if (crossings == null || crossings.length < yextent*maxXEntries) {
-            this.crossings = new int[Math.max(yextent*maxXEntries,
-                                              DEFAULT_CROSSINGS_SIZE)];
-        }
-        this.crossingMinY = minY;
-        this.crossingMaxY = maxY;
-        this.crossingMaxXEntries = maxXEntries;
-        resetCrossings();
-    }
-
-    private void resetCrossings() {
-        int yextent = crossingMaxY - crossingMinY + 1;
-        int start = 0;
-        for (int i = 0; i < yextent; i++) {
-            crossingIndices[i] = start;
-            start += crossingMaxXEntries;
-        }
-        crossingMinX = Integer.MAX_VALUE;
-        crossingMaxX = Integer.MIN_VALUE;
-        numCrossings = 0;
-        crossingsSorted = false;
-    }
-
-    // Free sorting arrays if larger than maximum size
-    private void crossingListFinished() {
-        if (crossings != null && crossings.length > DEFAULT_CROSSINGS_SIZE) {
-            crossings = new int[DEFAULT_CROSSINGS_SIZE];
-        }
-        if (crossingIndices != null &&
-            crossingIndices.length > DEFAULT_INDICES_SIZE)
-        {
-            crossingIndices = new int[DEFAULT_INDICES_SIZE];
-        }
-    }
-
-    private void sortCrossings(int[] x, int off, int len) {
-        for (int i = off + 1; i < off + len; i++) {
-            int j = i;
-            int xj = x[j];
-            int xjm1;
-
-            while (j > off && (xjm1 = x[j - 1]) > xj) {
-                x[j] = xjm1;
-                x[j - 1] = xj;
-                j--;
-            }
-        }
-    }
-
-    private void sortCrossings() {
-        int start = 0;
-        for (int i = 0; i <= crossingMaxY - crossingMinY; i++) {
-            sortCrossings(crossings, start, crossingIndices[i] - start);
-            start += crossingMaxXEntries;
-        }
-    }
-
-    private void addCrossing(int y, int x, int orientation) {
-        if (x < crossingMinX) {
-            crossingMinX = x;
-        }
-        if (x > crossingMaxX) {
-            crossingMaxX = x;
-        }
-
-        int index = crossingIndices[y - crossingMinY]++;
-        x <<= 1;
-        crossings[index] = (orientation == 1) ? (x | 0x1) : x;
-
-        ++numCrossings;
-    }
-
-    private void iterateCrossings() {
-        if (!crossingsSorted) {
-            sortCrossings();
-            crossingsSorted = true;
-        }
-        crossingY = crossingMinY - 1;
-        crossingRowOffset = -crossingMaxXEntries;
-    }
-
-    private boolean hasMoreCrossingRows() {
-        if (++crossingY <= crossingMaxY) {
-            crossingRowOffset += crossingMaxXEntries;
-            int y = crossingY - crossingMinY;
-            crossingRowCount = crossingIndices[y] - y*crossingMaxXEntries;
-            crossingRowIndex = 0;
-            return true;
-        } else {
-            return false;
-        }
+        java.util.Arrays.fill(alphaRow, (byte)0);
     }
 }
--- a/src/share/classes/sun/java2d/pisces/Stroker.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/java2d/pisces/Stroker.java	Sun Aug 29 22:41:28 2010 -0700
@@ -25,7 +25,7 @@
 
 package sun.java2d.pisces;
 
-public class Stroker extends LineSink {
+public class Stroker implements LineSink {
 
     private static final int MOVE_TO = 0;
     private static final int LINE_TO = 1;
@@ -61,19 +61,15 @@
      */
     public static final int CAP_SQUARE = 2;
 
-    LineSink output;
+    private final LineSink output;
 
-    int lineWidth;
-    int capStyle;
-    int joinStyle;
-    int miterLimit;
+    private final int capStyle;
+    private final int joinStyle;
 
-    Transform4 transform;
-    int m00, m01;
-    int m10, m11;
+    private final float m00, m01, m10, m11, det;
 
-    int lineWidth2;
-    long scaledLineWidth2;
+    private final float lineWidth2;
+    private final float scaledLineWidth2;
 
     // For any pen offset (pen_dx, pen_dy) that does not depend on
     // the line orientation, the pen should be transformed so that:
@@ -88,143 +84,86 @@
     //
     // pen_dx'(r, theta) = r*(m00*cos(theta) + m01*sin(theta))
     // pen_dy'(r, theta) = r*(m10*cos(theta) + m11*sin(theta))
-    int numPenSegments;
-    int[] pen_dx;
-    int[] pen_dy;
-    boolean[] penIncluded;
-    int[] join;
+    private int numPenSegments;
+    private final float[] pen_dx;
+    private final float[] pen_dy;
+    private boolean[] penIncluded;
+    private final float[] join;
 
-    int[] offset = new int[2];
-    int[] reverse = new int[100];
-    int[] miter = new int[2];
-    long miterLimitSq;
+    private final float[] offset = new float[2];
+    private float[] reverse = new float[100];
+    private final float[] miter = new float[2];
+    private final float miterLimitSq;
 
-    int prev;
-    int rindex;
-    boolean started;
-    boolean lineToOrigin;
-    boolean joinToOrigin;
+    private int prev;
+    private int rindex;
+    private boolean started;
+    private boolean lineToOrigin;
+    private boolean joinToOrigin;
 
-    int sx0, sy0, sx1, sy1, x0, y0, x1, y1;
-    int mx0, my0, mx1, my1, omx, omy;
-    int lx0, ly0, lx1, ly1, lx0p, ly0p, px0, py0;
+    private float sx0, sy0, sx1, sy1, x0, y0, px0, py0;
+    private float mx0, my0, omx, omy;
 
-    double m00_2_m01_2;
-    double m10_2_m11_2;
-    double m00_m10_m01_m11;
-
-    /**
-     * Empty constructor.  <code>setOutput</code> and
-     * <code>setParameters</code> must be called prior to calling any
-     * other methods.
-     */
-    public Stroker() {}
+    private float m00_2_m01_2;
+    private float m10_2_m11_2;
+    private float m00_m10_m01_m11;
 
     /**
      * Constructs a <code>Stroker</code>.
      *
      * @param output an output <code>LineSink</code>.
-     * @param lineWidth the desired line width in pixels, in S15.16
-     * format.
+     * @param lineWidth the desired line width in pixels
      * @param capStyle the desired end cap style, one of
      * <code>CAP_BUTT</code>, <code>CAP_ROUND</code> or
      * <code>CAP_SQUARE</code>.
      * @param joinStyle the desired line join style, one of
      * <code>JOIN_MITER</code>, <code>JOIN_ROUND</code> or
      * <code>JOIN_BEVEL</code>.
-     * @param miterLimit the desired miter limit, in S15.16 format.
+     * @param miterLimit the desired miter limit
      * @param transform a <code>Transform4</code> object indicating
      * the transform that has been previously applied to all incoming
      * coordinates.  This is required in order to produce consistently
      * shaped end caps and joins.
      */
     public Stroker(LineSink output,
-                   int lineWidth,
+                   float lineWidth,
                    int capStyle,
                    int joinStyle,
-                   int miterLimit,
-                   Transform4 transform) {
-        setOutput(output);
-        setParameters(lineWidth, capStyle, joinStyle, miterLimit, transform);
-    }
+                   float miterLimit,
+                   float m00, float m01, float m10, float m11) {
+        this.output = output;
 
-    /**
-     * Sets the output <code>LineSink</code> of this
-     * <code>Stroker</code>.
-     *
-     * @param output an output <code>LineSink</code>.
-     */
-    public void setOutput(LineSink output) {
-        this.output = output;
-    }
-
-    /**
-     * Sets the parameters of this <code>Stroker</code>.
-     * @param lineWidth the desired line width in pixels, in S15.16
-     * format.
-     * @param capStyle the desired end cap style, one of
-     * <code>CAP_BUTT</code>, <code>CAP_ROUND</code> or
-     * <code>CAP_SQUARE</code>.
-     * @param joinStyle the desired line join style, one of
-     * <code>JOIN_MITER</code>, <code>JOIN_ROUND</code> or
-     * <code>JOIN_BEVEL</code>.
-     * @param miterLimit the desired miter limit, in S15.16 format.
-     * @param transform a <code>Transform4</code> object indicating
-     * the transform that has been previously applied to all incoming
-     * coordinates.  This is required in order to produce consistently
-     * shaped end caps and joins.
-     */
-    public void setParameters(int lineWidth,
-                              int capStyle,
-                              int joinStyle,
-                              int miterLimit,
-                              Transform4 transform) {
-        this.lineWidth = lineWidth;
-        this.lineWidth2 = lineWidth >> 1;
-        this.scaledLineWidth2 = ((long)transform.m00*lineWidth2) >> 16;
+        this.lineWidth2 = lineWidth / 2;
+        this.scaledLineWidth2 = m00 * lineWidth2;
         this.capStyle = capStyle;
         this.joinStyle = joinStyle;
-        this.miterLimit = miterLimit;
 
-        this.transform = transform;
-        this.m00 = transform.m00;
-        this.m01 = transform.m01;
-        this.m10 = transform.m10;
-        this.m11 = transform.m11;
+        m00_2_m01_2 = m00*m00 + m01*m01;
+        m10_2_m11_2 = m10*m10 + m11*m11;
+        m00_m10_m01_m11 = m00*m10 + m01*m11;
 
-        this.m00_2_m01_2 = (double)m00*m00 + (double)m01*m01;
-        this.m10_2_m11_2 = (double)m10*m10 + (double)m11*m11;
-        this.m00_m10_m01_m11 = (double)m00*m10 + (double)m01*m11;
+        this.m00 = m00;
+        this.m01 = m01;
+        this.m10 = m10;
+        this.m11 = m11;
+        det = m00*m11 - m01*m10;
 
-        double dm00 = m00/65536.0;
-        double dm01 = m01/65536.0;
-        double dm10 = m10/65536.0;
-        double dm11 = m11/65536.0;
-        double determinant = dm00*dm11 - dm01*dm10;
+        float limit = miterLimit * lineWidth2 * det;
+        this.miterLimitSq = limit*limit;
 
-        if (joinStyle == JOIN_MITER) {
-            double limit =
-                (miterLimit/65536.0)*(lineWidth2/65536.0)*determinant;
-            double limitSq = limit*limit;
-            this.miterLimitSq = (long)(limitSq*65536.0*65536.0);
-        }
-
-        this.numPenSegments = (int)(3.14159f*lineWidth/65536.0f);
-        if (pen_dx == null || pen_dx.length < numPenSegments) {
-            this.pen_dx = new int[numPenSegments];
-            this.pen_dy = new int[numPenSegments];
-            this.penIncluded = new boolean[numPenSegments];
-            this.join = new int[2*numPenSegments];
-        }
+        this.numPenSegments = (int)(3.14159f * lineWidth);
+        this.pen_dx = new float[numPenSegments];
+        this.pen_dy = new float[numPenSegments];
+        this.penIncluded = new boolean[numPenSegments];
+        this.join = new float[2*numPenSegments];
 
         for (int i = 0; i < numPenSegments; i++) {
-            double r = lineWidth/2.0;
-            double theta = (double)i*2.0*Math.PI/numPenSegments;
+            double theta = (i * 2.0 * Math.PI)/numPenSegments;
 
             double cos = Math.cos(theta);
             double sin = Math.sin(theta);
-            pen_dx[i] = (int)(r*(dm00*cos + dm01*sin));
-            pen_dy[i] = (int)(r*(dm10*cos + dm11*sin));
+            pen_dx[i] = (float)(lineWidth2 * (m00*cos + m01*sin));
+            pen_dy[i] = (float)(lineWidth2 * (m10*cos + m11*sin));
         }
 
         prev = CLOSE;
@@ -233,32 +172,31 @@
         lineToOrigin = false;
     }
 
-    private void computeOffset(int x0, int y0, int x1, int y1, int[] m) {
-        long lx = (long)x1 - (long)x0;
-        long ly = (long)y1 - (long)y0;
+    private void computeOffset(float x0, float y0,
+                               float x1, float y1, float[] m) {
+        float lx = x1 - x0;
+        float ly = y1 - y0;
 
-        int dx, dy;
+        float dx, dy;
         if (m00 > 0 && m00 == m11 && m01 == 0 & m10 == 0) {
-            long ilen = PiscesMath.hypot(lx, ly);
+            float ilen = (float)Math.hypot(lx, ly);
             if (ilen == 0) {
                 dx = dy = 0;
             } else {
-                dx = (int)( (ly*scaledLineWidth2)/ilen);
-                dy = (int)(-(lx*scaledLineWidth2)/ilen);
+                dx = (ly * scaledLineWidth2)/ilen;
+                dy = -(lx * scaledLineWidth2)/ilen;
             }
         } else {
-            double dlx = x1 - x0;
-            double dly = y1 - y0;
-            double det = (double)m00*m11 - (double)m01*m10;
             int sdet = (det > 0) ? 1 : -1;
-            double a = dly*m00 - dlx*m10;
-            double b = dly*m01 - dlx*m11;
-            double dh = PiscesMath.hypot(a, b);
-            double div = sdet*lineWidth2/(65536.0*dh);
-            double ddx = dly*m00_2_m01_2 - dlx*m00_m10_m01_m11;
-            double ddy = dly*m00_m10_m01_m11 - dlx*m10_2_m11_2;
-            dx = (int)(ddx*div);
-            dy = (int)(ddy*div);
+            float a = ly * m00 - lx * m10;
+            float b = ly * m01 - lx * m11;
+            float dh = (float)Math.hypot(a, b);
+            float div = sdet * lineWidth2/dh;
+
+            float ddx = ly * m00_2_m01_2 - lx * m00_m10_m01_m11;
+            float ddy = ly * m00_m10_m01_m11 - lx * m10_2_m11_2;
+            dx = ddx*div;
+            dy = ddy*div;
         }
 
         m[0] = dx;
@@ -267,58 +205,43 @@
 
     private void ensureCapacity(int newrindex) {
         if (reverse.length < newrindex) {
-            int[] tmp = new int[Math.max(newrindex, 6*reverse.length/5)];
-            System.arraycopy(reverse, 0, tmp, 0, rindex);
-            this.reverse = tmp;
+            reverse = java.util.Arrays.copyOf(reverse, 6*reverse.length/5);
         }
     }
 
-    private boolean isCCW(int x0, int y0,
-                          int x1, int y1,
-                          int x2, int y2) {
-        int dx0 = x1 - x0;
-        int dy0 = y1 - y0;
-        int dx1 = x2 - x1;
-        int dy1 = y2 - y1;
-        return (long)dx0*dy1 < (long)dy0*dx1;
+    private boolean isCCW(float x0, float y0,
+                          float x1, float y1,
+                          float x2, float y2) {
+        return (x1 - x0) * (y2 - y1) < (y1 - y0) * (x2 - x1);
     }
 
-    private boolean side(int x, int y, int x0, int y0, int x1, int y1) {
-        long lx = x;
-        long ly = y;
-        long lx0 = x0;
-        long ly0 = y0;
-        long lx1 = x1;
-        long ly1 = y1;
-
-        return (ly0 - ly1)*lx + (lx1 - lx0)*ly + (lx0*ly1 - lx1*ly0) > 0;
+    private boolean side(float x,  float y,
+                         float x0, float y0,
+                         float x1, float y1) {
+        return (y0 - y1)*x + (x1 - x0)*y + (x0*y1 - x1*y0) > 0;
     }
 
-    private int computeRoundJoin(int cx, int cy,
-                                 int xa, int ya,
-                                 int xb, int yb,
+    private int computeRoundJoin(float cx, float cy,
+                                 float xa, float ya,
+                                 float xb, float yb,
                                  int side,
                                  boolean flip,
-                                 int[] join) {
-        int px, py;
+                                 float[] join) {
+        float px, py;
         int ncoords = 0;
 
         boolean centerSide;
         if (side == 0) {
             centerSide = side(cx, cy, xa, ya, xb, yb);
         } else {
-            centerSide = (side == 1) ? true : false;
+            centerSide = (side == 1);
         }
         for (int i = 0; i < numPenSegments; i++) {
             px = cx + pen_dx[i];
             py = cy + pen_dy[i];
 
             boolean penSide = side(px, py, xa, ya, xb, yb);
-            if (penSide != centerSide) {
-                penIncluded[i] = true;
-            } else {
-                penIncluded[i] = false;
-            }
+            penIncluded[i] = (penSide != centerSide);
         }
 
         int start = -1, end = -1;
@@ -338,10 +261,10 @@
         }
 
         if (start != -1 && end != -1) {
-            long dxa = cx + pen_dx[start] - xa;
-            long dya = cy + pen_dy[start] - ya;
-            long dxb = cx + pen_dx[start] - xb;
-            long dyb = cy + pen_dy[start] - yb;
+            float dxa = cx + pen_dx[start] - xa;
+            float dya = cy + pen_dy[start] - ya;
+            float dxb = cx + pen_dx[start] - xb;
+            float dyb = cy + pen_dy[start] - yb;
 
             boolean rev = (dxa*dxa + dya*dya > dxb*dxb + dyb*dyb);
             int i = rev ? end : start;
@@ -362,22 +285,25 @@
         return ncoords/2;
     }
 
-    private static final long ROUND_JOIN_THRESHOLD = 1000L;
-    private static final long ROUND_JOIN_INTERNAL_THRESHOLD = 1000000000L;
+    // pisces used to use fixed point arithmetic with 16 decimal digits. I
+    // didn't want to change the values of the constants below when I converted
+    // it to floating point, so that's why the divisions by 2^16 are there.
+    private static final float ROUND_JOIN_THRESHOLD = 1000/65536f;
+    private static final float ROUND_JOIN_INTERNAL_THRESHOLD = 1000000000/65536f;
 
-    private void drawRoundJoin(int x, int y,
-                               int omx, int omy, int mx, int my,
+    private void drawRoundJoin(float x, float y,
+                               float omx, float omy, float mx, float my,
                                int side,
                                boolean flip,
                                boolean rev,
-                               long threshold) {
+                               float threshold) {
         if ((omx == 0 && omy == 0) || (mx == 0 && my == 0)) {
             return;
         }
 
-        long domx = (long)omx - mx;
-        long domy = (long)omy - my;
-        long len = domx*domx + domy*domy;
+        float domx = omx - mx;
+        float domy = omy - my;
+        float len = domx*domx + domy*domy;
         if (len < threshold) {
             return;
         }
@@ -389,10 +315,10 @@
             my = -my;
         }
 
-        int bx0 = x + omx;
-        int by0 = y + omy;
-        int bx1 = x + mx;
-        int by1 = y + my;
+        float bx0 = x + omx;
+        float by0 = y + omy;
+        float bx1 = x + mx;
+        float by1 = y + my;
 
         int npoints = computeRoundJoin(x, y,
                                        bx0, by0, bx1, by1, side, flip,
@@ -404,40 +330,30 @@
 
     // Return the intersection point of the lines (ix0, iy0) -> (ix1, iy1)
     // and (ix0p, iy0p) -> (ix1p, iy1p) in m[0] and m[1]
-    private void computeMiter(int ix0, int iy0, int ix1, int iy1,
-                              int ix0p, int iy0p, int ix1p, int iy1p,
-                              int[] m) {
-        long x0 = ix0;
-        long y0 = iy0;
-        long x1 = ix1;
-        long y1 = iy1;
+    private void computeMiter(float x0, float y0, float x1, float y1,
+                              float x0p, float y0p, float x1p, float y1p,
+                              float[] m) {
+        float x10 = x1 - x0;
+        float y10 = y1 - y0;
+        float x10p = x1p - x0p;
+        float y10p = y1p - y0p;
 
-        long x0p = ix0p;
-        long y0p = iy0p;
-        long x1p = ix1p;
-        long y1p = iy1p;
-
-        long x10 = x1 - x0;
-        long y10 = y1 - y0;
-        long x10p = x1p - x0p;
-        long y10p = y1p - y0p;
-
-        long den = (x10*y10p - x10p*y10) >> 16;
+        float den = x10*y10p - x10p*y10;
         if (den == 0) {
-            m[0] = ix0;
-            m[1] = iy0;
+            m[0] = x0;
+            m[1] = y0;
             return;
         }
 
-        long t = (x1p*(y0 - y0p) - x0*y10p + x0p*(y1p - y0)) >> 16;
-        m[0] = (int)(x0 + (t*x10)/den);
-        m[1] = (int)(y0 + (t*y10)/den);
+        float t = x1p*(y0 - y0p) - x0*y10p + x0p*(y1p - y0);
+        m[0] = x0 + (t*x10)/den;
+        m[1] = y0 + (t*y10)/den;
     }
 
-    private void drawMiter(int px0, int py0,
-                           int x0, int y0,
-                           int x1, int y1,
-                           int omx, int omy, int mx, int my,
+    private void drawMiter(float px0, float py0,
+                           float x0, float y0,
+                           float x1, float y1,
+                           float omx, float omy, float mx, float my,
                            boolean rev) {
         if (mx == omx && my == omy) {
             return;
@@ -461,11 +377,11 @@
                      miter);
 
         // Compute miter length in untransformed coordinates
-        long dx = (long)miter[0] - x0;
-        long dy = (long)miter[1] - y0;
-        long a = (dy*m00 - dx*m10) >> 16;
-        long b = (dy*m01 - dx*m11) >> 16;
-        long lenSq = a*a + b*b;
+        float dx = miter[0] - x0;
+        float dy = miter[1] - y0;
+        float a = dy*m00 - dx*m10;
+        float b = dy*m01 - dx*m11;
+        float lenSq = a*a + b*b;
 
         if (lenSq < miterLimitSq) {
             emitLineTo(miter[0], miter[1], rev);
@@ -473,7 +389,7 @@
     }
 
 
-    public void moveTo(int x0, int y0) {
+    public void moveTo(float x0, float y0) {
         // System.out.println("Stroker.moveTo(" + x0/65536.0 + ", " + y0/65536.0 + ")");
 
         if (lineToOrigin) {
@@ -501,7 +417,7 @@
         this.joinSegment = true;
     }
 
-    public void lineTo(int x1, int y1) {
+    public void lineTo(float x1, float y1) {
         // System.out.println("Stroker.lineTo(" + x1/65536.0 + ", " + y1/65536.0 + ")");
 
         if (lineToOrigin) {
@@ -526,10 +442,10 @@
         joinSegment = false;
     }
 
-    private void lineToImpl(int x1, int y1, boolean joinSegment) {
+    private void lineToImpl(float x1, float y1, boolean joinSegment) {
         computeOffset(x0, y0, x1, y1, offset);
-        int mx = offset[0];
-        int my = offset[1];
+        float mx = offset[0];
+        float my = offset[1];
 
         if (!started) {
             emitMoveTo(x0 + mx, y0 + my);
@@ -567,10 +483,6 @@
         emitLineTo(x0 - mx, y0 - my, true);
         emitLineTo(x1 - mx, y1 - my, true);
 
-        lx0 = x1 + mx; ly0 = y1 + my;
-        lx0p = x1 - mx; ly0p = y1 - my;
-        lx1 = x1; ly1 = y1;
-
         this.omx = mx;
         this.omy = my;
         this.px0 = x0;
@@ -594,8 +506,8 @@
         }
 
         computeOffset(x0, y0, sx0, sy0, offset);
-        int mx = offset[0];
-        int my = offset[1];
+        float mx = offset[0];
+        float my = offset[1];
 
         // Draw penultimate join
         boolean ccw = isCCW(px0, py0, x0, y0, sx0, sy0);
@@ -678,12 +590,10 @@
         this.prev = MOVE_TO;
     }
 
-    long lineLength(long ldx, long ldy) {
-        long ldet = ((long)m00*m11 - (long)m01*m10) >> 16;
-        long la = ((long)ldy*m00 - (long)ldx*m10)/ldet;
-        long lb = ((long)ldy*m01 - (long)ldx*m11)/ldet;
-        long llen = (int)PiscesMath.hypot(la, lb);
-        return llen;
+    double userSpaceLineLength(double dx, double dy) {
+        double a = (dy*m00 - dx*m10)/det;
+        double b = (dy*m01 - dx*m11)/det;
+        return Math.hypot(a, b);
     }
 
     private void finish() {
@@ -692,13 +602,13 @@
                           omx, omy, -omx, -omy, 1, false, false,
                           ROUND_JOIN_THRESHOLD);
         } else if (capStyle == CAP_SQUARE) {
-            long ldx = (long)(px0 - x0);
-            long ldy = (long)(py0 - y0);
-            long llen = lineLength(ldx, ldy);
-            long s = (long)lineWidth2*65536/llen;
+            float dx = px0 - x0;
+            float dy = py0 - y0;
+            float len = (float)userSpaceLineLength(dx, dy);
+            float s = lineWidth2/len;
 
-            int capx = x0 - (int)(ldx*s >> 16);
-            int capy = y0 - (int)(ldy*s >> 16);
+            float capx = x0 - dx*s;
+            float capy = y0 - dy*s;
 
             emitLineTo(capx + omx, capy + omy);
             emitLineTo(capx - omx, capy - omy);
@@ -714,13 +624,13 @@
                           -mx0, -my0, mx0, my0, 1, false, false,
                           ROUND_JOIN_THRESHOLD);
         } else if (capStyle == CAP_SQUARE) {
-            long ldx = (long)(sx1 - sx0);
-            long ldy = (long)(sy1 - sy0);
-            long llen = lineLength(ldx, ldy);
-            long s = (long)lineWidth2*65536/llen;
+            float dx = sx1 - sx0;
+            float dy = sy1 - sy0;
+            float len = (float)userSpaceLineLength(dx, dy);
+            float s = lineWidth2/len;
 
-            int capx = sx0 - (int)(ldx*s >> 16);
-            int capy = sy0 - (int)(ldy*s >> 16);
+            float capx = sx0 - dx*s;
+            float capy = sy0 - dy*s;
 
             emitLineTo(capx - mx0, capy - my0);
             emitLineTo(capx + mx0, capy + my0);
@@ -730,17 +640,17 @@
         this.joinSegment = false;
     }
 
-    private void emitMoveTo(int x0, int y0) {
+    private void emitMoveTo(float x0, float y0) {
         // System.out.println("Stroker.emitMoveTo(" + x0/65536.0 + ", " + y0/65536.0 + ")");
         output.moveTo(x0, y0);
     }
 
-    private void emitLineTo(int x1, int y1) {
+    private void emitLineTo(float x1, float y1) {
         // System.out.println("Stroker.emitLineTo(" + x0/65536.0 + ", " + y0/65536.0 + ")");
         output.lineTo(x1, y1);
     }
 
-    private void emitLineTo(int x1, int y1, boolean rev) {
+    private void emitLineTo(float x1, float y1, boolean rev) {
         if (rev) {
             ensureCapacity(rindex + 2);
             reverse[rindex++] = x1;
@@ -755,3 +665,4 @@
         output.close();
     }
 }
+
--- a/src/share/classes/sun/java2d/pisces/Transform4.java	Thu Aug 26 16:17:02 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.java2d.pisces;
-
-public class Transform4 {
-
-    public int m00, m01, m10, m11;
-//     double det; // det*65536
-
-    public Transform4() {
-        this(1 << 16, 0, 0, 1 << 16);
-    }
-
-    public Transform4(int m00, int m01,
-                      int m10, int m11) {
-        this.m00 = m00;
-        this.m01 = m01;
-        this.m10 = m10;
-        this.m11 = m11;
-
-//         this.det = (double)m00*m11 - (double)m01*m10;
-    }
-
-//     public Transform4 createInverse() {
-//         double dm00 = m00/65536.0;
-//         double dm01 = m01/65536.0;
-//         double dm10 = m10/65536.0;
-//         double dm11 = m11/65536.0;
-
-//         double invdet = 65536.0/(dm00*dm11 - dm01*dm10);
-
-//         int im00 = (int)( dm11*invdet);
-//         int im01 = (int)(-dm01*invdet);
-//         int im10 = (int)(-dm10*invdet);
-//         int im11 = (int)( dm00*invdet);
-
-//         return new Transform4(im00, im01, im10, im11);
-//     }
-
-//     public void transform(int[] point) {
-//     }
-
-//     /**
-//      * Returns the length of the line segment obtained by inverse
-//      * transforming the points <code>(x0, y0)</code> and <code>(x1,
-//      * y1)</code>.
-//      */
-//     public int getTransformedLength(int x0, int x1, int y0, int y1) {
-//         int lx = x1 - x0;
-//         int ly = y1 - y0;
-
-//         double a = (double)m00*ly - (double)m10*lx;
-//         double b = (double)m01*ly - (double)m11*lx;
-//         double len = PiscesMath.sqrt((a*a + b*b)/(det*det));
-//         return (int)(len*65536.0);
-//     }
-
-//     public int getType() {
-//     }
-
-}
--- a/src/share/classes/sun/net/www/protocol/file/FileURLConnection.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/net/www/protocol/file/FileURLConnection.java	Sun Aug 29 22:41:28 2010 -0700
@@ -59,7 +59,7 @@
     String filename;
     boolean isDirectory = false;
     boolean exists = false;
-    List files;
+    List<String> files;
 
     long length = -1;
     long lastModified = 0;
@@ -81,7 +81,10 @@
                 filename = file.toString();
                 isDirectory = file.isDirectory();
                 if (isDirectory) {
-                    files = (List) Arrays.asList(file.list());
+                    String[] fileList = file.list();
+                    if (fileList == null)
+                        throw new FileNotFoundException(filename + " exists, but is not accessible");
+                    files = Arrays.<String>asList(fileList);
                 } else {
 
                     is = new BufferedInputStream(new FileInputStream(filename));
@@ -197,7 +200,7 @@
                 Collections.sort(files, Collator.getInstance());
 
                 for (int i = 0 ; i < files.size() ; i++) {
-                    String fileName = (String)files.get(i);
+                    String fileName = files.get(i);
                     buf.append(fileName);
                     buf.append("\n");
                 }
--- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1768,6 +1768,10 @@
         // Not really necessary for a tunnel, but can't hurt
         requests.setIfNotSet("Accept", acceptString);
 
+        if (http.getHttpKeepAliveSet()) {
+            requests.setIfNotSet("Proxy-Connection", "keep-alive");
+        }
+
         setPreemptiveProxyAuthentication(requests);
 
          /* Log the CONNECT request */
--- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Sun Aug 29 22:41:28 2010 -0700
@@ -536,9 +536,11 @@
         }
     }
 
-    private long read0(ByteBuffer[] bufs) throws IOException {
-        if (bufs == null)
-            throw new NullPointerException();
+    public long read(ByteBuffer[] dsts, int offset, int length)
+        throws IOException
+    {
+        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
+            throw new IndexOutOfBoundsException();
         synchronized (readLock) {
             synchronized (stateLock) {
                 ensureOpen();
@@ -552,7 +554,7 @@
                     return 0;
                 readerThread = NativeThread.current();
                 do {
-                    n = IOUtil.read(fd, bufs, nd);
+                    n = IOUtil.read(fd, dsts, offset, length, nd);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
                 return IOStatus.normalize(n);
             } finally {
@@ -563,15 +565,6 @@
         }
     }
 
-    public long read(ByteBuffer[] dsts, int offset, int length)
-        throws IOException
-    {
-        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
-           throw new IndexOutOfBoundsException();
-        // ## Fix IOUtil.write so that we can avoid this array copy
-        return read0(Util.subsequence(dsts, offset, length));
-    }
-
     public int write(ByteBuffer buf) throws IOException {
         if (buf == null)
             throw new NullPointerException();
@@ -599,9 +592,11 @@
         }
     }
 
-    private long write0(ByteBuffer[] bufs) throws IOException {
-        if (bufs == null)
-            throw new NullPointerException();
+    public long write(ByteBuffer[] srcs, int offset, int length)
+        throws IOException
+    {
+        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
+            throw new IndexOutOfBoundsException();
         synchronized (writeLock) {
             synchronized (stateLock) {
                 ensureOpen();
@@ -615,7 +610,7 @@
                     return 0;
                 writerThread = NativeThread.current();
                 do {
-                    n = IOUtil.write(fd, bufs, nd);
+                    n = IOUtil.write(fd, srcs, offset, length, nd);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
                 return IOStatus.normalize(n);
             } finally {
@@ -626,15 +621,6 @@
         }
     }
 
-    public long write(ByteBuffer[] srcs, int offset, int length)
-        throws IOException
-    {
-        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
-            throw new IndexOutOfBoundsException();
-        // ## Fix IOUtil.write so that we can avoid this array copy
-        return write0(Util.subsequence(srcs, offset, length));
-    }
-
     protected void implConfigureBlocking(boolean block) throws IOException {
         IOUtil.configureBlocking(fd, block);
     }
--- a/src/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/nio/ch/FileChannelImpl.java	Sun Aug 29 22:41:28 2010 -0700
@@ -143,7 +143,11 @@
         }
     }
 
-    private long read0(ByteBuffer[] dsts) throws IOException {
+    public long read(ByteBuffer[] dsts, int offset, int length)
+        throws IOException
+    {
+        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
+            throw new IndexOutOfBoundsException();
         ensureOpen();
         if (!readable)
             throw new NonReadableChannelException();
@@ -156,7 +160,7 @@
                 if (!isOpen())
                     return 0;
                 do {
-                    n = IOUtil.read(fd, dsts, nd);
+                    n = IOUtil.read(fd, dsts, offset, length, nd);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
                 return IOStatus.normalize(n);
             } finally {
@@ -167,15 +171,6 @@
         }
     }
 
-    public long read(ByteBuffer[] dsts, int offset, int length)
-        throws IOException
-    {
-        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
-           throw new IndexOutOfBoundsException();
-        // ## Fix IOUtil.write so that we can avoid this array copy
-        return read0(Util.subsequence(dsts, offset, length));
-    }
-
     public int write(ByteBuffer src) throws IOException {
         ensureOpen();
         if (!writable)
@@ -200,7 +195,11 @@
         }
     }
 
-    private long write0(ByteBuffer[] srcs) throws IOException {
+    public long write(ByteBuffer[] srcs, int offset, int length)
+        throws IOException
+    {
+        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
+            throw new IndexOutOfBoundsException();
         ensureOpen();
         if (!writable)
             throw new NonWritableChannelException();
@@ -213,7 +212,7 @@
                 if (!isOpen())
                     return 0;
                 do {
-                    n = IOUtil.write(fd, srcs, nd);
+                    n = IOUtil.write(fd, srcs, offset, length, nd);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
                 return IOStatus.normalize(n);
             } finally {
@@ -224,16 +223,6 @@
         }
     }
 
-    public long write(ByteBuffer[] srcs, int offset, int length)
-        throws IOException
-    {
-        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
-           throw new IndexOutOfBoundsException();
-        // ## Fix IOUtil.write so that we can avoid this array copy
-        return write0(Util.subsequence(srcs, offset, length));
-    }
-
-
     // -- Other operations --
 
     public long position() throws IOException {
@@ -440,24 +429,45 @@
         }
     }
 
-    private long transferToTrustedChannel(long position, int icount,
+    // Maximum size to map when using a mapped buffer
+    private static final long MAPPED_TRANSFER_SIZE = 8L*1024L*1024L;
+
+    private long transferToTrustedChannel(long position, long count,
                                           WritableByteChannel target)
         throws IOException
     {
-        if (  !((target instanceof FileChannelImpl)
-                || (target instanceof SelChImpl)))
+        boolean isSelChImpl = (target instanceof SelChImpl);
+        if (!((target instanceof FileChannelImpl) || isSelChImpl))
             return IOStatus.UNSUPPORTED;
 
         // Trusted target: Use a mapped buffer
-        MappedByteBuffer dbb = null;
-        try {
-            dbb = map(MapMode.READ_ONLY, position, icount);
-            // ## Bug: Closing this channel will not terminate the write
-            return target.write(dbb);
-        } finally {
-            if (dbb != null)
-                unmap(dbb);
+        long remaining = count;
+        while (remaining > 0L) {
+            long size = Math.min(remaining, MAPPED_TRANSFER_SIZE);
+            try {
+                MappedByteBuffer dbb = map(MapMode.READ_ONLY, position, size);
+                try {
+                    // ## Bug: Closing this channel will not terminate the write
+                    int n = target.write(dbb);
+                    assert n >= 0;
+                    remaining -= n;
+                    if (isSelChImpl) {
+                        // one attempt to write to selectable channel
+                        break;
+                    }
+                    assert n > 0;
+                    position += n;
+                } finally {
+                    unmap(dbb);
+                }
+            } catch (IOException ioe) {
+                // Only throw exception if no bytes have been written
+                if (remaining == count)
+                    throw ioe;
+                break;
+            }
         }
+        return count - remaining;
     }
 
     private long transferToArbitraryChannel(long position, int icount,
@@ -535,20 +545,34 @@
                                          long position, long count)
         throws IOException
     {
-        // Note we could loop here to accumulate more at once
         synchronized (src.positionLock) {
-            long p = src.position();
-            int icount = (int)Math.min(Math.min(count, Integer.MAX_VALUE),
-                                       src.size() - p);
-            // ## Bug: Closing this channel will not terminate the write
-            MappedByteBuffer bb = src.map(MapMode.READ_ONLY, p, icount);
-            try {
-                long n = write(bb, position);
-                src.position(p + n);
-                return n;
-            } finally {
-                unmap(bb);
+            long pos = src.position();
+            long max = Math.min(count, src.size() - pos);
+
+            long remaining = max;
+            long p = pos;
+            while (remaining > 0L) {
+                long size = Math.min(remaining, MAPPED_TRANSFER_SIZE);
+                // ## Bug: Closing this channel will not terminate the write
+                MappedByteBuffer bb = src.map(MapMode.READ_ONLY, p, size);
+                try {
+                    long n = write(bb, position);
+                    assert n > 0;
+                    p += n;
+                    position += n;
+                    remaining -= n;
+                } catch (IOException ioe) {
+                    // Only throw exception if no bytes have been written
+                    if (remaining == max)
+                        throw ioe;
+                    break;
+                } finally {
+                    unmap(bb);
+                }
             }
+            long nwritten = max - remaining;
+            src.position(pos + nwritten);
+            return nwritten;
         }
     }
 
--- a/src/share/classes/sun/nio/ch/IOUtil.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/nio/ch/IOUtil.java	Sun Aug 29 22:41:28 2010 -0700
@@ -38,34 +38,6 @@
 
     private IOUtil() { }                // No instantiation
 
-    /*
-     * Returns the index of first buffer in bufs with remaining,
-     * or -1 if there is nothing left
-     */
-    private static int remaining(ByteBuffer[] bufs) {
-        int numBufs = bufs.length;
-        for (int i=0; i<numBufs; i++) {
-            if (bufs[i].hasRemaining()) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    /*
-     * Returns a new ByteBuffer array with only unfinished buffers in it
-     */
-    private static ByteBuffer[] skipBufs(ByteBuffer[] bufs,
-                                         int nextWithRemaining)
-    {
-        int newSize = bufs.length - nextWithRemaining;
-        ByteBuffer[] temp = new ByteBuffer[newSize];
-        for (int i=0; i<newSize; i++) {
-            temp[i] = bufs[i + nextWithRemaining];
-        }
-        return temp;
-    }
-
     static int write(FileDescriptor fd, ByteBuffer src, long position,
                      NativeDispatcher nd, Object lock)
         throws IOException
@@ -93,7 +65,7 @@
             }
             return n;
         } finally {
-            Util.releaseTemporaryDirectBuffer(bb);
+            Util.offerFirstTemporaryDirectBuffer(bb);
         }
     }
 
@@ -125,88 +97,81 @@
     static long write(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
         throws IOException
     {
-        int nextWithRemaining = remaining(bufs);
-        // if all bufs are empty we should return immediately
-        if (nextWithRemaining < 0)
-            return 0;
-        // If some bufs are empty we should skip them
-        if (nextWithRemaining > 0)
-            bufs = skipBufs(bufs, nextWithRemaining);
+        return write(fd, bufs, 0, bufs.length, nd);
+    }
 
-        int numBufs = bufs.length;
+    static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
+                      NativeDispatcher nd)
+        throws IOException
+    {
+        IOVecWrapper vec = IOVecWrapper.get(length);
 
-        // Create shadow to ensure DirectByteBuffers are used
-        ByteBuffer[] shadow = new ByteBuffer[numBufs];
+        boolean completed = false;
+        int iov_len = 0;
         try {
-            for (int i=0; i<numBufs; i++) {
-                if (!(bufs[i] instanceof DirectBuffer)) {
-                    int pos = bufs[i].position();
-                    int lim = bufs[i].limit();
-                    assert (pos <= lim);
-                    int rem = (pos <= lim ? lim - pos : 0);
 
-                    ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
-                    shadow[i] = bb;
-                    // Leave slow buffer position untouched; it will be updated
-                    // after we see how many bytes were really written out
-                    bb.put(bufs[i]);
-                    bufs[i].position(pos);
-                    bb.flip();
-                } else {
-                    shadow[i] = bufs[i];
+            // Iterate over buffers to populate native iovec array.
+            int count = offset + length;
+            for (int i=offset; i<count; i++) {
+                ByteBuffer buf = bufs[i];
+                int pos = buf.position();
+                int lim = buf.limit();
+                assert (pos <= lim);
+                int rem = (pos <= lim ? lim - pos : 0);
+                if (rem > 0) {
+                    vec.setBuffer(iov_len, buf, pos, rem);
+
+                    // allocate shadow buffer to ensure I/O is done with direct buffer
+                    if (!(buf instanceof DirectBuffer)) {
+                        ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
+                        shadow.put(buf);
+                        shadow.flip();
+                        vec.setShadow(iov_len, shadow);
+                        buf.position(pos);  // temporarily restore position in user buffer
+                        buf = shadow;
+                        pos = shadow.position();
+                    }
+
+                    vec.putBase(iov_len, ((DirectBuffer)buf).address() + pos);
+                    vec.putLen(iov_len, rem);
+                    iov_len++;
                 }
             }
+            if (iov_len == 0)
+                return 0L;
 
-            IOVecWrapper vec = null;
-            long bytesWritten = 0;
-            try {
-                // Create a native iovec array
-                vec= new IOVecWrapper(numBufs);
-
-                // Fill in the iovec array with appropriate data
-                for (int i=0; i<numBufs; i++) {
-                    ByteBuffer nextBuffer = shadow[i];
-                    // put in the buffer addresses
-                    long pos = nextBuffer.position();
-                    long len = nextBuffer.limit() - pos;
-                    vec.putBase(i, ((DirectBuffer)nextBuffer).address() + pos);
-                    vec.putLen(i, len);
-                }
-
-                // Invoke native call to fill the buffers
-                bytesWritten = nd.writev(fd, vec.address, numBufs);
-            } finally {
-                vec.free();
-            }
-            long returnVal = bytesWritten;
+            long bytesWritten = nd.writev(fd, vec.address, iov_len);
 
             // Notify the buffers how many bytes were taken
-            for (int i=0; i<numBufs; i++) {
-                ByteBuffer nextBuffer = bufs[i];
-                int pos = nextBuffer.position();
-                int lim = nextBuffer.limit();
-                assert (pos <= lim);
-                int len = (pos <= lim ? lim - pos : lim);
-                if (bytesWritten >= len) {
-                    bytesWritten -= len;
-                    int newPosition = pos + len;
-                    nextBuffer.position(newPosition);
-                } else { // Buffers not completely filled
-                    if (bytesWritten > 0) {
-                        assert(pos + bytesWritten < (long)Integer.MAX_VALUE);
-                        int newPosition = (int)(pos + bytesWritten);
-                        nextBuffer.position(newPosition);
-                    }
-                    break;
+            long left = bytesWritten;
+            for (int j=0; j<iov_len; j++) {
+                if (left > 0) {
+                    ByteBuffer buf = vec.getBuffer(j);
+                    int pos = vec.getPosition(j);
+                    int rem = vec.getRemaining(j);
+                    int n = (left > rem) ? rem : (int)left;
+                    buf.position(pos + n);
+                    left -= n;
                 }
+                // return shadow buffers to buffer pool
+                ByteBuffer shadow = vec.getShadow(j);
+                if (shadow != null)
+                    Util.offerLastTemporaryDirectBuffer(shadow);
+                vec.clearRefs(j);
             }
-            return returnVal;
+
+            completed = true;
+            return bytesWritten;
+
         } finally {
-            // return any substituted buffers to cache
-            for (int i=0; i<numBufs; i++) {
-                ByteBuffer bb = shadow[i];
-                if (bb != null && bb != bufs[i]) {
-                    Util.releaseTemporaryDirectBuffer(bb);
+            // if an error occurred then clear refs to buffers and return any shadow
+            // buffers to cache
+            if (!completed) {
+                for (int j=0; j<iov_len; j++) {
+                    ByteBuffer shadow = vec.getShadow(j);
+                    if (shadow != null)
+                        Util.offerLastTemporaryDirectBuffer(shadow);
+                    vec.clearRefs(j);
                 }
             }
         }
@@ -231,7 +196,7 @@
                 dst.put(bb);
             return n;
         } finally {
-            Util.releaseTemporaryDirectBuffer(bb);
+            Util.offerFirstTemporaryDirectBuffer(bb);
         }
     }
 
@@ -262,92 +227,85 @@
     static long read(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
         throws IOException
     {
-        int nextWithRemaining = remaining(bufs);
-        // if all bufs are empty we should return immediately
-        if (nextWithRemaining < 0)
-            return 0;
-        // If some bufs are empty we should skip them
-        if (nextWithRemaining > 0)
-            bufs = skipBufs(bufs, nextWithRemaining);
+        return read(fd, bufs, 0, bufs.length, nd);
+    }
 
-        int numBufs = bufs.length;
+    static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
+                     NativeDispatcher nd)
+        throws IOException
+    {
+        IOVecWrapper vec = IOVecWrapper.get(length);
 
-        // Read into the shadow to ensure DirectByteBuffers are used
-        ByteBuffer[] shadow = new ByteBuffer[numBufs];
-        boolean usingSlowBuffers = false;
+        boolean completed = false;
+        int iov_len = 0;
         try {
-            for (int i=0; i<numBufs; i++) {
-                if (bufs[i].isReadOnly())
+
+            // Iterate over buffers to populate native iovec array.
+            int count = offset + length;
+            for (int i=offset; i<count; i++) {
+                ByteBuffer buf = bufs[i];
+                if (buf.isReadOnly())
                     throw new IllegalArgumentException("Read-only buffer");
-                if (!(bufs[i] instanceof DirectBuffer)) {
-                    shadow[i] = Util.getTemporaryDirectBuffer(bufs[i].remaining());
-                    usingSlowBuffers = true;
-                } else {
-                    shadow[i] = bufs[i];
+                int pos = buf.position();
+                int lim = buf.limit();
+                assert (pos <= lim);
+                int rem = (pos <= lim ? lim - pos : 0);
+
+                if (rem > 0) {
+                    vec.setBuffer(iov_len, buf, pos, rem);
+
+                    // allocate shadow buffer to ensure I/O is done with direct buffer
+                    if (!(buf instanceof DirectBuffer)) {
+                        ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
+                        vec.setShadow(iov_len, shadow);
+                        buf = shadow;
+                        pos = shadow.position();
+                    }
+
+                    vec.putBase(iov_len, ((DirectBuffer)buf).address() + pos);
+                    vec.putLen(iov_len, rem);
+                    iov_len++;
                 }
             }
+            if (iov_len == 0)
+                return 0L;
 
-            IOVecWrapper vec = null;
-            long bytesRead = 0;
-            try {
-                // Create a native iovec array
-                vec = new IOVecWrapper(numBufs);
-
-                // Fill in the iovec array with appropriate data
-                for (int i=0; i<numBufs; i++) {
-                    ByteBuffer nextBuffer = shadow[i];
-                    // put in the buffer addresses
-                    long pos = nextBuffer.position();
-                    long len = nextBuffer.remaining();
-                    vec.putBase(i, ((DirectBuffer)nextBuffer).address() + pos);
-                    vec.putLen(i, len);
-                }
-
-                // Invoke native call to fill the buffers
-                bytesRead = nd.readv(fd, vec.address, numBufs);
-            } finally {
-                vec.free();
-            }
-            long returnVal = bytesRead;
+            long bytesRead = nd.readv(fd, vec.address, iov_len);
 
             // Notify the buffers how many bytes were read
-            for (int i=0; i<numBufs; i++) {
-                ByteBuffer nextBuffer = shadow[i];
-                // Note: should this have been cached from above?
-                int pos = nextBuffer.position();
-                int len = nextBuffer.remaining();
-                if (bytesRead >= len) {
-                    bytesRead -= len;
-                    int newPosition = pos + len;
-                    nextBuffer.position(newPosition);
-                } else { // Buffers not completely filled
-                    if (bytesRead > 0) {
-                        assert(pos + bytesRead < (long)Integer.MAX_VALUE);
-                        int newPosition = (int)(pos + bytesRead);
-                        nextBuffer.position(newPosition);
+            long left = bytesRead;
+            for (int j=0; j<iov_len; j++) {
+                ByteBuffer shadow = vec.getShadow(j);
+                if (left > 0) {
+                    ByteBuffer buf = vec.getBuffer(j);
+                    int rem = vec.getRemaining(j);
+                    int n = (left > rem) ? rem : (int)left;
+                    if (shadow == null) {
+                        int pos = vec.getPosition(j);
+                        buf.position(pos + n);
+                    } else {
+                        shadow.limit(shadow.position() + n);
+                        buf.put(shadow);
                     }
-                    break;
+                    left -= n;
                 }
+                if (shadow != null)
+                    Util.offerLastTemporaryDirectBuffer(shadow);
+                vec.clearRefs(j);
             }
 
-            // Put results from shadow into the slow buffers
-            if (usingSlowBuffers) {
-                for (int i=0; i<numBufs; i++) {
-                    if (!(bufs[i] instanceof DirectBuffer)) {
-                        shadow[i].flip();
-                        bufs[i].put(shadow[i]);
-                    }
-                }
-            }
-            return returnVal;
+            completed = true;
+            return bytesRead;
+
         } finally {
-            // return any substituted buffers to cache
-            if (usingSlowBuffers) {
-                for (int i=0; i<numBufs; i++) {
-                    ByteBuffer bb = shadow[i];
-                    if (bb != null && bb != bufs[i]) {
-                        Util.releaseTemporaryDirectBuffer(bb);
-                    }
+            // if an error occurred then clear refs to buffers and return any shadow
+            // buffers to cache
+            if (!completed) {
+                for (int j=0; j<iov_len; j++) {
+                    ByteBuffer shadow = vec.getShadow(j);
+                    if (shadow != null)
+                        Util.offerLastTemporaryDirectBuffer(shadow);
+                    vec.clearRefs(j);
                 }
             }
         }
--- a/src/share/classes/sun/nio/ch/IOVecWrapper.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/nio/ch/IOVecWrapper.java	Sun Aug 29 22:41:28 2010 -0700
@@ -25,6 +25,7 @@
 
 package sun.nio.ch;
 
+import java.nio.ByteBuffer;
 import sun.misc.*;
 
 
@@ -43,23 +44,98 @@
 class IOVecWrapper {
 
     // Miscellaneous constants
-    static int BASE_OFFSET = 0;
-    static int LEN_OFFSET;
-    static int SIZE_IOVEC;
+    private static final int BASE_OFFSET = 0;
+    private static final int LEN_OFFSET;
+    private static final int SIZE_IOVEC;
 
     // The iovec array
-    private AllocatedNativeObject vecArray;
+    private final AllocatedNativeObject vecArray;
+
+    // Number of elements in iovec array
+    private final int size;
+
+    // Buffers and position/remaining corresponding to elements in iovec array
+    private final ByteBuffer[] buf;
+    private final int[] position;
+    private final int[] remaining;
+
+    // Shadow buffers for cases when original buffer is substituted
+    private final ByteBuffer[] shadow;
 
     // Base address of this array
-    long address;
+    final long address;
 
     // Address size in bytes
     static int addressSize;
 
-    IOVecWrapper(int newSize) {
-        newSize = (newSize + 1) * SIZE_IOVEC;
-        vecArray = new AllocatedNativeObject(newSize, false);
-        address = vecArray.address();
+    private static class Deallocator implements Runnable {
+        private final AllocatedNativeObject obj;
+        Deallocator(AllocatedNativeObject obj) {
+            this.obj = obj;
+        }
+        public void run() {
+            obj.free();
+        }
+    }
+
+    // per thread IOVecWrapper
+    private static final ThreadLocal<IOVecWrapper> cached =
+        new ThreadLocal<IOVecWrapper>();
+
+    private IOVecWrapper(int size) {
+        this.size      = size;
+        this.buf       = new ByteBuffer[size];
+        this.position  = new int[size];
+        this.remaining = new int[size];
+        this.shadow    = new ByteBuffer[size];
+        this.vecArray  = new AllocatedNativeObject(size * SIZE_IOVEC, false);
+        this.address   = vecArray.address();
+    }
+
+    static IOVecWrapper get(int size) {
+        IOVecWrapper wrapper = cached.get();
+        if (wrapper != null && wrapper.size < size) {
+            // not big enough; eagerly release memory
+            wrapper.vecArray.free();
+            wrapper = null;
+        }
+        if (wrapper == null) {
+            wrapper = new IOVecWrapper(size);
+            Cleaner.create(wrapper, new Deallocator(wrapper.vecArray));
+            cached.set(wrapper);
+        }
+        return wrapper;
+    }
+
+    void setBuffer(int i, ByteBuffer buf, int pos, int rem) {
+        this.buf[i] = buf;
+        this.position[i] = pos;
+        this.remaining[i] = rem;
+    }
+
+    void setShadow(int i, ByteBuffer buf) {
+        shadow[i] = buf;
+    }
+
+    ByteBuffer getBuffer(int i) {
+        return buf[i];
+    }
+
+    int getPosition(int i) {
+        return position[i];
+    }
+
+    int getRemaining(int i) {
+        return remaining[i];
+    }
+
+    ByteBuffer getShadow(int i) {
+        return shadow[i];
+    }
+
+    void clearRefs(int i) {
+        buf[i] = null;
+        shadow[i] = null;
     }
 
     void putBase(int i, long base) {
@@ -78,10 +154,6 @@
             vecArray.putLong(offset, len);
     }
 
-    void free() {
-        vecArray.free();
-    }
-
     static {
         addressSize = Util.unsafe().addressSize();
         LEN_OFFSET = addressSize;
--- a/src/share/classes/sun/nio/ch/SocketChannelImpl.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/nio/ch/SocketChannelImpl.java	Sun Aug 29 22:41:28 2010 -0700
@@ -385,9 +385,11 @@
         }
     }
 
-    private long read0(ByteBuffer[] bufs) throws IOException {
-        if (bufs == null)
-            throw new NullPointerException();
+    public long read(ByteBuffer[] dsts, int offset, int length)
+        throws IOException
+    {
+        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
+            throw new IndexOutOfBoundsException();
         synchronized (readLock) {
             if (!ensureReadOpen())
                 return -1;
@@ -401,7 +403,7 @@
                 }
 
                 for (;;) {
-                    n = IOUtil.read(fd, bufs, nd);
+                    n = IOUtil.read(fd, dsts, offset, length, nd);
                     if ((n == IOStatus.INTERRUPTED) && isOpen())
                         continue;
                     return IOStatus.normalize(n);
@@ -418,15 +420,6 @@
         }
     }
 
-    public long read(ByteBuffer[] dsts, int offset, int length)
-        throws IOException
-    {
-        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
-            throw new IndexOutOfBoundsException();
-        // ## Fix IOUtil.write so that we can avoid this array copy
-        return read0(Util.subsequence(dsts, offset, length));
-    }
-
     public int write(ByteBuffer buf) throws IOException {
         if (buf == null)
             throw new NullPointerException();
@@ -458,9 +451,11 @@
         }
     }
 
-    public long write0(ByteBuffer[] bufs) throws IOException {
-        if (bufs == null)
-            throw new NullPointerException();
+    public long write(ByteBuffer[] srcs, int offset, int length)
+        throws IOException
+    {
+        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
+            throw new IndexOutOfBoundsException();
         synchronized (writeLock) {
             ensureWriteOpen();
             long n = 0;
@@ -472,7 +467,7 @@
                     writerThread = NativeThread.current();
                 }
                 for (;;) {
-                    n = IOUtil.write(fd, bufs, nd);
+                    n = IOUtil.write(fd, srcs, offset, length, nd);
                     if ((n == IOStatus.INTERRUPTED) && isOpen())
                         continue;
                     return IOStatus.normalize(n);
@@ -489,15 +484,6 @@
         }
     }
 
-    public long write(ByteBuffer[] srcs, int offset, int length)
-        throws IOException
-    {
-        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
-            throw new IndexOutOfBoundsException();
-        // ## Fix IOUtil.write so that we can avoid this array copy
-        return write0(Util.subsequence(srcs, offset, length));
-    }
-
     // package-private
     int sendOutOfBandData(byte b) throws IOException {
         synchronized (writeLock) {
--- a/src/share/classes/sun/nio/ch/Util.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/nio/ch/Util.java	Sun Aug 29 22:41:28 2010 -0700
@@ -41,67 +41,180 @@
 
 class Util {
 
-
     // -- Caches --
 
     // The number of temp buffers in our pool
-    private static final int TEMP_BUF_POOL_SIZE = 3;
+    private static final int TEMP_BUF_POOL_SIZE = 8;
 
-    // Per-thread soft cache of the last temporary direct buffer
-    private static ThreadLocal<SoftReference<ByteBuffer>>[] bufferPool;
+    // Per-thread cache of temporary direct buffers
+    private static ThreadLocal<BufferCache> bufferCache =
+        new ThreadLocal<BufferCache>()
+    {
+        @Override
+        protected BufferCache initialValue() {
+            return new BufferCache();
+        }
+    };
 
-    @SuppressWarnings("unchecked")
-    static ThreadLocal<SoftReference<ByteBuffer>>[] createThreadLocalBufferPool() {
-        return new ThreadLocal[TEMP_BUF_POOL_SIZE];
-    }
+    /**
+     * A simple cache of direct buffers.
+     */
+    private static class BufferCache {
+        // the array of buffers
+        private ByteBuffer[] buffers;
 
-    static {
-        bufferPool = createThreadLocalBufferPool();
-        for (int i=0; i<TEMP_BUF_POOL_SIZE; i++)
-            bufferPool[i] = new ThreadLocal<SoftReference<ByteBuffer>>();
-    }
+        // the number of buffers in the cache
+        private int count;
 
-    static ByteBuffer getTemporaryDirectBuffer(int size) {
-        ByteBuffer buf = null;
-        // Grab a buffer if available
-        for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
-            SoftReference<ByteBuffer> ref = bufferPool[i].get();
-            if ((ref != null) && ((buf = ref.get()) != null) &&
-                (buf.capacity() >= size)) {
-                buf.rewind();
-                buf.limit(size);
-                bufferPool[i].set(null);
-                return buf;
+        // the index of the first valid buffer (undefined if count == 0)
+        private int start;
+
+        private int next(int i) {
+            return (i + 1) % TEMP_BUF_POOL_SIZE;
+        }
+
+        BufferCache() {
+            buffers = new ByteBuffer[TEMP_BUF_POOL_SIZE];
+        }
+
+        /**
+         * Removes and returns a buffer from the cache of at least the given
+         * size (or null if no suitable buffer is found).
+         */
+        ByteBuffer get(int size) {
+            if (count == 0)
+                return null;  // cache is empty
+
+            ByteBuffer[] buffers = this.buffers;
+
+            // search for suitable buffer (often the first buffer will do)
+            ByteBuffer buf = buffers[start];
+            if (buf.capacity() < size) {
+                buf = null;
+                int i = start;
+                while ((i = next(i)) != start) {
+                    ByteBuffer bb = buffers[i];
+                    if (bb == null)
+                        break;
+                    if (bb.capacity() >= size) {
+                        buf = bb;
+                        break;
+                    }
+                }
+                if (buf == null)
+                    return null;
+                // move first element to here to avoid re-packing
+                buffers[i] = buffers[start];
+            }
+
+            // remove first element
+            buffers[start] = null;
+            start = next(start);
+            count--;
+
+            // prepare the buffer and return it
+            buf.rewind();
+            buf.limit(size);
+            return buf;
+        }
+
+        boolean offerFirst(ByteBuffer buf) {
+            if (count >= TEMP_BUF_POOL_SIZE) {
+                return false;
+            } else {
+                start = (start + TEMP_BUF_POOL_SIZE - 1) % TEMP_BUF_POOL_SIZE;
+                buffers[start] = buf;
+                count++;
+                return true;
             }
         }
 
-        // Make a new one
-        return ByteBuffer.allocateDirect(size);
-    }
-
-    static void releaseTemporaryDirectBuffer(ByteBuffer buf) {
-        if (buf == null)
-            return;
-        // Put it in an empty slot if such exists
-        for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
-            SoftReference<ByteBuffer> ref = bufferPool[i].get();
-            if ((ref == null) || (ref.get() == null)) {
-                bufferPool[i].set(new SoftReference<ByteBuffer>(buf));
-                return;
-            }
-        }
-        // Otherwise replace a smaller one in the cache if such exists
-        for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
-            SoftReference<ByteBuffer> ref = bufferPool[i].get();
-            ByteBuffer inCacheBuf = ref.get();
-            if ((inCacheBuf == null) || (buf.capacity() > inCacheBuf.capacity())) {
-                bufferPool[i].set(new SoftReference<ByteBuffer>(buf));
-                return;
+        boolean offerLast(ByteBuffer buf) {
+            if (count >= TEMP_BUF_POOL_SIZE) {
+                return false;
+            } else {
+                int next = (start + count) % TEMP_BUF_POOL_SIZE;
+                buffers[next] = buf;
+                count++;
+                return true;
             }
         }
 
-        // release memory
-       ((DirectBuffer)buf).cleaner().clean();
+        boolean isEmpty() {
+            return count == 0;
+        }
+
+        ByteBuffer removeFirst() {
+            assert count > 0;
+            ByteBuffer buf = buffers[start];
+            buffers[start] = null;
+            start = next(start);
+            count--;
+            return buf;
+        }
+    }
+
+    /**
+     * Returns a temporary buffer of at least the given size
+     */
+    static ByteBuffer getTemporaryDirectBuffer(int size) {
+        BufferCache cache = bufferCache.get();
+        ByteBuffer buf = cache.get(size);
+        if (buf != null) {
+            return buf;
+        } else {
+            // No suitable buffer in the cache so we need to allocate a new
+            // one. To avoid the cache growing then we remove the first
+            // buffer from the cache and free it.
+            if (!cache.isEmpty()) {
+                buf = cache.removeFirst();
+                free(buf);
+            }
+            return ByteBuffer.allocateDirect(size);
+        }
+    }
+
+    /**
+     * Releases a temporary buffer by returning to the cache or freeing it.
+     */
+    static void releaseTemporaryDirectBuffer(ByteBuffer buf) {
+        offerFirstTemporaryDirectBuffer(buf);
+    }
+
+    /**
+     * Releases a temporary buffer by returning to the cache or freeing it. If
+     * returning to the cache then insert it at the start so that it is
+     * likely to be returned by a subsequent call to getTemporaryDirectBuffer.
+     */
+    static void offerFirstTemporaryDirectBuffer(ByteBuffer buf) {
+        assert buf != null;
+        BufferCache cache = bufferCache.get();
+        if (!cache.offerFirst(buf)) {
+            // cache is full
+            free(buf);
+        }
+    }
+
+    /**
+     * Releases a temporary buffer by returning to the cache or freeing it. If
+     * returning to the cache then insert it at the end. This makes it
+     * suitable for scatter/gather operations where the buffers are returned to
+     * cache in same order that they were obtained.
+     */
+    static void offerLastTemporaryDirectBuffer(ByteBuffer buf) {
+        assert buf != null;
+        BufferCache cache = bufferCache.get();
+        if (!cache.offerLast(buf)) {
+            // cache is full
+            free(buf);
+        }
+    }
+
+    /**
+     * Frees the memory for the given direct buffer
+     */
+    private static void free(ByteBuffer buf) {
+        ((DirectBuffer)buf).cleaner().clean();
     }
 
     private static class SelectorWrapper {
--- a/src/share/classes/sun/util/resources/TimeZoneNames.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/util/resources/TimeZoneNames.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "Central European Summer Time", "CEST"};
         String CHAST[] = new String[] {"Chatham Standard Time", "CHAST",
                                        "Chatham Daylight Time", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"Central Indonesia Time", "CIT",
                                      "Central Indonesia Summer Time", "CIST"};
         String CLT[] = new String[] {"Chile Time", "CLT",
@@ -153,6 +155,8 @@
                                           "Pitcairn Daylight Time", "PDT"};
         String PKT[] = new String[] {"Pakistan Time", "PKT",
                                      "Pakistan Summer Time", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"Pacific Standard Time", "PST",
                                      "Pacific Daylight Time", "PDT"};
         String RST[] = new String[] {"Eastern Standard Time", "EST",
@@ -169,8 +173,6 @@
                                           "Eastern Summer Time (Tasmania)", "EST"};
         String TMT[] = new String[] {"Turkmenistan Time", "TMT",
                                      "Turkmenistan Summer Time", "TMST"};
-        String TRUT[] = new String[] {"Truk Time", "TRUT",
-                                      "Truk Summer Time", "TRUST"};
         String ULAT[]= new String[] {"Ulaanbaatar Time", "ULAT",
                                      "Ulaanbaatar Summer Time", "ULAST"};
         String WART[] = new String[] {"Western Argentine Time", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -755,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"Vanuatu Time", "VUT",
                                             "Vanuatu Summer Time", "VUST"}},
@@ -793,8 +797,8 @@
             {"Pacific/Palau", new String[] {"Palau Time", "PWT",
                                             "Palau Summer Time", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Ponape Time", "PONT",
-                                             "Ponape Summer Time", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"Papua New Guinea Time", "PGT",
                                                    "Papua New Guinea Summer Time", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"Cook Is. Time", "CKT",
@@ -807,12 +811,12 @@
                                              "Gilbert Is. Summer Time", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"Tonga Time", "TOT",
                                                 "Tonga Summer Time", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"Wake Time", "WAKT",
                                            "Wake Summer Time", "WAKST"}},
             {"Pacific/Wallis", new String[] {"Wallis & Futuna Time", "WFT",
                                              "Wallis & Futuna Summer Time", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_de.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_de.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "Mitteleurop\u00e4ische Sommerzeit", "MESZ"};
         String CHAST[] = new String[] {"Chatham Normalzeit", "CHAST",
                                        "Chatham Sommerzeit", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"Zentralindonesische Zeit", "CIT",
                                      "Zentralindonesische Sommerzeit", "CIST"};
         String CLT[] = new String[] {"Chilenische Zeit", "CLT",
@@ -153,6 +155,8 @@
                                           "Pitcairn Sommerzeit", "PDT"};
         String PKT[] = new String[] {"Pakistanische Zeit", "PKT",
                                      "Pakistanische Sommerzeit", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"Pazifische Normalzeit", "PST",
                                      "Pazifische Sommerzeit", "PDT"};
         String RST[] = new String[] {"\u00d6stliche Normalzeit", "EST",
@@ -169,8 +173,6 @@
                                           "\u00d6stliche Sommerzeit (Tasmanien)", "EST"};
         String TMT[] = new String[] {"Turkmenische Zeit", "TMT",
                                      "Turkmenische Sommerzeit", "TMST"};
-        String TRUT[] = new String[] {"Truk Zeit", "TRUT",
-                                      "Truk Sommerzeit", "TRUST"};
         String ULAT[]= new String[] {"Ulaanbaatar Zeit", "ULAT",
                                      "Ulaanbaatar Sommerzeit", "ULAST"};
         String WART[] = new String[] {"Westargentinische Zeit", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"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",
                                                         "Dumont-d'Urville Sommerzeit", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"Mawson Zeit", "MAWT",
                                                 "Mawson Sommerzeit", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"Vanuatu Zeit", "VUT",
                                             "Vanuatu Sommerzeit", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"Palau Zeit", "PWT",
                                             "Palau Sommerzeit", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Ponape Zeit", "PONT",
-                                             "Ponape Sommerzeit", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"Papua-Neuguinea Zeit", "PGT",
                                                    "Papua-Neuguinea Sommerzeit", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"Cook-Inseln Zeit", "CKT",
@@ -804,12 +811,12 @@
                                              "Gilbert-Inseln Sommerzeit", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"Tonga Zeit", "TOT",
                                                 "Tonga Sommerzeit", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"Wake Zeit", "WAKT",
                                            "Wake Sommerzeit", "WAKST"}},
             {"Pacific/Wallis", new String[] {"Wallis u. Futuna Zeit", "WFT",
                                              "Wallis u. Futuna Sommerzeit", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_es.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_es.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "Hora de verano de Europa Central", "CEST"};
         String CHAST[] = new String[] {"Hora est\u00e1ndar de Chatham", "CHAST",
                                        "Hora de verano de Chatham", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"Hora de Indonesia Central", "CIT",
                                      "Hora de verano de Indonesia Central", "CIST"};
         String CLT[] = new String[] {"Hora de Chile", "CLT",
@@ -153,6 +155,8 @@
                                           "Hora de verano de Pitcairn", "PDT"};
         String PKT[] = new String[] {"Hora de Pakist\u00e1n", "PKT",
                                      "Hora de verano de Pakist\u00e1n", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"Hora est\u00e1ndar del Pac\u00edfico", "PST",
                                      "Hora de verano del Pac\u00edfico", "PDT"};
         String RST[] = new String[] {"Hora est\u00e1ndar Oriental", "EST",
@@ -169,8 +173,6 @@
                                           "Hora de verano del Este (Tasmania)", "EST"};
         String TMT[] = new String[] {"Hora de Turkmenist\u00e1n", "TMT",
                                      "Hora de verano de Turkmenist\u00e1n", "TMST"};
-        String TRUT[] =new String[] {"Hora de Truk", "TRUT",
-                                     "Hora de verano de Truk", "TRUST"};
         String ULAT[]= new String[] {"Hora de Ulan Bator", "ULAT",
                                      "Hora de verano de Ulan Bator", "ULAST"};
         String WART[] = new String[] {"Hora de Argentina Occidental", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"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",
                                                         "Hora de verano de Dumont-d'Urville", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"Hora de Mawson", "MAWT",
                                                 "Hora de verano de Mawson", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -533,7 +539,6 @@
                                           "Hora de verano de Filipinas", "PHST"}},
             {"Asia/Muscat", GST},
             {"Asia/Nicosia", EET},
-
             {"Asia/Novokuznetsk", NOVT},
             {"Asia/Novosibirsk", NOVT},
             {"Asia/Oral", new String[] {"Hora de Uralsk", "ORAT",
@@ -753,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"Hora de Vanuatu", "VUT",
                                             "Hora de verano de Vanuatu", "VUST"}},
@@ -791,8 +797,8 @@
             {"Pacific/Palau", new String[] {"Hora de Palau", "PWT",
                                             "Hora de verano de Palau", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Hora de Ponape", "PONT",
-                                             "Hora de verano de Ponape", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"Hora de Pap\u00faa-Nueva Guinea", "PGT",
                                                    "Hora de verano de Pap\u00faa-Nueva Guinea", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"Hora de las islas Cook", "CKT",
@@ -805,12 +811,12 @@
                                              "Hora de verano de las islas Gilbert", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"Hora de Tonga", "TOT",
                                                 "Hora de verano de Tonga", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"Hora de Wake", "WAKT",
                                            "Hora de verano de Wake", "WAKST"}},
             {"Pacific/Wallis", new String[] {"Hora de Wallis y Futuna", "WFT",
                                              "Hora de verano de Wallis y Futuna", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_fr.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_fr.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "Heure d'\u00e9t\u00e9 d'Europe centrale", "CEST"} ;
         String CHAST[] = new String[] {"Heure standard de Chatham", "CHAST",
                                        "Heure avanc\u00e9e de Chatham", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"Heure d'Indon\u00e9sie centrale", "CIT",
                                      "Heure d'\u00e9t\u00e9 d'Indon\u00e9sie centrale", "CIST"};
         String CLT[] = new String[] {"Heure du Chili", "CLT",
@@ -153,6 +155,8 @@
                                           "heure avanc\u00e9e des Pitcairn", "PDT"};
         String PKT[] = new String[] {"Heure du Pakistan", "PKT",
                                      "Heure d'\u00e9t\u00e9 du Pakistan", "PKST"} ;
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"Heure normale du Pacifique", "PST",
                                      "Heure avanc\u00e9e du Pacifique", "PDT"} ;
         String RST[] = new String[] {"Heure normale de l'Est", "EST",
@@ -169,8 +173,6 @@
                                           "Heure d'\u00e9t\u00e9 d'Australie orientale (Tasmanie)", "EST"};
         String TMT[] = new String[] {"Heure du Turkm\u00e9nistan", "TMT",
                                      "Heure d'\u00e9t\u00e9 du Turkm\u00e9nistan", "TMST"} ;
-        String TRUT[] = new String[] {"Heure de Truk", "TRUT",
-                                      "Heure d'\u00e9t\u00e9 de Truk", "TRUST"};
         String ULAT[]= new String[] {"Heure de l'Ulaanbaatar", "ULAT",
                                      "Heure d'\u00e9t\u00e9 de l'Ulaanbaatar", "ULAST"} ;
         String WART[] = new String[] {"Heure D'Argentine de l'Ouest", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"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",
                                                         "Heure d'\u00e9t\u00e9 de Dumont-d'Urville", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"Heure de Mawson", "MAWT",
                                                 "Heure d'\u00e9t\u00e9 de Mawson", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"Heure du Vanuatu", "VUT",
                                             "Heure d'\u00e9t\u00e9 du Vanuatu", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"Heure de Palaos", "PWT",
                                             "Heure d'\u00e9t\u00e9 de Palaos", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Heure de Ponap\u00e9", "PONT",
-                                             "Heure d'\u00e9t\u00e9 de Ponap\u00e9", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"Heure de Papouasie-Nouvelle-Guin\u00e9e", "PGT",
                                                    "Heure d'\u00e9t\u00e9 de de Papouasie-Nouvelle-Guin\u00e9e", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"Heure des \u00celes Cook", "CKT",
@@ -804,12 +811,12 @@
                                              "Heure d'\u00e9t\u00e9 de Kiribati", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"Heure de Tonga", "TOT",
                                                 "Heure d'\u00e9t\u00e9 de Tonga", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"Heure de Wake", "WAKT",
                                            "Heure d'\u00e9t\u00e9 de Wake", "WAKST"}},
             {"Pacific/Wallis", new String[] {"Heure de Wallis et Futuna", "WFT",
                                              "Heure d'\u00e9t\u00e9 de Wallis et Futuna", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_it.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_it.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "Ora estiva dell'Europa centrale", "CEST"};
         String CHAST[] = new String[] {"Ora di Chatham standard", "CHAST",
                                        "Ora legale di Chatham", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"Ora dell'Indonesia centrale", "CIT",
                                      "Ora estiva dell'Indonesia centrale", "CIST"};
         String CLT[] = new String[] {"Ora del Cile", "CLT",
@@ -153,6 +155,8 @@
                                           "Ora legale di Pitcairn", "PDT"};
         String PKT[] = new String[] {"Ora del Pakistan", "PKT",
                                      "Ora estiva del Pakistan", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"Ora solare della costa occidentale USA", "PST",
                                      "Ora legale della costa occidentale USA", "PDT"};
         String RST[] = new String[] {"Ora solare USA orientale", "EST",
@@ -169,8 +173,6 @@
                                           "Ora estiva orientale (Tasmania)", "EST"};
         String TMT[] = new String[] {"Ora del Turkmenistan", "TMT",
                                      "Ora estiva del Turkmenistan", "TMST"};
-        String TRUT[] = new String[] {"Ora di Truk", "TRUT",
-                                      "Ora estiva di Truk", "TRUST"};
         String ULAT[]= new String[] {"Ora di Ulaanbaatar", "ULAT",
                                      "Ora estiva di Ulaanbaatar", "ULAST"};
         String WART[] = new String[] {"Ora dell'Argentina occidentale", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"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",
                                                         "Ora estiva di Dumont-d'Urville", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"Ora di Mawson", "MAWT",
                                                 "Ora estiva di Mawson", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"Ora di Vanuatu", "VUT",
                                             "Ora estiva di Vanuatu", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"Ora di Palau", "PWT",
                                             "Ora estiva di Palau", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Ora di Ponape", "PONT",
-                                             "Ora estiva di Ponape", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"Ora di Papua Nuova Guinea", "PGT",
                                                    "Ora estiva di Papua Nuova Guinea", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"Ora delle Isole Cook", "CKT",
@@ -804,12 +811,12 @@
                                              "Ora estiva delle Isole Gilbert", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"Ora di Tonga", "TOT",
                                                 "Ora estiva di Tonga", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"Ora di Wake", "WAKT",
                                            "Ora estiva di Wake", "WAKST"}},
             {"Pacific/Wallis", new String[] {"Ora di Wallis e Futuna", "WFT",
                                              "Ora estiva di Wallis e Futuna", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_ja.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_ja.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "\u4e2d\u90e8\u30e8\u30fc\u30ed\u30c3\u30d1\u590f\u6642\u9593", "CEST"};
         String CHAST[] = new String[] {"\u30c1\u30e3\u30bf\u30e0\u6a19\u6e96\u6642", "CHAST",
                                        "\u30c1\u30e3\u30bf\u30e0\u590f\u6642\u9593", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"\u4e2d\u592e\u30a4\u30f3\u30c9\u30cd\u30b7\u30a2\u6642\u9593", "CIT",
                                      "\u4e2d\u592e\u30a4\u30f3\u30c9\u30cd\u30b7\u30a2\u590f\u6642\u9593", "CIST"};
         String CLT[] = new String[] {"\u30c1\u30ea\u6642\u9593", "CLT",
@@ -153,6 +155,8 @@
                                           "\u30d4\u30c8\u30b1\u30eb\u30f3\u5cf6\u590f\u6642\u9593", "PDT"};
         String PKT[] = new String[] {"\u30d1\u30ad\u30b9\u30bf\u30f3\u6642\u9593", "PKT",
                                      "\u30d1\u30ad\u30b9\u30bf\u30f3\u590f\u6642\u9593", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6a19\u6e96\u6642", "PST",
                                      "\u592a\u5e73\u6d0b\u590f\u6642\u9593", "PDT"};
         String RST[] = new String[] {"\u6771\u90e8\u6a19\u6e96\u6642", "EST",
@@ -169,8 +173,6 @@
                                           "\u6771\u90e8\u590f\u6642\u9593 (\u30bf\u30b9\u30de\u30cb\u30a2)", "EST"};
         String TMT[] = new String[] {"\u30c8\u30eb\u30af\u30e1\u30cb\u30b9\u30bf\u30f3\u6642\u9593", "TMT",
                                      "\u30c8\u30eb\u30af\u30e1\u30cb\u30b9\u30bf\u30f3\u590f\u6642\u9593", "TMST"};
-        String TRUT[] = new String[] {"\u30c8\u30e9\u30c3\u30af\u6642\u9593", "TRUT",
-                                      "\u30c8\u30e9\u30c3\u30af\u590f\u6642\u9593", "TRUST"};
         String ULAT[]= new String[] {"\u30a6\u30e9\u30fc\u30f3\u30d0\u30fc\u30c8\u30eb\u6642\u9593", "ULAT",
                                      "\u30a6\u30e9\u30fc\u30f3\u30d0\u30fc\u30c8\u30eb\u590f\u6642\u9593", "ULAST"};
         String WART[] = new String[] {"\u897f\u30a2\u30eb\u30bc\u30f3\u30c1\u30f3\u6642\u9593", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"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",
                                                         "\u30c7\u30e5\u30e2\u30f3\u30c7\u30e5\u30eb\u30f4\u30a3\u30eb\u590f\u6642\u9593", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"\u30e2\u30fc\u30bd\u30f3\u6642\u9593", "MAWT",
                                                 "\u30e2\u30fc\u30bd\u30f3\u590f\u6642\u9593", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"\u30d0\u30cc\u30a2\u30c4\u6642\u9593", "VUT",
                                             "\u30d0\u30cc\u30a2\u30c4\u590f\u6642\u9593", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"\u30d1\u30e9\u30aa\u6642\u9593", "PWT",
                                             "\u30d1\u30e9\u30aa\u590f\u6642\u9593", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"\u30dd\u30ca\u30da\u6642\u9593", "PONT",
-                                             "\u30dd\u30ca\u30da\u590f\u6642\u9593", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"\u30d1\u30d7\u30a2\u30cb\u30e5\u30fc\u30ae\u30cb\u30a2\u6642\u9593", "PGT",
                                                    "\u30d1\u30d7\u30a2\u30cb\u30e5\u30fc\u30ae\u30cb\u30a2\u590f\u6642\u9593", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"\u30af\u30c3\u30af\u8af8\u5cf6\u6642\u9593", "CKT",
@@ -804,12 +811,12 @@
                                              "\u30ae\u30eb\u30d0\u30fc\u30c8\u8af8\u5cf6\u590f\u6642\u9593", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"\u30c8\u30f3\u30ac\u6642\u9593", "TOT",
                                                 "\u30c8\u30f3\u30ac\u590f\u6642\u9593", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"\u30a6\u30a7\u30fc\u30af\u6642\u9593", "WAKT",
                                            "\u30a6\u30a7\u30fc\u30af\u590f\u6642\u9593", "WAKST"}},
             {"Pacific/Wallis", new String[] {"\u30ef\u30ea\u30b9\u53ca\u3073\u30d5\u30c4\u30ca\u6642\u9593", "WFT",
                                              "\u30ef\u30ea\u30b9\u53ca\u3073\u30d5\u30c4\u30ca\u590f\u6642\u9593", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_ko.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_ko.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "\uc911\uc559 \uc720\ub7fd \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CEST"};
         String CHAST[] = new String[] {"Chatham \ud45c\uc900\uc2dc", "CHAST",
                                        "Chatham \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"\uc911\uc559 \uc778\ub3c4\ub124\uc2dc\uc544 \uc2dc\uac04", "CIT",
                                      "\uc911\uc559 \uc778\ub3c4\ub124\uc2dc\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CIST"};
         String CLT[] = new String[] {"\uce60\ub808 \uc2dc\uac04", "CLT",
@@ -153,6 +155,8 @@
                                           "Pitcairn \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PDT"};
         String PKT[] = new String[] {"\ud30c\ud0a4\uc2a4\ud0c4 \uc2dc\uac04", "PKT",
                                      "\ud30c\ud0a4\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"\ud0dc\ud3c9\uc591 \ud45c\uc900\uc2dc", "PST",
                                      "\ud0dc\ud3c9\uc591 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PDT"};
         String RST[] = new String[] {"\ub3d9\ubd80 \ud45c\uc900\uc2dc", "EST",
@@ -169,8 +173,6 @@
                                           "\ub3d9\ubd80 \uc77c\uad11\uc808\uc57d\uc2dc\uac04(\ud0dc\uc988\uba54\uc774\ub2c8\uc544)", "EST"};
         String TMT[] = new String[] {"\ud22c\ub974\ud06c\uba54\ub2c8\uc2a4\ud0c4 \uc2dc\uac04", "TMT",
                                      "\ud22c\ub974\ud06c\uba54\ub2c8\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TMST"};
-        String TRUT[] = new String[] {"\ud2b8\ub8e8\ud06c \uc2dc\uac04", "TRUT",
-                                      "\ud2b8\ub8e8\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TRUST"};
         String ULAT[]= new String[] {"\uc6b8\ub780\ubc14\ud0c0\ub974 \uc2dc\uac04", "ULAT",
                                      "\uc6b8\ub780\ubc14\ud0c0\ub974 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ULAST"};
         String WART[] = new String[] {"\uc11c\ubd80 \uc544\ub974\ud5e8\ud2f0\ub098 \uc2dc\uac04", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"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",
                                                         "\ub4a4\ubabd \ub4a4\ub974\ube4c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"\ubaa8\uc2a8 \uc2dc\uac04", "MAWT",
                                                 "\ubaa8\uc2a8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"\ube44\ub204\uc544\ud22c \uc2dc\uac04", "VUT",
                                             "\ubc14\ub204\uc544\ud22c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"\ud314\ub77c\uc6b0 \uc2dc\uac04", "PWT",
                                             "\ud314\ub77c\uc6b0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"\ud3ec\ub098\ud504 \uc2dc\uac04", "PONT",
-                                            "\ud3ec\ub098\ud504 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"\ud30c\ud478\uc544\ub274\uae30\ub2c8 \uc2dc\uac04", "PGT",
                                                   "\ud30c\ud478\uc544\ub274\uae30\ub2c8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"\ucfe0\ud06c \uad70\ub3c4 \uc2dc\uac04", "CKT",
@@ -804,12 +811,12 @@
                                              "\uae38\ubc84\ud2b8 \uad70\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"\ud1b5\uac00 \uc2dc\uac04", "TOT",
                                                 "\ud1b5\uac00 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"\uc6e8\uc774\ud06c \uc2dc\uac04", "WAKT",
                                            "\uc6e8\uc774\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WAKST"}},
             {"Pacific/Wallis", new String[] {"\uc6d4\ub9ac\uc2a4 \ud6c4\ud22c\ub098 \uc2dc\uac04", "WFT",
                                              "\uc6d4\ub9ac\uc2a4 \ud6c4\ud2b8\ub098 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_sv.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_sv.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "Centraleuropeisk sommartid", "CEST"};
         String CHAST[] = new String[] {"Chatham, normaltid", "CHAST",
                                        "Chatham, sommartid", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"Centralindonesisk tid", "CIT",
                                      "Centralindonesisk sommartid", "CIST"};
         String CLT[] = new String[] {"Chile, normaltid", "CLT",
@@ -153,6 +155,8 @@
                                           "Pitcairn, sommartid", "PDT"};
         String PKT[] = new String[] {"Pakistan, normaltid", "PKT",
                                      "Pakistan, sommartid", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"Stilla havet, normaltid", "PST",
                                      "Stilla havet, sommartid", "PDT"};
         String RST[] = new String[] {"Eastern, normaltid", "EST",
@@ -169,8 +173,6 @@
                                           "Eastern, sommartid (Tasmanien)", "EST"};
         String TMT[] = new String[] {"Turkmenistan, normaltid", "TMT",
                                      "Turkmenistan, sommartid", "TMST"};
-        String TRUT[] = new String[] {"Truk, normaltid", "TRUT",
-                                      "Truk, sommartid", "TRUST"};
         String ULAT[]= new String[] {"Ulaanbaatar, normaltid", "ULAT",
                                      "Ulaanbaatar, sommartid", "ULAST"};
         String WART[] = new String[] {"V\u00e4stargentina, normaltid", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"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",
                                                         "Dumont-d'Urville, sommartid", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"Mawson, normaltid", "MAWT",
                                                 "Mawson, sommartid", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"Vanuatu, normaltid", "VUT",
                                             "Vanuatu, sommartid", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"Palau, normaltid", "PWT",
                                             "Palau, sommartid", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Ponape, normaltid", "PONT",
-                                             "Ponape, sommartid", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"Papua Nya Guinea, normaltid", "PGT",
                                                    "Papua Nya Guinea, sommartid", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"Cook\u00f6arna, normaltid", "CKT",
@@ -804,12 +811,12 @@
                                              "Gilbert\u00f6arna, sommartid", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"Tonga, normaltid", "TOT",
                                                 "Tonga, sommartid", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"Wake, normaltid", "WAKT",
                                            "Wake, sommartid", "WAKST"}},
             {"Pacific/Wallis", new String[] {"Wallis & Futuna, normaltid", "WFT",
                                              "Wallis & Futuna, sommartid", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "\u4e2d\u6b27\u590f\u4ee4\u65f6", "CEST"};
         String CHAST[] = new String[] {"\u67e5\u8428\u59c6\u6807\u51c6\u65f6\u95f4", "CHAST",
                                        "\u67e5\u8428\u59c6\u590f\u4ee4\u65f6", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"\u4e2d\u90e8\u5370\u5ea6\u5c3c\u897f\u4e9a\u65f6\u95f4", "CIT",
                                      "\u4e2d\u90e8\u5370\u5ea6\u5c3c\u897f\u4e9a\u590f\u4ee4\u65f6", "CIST"};
         String CLT[] = new String[] {"\u667a\u5229\u65f6\u95f4", "CLT",
@@ -153,6 +155,8 @@
                                           "\u76ae\u7279\u5eb7\u5c9b\u590f\u4ee4\u65f6", "PDT"};
         String PKT[] = new String[] {"\u5df4\u57fa\u65af\u5766\u65f6\u95f4", "PKT",
                                      "\u5df4\u57fa\u65af\u5766\u590f\u4ee4\u65f6", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6807\u51c6\u65f6\u95f4", "PST",
                                      "\u592a\u5e73\u6d0b\u590f\u4ee4\u65f6", "PDT"};
         String RST[] = new String[] {"\u4e1c\u90e8\u6807\u51c6\u65f6\u95f4", "EST",
@@ -169,8 +173,6 @@
                                           "\u4e1c\u90e8\u590f\u4ee4\u65f6\uff08\u5854\u65af\u9a6c\u5c3c\u4e9a\uff09", "EST"};
         String TMT[] = new String[] {"\u571f\u5e93\u66fc\u65f6\u95f4", "TMT",
                                      "\u571f\u5e93\u66fc\u590f\u4ee4\u65f6", "TMST"};
-        String TRUT[] = new String[] {"\u7279\u9c81\u514b\u65f6\u95f4", "TRUT",
-                                      "\u7279\u9c81\u514b\u590f\u4ee4\u65f6", "TRUST"};
         String ULAT[]= new String[] {"\u5e93\u4f26\u65f6\u95f4", "ULAT",
                                      "\u5e93\u4f26\u590f\u4ee4\u65f6", "ULAST"};
         String WART[] = new String[] {"\u897f\u963f\u6839\u5ef7\u65f6\u95f4", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"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",
                                                         "Dumont-d'Urville \u590f\u4ee4\u65f6", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"\u83ab\u68ee\u65f6\u95f4", "MAWT",
                                                 "\u83ab\u68ee\u590f\u4ee4\u65f6", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"\u74e6\u5974\u963f\u56fe\u65f6\u95f4", "VUT",
                                             "\u74e6\u5974\u963f\u56fe\u590f\u4ee4\u65f6", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"\u5e1b\u7409\u65f6\u95f4", "PWT",
                                             "\u5e1b\u7409\u590f\u4ee4\u65f6", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Ponape \u65f6\u95f4", "PONT",
-                                             "Ponape \u590f\u4ee4\u65f6", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"\u5df4\u5e03\u4e9a\u65b0\u51e0\u5185\u4e9a\u65f6\u95f4", "PGT",
                                                    "\u5df4\u5e03\u4e9a\u65b0\u51e0\u5185\u4e9a\u590f\u4ee4\u65f6", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"\u5e93\u514b\u7fa4\u5c9b\u65f6\u95f4", "CKT",
@@ -804,12 +811,12 @@
                                              "\u5409\u4f2f\u7279\u7fa4\u5c9b\u590f\u4ee4\u65f6", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"\u4e1c\u52a0\u65f6\u95f4", "TOT",
                                                 "\u4e1c\u52a0\u590f\u4ee4\u65f6", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"\u5a01\u514b\u65f6\u95f4", "WAKT",
                                            "\u5a01\u514b\u590f\u4ee4\u65f6", "WAKST"}},
             {"Pacific/Wallis", new String[] {"\u74e6\u5229\u65af\u53ca\u798f\u675c\u7eb3\u7fa4\u5c9b\u65f6\u95f4", "WFT",
                                              "\u74e6\u5229\u65af\u53ca\u798f\u675c\u7eb3\u7fa4\u5c9b\u590f\u4ee4\u65f6", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "\u4e2d\u6b50\u590f\u4ee4\u6642\u9593", "CEST"};
         String CHAST[] = new String[] {"\u67e5\u5766\u6a19\u6e96\u6642\u9593", "CHAST",
                                        "\u67e5\u5766\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"\u4e2d\u5370\u5ea6\u5c3c\u897f\u4e9e\u6642\u9593", "CIT",
                                      "\u4e2d\u5370\u5ea6\u5c3c\u897f\u4e9e\u590f\u4ee4\u6642\u9593", "CIST"};
         String CLT[] = new String[] {"\u667a\u5229\u6642\u9593", "CLT",
@@ -153,6 +155,8 @@
                                         "\u76ae\u7279\u5eb7\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "PDT"};
         String PKT[] = new String[] {"\u5df4\u57fa\u65af\u5766\u6642\u9593", "PKT",
                                      "\u5df4\u57fa\u65af\u5766\u590f\u4ee4\u6642\u9593", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6a19\u6e96\u6642\u9593", "PST",
                                      "\u592a\u5e73\u6d0b\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "PDT"};
         String RST[] = new String[] {"\u6771\u65b9\u6a19\u6e96\u6642\u9593", "EST",
@@ -169,8 +173,6 @@
                                           "\u6771\u90e8\u590f\u4ee4\u6642\u9593 (\u5854\u65af\u6885\u5c3c\u4e9e\u5cf6)", "EST"};
         String TMT[] = new String[] {"\u571f\u5eab\u66fc\u6642\u9593", "TMT",
                                      "\u571f\u5eab\u66fc\u590f\u4ee4\u6642\u9593", "TMST"};
-        String TRUT[] = new String[] {"\u7279\u9b6f\u514b\u6642\u9593", "TRUT",
-                                      "\u7279\u9b6f\u514b\u590f\u4ee4\u6642\u9593", "TRUST"};
         String ULAT[]= new String[] {"\u5eab\u502b\u6642\u9593", "ULAT",
                                      "\u5eab\u502b\u590f\u4ee4\u6642\u9593", "ULAST"};
           String WART[] = new String[] {"\u897f\u963f\u6839\u5ef7\u6642\u9593", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"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",
                                                         "Dumont-d'Urville \u590f\u4ee4\u6642\u9593", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"\u83ab\u68ee\u6642\u9593", "MAWT",
                                                 "\u83ab\u68ee\u590f\u4ee4\u6642\u9593", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -753,6 +759,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"\u74e6\u5974\u963f\u5716\u6642\u9593", "VUT",
                                             "\u74e6\u5974\u963f\u5716\u590f\u4ee4\u6642\u9593", "VUST"}},
@@ -791,8 +798,8 @@
             {"Pacific/Palau", new String[] {"\u5e1b\u7409\u6642\u9593", "PWT",
                                             "\u5e1b\u7409\u590f\u4ee4\u6642\u9593", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Ponape \u6642\u9593", "PONT",
-                                             "Ponape \u590f\u4ee4\u6642\u9593", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"\u5df4\u5e03\u4e9e\u65b0\u5e7e\u5167\u4e9e\u6642\u9593", "PGT",
                                                    "\u5df4\u5e03\u4e9e\u65b0\u5e7e\u5167\u4e9e\u590f\u4ee4\u6642\u9593", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"\u5eab\u514b\u7fa4\u5cf6\u6642\u9593", "CKT",
@@ -805,12 +812,12 @@
                                              "\u5409\u4f2f\u7279\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"\u6771\u52a0\u6642\u9593", "TOT",
                                                 "\u6771\u52a0\u590f\u4ee4\u6642\u9593", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"\u5a01\u514b\u6642\u9593", "WAKT",
                                            "\u5a01\u514b\u590f\u4ee4\u6642\u9593", "WAKST"}},
             {"Pacific/Wallis", new String[] {"\u74e6\u5229\u65af\u53ca\u798f\u675c\u7d0d\u7fa4\u5cf6\u6642\u9593", "WFT",
                                              "\u74e6\u5229\u65af\u53ca\u798f\u675c\u7d0d\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/src/share/lib/security/java.security-solaris	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/lib/security/java.security-solaris	Sun Aug 29 22:41:28 2010 -0700
@@ -260,3 +260,30 @@
 # Example,
 #   ocsp.responderCertSerialNumber=2A:FF:00
  
+#
+# Policy for failed Kerberos KDC lookups:
+#
+# When a KDC is unavailable (network error, service failure, etc), it is
+# put inside a blacklist and accessed less often for future requests. The
+# value (case-insensitive) for this policy can be:
+#
+# tryLast
+#    KDCs in the blacklist are always tried after those not on the list.
+#
+# tryLess[:max_retries,timeout]
+#    KDCs in the blacklist are still tried by their order in the configuration,
+#    but with smaller max_retries and timeout values. max_retries and timeout
+#    are optional numerical parameters (default 1 and 5000, which means once
+#    and 5 seconds). Please notes that if any of the values defined here is
+#    more than what is defined in krb5.conf, it will be ignored.
+#
+# Whenever a KDC is detected as available, it is removed from the blacklist.
+# The blacklist is reset when krb5.conf is reloaded. You can add
+# refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is
+# reloaded whenever a JAAS authentication is attempted.
+#
+# Example,
+#   krb5.kdc.bad.policy = tryLast
+#   krb5.kdc.bad.policy = tryLess:2,2000
+krb5.kdc.bad.policy = tryLast
+
--- a/src/share/lib/security/java.security-windows	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/lib/security/java.security-windows	Sun Aug 29 22:41:28 2010 -0700
@@ -260,3 +260,30 @@
 # Example,
 #   ocsp.responderCertSerialNumber=2A:FF:00
  
+#
+# Policy for failed Kerberos KDC lookups:
+#
+# When a KDC is unavailable (network error, service failure, etc), it is
+# put inside a blacklist and accessed less often for future requests. The
+# value (case-insensitive) for this policy can be:
+#
+# tryLast
+#    KDCs in the blacklist are always tried after those not on the list.
+#
+# tryLess[:max_retries,timeout]
+#    KDCs in the blacklist are still tried by their order in the configuration,
+#    but with smaller max_retries and timeout values. max_retries and timeout
+#    are optional numerical parameters (default 1 and 5000, which means once
+#    and 5 seconds). Please notes that if any of the values defined here is
+#    more than what is defined in krb5.conf, it will be ignored.
+#
+# Whenever a KDC is detected as available, it is removed from the blacklist.
+# The blacklist is reset when krb5.conf is reloaded. You can add
+# refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is
+# reloaded whenever a JAAS authentication is attempted.
+#
+# Example,
+#   krb5.kdc.bad.policy = tryLast
+#   krb5.kdc.bad.policy = tryLess:2,2000
+krb5.kdc.bad.policy = tryLast
+
--- a/src/share/native/common/check_code.c	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/share/native/common/check_code.c	Sun Aug 29 22:41:28 2010 -0700
@@ -2730,7 +2730,10 @@
                                                                 operand);
             const char *result_signature;
             check_and_push(context, signature, VM_STRING_UTF);
-            result_signature = strchr(signature, JVM_SIGNATURE_ENDFUNC) + 1;
+            result_signature = strchr(signature, JVM_SIGNATURE_ENDFUNC);
+            if (result_signature++ == NULL) {
+                CCerror(context, "Illegal signature %s", signature);
+            }
             if (result_signature[0] == JVM_SIGNATURE_VOID) {
                 stack_results = "";
             } else {
@@ -3654,14 +3657,13 @@
                        const char **signature_p, fullinfo_type *full_info_p)
 {
     const char *p = *signature_p;
-    fullinfo_type full_info = MAKE_FULLINFO(0, 0, 0);
+    fullinfo_type full_info = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
     char result;
     int array_depth = 0;
 
     for (;;) {
         switch(*p++) {
             default:
-                full_info = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
                 result = 0;
                 break;
 
@@ -3714,7 +3716,14 @@
                 char buffer_space[256];
                 char *buffer = buffer_space;
                 char *finish = strchr(p, JVM_SIGNATURE_ENDCLASS);
-                int length = finish - p;
+                int length;
+                if (finish == NULL) {
+                    /* Signature must have ';' after the class name.
+                     * If it does not, return 0 and ITEM_Bogus in full_info. */
+                    result = 0;
+                    break;
+                }
+                length = finish - p;
                 if (length + 1 > (int)sizeof(buffer_space)) {
                     buffer = malloc(length + 1);
                     check_and_push(context, buffer, VM_MALLOC_BLK);
--- a/src/solaris/classes/java/io/UnixFileSystem.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/solaris/classes/java/io/UnixFileSystem.java	Sun Aug 29 22:41:28 2010 -0700
@@ -187,7 +187,6 @@
                     }
                 }
             }
-            assert canonicalize0(path).equals(res) || path.startsWith(javaHome);
             return res;
         }
     }
--- a/src/solaris/classes/sun/nio/fs/UnixPath.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/solaris/classes/sun/nio/fs/UnixPath.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1141,6 +1141,13 @@
             }
             result = result.resolve(element);
         }
+
+        // check file exists (without following links)
+        try {
+            UnixFileAttributes.get(result, false);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(result);
+        }
         return result;
     }
 
--- a/src/solaris/native/java/net/PlainDatagramSocketImpl.c	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/solaris/native/java/net/PlainDatagramSocketImpl.c	Sun Aug 29 22:41:28 2010 -0700
@@ -1052,30 +1052,38 @@
 Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
                                                            jobject this) {
     jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    int fd;
-
-    int t = 1;
+    int fd, t = 1;
+#ifdef AF_INET6
+    int domain = ipv6_available() ? AF_INET6 : AF_INET;
+#else
+    int domain = AF_INET;
+#endif
 
     if (IS_NULL(fdObj)) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Socket closed");
         return;
-    } else {
-#ifdef AF_INET6
-        if (ipv6_available()) {
-            fd =  JVM_Socket(AF_INET6, SOCK_DGRAM, 0);
-        } else
-#endif /* AF_INET6 */
-            {
-                fd =  JVM_Socket(AF_INET, SOCK_DGRAM, 0);
-            }
     }
-    if (fd == JVM_IO_ERR) {
+
+    if ((fd = JVM_Socket(domain, SOCK_DGRAM, 0)) == JVM_IO_ERR) {
         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
                        "Error creating socket");
         return;
     }
 
+#ifdef AF_INET6
+    /* Disable IPV6_V6ONLY to ensure dual-socket support */
+    if (domain == AF_INET6) {
+        int arg = 0;
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
+                       sizeof(int)) < 0) {
+            NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
+            close(fd);
+            return;
+        }
+    }
+#endif /* AF_INET6 */
+
      setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int));
 
 #ifdef __linux__
@@ -1088,7 +1096,7 @@
      * On Linux for IPv6 sockets we must set the hop limit
      * to 1 to be compatible with default ttl of 1 for IPv4 sockets.
      */
-    if (ipv6_available()) {
+    if (domain == AF_INET6) {
         int ttl = 1;
         setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl,
                    sizeof(ttl));
--- a/src/solaris/native/java/net/PlainSocketImpl.c	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/solaris/native/java/net/PlainSocketImpl.c	Sun Aug 29 22:41:28 2010 -0700
@@ -181,6 +181,12 @@
                                            jboolean stream) {
     jobject fdObj, ssObj;
     int fd;
+    int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
+#ifdef AF_INET6
+    int domain = ipv6_available() ? AF_INET6 : AF_INET;
+#else
+    int domain = AF_INET;
+#endif
 
     if (socketExceptionCls == NULL) {
         jclass c = (*env)->FindClass(env, "java/net/SocketException");
@@ -194,25 +200,29 @@
         (*env)->ThrowNew(env, socketExceptionCls, "null fd object");
         return;
     }
-#ifdef AF_INET6
-    if (ipv6_available()) {
-        fd = JVM_Socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
-    } else
-#endif /* AF_INET6 */
-        {
-            fd = JVM_Socket(AF_INET, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
-        }
-    if (fd == JVM_IO_ERR) {
+
+    if ((fd = JVM_Socket(domain, type, 0)) == JVM_IO_ERR) {
         /* note: if you run out of fds, you may not be able to load
          * the exception class, and get a NoClassDefFoundError
          * instead.
          */
         NET_ThrowNew(env, errno, "can't create socket");
         return;
-    } else {
-        (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
     }
 
+#ifdef AF_INET6
+    /* Disable IPV6_V6ONLY to ensure dual-socket support */
+    if (domain == AF_INET6) {
+        int arg = 0;
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
+                       sizeof(int)) < 0) {
+            NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
+            close(fd);
+            return;
+        }
+    }
+#endif /* AF_INET6 */
+
     /*
      * If this is a server socket then enable SO_REUSEADDR
      * automatically and set to non blocking.
@@ -221,9 +231,15 @@
     if (ssObj != NULL) {
         int arg = 1;
         SET_NONBLOCKING(fd);
-        JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
-            sizeof(arg));
+        if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
+                           sizeof(arg)) < 0) {
+            NET_ThrowNew(env, errno, "cannot set SO_REUSEADDR");
+            close(fd);
+            return;
+        }
     }
+
+    (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
 }
 
 /*
--- a/src/solaris/native/sun/nio/ch/Net.c	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/solaris/native/sun/nio/ch/Net.c	Sun Aug 29 22:41:28 2010 -0700
@@ -170,6 +170,22 @@
     if (fd < 0) {
         return handleSocketError(env, errno);
     }
+
+#ifdef AF_INET6
+    /* Disable IPV6_V6ONLY to ensure dual-socket support */
+    if (domain == AF_INET6) {
+        int arg = 0;
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
+                       sizeof(int)) < 0) {
+            JNU_ThrowByNameWithLastError(env,
+                                         JNU_JAVANETPKG "SocketException",
+                                         "sun.nio.ch.Net.setIntOption");
+            close(fd);
+            return -1;
+        }
+    }
+#endif
+
     if (reuse) {
         int arg = 1;
         if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
--- a/src/windows/classes/java/io/Win32FileSystem.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/src/windows/classes/java/io/Win32FileSystem.java	Sun Aug 29 22:41:28 2010 -0700
@@ -424,7 +424,6 @@
                     }
                 }
             }
-            assert canonicalize0(path).equalsIgnoreCase(res);
             return res;
         }
     }
--- a/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh	Thu Aug 26 16:17:02 2010 -0700
+++ b/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh	Sun Aug 29 22:41:28 2010 -0700
@@ -55,7 +55,7 @@
   Linux )
     FS="/"
     ;;
-  Windows* )
+  Windows* | CYGWIN* )
     FS="\\"
     ;;
 esac
--- a/test/java/net/URI/Test.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/test/java/net/URI/Test.java	Sun Aug 29 22:41:28 2010 -0700
@@ -1536,6 +1536,7 @@
         serial();
         urls();
         npes();
+        bugs();
     }
 
 
@@ -1572,6 +1573,19 @@
     }
 
 
+    // miscellaneous bugs/rfes that don't fit in with the test framework
+
+    static void bugs() {
+        // 6339649 - include detail message from nested exception
+        try {
+            URI uri = URI.create("http://nowhere.net/should not be permitted");
+        } catch (IllegalArgumentException e) {
+            if ("".equals(e.getMessage()) || e.getMessage() == null) {
+                throw new RuntimeException ("No detail message");
+            }
+        }
+    }
+
     public static void main(String[] args) throws Exception {
         switch (args.length) {
 
--- a/test/java/nio/file/Path/Misc.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/test/java/nio/file/Path/Misc.java	Sun Aug 29 22:41:28 2010 -0700
@@ -261,6 +261,21 @@
         assertTrue(file.toRealPath(true).isSameFile(file.toRealPath(false)));
 
         /**
+         * Test: toRealPath should fail if file does not exist
+         */
+        Path doesNotExist = dir.resolve("DoesNotExist");
+        try {
+            doesNotExist.toRealPath(true);
+            throw new RuntimeException("IOException expected");
+        } catch (IOException expected) {
+        }
+        try {
+            doesNotExist.toRealPath(false);
+            throw new RuntimeException("IOException expected");
+        } catch (IOException expected) {
+        }
+
+        /**
          * Test: toRealPath(true) should resolve links
          */
         if (supportsLinks) {
--- a/test/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.sh	Thu Aug 26 16:17:02 2010 -0700
+++ b/test/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.sh	Sun Aug 29 22:41:28 2010 -0700
@@ -23,6 +23,7 @@
 
 #
 # @test
+# @ignore until 6543856 is fixed
 # @bug 4990825
 # @summary attach to external but local JVM processes
 # @library ../../testlibrary
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/net/www/protocol/file/DirPermissionDenied.java	Sun Aug 29 22:41:28 2010 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.net.URL;
+import java.net.URLConnection;
+import java.io.IOException;
+
+public class DirPermissionDenied {
+    public static void main(String[] args) throws Exception {
+        URL url = new URL("file:" + args[0]);
+
+        try {
+            URLConnection uc = url.openConnection();
+            uc.connect();
+        } catch (IOException e) {
+            // OK
+        } catch (Exception e) {
+            throw new RuntimeException("Failed " + e);
+        }
+
+        try {
+            URLConnection uc = url.openConnection();
+            uc.getInputStream();
+        } catch (IOException e) {
+            // OK
+        } catch (Exception e) {
+            throw new RuntimeException("Failed " + e);
+        }
+
+        try {
+            URLConnection uc = url.openConnection();
+            uc.getContentLengthLong();
+        } catch (IOException e) {
+            // OK
+        } catch (Exception e) {
+            throw new RuntimeException("Failed " + e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/net/www/protocol/file/DirPermissionDenied.sh	Sun Aug 29 22:41:28 2010 -0700
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# @test
+# @bug 6977851
+# @summary NPE from FileURLConnection.connect
+# @build DirPermissionDenied
+# @run shell DirPermissionDenied.sh
+
+TESTDIR="${TESTCLASSES}/DirPermissionDeniedDirectory"
+echo ${TESTDIR}
+
+rm -rf ${TESTDIR}
+mkdir -p ${TESTDIR}
+chmod 333 ${TESTDIR}
+
+$TESTJAVA/bin/java -classpath $TESTCLASSES DirPermissionDenied ${TESTDIR}
+result=$?
+rm -rf ${TESTDIR}
+exit $result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/BadKdcDefaultValue.java	Sun Aug 29 22:41:28 2010 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 6976536
+ * @summary Solaris JREs do not have the krb5.kdc.bad.policy configured by default.
+ * @run main/othervm BadKdcDefaultValue
+ */
+
+import java.security.Security;
+
+public class BadKdcDefaultValue {
+    public static void main(String[] args) throws Exception {
+        if (!"tryLast".equalsIgnoreCase(
+                Security.getProperty("krb5.kdc.bad.policy"))) {
+            throw new Exception("Default value not correct");
+        }
+    }
+}
+
--- a/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6226610.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6226610.java	Sun Aug 29 22:41:28 2010 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6226610
+ * @bug 6226610 6973030
  * @run main/othervm B6226610
  * @summary HTTP tunnel connections send user headers to proxy
  */
@@ -36,45 +36,23 @@
 
 import java.io.*;
 import java.net.*;
-import javax.net.ssl.*;
-import javax.net.ServerSocketFactory;
-import sun.net.www.*;
-import java.util.Enumeration;
+import sun.net.www.MessageHeader;
 
 public class B6226610 {
     static HeaderCheckerProxyTunnelServer proxy;
 
-    // it seems there's no proxy ever if a url points to 'localhost',
-    // even if proxy related properties are set. so we need to bind
-    // our simple http proxy and http server to a non-loopback address
-    static InetAddress firstNonLoAddress = null;
+    public static void main(String[] args) throws Exception
+    {
+        proxy = new HeaderCheckerProxyTunnelServer();
+        proxy.start();
 
-    public static void main(String[] args)
-    {
-       try {
-          proxy = new HeaderCheckerProxyTunnelServer();
-          proxy.start();
-       } catch (Exception e) {
-          System.out.println("Cannot create proxy: " + e);
-       }
-
-       try {
-            firstNonLoAddress = getNonLoAddress();
-
-            if (firstNonLoAddress == null) {
-                System.out.println("The test needs at least one non-loopback address to run. Quit now.");
-                System.exit(0);
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-
-        System.setProperty( "https.proxyHost", firstNonLoAddress.getHostAddress());
-        System.setProperty( "https.proxyPort", (new Integer(proxy.getLocalPort())).toString() );
+        String hostname = InetAddress.getLocalHost().getHostName();
 
         try {
-           URL u = new URL("https://" + firstNonLoAddress.getHostAddress());
-           java.net.URLConnection c = u.openConnection();
+           URL u = new URL("https://" + hostname + "/");
+           System.out.println("Connecting to " + u);
+           InetSocketAddress proxyAddr = new InetSocketAddress(hostname, proxy.getLocalPort());
+           java.net.URLConnection c = u.openConnection(new Proxy(Proxy.Type.HTTP, proxyAddr));
 
            /* I want this header to go to the destination server only, protected
             * by SSL
@@ -89,33 +67,15 @@
             }
             else
                System.out.println(e);
-
+         } finally {
+             if (proxy != null) proxy.shutdown();
          }
 
          if (HeaderCheckerProxyTunnelServer.failed)
-            throw new RuntimeException("Test failed: Proxy should not receive user defined headers for tunneled requests");
+            throw new RuntimeException("Test failed; see output");
     }
-
-    public static InetAddress getNonLoAddress() throws Exception {
-        NetworkInterface loNIC = NetworkInterface.getByInetAddress(InetAddress.getByName("localhost"));
-        Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces();
-        while (nics.hasMoreElements()) {
-            NetworkInterface nic = nics.nextElement();
-            if (!nic.getName().equalsIgnoreCase(loNIC.getName())) {
-                Enumeration<InetAddress> addrs = nic.getInetAddresses();
-                while (addrs.hasMoreElements()) {
-                    InetAddress addr = addrs.nextElement();
-                    if (!addr.isLoopbackAddress())
-                        return addr;
-                }
-            }
-        }
-        return null;
-    }
-
 }
 
-
 class HeaderCheckerProxyTunnelServer extends Thread
 {
     public static boolean failed = false;
@@ -139,6 +99,10 @@
        }
     }
 
+    void shutdown() {
+        try { ss.close(); } catch (IOException e) {}
+    }
+
     public void run()
     {
         try {
@@ -178,6 +142,15 @@
            retrieveConnectInfo(statusLine);
 
            if (mheader.findValue("X-TestHeader") != null) {
+             System.out.println("Proxy should not receive user defined headers for tunneled requests");
+             failed = true;
+           }
+
+           // 6973030
+           String value;
+           if ((value = mheader.findValue("Proxy-Connection")) == null ||
+                !value.equals("keep-alive")) {
+             System.out.println("Proxy-Connection:keep-alive not being sent");
              failed = true;
            }
 
--- a/test/tools/jar/JarEntryTime.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/test/tools/jar/JarEntryTime.java	Sun Aug 29 22:41:28 2010 -0700
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 4225317
+ * @bug 4225317 6969651
  * @summary Check extracted files have date as per those in the .jar file
  */
 
@@ -68,17 +68,9 @@
     }
 
     public static void realMain(String[] args) throws Throwable {
-        final long now = System.currentTimeMillis();
-        final long earlier = now - (60L * 60L * 6L * 1000L);
-        final long yesterday = now - (60L * 60L * 24L * 1000L);
-
-        // ZipEntry's mod date has 2 seconds precision: give extra time to
-        // allow for e.g. rounding/truncation and networked/samba drives.
-        final long PRECISION = 10000L;
 
         File dirOuter = new File("outer");
         File dirInner = new File(dirOuter, "inner");
-
         File jarFile = new File("JarEntryTime.jar");
 
         // Remove any leftovers from prior run
@@ -99,6 +91,17 @@
         PrintWriter pw = new PrintWriter(fileInner);
         pw.println("hello, world");
         pw.close();
+
+        // Get the "now" from the "last-modified-time" of the last file we
+        // just created, instead of the "System.currentTimeMillis()", to
+        // workaround the possible "time difference" due to nfs.
+        final long now = fileInner.lastModified();
+        final long earlier = now - (60L * 60L * 6L * 1000L);
+        final long yesterday = now - (60L * 60L * 24L * 1000L);
+        // ZipEntry's mod date has 2 seconds precision: give extra time to
+        // allow for e.g. rounding/truncation and networked/samba drives.
+        final long PRECISION = 10000L;
+
         dirOuter.setLastModified(now);
         dirInner.setLastModified(yesterday);
         fileInner.setLastModified(earlier);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/pack200/CommandLineTests.java	Sun Aug 29 22:41:28 2010 -0700
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2007, 2010 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test CommandLineTests.sh
+ * @bug  6521334 6965836 6965836
+ * @compile -XDignore.symbol.file CommandLineTests.java Pack200Test.java
+ * @run main/timeout=1200 CommandLineTests
+ * @summary An ad hoc test to verify the behavior of pack200/unpack200 CLIs,
+ *           and a simulation of pack/unpacking in the install repo.
+ * @author ksrini
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+/*
+ * We try a potpouri of things ie. we have pack.conf to setup some
+ * options as well as a couple of command line options. We also test
+ * the packing and unpacking mechanism using the Java APIs. This also
+ * simulates pack200 the install workspace, noting that this is a simulation
+ * and can only test jars that are guaranteed to be available, also the
+ * configuration may not be in sync with the installer workspace.
+ */
+
+public class CommandLineTests {
+    private static final File CWD = new File(".");
+    private static final File EXP_SDK = new File(CWD, "exp-sdk-image");
+    private static final File EXP_SDK_LIB_DIR = new File(EXP_SDK, "lib");
+    private static final File EXP_SDK_BIN_DIR = new File(EXP_SDK, "bin");
+    private static final File EXP_JRE_DIR = new File(EXP_SDK, "jre");
+    private static final File EXP_JRE_LIB_DIR = new File(EXP_JRE_DIR, "lib");
+    private static final File RtJar = new File(EXP_JRE_LIB_DIR, "rt.jar");
+    private static final File CharsetsJar = new File(EXP_JRE_LIB_DIR, "charsets.jar");
+    private static final File JsseJar = new File(EXP_JRE_LIB_DIR, "jsse.jar");
+    private static final File ToolsJar = new File(EXP_SDK_LIB_DIR, "tools.jar");
+    private static final File javaCmd;
+    private static final File javacCmd;
+    private static final File ConfigFile = new File("pack.conf");
+    private static final List<File> jarList;
+
+    static {
+        javaCmd = Utils.IsWindows
+                    ? new File(EXP_SDK_BIN_DIR, "java.exe")
+                    : new File(EXP_SDK_BIN_DIR, "java");
+
+        javacCmd = Utils.IsWindows
+                    ? new File(EXP_SDK_BIN_DIR, "javac.exe")
+                    : new File(EXP_SDK_BIN_DIR, "javac");
+
+        jarList = new ArrayList<File>();
+        jarList.add(RtJar);
+        jarList.add(CharsetsJar);
+        jarList.add(JsseJar);
+        jarList.add(ToolsJar);
+    }
+
+    // init test area with a copy of the sdk
+    static void init() throws IOException {
+            Utils.recursiveCopy(Utils.JavaSDK, EXP_SDK);
+            creatConfigFile();
+    }
+
+    // Hopefully, this should be kept in sync with what the installer does.
+    static void creatConfigFile() throws IOException {
+        FileOutputStream fos = null;
+        PrintStream ps = null;
+        try {
+            fos = new FileOutputStream(ConfigFile);
+            ps = new PrintStream(fos);
+            ps.println("com.sun.java.util.jar.pack.debug.verbose=0");
+            ps.println("pack.modification.time=keep");
+            ps.println("pack.keep.class.order=true");
+            ps.println("pack.deflate.hint=false");
+            // Fail the build, if new or unknown attributes are introduced.
+            ps.println("pack.unknown.attribute=error");
+            ps.println("pack.segment.limit=-1");
+            // BugId: 6328502,  These files will be passed-through as-is.
+            ps.println("pack.pass.file.0=java/lang/Error.class");
+            ps.println("pack.pass.file.1=java/lang/LinkageError.class");
+            ps.println("pack.pass.file.2=java/lang/Object.class");
+            ps.println("pack.pass.file.3=java/lang/Throwable.class");
+            ps.println("pack.pass.file.4=java/lang/VerifyError.class");
+            ps.println("pack.pass.file.5=com/sun/demo/jvmti/hprof/Tracker.class");
+        } finally {
+            Utils.close(ps);
+            Utils.close(fos);
+        }
+    }
+
+    static void runPack200(boolean jre) throws IOException {
+        List<String> cmdsList = new ArrayList<String>();
+        for (File f : jarList) {
+            if (jre && f.getName().equals("tools.jar")) {
+                continue;  // need not worry about tools.jar for JRE
+            }
+            // make a backup copy for re-use
+            File bakFile = new File(f.getName() + ".bak");
+            if (!bakFile.exists()) {  // backup
+                Utils.copyFile(f.getAbsoluteFile(), bakFile.getAbsoluteFile());
+            } else {  // restore
+                Utils.copyFile(bakFile.getAbsoluteFile(), f.getAbsoluteFile());
+            }
+            cmdsList.clear();
+            cmdsList.add(Utils.getPack200Cmd());
+            cmdsList.add("-J-esa");
+            cmdsList.add("-J-ea");
+            cmdsList.add(Utils.Is64Bit ? "-J-Xmx1g" : "-J-Xmx512m");
+            cmdsList.add("--repack");
+            cmdsList.add("--config-file=" + ConfigFile.getAbsolutePath());
+            if (jre) {
+                cmdsList.add("--strip-debug");
+            }
+            // NOTE: commented until 6965836 is fixed
+            // cmdsList.add("--code-attribute=StackMapTable=strip");
+            cmdsList.add(f.getAbsolutePath());
+            Utils.runExec(cmdsList);
+        }
+    }
+
+    static void testJRE() throws IOException {
+        runPack200(true);
+        // the speciment JRE
+        List<String> cmdsList = new ArrayList<String>();
+        cmdsList.add(javaCmd.getAbsolutePath());
+        cmdsList.add("-verify");
+        cmdsList.add("-version");
+        Utils.runExec(cmdsList);
+    }
+
+    static void testJDK() throws IOException {
+        runPack200(false);
+        // test the specimen JDK
+        List<String> cmdsList = new ArrayList<String>();
+        cmdsList.add(javaCmd.getAbsolutePath());
+        cmdsList.add("-verify");
+        cmdsList.add("-version");
+        Utils.runExec(cmdsList);
+
+        // invoke javac to test the tools.jar
+        cmdsList.clear();
+        cmdsList.add(javacCmd.getAbsolutePath());
+        cmdsList.add("-J-verify");
+        cmdsList.add("-help");
+        Utils.runExec(cmdsList);
+    }
+    public static void main(String... args) {
+        try {
+            init();
+            testJRE();
+            testJDK();
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/pack200/Pack200Props.java	Sun Aug 29 22:41:28 2010 -0700
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6575373 6969063
+ * @summary verify default properties of the packer/unpacker and segment limit
+ * @compile -XDignore.symbol.file Utils.java Pack200Props.java
+ * @run main Pack200Props
+ * @author ksrini
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.Pack200;
+import java.util.jar.Pack200.Packer;
+
+/*
+ * Run this against a large jar file, by default the packer should generate only
+ * one segment, parse the output of the packer to verify if this is indeed true.
+ */
+
+public class Pack200Props {
+
+    public static void main(String... args) {
+        verifyDefaults();
+        File out = new File("test" + Utils.PACK_FILE_EXT);
+        out.delete();
+        verifySegmentLimit(out);
+    }
+
+    static void verifySegmentLimit(File outFile) {
+        File sdkHome = Utils.JavaSDK;
+        File testJar = new File(new File(sdkHome, "lib"), "tools.jar");
+
+        System.out.println("using pack200: " + Utils.getPack200Cmd());
+
+        List<String> cmdsList = new ArrayList<>();
+        cmdsList.add(Utils.getPack200Cmd());
+        cmdsList.add("--effort=1");
+        cmdsList.add("--verbose");
+        cmdsList.add("--no-gzip");
+        cmdsList.add(outFile.getName());
+        cmdsList.add(testJar.getAbsolutePath());
+        List<String> outList = Utils.runExec(cmdsList);
+
+        int count = 0;
+        for (String line : outList) {
+            System.out.println(line);
+            if (line.matches(".*Transmitted.*files of.*input bytes in a segment of.*bytes")) {
+                count++;
+            }
+        }
+        if (count == 0) {
+            throw new RuntimeException("no segments or no output ????");
+        } else if (count > 1) {
+            throw new RuntimeException("multiple segments detected, expected 1");
+        }
+    }
+
+    private static void verifyDefaults() {
+        Map<String, String> expectedDefaults = new HashMap<>();
+        Packer p = Pack200.newPacker();
+        expectedDefaults.put("com.sun.java.util.jar.pack.default.timezone",
+                p.FALSE);
+        expectedDefaults.put("com.sun.java.util.jar.pack.disable.native",
+                p.FALSE);
+        expectedDefaults.put("com.sun.java.util.jar.pack.verbose", "0");
+        expectedDefaults.put(p.CLASS_ATTRIBUTE_PFX + "CompilationID", "RUH");
+        expectedDefaults.put(p.CLASS_ATTRIBUTE_PFX + "SourceID", "RUH");
+        expectedDefaults.put(p.CODE_ATTRIBUTE_PFX + "CharacterRangeTable",
+                "NH[PHPOHIIH]");
+        expectedDefaults.put(p.CODE_ATTRIBUTE_PFX + "CoverageTable",
+                "NH[PHHII]");
+        expectedDefaults.put(p.DEFLATE_HINT, p.KEEP);
+        expectedDefaults.put(p.EFFORT, "5");
+        expectedDefaults.put(p.KEEP_FILE_ORDER, p.TRUE);
+        expectedDefaults.put(p.MODIFICATION_TIME, p.KEEP);
+        expectedDefaults.put(p.SEGMENT_LIMIT, "-1");
+        expectedDefaults.put(p.UNKNOWN_ATTRIBUTE, p.PASS);
+
+        Map<String, String> props = p.properties();
+        int errors = 0;
+        for (String key : expectedDefaults.keySet()) {
+            String def = expectedDefaults.get(key);
+            String x = props.get(key);
+            if (x == null) {
+                System.out.println("Error: key not found:" + key);
+                errors++;
+            } else {
+                if (!def.equals(x)) {
+                    System.out.println("Error: key " + key
+                            + "\n  value expected: " + def
+                            + "\n  value obtained: " + x);
+                    errors++;
+                }
+            }
+        }
+        if (errors > 0) {
+            throw new RuntimeException(errors +
+                    " error(s) encountered in default properties verification");
+        }
+    }
+}
+
--- a/test/tools/pack200/Pack200Simple.sh	Thu Aug 26 16:17:02 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-#
-# Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test Pack200Simple.sh
-# @bug  6521334
-# @build Pack200Test
-# @run shell/timeout=1200 Pack200Simple.sh
-# @summary An ad hoc test to verify class-file format.
-# @author Kumar Srinivasan
-
-# The goal of this test is to assist javac or other developers 
-# who modify class file formats, to quickly test those modifications
-# without having to build the install workspace. However it must
-# be noted that building the install workspace is the only know
-# way to prevent build breakages.
-
-# Pack200 developers could use this  as a basic smoke-test, however 
-# please note, there are other more elaborate and  thorough tests for 
-# this very purpose. 
-
-# We try a potpouri of things ie. we have pack.conf to setup some 
-# options as well as a couple of command line options. We also test
-# the packing and unpacking mechanism using the Java APIs.
-
-# print error and exit with a message 
-errorOut() {
-  if [ "x$1" = "x" ]; then
-    printf "Error: Unknown error\n"
-  else
-    printf "Error: %s\n" "$1"
-  fi
-
-  exit 1
-}
-
-# Verify directory context variables are set
-if [ "${TESTJAVA}" = "" ]; then
-  errorOut "TESTJAVA not set.  Test cannot execute.  Failed."
-fi
-
-if [ "${TESTSRC}" = "" ]; then
-  errorOut "TESTSRC not set.  Test cannot execute.  Failed."
-fi
-
-
-if [ "${TESTCLASSES}" = "" ]; then
-  errorOut "TESTCLASSES not set.  Test cannot execute.  Failed."
-fi
-
-# The common java utils we need
-PACK200=${TESTJAVA}/bin/pack200
-UNPACK200=${TESTJAVA}/bin/unpack200
-JAR=${TESTJAVA}/bin/jar
-
-# For Windows and Linux needs the heap to be set, for others ergonomics
-# will do the rest. It is important to use ea, which can expose class
-# format errors much earlier than later.
-
-OS=`uname -s`
-
-
-case "$OS" in
-  Windows*|CYGWIN* )
-    PackOptions="-J-Xmx512m -J-ea"
-    break
-    ;;
-
-  Linux )
-    PackOptions="-J-Xmx512m -J-ea"
-    break
-    ;;
-
-  * )
-    PackOptions="-J-ea"
-    ;;
-esac
-
-# Creates a packfile of choice expects 1 argument the filename
-createConfigFile() {
- # optimize for speed
- printf "pack.effort=1\n" > $1
- # we DO want to know about new attributes
- printf "pack.unknown.attribute=error\n" >> $1
- # optimize for speed
- printf "pack.deflate.hint=false\n" >> $1
- # keep the ordering for easy compare
- printf "pack.keep.class.order=true\n" >> $1
-}
-
-
-# Tests a given jar, expects 1 argument the fully qualified
-# name to a test jar, it writes all output to the current
-# directory which is a scratch  area.
-testAJar() {
-  PackConf="pack.conf"
-  createConfigFile $PackConf
-
-  # Try some command line options
-  CLIPackOptions="$PackOptions -v --no-gzip --segment-limit=10000 --config-file=$PackConf"
-
-  jfName=`basename $1`
-
-  ${PACK200}   $CLIPackOptions  ${jfName}.pack $1 > ${jfName}.pack.log 2>&1
-  if [ $? != 0 ]; then
-    errorOut "$jfName packing failed"
-  fi
-
-  # We want to test unpack200, therefore we dont use -r with pack
-  ${UNPACK200} -v ${jfName}.pack $jfName > ${jfName}.unpack.log 2>&1
-  if [ $? != 0 ]; then
-    errorOut "$jfName unpacking failed"
-  fi
-
-  # A quick crc compare test to ensure a well formed zip
-  # archive, this is a critical unpack200 behaviour.
-
-  unzip -t $jfName > ${jfName}.unzip.log 2>&1 
-  if [ $? != 0 ]; then
-    errorOut "$jfName unzip -t test failed"
-  fi
-
-  # The PACK200 signature should be at the top of the log
-  # this tag is critical for deployment related tools.
-
-  head -5 ${jfName}.unzip.log | grep PACK200 > /dev/null 2>&1
-  if [ $? != 0 ]; then
-    errorOut "$jfName PACK200 signature missing"
-  fi
-
-
-  # we know  the size fields don't match, strip 'em out, its
-  # extremely important to ensure that the date stamps match up.
-  # Don't EVER sort the output we are checking for correct ordering.
-
-  ${JAR} -tvf $1 | sed -e 's/^ *[0-9]* //g'> ${jfName}.ref.txt
-  ${JAR} -tvf $jfName | sed -e 's/^ *[0-9]* //g'> ${jfName}.cmp.txt
-
-  diff ${jfName}.ref.txt ${jfName}.cmp.txt > ${jfName}.diff.log 2>&1
-  if [ $? != 0 ]; then
-    errorOut "$jfName files missing"
-  fi
-}
-
-# These JARs are the largest and also the most likely specimens to 
-# expose class format issues and stress the packer as well.
-
-JLIST="${TESTJAVA}/lib/tools.jar ${TESTJAVA}/jre/lib/rt.jar"
-
-
-# Test the Command Line Interfaces (CLI).
-mkdir cliTestDir 
-_pwd=`pwd`
-cd cliTestDir
-
-for jarfile in $JLIST ; do 
-  if [ -f $jarfile ]; then
-    testAJar $jarfile
-  else
-    errorOut "Error: '$jarFile' does not exist\nTest requires a j2sdk-image\n"
-  fi
-done
-cd $_pwd
-
-# Test the Java APIs.
-mkdir apiTestDir 
-_pwd=`pwd`
-cd  apiTestDir
-
-# Strip out the -J prefixes.
-JavaPackOptions=`printf %s "$PackOptions" | sed -e 's/-J//g'`
-
-# Test the Java APIs now.
-$TESTJAVA/bin/java $JavaPackOptions -cp $TESTCLASSES Pack200Test $JLIST || exit 1
-
-cd $_pwd
-
-exit 0
--- a/test/tools/pack200/Pack200Test.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/test/tools/pack200/Pack200Test.java	Sun Aug 29 22:41:28 2010 -0700
@@ -24,111 +24,97 @@
 
 import java.util.*;
 import java.io.*;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
 import java.util.jar.*;
-import java.util.zip.*;
 
-/*
- * Pack200Test.java
- *
- * @author ksrini
- */
+ /*
+  * @test
+  * @bug 6521334 6712743
+  * @summary check for memory leaks, test general packer/unpacker functionality\
+  *          using native and java unpackers
+  * @compile -XDignore.symbol.file Utils.java Pack200Test.java
+  * @run main/othervm/timeout=1200 -Xmx512m Pack200Test
+  * @author ksrini
+  */
 
 /**
- * These tests are very rudimentary smoke tests to ensure that the packing
- * unpacking process works on a select set of JARs.
+ * Tests the packing/unpacking via the APIs.
  */
 public class Pack200Test {
 
     private static ArrayList <File> jarList = new ArrayList<File>();
-    static final String PACKEXT = ".pack";
+    static final MemoryMXBean mmxbean = ManagementFactory.getMemoryMXBean();
+    static final long m0 = getUsedMemory();
+    static final int LEAK_TOLERANCE = 20000; // OS and GC related variations.
 
     /** Creates a new instance of Pack200Test */
     private Pack200Test() {}
 
-    private static void doPackUnpack() {
-        for (File in : jarList) {
-            Pack200.Packer packer = Pack200.newPacker();
-            Map<String, String> p = packer.properties();
-            // Take the time optimization vs. space
-            p.put(packer.EFFORT, "1");  // CAUTION: do not use 0.
-            // Make the memory consumption as effective as possible
-            p.put(packer.SEGMENT_LIMIT,"10000");
-            // throw an error if an attribute is unrecognized
-            p.put(packer.UNKNOWN_ATTRIBUTE, packer.ERROR);
-            // ignore all JAR deflation requests to save time
-            p.put(packer.DEFLATE_HINT, packer.FALSE);
-            // save the file ordering of the original JAR
-            p.put(packer.KEEP_FILE_ORDER, packer.TRUE);
+    static long getUsedMemory() {
+        mmxbean.gc();
+        mmxbean.gc();
+        mmxbean.gc();
+        return mmxbean.getHeapMemoryUsage().getUsed()/1024;
+    }
 
-            try {
-                JarFile jarFile = new JarFile(in);
-
-                // Write out to a jtreg scratch area
-                FileOutputStream fos = new FileOutputStream(in.getName() + PACKEXT);
-
-                System.out.print("Packing [" + in.toString() + "]...");
-                // Call the packer
-                packer.pack(jarFile, fos);
-                jarFile.close();
-                fos.close();
-
-                System.out.print("Unpacking...");
-                File f = new File(in.getName() + PACKEXT);
-
-                // Write out to current directory, jtreg will setup a scratch area
-                JarOutputStream jostream = new JarOutputStream(new FileOutputStream(in.getName()));
-
-                // Unpack the files
-                Pack200.Unpacker unpacker = Pack200.newUnpacker();
-                // Call the unpacker
-                unpacker.unpack(f, jostream);
-                // Must explicitly close the output.
-                jostream.close();
-                System.out.print("Testing...");
-                // Ok we have unpacked the file, lets test it.
-                doTest(in);
-                System.out.println("Done.");
-            } catch (Exception e) {
-                System.out.println("ERROR: " + e.getMessage());
-                System.exit(1);
-            }
+    private static void leakCheck() throws Exception {
+        long diff = getUsedMemory() - m0;
+        System.out.println("  Info: memory diff = " + diff + "K");
+        if ( diff  > LEAK_TOLERANCE) {
+            throw new Exception("memory leak detected " + diff);
         }
     }
 
-    private static ArrayList <String> getZipFileEntryNames(ZipFile z) {
-        ArrayList <String> out = new ArrayList<String>();
-        for (ZipEntry ze : Collections.list(z.entries())) {
-            out.add(ze.getName());
-        }
-        return out;
-    }
+    private static void doPackUnpack() {
+        for (File in : jarList) {
+            JarOutputStream javaUnpackerStream = null;
+            JarOutputStream nativeUnpackerStream = null;
+            JarFile jarFile = null;
+            try {
+                jarFile = new JarFile(in);
 
-    private static void doTest(File in) throws Exception {
-       // make sure all the files in the original jar exists in the other
-       ArrayList <String> refList = getZipFileEntryNames(new ZipFile(in));
-       ArrayList <String> cmpList = getZipFileEntryNames(new ZipFile(in.getName()));
+                // Write out to a jtreg scratch area
+                File packFile = new File(in.getName() + Utils.PACK_FILE_EXT);
 
-       System.out.print(refList.size() + "/" + cmpList.size() + " entries...");
+                System.out.println("Packing [" + in.toString() + "]");
+                // Call the packer
+                Utils.pack(jarFile, packFile);
+                jarFile.close();
+                leakCheck();
 
-       if (refList.size() != cmpList.size()) {
-           throw new Exception("Missing: files ?, entries don't match");
-       }
+                System.out.println("  Unpacking using java unpacker");
+                File javaUnpackedJar = new File("java-" + in.getName());
+                // Write out to current directory, jtreg will setup a scratch area
+                javaUnpackerStream = new JarOutputStream(
+                        new FileOutputStream(javaUnpackedJar));
+                Utils.unpackj(packFile, javaUnpackerStream);
+                javaUnpackerStream.close();
+                System.out.println("  Testing...java unpacker");
+                leakCheck();
+                // Ok we have unpacked the file, lets test it.
+                Utils.doCompareVerify(in.getAbsoluteFile(), javaUnpackedJar);
 
-       for (String ename: refList) {
-          if (!cmpList.contains(ename)) {
-              throw new Exception("Does not contain : " + ename);
-          }
-       }
-    }
-
-    private static void doSanity(String[] args) {
-        for (String s: args) {
-            File f = new File(s);
-            if (f.exists()) {
-                jarList.add(f);
-            } else {
-                System.out.println("Warning: The JAR file " + f.toString() + " does not exist,");
-                System.out.println("         this test requires a JDK image, this file will be skipped.");
+                System.out.println("  Unpacking using native unpacker");
+                // Write out to current directory
+                File nativeUnpackedJar = new File("native-" + in.getName());
+                nativeUnpackerStream = new JarOutputStream(
+                        new FileOutputStream(nativeUnpackedJar));
+                Utils.unpackn(packFile, nativeUnpackerStream);
+                nativeUnpackerStream.close();
+                System.out.println("  Testing...native unpacker");
+                leakCheck();
+                // the unpackers (native and java) should produce identical bits
+                // so we use use bit wise compare, the verification compare is
+                // very expensive wrt. time.
+                Utils.doCompareBitWise(javaUnpackedJar, nativeUnpackedJar);
+                System.out.println("Done.");
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            } finally {
+                Utils.close(nativeUnpackerStream);
+                Utils.close(javaUnpackerStream);
+                Utils.close((Closeable) jarFile);
             }
         }
     }
@@ -137,11 +123,12 @@
      * @param args the command line arguments
      */
     public static void main(String[] args) {
-        if (args.length < 1) {
-            System.out.println("Usage: jar1 jar2 jar3 .....");
-            System.exit(1);
-        }
-        doSanity(args);
+        // select the jars carefully, adding more jars will increase the
+        // testing time, especially for jprt.
+        jarList.add(Utils.locateJar("tools.jar"));
+        jarList.add(Utils.locateJar("rt.jar"));
+        jarList.add(Utils.locateJar("golden.jar"));
+        System.out.println(jarList);
         doPackUnpack();
     }
 }
--- a/test/tools/pack200/PackageVersionTest.java	Thu Aug 26 16:17:02 2010 -0700
+++ b/test/tools/pack200/PackageVersionTest.java	Sun Aug 29 22:41:28 2010 -0700
@@ -22,13 +22,14 @@
  * questions.
  */
 
-/**
-  * @test
-  * @bug 6712743
-  * @summary verify package versioning
-  * @compile -XDignore.symbol.file PackageVersionTest.java
-  * @run main PackageVersionTest
-  */
+/*
+ * @test
+ * @bug 6712743
+ * @summary verify package versions
+ * @compile -XDignore.symbol.file Utils.java PackageVersionTest.java
+ * @run main PackageVersionTest
+ * @author ksrini
+ */
 
 import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
@@ -74,14 +75,6 @@
                 JAVA5_PACKAGE_MINOR_VERSION);
     }
 
-    static void close(Closeable c) {
-        if (c == null) {
-            return;
-        }
-        try {
-            c.close();
-        } catch (IOException ignore) {}
-    }
 
     static void createClassFile(String name) {
         createJavaFile(name);
@@ -93,7 +86,7 @@
             name.substring(name.length() - 1),
             name + ".java"
         };
-        compileJava(javacCmds);
+        Utils.compiler(javacCmds);
     }
 
     static void createJavaFile(String name) {
@@ -108,22 +101,8 @@
         } catch (IOException ioe) {
             throw new RuntimeException("creation of test file failed");
         } finally {
-            close(ps);
-            close(fos);
-        }
-    }
-
-    static void compileJava(String... javacCmds) {
-        if (com.sun.tools.javac.Main.compile(javacCmds) != 0) {
-            throw new RuntimeException("compilation failed");
-        }
-    }
-
-    static void makeJar(String... jargs) {
-        sun.tools.jar.Main jarTool =
-                new sun.tools.jar.Main(System.out, System.err, "jartool");
-        if (!jarTool.run(jargs)) {
-            throw new RuntimeException("jar command failed");
+            Utils.close(ps);
+            Utils.close(fos);
         }
     }
 
@@ -136,7 +115,7 @@
             jarFileName.getName(),
             filename
         };
-        makeJar(jargs);
+        Utils.jar(jargs);
         JarFile jfin = null;
 
         try {
@@ -163,7 +142,7 @@
         } catch (IOException ioe) {
             throw new RuntimeException(ioe.getMessage());
         } finally {
-            close(jfin);
+            Utils.close((Closeable) jfin);
         }
     }
 }
--- a/test/tools/pack200/SegmentLimit.java	Thu Aug 26 16:17:02 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @bug 6575373
- * @summary verify default segment limit
- * @compile SegmentLimit.java
- * @run main SegmentLimit
- */
-
-import java.io.BufferedReader;
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
-
-/*
- * Run this against a large jar file, by default the packer should generate only
- * one segment, parse the output of the packer to verify if this is indeed true.
- */
-
-public class SegmentLimit {
-
-    private static final File  javaHome = new File(System.getProperty("java.home"));
-
-    public static void main(String... args) {
-        if (!javaHome.getName().endsWith("jre")) {
-            throw new RuntimeException("Error: requires an SDK to run");
-        }
-
-        File out = new File("test" + Pack200Test.PACKEXT);
-        out.delete();
-        runPack200(out);
-    }
-
-    static void close(Closeable c) {
-        if (c == null) {
-            return;
-        }
-        try {
-            c.close();
-        } catch (IOException ignore) {}
-    }
-
-    static void runPack200(File outFile) {
-        File binDir = new File(javaHome, "bin");
-        File pack200Exe = System.getProperty("os.name").startsWith("Windows")
-                ? new File(binDir, "pack200.exe")
-                : new File(binDir, "pack200");
-        File sdkHome = javaHome.getParentFile();
-        File testJar = new File(new File(sdkHome, "lib"), "tools.jar");
-
-        System.out.println("using pack200: " + pack200Exe.getAbsolutePath());
-
-        String[] cmds = { pack200Exe.getAbsolutePath(),
-                          "--effort=1",
-                          "--verbose",
-                          "--no-gzip",
-                          outFile.getName(),
-                          testJar.getAbsolutePath()
-        };
-        InputStream is = null;
-        BufferedReader br = null;
-        InputStreamReader ir = null;
-
-        FileOutputStream fos = null;
-        PrintStream ps = null;
-
-        try {
-            ProcessBuilder pb = new ProcessBuilder(cmds);
-            pb.redirectErrorStream(true);
-            Process p = pb.start();
-            is = p.getInputStream();
-            ir = new InputStreamReader(is);
-            br = new BufferedReader(ir);
-
-            File logFile = new File("pack200.log");
-            fos = new FileOutputStream(logFile);
-            ps  = new PrintStream(fos);
-
-            String line = br.readLine();
-            int count = 0;
-            while (line != null) {
-                line = line.trim();
-                if (line.matches(".*Transmitted.*files of.*input bytes in a segment of.*bytes")) {
-                    count++;
-                }
-                ps.println(line);
-                line=br.readLine();
-            }
-            p.waitFor();
-            if (p.exitValue() != 0) {
-                throw new RuntimeException("pack200 failed");
-            }
-            p.destroy();
-            if (count > 1) {
-                throw new Error("test fails: check for multiple segments(" +
-                        count + ") in: " + logFile.getAbsolutePath());
-            }
-        } catch (IOException ex) {
-            throw new RuntimeException(ex.getMessage());
-        } catch (InterruptedException ignore){
-        } finally {
-            close(is);
-            close(ps);
-            close(fos);
-        }
-    }
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/pack200/TimeStamp.java	Sun Aug 29 22:41:28 2010 -0700
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+/*
+ * @test
+ * @bug 6966740
+ * @summary verify identical timestamps, unpacked in any timezone
+ * @compile -XDignore.symbol.file Utils.java TimeStamp.java
+ * @run main/othervm TimeStamp
+ * @author ksrini
+ */
+
+/**
+ * First we pack the file in some time zone say India, then we unpack the  file
+ * in the current time zone, and ensure the timestamp recorded in the unpacked
+ * jar are the same.
+ */
+public class TimeStamp {
+    static final TimeZone tz = TimeZone.getDefault();
+
+
+    public static void main(String... args) throws IOException {
+
+        // make a local copy of our test file
+        File srcFile = Utils.locateJar("golden.jar");
+        File goldenFile = new File("golden.jar");
+        Utils.copyFile(srcFile, goldenFile.getAbsoluteFile());
+
+        JarFile goldenJarFile = new JarFile(goldenFile);
+        File packFile = new File("golden.pack");
+
+        // set the test timezone and pack the file
+        TimeZone.setDefault(TimeZone.getTimeZone("IST"));
+        Utils.pack(goldenJarFile, packFile);
+        TimeZone.setDefault(tz);   // reset the timezone
+
+        // unpack in the  test timezone
+        File istFile = new File("golden.jar.java.IST");
+        unpackJava(packFile, istFile);
+        verifyJar(goldenFile, istFile);
+        istFile.delete();
+
+        // unpack in some other timezone
+        File pstFile = new File("golden.jar.java.PST");
+        unpackJava(packFile, pstFile);
+        verifyJar(goldenFile, pstFile);
+        pstFile.delete();
+
+        // repeat the test for unpack200 tool.
+        istFile = new File("golden.jar.native.IST");
+        unpackNative(packFile, istFile);
+        verifyJar(goldenFile, istFile);
+        istFile.delete();
+
+        pstFile = new File("golden.jar.native.PST");
+        unpackNative(packFile, pstFile);
+        verifyJar(goldenFile, pstFile);
+        pstFile.delete();
+    }
+
+    static void unpackNative(File packFile, File outFile) {
+        String name = outFile.getName();
+        String tzname = name.substring(name.lastIndexOf(".") + 1);
+        HashMap<String, String> env = new HashMap<>();
+        switch(tzname) {
+            case "PST":
+                env.put("TZ", "US/Pacific");
+                break;
+            case "IST":
+                env.put("TZ", "Asia/Calcutta");
+                break;
+            default:
+                throw new RuntimeException("not implemented: " + tzname);
+        }
+        List<String> cmdsList = new ArrayList<>();
+        cmdsList.add(Utils.getUnpack200Cmd());
+        cmdsList.add(packFile.getName());
+        cmdsList.add(outFile.getName());
+        Utils.runExec(cmdsList, env);
+    }
+
+    static void unpackJava(File packFile, File outFile) throws IOException {
+        String name = outFile.getName();
+        String tzname = name.substring(name.lastIndexOf(".") + 1);
+        JarOutputStream jos = null;
+        try {
+            TimeZone.setDefault(TimeZone.getTimeZone(tzname));
+            jos = new JarOutputStream(new FileOutputStream(outFile));
+            System.out.println("Using timezone: " + TimeZone.getDefault());
+            Utils.unpackj(packFile, jos);
+        } finally {
+            Utils.close(jos);
+            TimeZone.setDefault(tz); // always reset
+        }
+    }
+
+    static void verifyJar(File f1, File f2) throws IOException {
+        int errors = 0;
+        JarFile jf1 = null;
+        JarFile jf2 = null;
+        try {
+            jf1 = new JarFile(f1);
+            jf2 = new JarFile(f2);
+            System.out.println("Verifying: " + f1 + " and " + f2);
+            for (JarEntry je1 : Collections.list(jf1.entries())) {
+                JarEntry je2 = jf2.getJarEntry(je1.getName());
+                if (je1.getTime() != je2.getTime()) {
+                    System.out.println("Error:");
+                    System.out.println("  expected:" + jf1.getName() + ":"
+                            + je1.getName() + ":" + je1.getTime());
+                    System.out.println("  obtained:" + jf2.getName() + ":"
+                            + je2.getName() + ":" + je2.getTime());
+                    errors++;
+                }
+            }
+        } finally {
+            Utils.close(jf1);
+            Utils.close(jf2);
+        }
+        if (errors > 0) {
+            throw new RuntimeException("FAIL:" + errors + " error(s) encounted");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/pack200/UnpackerMemoryTest.java	Sun Aug 29 22:41:28 2010 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6531345
+ * @summary check for unpacker memory leaks
+ * @compile -XDignore.symbol.file Utils.java UnpackerMemoryTest.java
+ * @run main/othervm/timeout=1200 -Xmx32m UnpackerMemoryTest
+ * @author ksrini
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.io.IOException;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+public class UnpackerMemoryTest {
+
+    private static void createPackFile(File packFile) throws IOException {
+        File tFile = new File("test.dat");
+        FileOutputStream fos = null;
+        PrintStream ps = null;
+        String jarFileName = Utils.baseName(packFile, Utils.PACK_FILE_EXT)
+                + Utils.JAR_FILE_EXT;
+        JarFile jarFile = null;
+        try {
+            fos = new FileOutputStream(tFile);
+            ps = new PrintStream(fos);
+            ps.println("A quick brown fox");
+            Utils.jar("cvf", jarFileName, tFile.getName());
+            jarFile = new JarFile(jarFileName);
+            Utils.pack(jarFile, packFile);
+        } finally {
+            Utils.close(ps);
+            tFile.delete();
+            Utils.close(jarFile);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        String name = "foo";
+        File packFile = new File(name + Utils.PACK_FILE_EXT);
+        createPackFile(packFile);
+        if (!packFile.exists()) {
+           throw new RuntimeException(packFile + " not found");
+        }
+        File jarOut = new File(name + ".out");
+        for (int i = 0; i < 2000; i++) {
+            JarOutputStream jarOS = null;
+            FileOutputStream fos = null;
+            try {
+                fos = new FileOutputStream(jarOut);
+                jarOS = new JarOutputStream(fos);
+                System.out.println("Unpacking[" + i + "]" + packFile);
+                Utils.unpackn(packFile, jarOS);
+            }  finally {
+                Utils.close(jarOS);
+                Utils.close(fos);
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/pack200/Utils.java	Sun Aug 29 22:41:28 2010 -0700
@@ -0,0 +1,516 @@
+/*
+ * Copyright (c) 2007, 2010 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Pack200;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ *
+ * @author ksrini
+ */
+
+/*
+ * This class contains all the commonly used utilities used by various tests
+ * in this directory.
+ */
+class Utils {
+    static final String JavaHome = System.getProperty("test.java",
+            System.getProperty("java.home"));
+    static final boolean IsWindows =
+            System.getProperty("os.name").startsWith("Windows");
+    static final boolean Is64Bit =
+            System.getProperty("sun.arch.data.model", "32").equals("64");
+    static final File   JavaSDK =  new File(JavaHome).getParentFile();
+
+    static final String PACK_FILE_EXT   = ".pack";
+    static final String JAVA_FILE_EXT   = ".java";
+    static final String CLASS_FILE_EXT  = ".class";
+    static final String JAR_FILE_EXT    = ".jar";
+
+    static final File   TEST_SRC_DIR = new File(System.getProperty("test.src"));
+    static final String VERIFIER_DIR_NAME = "pack200-verifier";
+    static final File   VerifierJar = new File(VERIFIER_DIR_NAME + JAR_FILE_EXT);
+
+    private Utils() {} // all static
+
+    static {
+        if (!JavaHome.endsWith("jre")) {
+            throw new RuntimeException("Error: requires an SDK to run");
+        }
+    }
+
+    private static void init() throws IOException {
+        if (VerifierJar.exists()) {
+            return;
+        }
+        File srcDir = new File(TEST_SRC_DIR, VERIFIER_DIR_NAME);
+        List<File> javaFileList = findFiles(srcDir, createFilter(JAVA_FILE_EXT));
+        File tmpFile = File.createTempFile("javac", ".tmp");
+        File classesDir = new File("xclasses");
+        classesDir.mkdirs();
+        FileOutputStream fos = null;
+        PrintStream ps = null;
+        try {
+            fos = new FileOutputStream(tmpFile);
+            ps = new PrintStream(fos);
+            for (File f : javaFileList) {
+                ps.println(f.getAbsolutePath());
+            }
+        } finally {
+            close(ps);
+            close(fos);
+        }
+
+        compiler("-d",
+                "xclasses",
+                "@" + tmpFile.getAbsolutePath());
+
+        jar("cvfe",
+            VerifierJar.getName(),
+            "sun.tools.pack.verify.Main",
+            "-C",
+            "xclasses",
+            ".");
+    }
+
+    static void dirlist(File dir) {
+        File[] files = dir.listFiles();
+        System.out.println("--listing " + dir.getAbsolutePath() + "---");
+        for (File f : files) {
+            StringBuffer sb = new StringBuffer();
+            sb.append(f.isDirectory() ? "d " : "- ");
+            sb.append(f.getName());
+            System.out.println(sb);
+        }
+    }
+    static void doCompareVerify(File reference, File specimen) throws IOException {
+        init();
+        List<String> cmds = new ArrayList<String>();
+        cmds.add(getJavaCmd());
+        cmds.add("-jar");
+        cmds.add(VerifierJar.getName());
+        cmds.add(reference.getAbsolutePath());
+        cmds.add(specimen.getAbsolutePath());
+        cmds.add("-O");
+        runExec(cmds);
+    }
+
+    static void doCompareBitWise(File reference, File specimen)
+            throws IOException {
+        init();
+        List<String> cmds = new ArrayList<String>();
+        cmds.add(getJavaCmd());
+        cmds.add("-jar");
+        cmds.add(VerifierJar.getName());
+        cmds.add(reference.getName());
+        cmds.add(specimen.getName());
+        cmds.add("-O");
+        cmds.add("-b");
+        runExec(cmds);
+    }
+
+    static FileFilter createFilter(final String extension) {
+        return new FileFilter() {
+            @Override
+            public boolean accept(File pathname) {
+                String name = pathname.getName();
+                if (name.endsWith(extension)) {
+                    return true;
+                }
+                return false;
+            }
+        };
+    }
+
+    static final FileFilter DIR_FILTER = new FileFilter() {
+        public boolean accept(File pathname) {
+            if (pathname.isDirectory()) {
+                return true;
+            }
+            return false;
+        }
+    };
+
+    static final FileFilter FILE_FILTER = new FileFilter() {
+        public boolean accept(File pathname) {
+            if (pathname.isFile()) {
+                return true;
+            }
+            return false;
+        }
+    };
+
+    private static void setFileAttributes(File src, File dst) throws IOException {
+        dst.setExecutable(src.canExecute());
+        dst.setReadable(src.canRead());
+        dst.setWritable(src.canWrite());
+        dst.setLastModified(src.lastModified());
+    }
+
+    static void copyFile(File src, File dst) throws IOException {
+        if (src.isDirectory()) {
+            dst.mkdirs();
+            setFileAttributes(src, dst);
+            return;
+        } else {
+            File baseDirFile = dst.getParentFile();
+            if (!baseDirFile.exists()) {
+                baseDirFile.mkdirs();
+            }
+        }
+        FileInputStream in = null;
+        FileOutputStream out = null;
+        FileChannel srcChannel = null;
+        FileChannel dstChannel = null;
+        try {
+            in = new FileInputStream(src);
+            out = new FileOutputStream(dst);
+            srcChannel = in.getChannel();
+            dstChannel = out.getChannel();
+
+            long retval = srcChannel.transferTo(0, src.length(), dstChannel);
+            if (src.length() != dst.length()) {
+                throw new IOException("file copy failed for " + src);
+            }
+        } finally {
+            close(srcChannel);
+            close(dstChannel);
+            close(in);
+            close(out);
+        }
+        setFileAttributes(src, dst);
+    }
+
+    static String baseName(File file, String extension) {
+        return baseName(file.getAbsolutePath(), extension);
+    }
+
+    static String baseName(String name, String extension) {
+        int cut = name.length() - extension.length();
+        return name.lastIndexOf(extension) == cut
+                ? name.substring(0, cut)
+                : name;
+
+    }
+
+    /*
+     * Suppose a path is provided which consists of a full path
+     * this method returns the sub path for a full path ex: /foo/bar/baz/foobar.z
+     * and the base path is /foo/bar it will will return baz/foobar.z.
+     */
+    private static String getEntryPath(String basePath, String fullPath) {
+        if (!fullPath.startsWith(basePath)) {
+            return null;
+        }
+        return fullPath.substring(basePath.length());
+    }
+
+    static String getEntryPath(File basePathFile, File fullPathFile) {
+        return getEntryPath(basePathFile.toString(), fullPathFile.toString());
+    }
+
+    public static void recursiveCopy(File src, File dest) throws IOException {
+        if (!src.exists() || !src.canRead()) {
+            throw new IOException("file not found or readable: " + src);
+        }
+        if (dest.exists() && !dest.isDirectory() && !dest.canWrite()) {
+            throw new IOException("file not found or writeable: " + dest);
+        }
+        if (!dest.exists()) {
+            dest.mkdirs();
+        }
+        List<File> a = directoryList(src);
+        for (File f : a) {
+            copyFile(f, new File(dest, getEntryPath(src, f)));
+        }
+    }
+
+    static List<File> directoryList(File dirname) {
+        List<File>  dirList = new ArrayList<File>();
+        return directoryList(dirname, dirList, null);
+    }
+
+    private static List<File> directoryList(File dirname, List<File> dirList,
+            File[] dirs) {
+        dirList.addAll(Arrays.asList(dirname.listFiles(FILE_FILTER)));
+        dirs = dirname.listFiles(DIR_FILTER);
+        for (File f : dirs) {
+            if (f.isDirectory() && !f.equals(dirname)) {
+                dirList.add(f);
+                directoryList(f, dirList, dirs);
+            }
+        }
+        return dirList;
+    }
+
+    static void recursiveDelete(File dir) throws IOException {
+        if (dir.isFile()) {
+            dir.delete();
+        } else if (dir.isDirectory()) {
+            File[] entries = dir.listFiles();
+            for (int i = 0; i < entries.length; i++) {
+                if (entries[i].isDirectory()) {
+                    recursiveDelete(entries[i]);
+                }
+                entries[i].delete();
+            }
+            dir.delete();
+        }
+    }
+
+    static List<File> findFiles(File startDir, FileFilter filter)
+            throws IOException {
+        List<File> list = new ArrayList<File>();
+        findFiles0(startDir, list, filter);
+        return list;
+    }
+    /*
+     * finds files in the start directory using the the filter, appends
+     * the files to the dirList.
+     */
+    private static void findFiles0(File startDir, List<File> list,
+                                    FileFilter filter) throws IOException {
+        File[] foundFiles = startDir.listFiles(filter);
+        list.addAll(Arrays.asList(foundFiles));
+        File[] dirs = startDir.listFiles(DIR_FILTER);
+        for (File dir : dirs) {
+            findFiles0(dir, list, filter);
+        }
+    }
+
+    static void close(Closeable c) {
+        if (c == null) {
+            return;
+        }
+        try {
+            c.close();
+        } catch (IOException ignore) {
+        }
+    }
+
+    static void compiler(String... javacCmds) {
+        if (com.sun.tools.javac.Main.compile(javacCmds) != 0) {
+            throw new RuntimeException("compilation failed");
+        }
+    }
+
+    static void jar(String... jargs) {
+        sun.tools.jar.Main jarTool =
+                new sun.tools.jar.Main(System.out, System.err, "jartool");
+        if (!jarTool.run(jargs)) {
+            throw new RuntimeException("jar command failed");
+        }
+    }
+
+    // given a jar file foo.jar will write to foo.pack
+    static void pack(JarFile jarFile, File packFile) throws IOException {
+        Pack200.Packer packer = Pack200.newPacker();
+        Map<String, String> p = packer.properties();
+        // Take the time optimization vs. space
+        p.put(packer.EFFORT, "1");  // CAUTION: do not use 0.
+        // Make the memory consumption as effective as possible
+        p.put(packer.SEGMENT_LIMIT, "10000");
+        // ignore all JAR deflation requests to save time
+        p.put(packer.DEFLATE_HINT, packer.FALSE);
+        // save the file ordering of the original JAR
+        p.put(packer.KEEP_FILE_ORDER, packer.TRUE);
+        FileOutputStream fos = null;
+        try {
+            // Write out to a jtreg scratch area
+            fos = new FileOutputStream(packFile);
+            // Call the packer
+            packer.pack(jarFile, fos);
+        } finally {
+            close(fos);
+        }
+    }
+
+    // uses java unpacker, slow but useful to discover issues with the packer
+    static void unpackj(File inFile, JarOutputStream jarStream)
+            throws IOException {
+        unpack0(inFile, jarStream, true);
+
+    }
+
+    // uses native unpacker using the java APIs
+    static void unpackn(File inFile, JarOutputStream jarStream)
+            throws IOException {
+        unpack0(inFile, jarStream, false);
+    }
+
+    // given a packed file, create the jar file in the current directory.
+    private static void unpack0(File inFile, JarOutputStream jarStream,
+            boolean useJavaUnpack) throws IOException {
+        // Unpack the files
+        Pack200.Unpacker unpacker = Pack200.newUnpacker();
+        Map<String, String> props = unpacker.properties();
+        if (useJavaUnpack) {
+            props.put("com.sun.java.util.jar.pack.disable.native", "true");
+        }
+        // Call the unpacker
+        unpacker.unpack(inFile, jarStream);
+    }
+
+    static byte[] getBuffer(ZipFile zf, ZipEntry ze) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte buf[] = new byte[8192];
+        InputStream is = null;
+        try {
+            is = zf.getInputStream(ze);
+            int n = is.read(buf);
+            while (n > 0) {
+                baos.write(buf, 0, n);
+                n = is.read(buf);
+            }
+            return baos.toByteArray();
+        } finally {
+            close(is);
+        }
+    }
+
+    static ArrayList<String> getZipFileEntryNames(ZipFile z) {
+        ArrayList<String> out = new ArrayList<String>();
+        for (ZipEntry ze : Collections.list(z.entries())) {
+            out.add(ze.getName());
+        }
+        return out;
+    }
+    static List<String> runExec(List<String> cmdsList) {
+        return runExec(cmdsList, null);
+    }
+    static List<String> runExec(List<String> cmdsList, Map<String, String> penv) {
+        ArrayList<String> alist = new ArrayList<String>();
+        ProcessBuilder pb =
+                new ProcessBuilder(cmdsList);
+        Map<String, String> env = pb.environment();
+        if (penv != null && !penv.isEmpty()) {
+            env.putAll(penv);
+        }
+        pb.directory(new File("."));
+        dirlist(new File("."));
+        for (String x : cmdsList) {
+            System.out.print(x + " ");
+        }
+        System.out.println("");
+        int retval = 0;
+        Process p = null;
+        InputStreamReader ir = null;
+        BufferedReader rd = null;
+        InputStream is = null;
+        try {
+            pb.redirectErrorStream(true);
+            p = pb.start();
+            is = p.getInputStream();
+            ir = new InputStreamReader(is);
+            rd = new BufferedReader(ir, 8192);
+
+            String in = rd.readLine();
+            while (in != null) {
+                alist.add(in);
+                System.out.println(in);
+                in = rd.readLine();
+            }
+            retval = p.waitFor();
+            if (retval != 0) {
+                throw new RuntimeException("process failed with non-zero exit");
+            }
+        } catch (Exception ex) {
+            throw new RuntimeException(ex.getMessage());
+        } finally {
+            close(rd);
+            close(ir);
+            close(is);
+            if (p != null) {
+                p.destroy();
+            }
+        }
+        return alist;
+    }
+
+    static String getUnpack200Cmd() {
+        return getAjavaCmd("unpack200");
+    }
+
+    static String getPack200Cmd() {
+        return getAjavaCmd("pack200");
+    }
+
+    static String getJavaCmd() {
+        return getAjavaCmd("java");
+    }
+
+    static String getAjavaCmd(String cmdStr) {
+        File binDir = new File(JavaHome, "bin");
+        File unpack200File = IsWindows
+                ? new File(binDir, cmdStr + ".exe")
+                : new File(binDir, cmdStr);
+
+        String cmd = unpack200File.getAbsolutePath();
+        if (!unpack200File.canExecute()) {
+            throw new RuntimeException("please check" +
+                    cmd + " exists and is executable");
+        }
+        return cmd;
+    }
+
+    private static List<File> locaterCache = null;
+    // search the source dir and jdk dir for requested file and returns