changeset 294:90e1f09ce553

Merge
author jgodinez
date Mon, 14 Apr 2008 11:34:15 -0700
parents 99f3a382f574 (current diff) aaa5637a841d (diff)
children 804b0757d801
files
diffstat 441 files changed, 34563 insertions(+), 8797 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Apr 10 13:57:15 2008 -0700
+++ b/.hgtags	Mon Apr 14 11:34:15 2008 -0700
@@ -1,1 +1,2 @@
 37a05a11f281b4d238e2f9e7ebb67c63f64d0e77 jdk7-b24
+75fca0b0ab83ab1392e615910cea020f66535390 jdk7-b25
--- a/make/common/Defs-linux.gmk	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/common/Defs-linux.gmk	Mon Apr 14 11:34:15 2008 -0700
@@ -50,13 +50,13 @@
 CC_DEPEND_FILTER = $(SED) -e 's!$*\.$(OBJECT_SUFFIX)!$(dir $@)& $(dir $@)$*.$(DEPEND_SUFFIX)!g'
 
 ifndef PLATFORM_SRC
-  PLATFORM_SRC = $(JDK_TOPDIR)/src/solaris
+  PLATFORM_SRC = $(BUILDDIR)/../src/solaris
 endif # PLATFORM_SRC
 
 # Platform specific closed sources
 ifndef OPENJDK
   ifndef CLOSED_PLATFORM_SRC
-    CLOSED_PLATFORM_SRC = $(JDK_TOPDIR)/src/closed/solaris
+    CLOSED_PLATFORM_SRC = $(BUILDDIR)/../src/closed/solaris
   endif
 endif
 
--- a/make/common/Defs-solaris.gmk	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/common/Defs-solaris.gmk	Mon Apr 14 11:34:15 2008 -0700
@@ -45,13 +45,13 @@
 include $(JDK_MAKE_SHARED_DIR)/Defs.gmk
 
 ifndef PLATFORM_SRC
-PLATFORM_SRC = $(JDK_TOPDIR)/src/solaris
+PLATFORM_SRC = $(BUILDDIR)/../src/solaris
 endif # PLATFORM_SRC
 
 # Platform specific closed sources
 ifndef OPENJDK
   ifndef CLOSED_PLATFORM_SRC
-    CLOSED_PLATFORM_SRC = $(JDK_TOPDIR)/src/closed/solaris
+    CLOSED_PLATFORM_SRC = $(BUILDDIR)/../src/closed/solaris
   endif
 endif
 
--- a/make/common/Defs-windows.gmk	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/common/Defs-windows.gmk	Mon Apr 14 11:34:15 2008 -0700
@@ -51,13 +51,13 @@
 endif # LIB_LOCATION
 
 ifndef PLATFORM_SRC
-  PLATFORM_SRC  = $(JDK_TOPDIR)/src/windows
+  PLATFORM_SRC  = $(BUILDDIR)/../src/windows
 endif # PLATFORM_SRC
 
 # Platform specific closed sources
 ifndef OPENJDK
   ifndef CLOSED_PLATFORM_SRC
-    CLOSED_PLATFORM_SRC  = $(JDK_TOPDIR)/src/closed/windows
+    CLOSED_PLATFORM_SRC  = $(BUILDDIR)/../src/closed/windows
   endif
 endif
 
@@ -367,7 +367,7 @@
 endif
 
 # Settings for the VERSIONINFO tap on windows. 
-VERSIONINFO_RESOURCE = $(JDK_TOPDIR)/src/windows/resource/version.rc
+VERSIONINFO_RESOURCE = $(BUILDDIR)/../src/windows/resource/version.rc
 
 ifneq ($(JDK_BUILD_NUMBER),)
  COOKED_BUILD_NUMBER = $(shell $(ECHO) $(JDK_BUILD_NUMBER) | $(SED) -e 's/^b//' -e 's/^0//')
--- a/make/common/Defs.gmk	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/common/Defs.gmk	Mon Apr 14 11:34:15 2008 -0700
@@ -32,6 +32,13 @@
 #          So when it includes other files, it must use JDK_TOPDIR.
 #
 
+# Check for strange explicit settings (change to empty or true)
+ifdef OPENJDK
+  ifneq ($(OPENJDK),true)
+    x:=$(error "OPENJDK (if defined) can only be set to true")
+  endif
+endif
+
 #
 # On Solaris, the 'make' utility from Sun will not work with these makefiles.
 #    This little rule is only understood by Sun's make, and is harmless
@@ -41,7 +48,15 @@
 SUN_MAKE_TEST:sh = echo "ERROR: PLEASE USE GNU VERSION OF MAKE"; exit 33
 
 ifndef JDK_TOPDIR
-  JDK_TOPDIR=$(BUILDDIR)/..
+  ifdef BUILDDIR
+    JDK_TOPDIR=$(BUILDDIR)/..
+  else
+    JDK_TOPDIR:=$(error "ERROR: Cannot define top of jdk repository")
+  endif
+endif
+ifndef BUILDDIR
+  # Hack, due to deploy repository using this file.
+  BUILDDIR=$(JDK_TOPDIR)/make
 endif
 ifndef JDK_MAKE_SHARED_DIR
   JDK_MAKE_SHARED_DIR=$(JDK_TOPDIR)/make/common/shared
@@ -59,13 +74,13 @@
 # there yet.
 #
 ifndef SHARE_SRC
-  SHARE_SRC    = $(JDK_TOPDIR)/src/share
+  SHARE_SRC    = $(BUILDDIR)/../src/share
 endif
 
 # Files that cannot be included in the OpenJDK distribution are
 # collected under a parent directory which contains just those files.
 ifndef CLOSED_SRC
-  CLOSED_SRC  = $(JDK_TOPDIR)/src/closed
+  CLOSED_SRC  = $(BUILDDIR)/../src/closed
 endif
 
 # If we have no closed directory, force it to an openjdk build
@@ -79,19 +94,6 @@
   OPENJDK = true
 endif
 
-# Check for strange explicit settings (change to empty or true)
-ifdef OPENJDK
-  ifeq ($(OPENJDK),false)
-    # Silently treat as not defined
-    OPENJDK =
-  else
-    ifneq ($(OPENJDK),true)
-      dummy := $(warning "WARNING: OPENKJDK=$(OPENJDK) being treated as true")
-      OPENJDK = true
-    endif
-  endif
-endif
-
 # Define where closed directories are
 ifdef OPENJDK
   CLOSED_SRC =
@@ -170,14 +172,6 @@
   endif
 endif # OPENJDK
 
-# Default output directory
-ifdef OPENJDK
-_OUTPUTDIR=$(JDK_TOPDIR)/build/$(PLATFORM)-$(ARCH)$(OPENJDK_SUFFIX)
-else
-_OUTPUTDIR=$(JDK_TOPDIR)/build/$(PLATFORM)-$(ARCH)
-endif
-
-
 #
 # Get platform definitions
 #
--- a/make/common/internal/BinaryPlugs.gmk	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/common/internal/BinaryPlugs.gmk	Mon Apr 14 11:34:15 2008 -0700
@@ -126,44 +126,10 @@
 com/sun/media/sound/SimpleInputDeviceProvider\$$InputDeviceInfo.class \
 com/sun/media/sound/SimpleInputDeviceProvider.class
 
-PLUG_AWT_CLASS_NAMES = \
-java/awt/color/CMMException.class \
-java/awt/color/ColorSpace.class \
-java/awt/color/ICC_ColorSpace.class \
-java/awt/color/ICC_Profile\$$1.class \
-java/awt/color/ICC_Profile\$$2.class \
-java/awt/color/ICC_Profile\$$3.class \
-java/awt/color/ICC_Profile.class \
-java/awt/color/ICC_ProfileGray.class \
-java/awt/color/ICC_ProfileRGB.class \
-java/awt/image/BandedSampleModel.class \
-java/awt/image/ColorConvertOp.class \
-java/awt/image/ComponentSampleModel.class \
-java/awt/image/DataBuffer\$$1.class \
-java/awt/image/DataBuffer.class \
-java/awt/image/DataBufferByte.class \
-java/awt/image/DataBufferInt.class \
-java/awt/image/DataBufferShort.class \
-java/awt/image/DataBufferUShort.class \
-java/awt/image/MultiPixelPackedSampleModel.class \
-java/awt/image/Raster.class \
-java/awt/image/RenderedImage.class \
-java/awt/image/SampleModel.class \
-java/awt/image/SinglePixelPackedSampleModel.class \
-java/awt/image/WritableRaster.class \
-java/awt/image/WritableRenderedImage.class \
-java/awt/image/renderable/ContextualRenderedImageFactory.class \
-java/awt/image/renderable/ParameterBlock.class \
-java/awt/image/renderable/RenderContext.class \
-java/awt/image/renderable/RenderableImage.class \
-java/awt/image/renderable/RenderableImageOp.class \
-java/awt/image/renderable/RenderableImageProducer.class \
-java/awt/image/renderable/RenderedImageFactory.class
-
 # Class list temp files (used by both import and export of plugs)
 
 PLUG_TEMPDIR=$(ABS_TEMPDIR)/plugs
-PLUG_CLASS_AREAS = jmf sound awt
+PLUG_CLASS_AREAS = jmf sound
 PLUG_CLISTS = $(PLUG_CLASS_AREAS:%=$(PLUG_TEMPDIR)/%.clist)
 
 # Create jargs file command
@@ -186,11 +152,6 @@
 	@for i in $(PLUG_SOUND_CLASS_NAMES) ; do \
 	  $(ECHO) "$$i" >> $@ ; \
 	done
-$(PLUG_TEMPDIR)/awt.clist:
-	@$(prep-target)
-	@for i in $(PLUG_AWT_CLASS_NAMES) ; do \
-	  $(ECHO) "$$i" >> $@ ; \
-	done
 $(PLUG_TEMPDIR)/all.clist: $(PLUG_CLISTS)
 	@$(prep-target)
 	$(CAT) $(PLUG_CLISTS) > $@
@@ -198,8 +159,6 @@
 	$(plug-create-jargs)
 $(PLUG_TEMPDIR)/sound.jargs: $(PLUG_TEMPDIR)/sound.clist
 	$(plug-create-jargs)
-$(PLUG_TEMPDIR)/awt.jargs: $(PLUG_TEMPDIR)/awt.clist
-	$(plug-create-jargs)
 $(PLUG_TEMPDIR)/all.jargs: $(PLUG_TEMPDIR)/all.clist
 	$(plug-create-jargs)
 
@@ -235,15 +194,12 @@
 	$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/jmf.clist)
 import-binary-plug-sound-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/sound.clist
 	$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/sound.clist)
-import-binary-plug-awt-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/awt.clist
-	$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/awt.clist)
 
 # Import all classes from the jar file
 
 import-binary-plug-jar: \
 	     import-binary-plug-jmf-classes \
-	     import-binary-plug-sound-classes \
-	     import-binary-plug-awt-classes
+	     import-binary-plug-sound-classes
 
 # Import native libraries
 
@@ -286,7 +242,6 @@
 	import-binary-plug-jar \
         import-binary-plug-jmf-classes \
         import-binary-plug-sound-classes \
-	import-binary-plug-awt-classes \
         import-binary-plug-jsound-library
 
 else # !OPENJDK
--- a/make/common/shared/Defs-control.gmk	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/common/shared/Defs-control.gmk	Mon Apr 14 11:34:15 2008 -0700
@@ -36,7 +36,7 @@
 endif
 
 ifndef CONTROL_TOPDIR
-  CONTROL_TOPDIR=$(TOPDIR)/control
+  CONTROL_TOPDIR=$(TOPDIR)
 endif
 ifndef HOTSPOT_TOPDIR
   HOTSPOT_TOPDIR=$(TOPDIR)/hotspot
@@ -70,7 +70,8 @@
 include $(JDK_MAKE_SHARED_DIR)/Platform.gmk
 
 # Default output directory
-_OUTPUTDIR=$(CONTROL_TOPDIR)/build/$(PLATFORM)-$(ARCH)
+BUILD_PARENT_DIRECTORY=$(TOPDIR)
+_OUTPUTDIR=$(TOPDIR)/build/$(PLATFORM)-$(ARCH)
 
 # Get platform specific settings
 include $(JDK_MAKE_SHARED_DIR)/Defs.gmk
--- a/make/common/shared/Defs-utils.gmk	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/common/shared/Defs-utils.gmk	Mon Apr 14 11:34:15 2008 -0700
@@ -67,16 +67,6 @@
   UTILS_DEVTOOL_PATH=$(DEVTOOLS_PATH)
 endif
 
-# Utilities ant and findbugs
-ifndef ANT_HOME
-  ANT_HOME = $(JDK_DEVTOOLS_DIR)/share/ant/latest
-endif
-ANT = $(ANT_HOME)/bin/ant
-ifndef FINDBUGS_HOME
-  FINDBUGS_HOME = $(JDK_DEVTOOLS_DIR)/share/findbugs/latest
-endif
-FINDBUGS = $(FINDBUGS_HOME)/bin/findbugs
-
 # Utilities
 ADB            = $(UTILS_COMMAND_PATH)adb
 AR             = $(UTILS_CCS_BIN_PATH)ar
--- a/make/common/shared/Defs.gmk	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/common/shared/Defs.gmk	Mon Apr 14 11:34:15 2008 -0700
@@ -55,7 +55,10 @@
 
 # Simple pwd path
 define PwdPath
-$(shell cd $1 2> $(DEV_NULL) && pwd)
+$(shell $(CD) $1 2> $(DEV_NULL) && $(PWD))
+endef
+define AbsPwdPathCheck
+$(shell $(CD) .. 2> $(DEV_NULL) && $(CD) $1 2> $(DEV_NULL) && $(PWD))
 endef
 
 # Checks an ALT value for spaces (should be one word), 
@@ -422,23 +425,54 @@
 CACERTS_FILE:=$(call AltCheckValue,CACERTS_FILE)
 
 # OUTPUTDIR: Location of all output for the build
-_BACKUP_OUTPUTDIR = $(TEMP_DISK)/$(USER)/jdk-outputdir
 ifdef ALT_OUTPUTDIR
-  _POSSIBLE_OUTPUTDIR =$(subst \,/,$(ALT_OUTPUTDIR))
+  OUTPUTDIR:=$(subst \,/,$(ALT_OUTPUTDIR))
+  # Assumes this is absolute (checks later)
+  ABS_OUTPUTDIR:=$(OUTPUTDIR)
 else
   ifndef _OUTPUTDIR
-    _OUTPUTDIR = $(_BACKUP_OUTPUTDIR)
+    # Default:  Get "build" parent directory, which should always exist
+    ifndef BUILD_PARENT_DIRECTORY
+      BUILD_PARENT_DIRECTORY=$(BUILDDIR)/..
+    endif
+    ABS_BUILD_PARENT_DIRECTORY:=$(call FullPath,$(BUILD_PARENT_DIRECTORY))
+    ifdef OPENJDK
+      _OUTPUTDIRNAME=$(PLATFORM)-$(ARCH)$(OPENJDK_SUFFIX)
+    else
+      _OUTPUTDIRNAME=$(PLATFORM)-$(ARCH)
+    endif
+    _OUTPUTDIR=$(BUILD_PARENT_DIRECTORY)/build/$(_OUTPUTDIRNAME)
+    ABS_OUTPUTDIR:=$(ABS_BUILD_PARENT_DIRECTORY)/build/$(_OUTPUTDIRNAME)
   endif
-  _POSSIBLE_OUTPUTDIR =$(_OUTPUTDIR)
+  OUTPUTDIR:=$(_OUTPUTDIR)
 endif
-_create_outputdir1:=$(shell mkdir -p $(_POSSIBLE_OUTPUTDIR) > $(DEV_NULL) 2>&1)
-OUTPUTDIR:=$(call WriteDirExists,$(_POSSIBLE_OUTPUTDIR),$(_BACKUP_OUTPUTDIR))
-_create_outputdir2:=$(shell mkdir -p $(OUTPUTDIR) > $(DEV_NULL) 2>&1)
-ifeq "$(OUTPUTDIR)" "$(_BACKUP_OUTPUTDIR)"
-  _outputdir_warning:=$(warning "WARNING: OUTPUTDIR '$(_POSSIBLE_OUTPUTDIR)' not writable, will use '$(_BACKUP_OUTPUTDIR)'")
-endif
+# Check for spaces and null value
 OUTPUTDIR:=$(call AltCheckSpaces,OUTPUTDIR)
 OUTPUTDIR:=$(call AltCheckValue,OUTPUTDIR)
+# Create the output directory and make sure it exists and is writable
+_create_outputdir:=$(shell $(MKDIR) -p "$(OUTPUTDIR)" > $(DEV_NULL) 2>&1)
+ifeq ($(call WriteDirExists,$(OUTPUTDIR),/dev/null),/dev/null)
+  _outputdir_error:=$(error "ERROR: OUTPUTDIR '$(OUTPUTDIR)' not created or not writable")
+endif
+# Define absolute path if needed and check for spaces and null value
+ifndef ABS_OUTPUTDIR
+  ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR))
+endif
+ABS_OUTPUTDIR:=$(call AltCheckSpaces,ABS_OUTPUTDIR)
+ABS_OUTPUTDIR:=$(call AltCheckValue,ABS_OUTPUTDIR)
+# Make doubly sure this is a full path
+ifeq ($(call AbsPwdPathCheck,$(ABS_OUTPUTDIR)), )
+  ifdef ALT_OUTPUTDIR
+    _outputdir_error:=$(error "ERROR: Trouble with the absolute path for OUTPUTDIR '$(OUTPUTDIR)', was ALT_OUTPUTDIR '$(ALT_OUTPUTDIR)' an absolute path?")
+  else
+    _outputdir_error:=$(error "ERROR: Trouble with the absolute path for OUTPUTDIR '$(OUTPUTDIR)'")
+  endif
+endif
+_dir1:=$(call FullPath,$(ABS_OUTPUTDIR))
+_dir2:=$(call FullPath,$(OUTPUTDIR))
+ifneq ($(_dir1),$(_dir2))
+  _outputdir_error:=$(error "ERROR: ABS_OUTPUTDIR '$(ABS_OUTPUTDIR)' is not the same directory as OUTPUTDIR '$(OUTPUTDIR)', '$(_dir1)'!='$(_dir2)'")
+endif
 
 # Bin directory
 #   NOTE: ISA_DIR is usually empty, on Solaris it might be /sparcv9 or /amd64
@@ -469,15 +503,30 @@
   endif
 endif
 
+# Utilities ant and findbugs
+ifeq ($(ANT_HOME),)
+  ANT_HOME := $(call DirExists,/usr/share/ant,$(JDK_DEVTOOLS_DIR)/share/ant/latest,)
+endif
+ifeq ($(ANT_HOME),)
+  ANT = ant
+else
+  ANT = $(ANT_HOME)/bin/ant
+endif
+ifeq ($(FINDBUGS_HOME),)
+  FINDBUGS_HOME := $(call DirExists,/usr/share/findbugs,$(JDK_DEVTOOLS_DIR)/share/findbugs/latest,)
+endif
+ifeq ($(FINDBUGS_HOME),)
+  FINDBUGS = findbugs
+else
+  FINDBUGS = $(FINDBUGS_HOME)/bin/findbugs
+endif
+
 ifdef ALT_COPYRIGHT_YEAR
   COPYRIGHT_YEAR = $(ALT_COPYRIGHT_YEAR)
 else
   COPYRIGHT_YEAR = $(shell $(DATE) '+%Y')
 endif
 
-# Absolute path to output directory
-ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR))
-
 # Get shared compiler settings
 include $(JDK_MAKE_SHARED_DIR)/Compiler.gmk
 
--- a/make/common/shared/Platform.gmk	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/common/shared/Platform.gmk	Mon Apr 14 11:34:15 2008 -0700
@@ -93,20 +93,18 @@
 # Normal boot jdk is previous release, but a hard requirement is a 1.5 boot
 REQUIRED_BOOT_VER = 1.5
 
-#This is specific to OpenJDK build
-ifdef OPENJDK
-  REQUIRED_FREETYPE_VERSION=2.3.0
-endif
+# If we are using freetype, this is the required version
+REQUIRED_FREETYPE_VERSION=2.3.0
 
 #
 # Prune out all known SCM (Source Code Management) directories
 # so they will not be included when copying directory trees
 # or packaging up .jar files, etc.  This applies to all workspaces.
 #
-SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files
+SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files .hgignore .hgtags
 # When changing SCM_DIRs also change SCM_DIRS_rexp and SCM_DIRS_prune:
-SCM_DIRS_rexp = ".hg|.svn|CVS|RCS|SCCS|Codemgr_wsdata|deleted_files"
-SCM_DIRS_prune = \( -name .hg -o -name .svn -o -name CVS -o -name RCS -o -name SCCS -o -name Codemgr_wsdata -o -name deleted_files \) -prune
+SCM_DIRS_rexp = ".hg|.svn|CVS|RCS|SCCS|Codemgr_wsdata|deleted_files|.hgignore|.hgtags"
+SCM_DIRS_prune = \( -name .hg -o -name .svn -o -name CVS -o -name RCS -o -name SCCS -o -name Codemgr_wsdata -o -name deleted_files -o -name .hgignore -o -name .hgtags \) -prune
 
 # Don't define this unless it's not defined
 ifndef VARIANT
@@ -272,7 +270,7 @@
     REQUIRED_ALSA_VERSION = ^((0[.]9[.][1-9])|(1[.]0[.][0-9]))[0-9]*
   endif
   # How much RAM does this machine have:
-  MB_OF_MEMORY := $(shell free -m | fgrep Mem: | sed -e 's@\ \ *@ @g' | cut -d' ' -f2)
+  MB_OF_MEMORY := $(shell free -m | fgrep Mem: | awk '{print $$2;}' )
 endif
 
 # Windows with and without CYGWIN will be slightly different
@@ -376,45 +374,35 @@
   REQUIRED_DXSDK_VER = 0x0700
   OS_VENDOR = Microsoft
   # How much RAM does this machine have:
-  MB_OF_MEMORY := $(shell \
-    if [ -f "C:/cygwin/bin/free.exe" ] ; then \
-      ( C:/cygwin/bin/bash.exe -c "C:/cygwin/bin/free.exe -m" ) | \
-	grep Mem: | \
-	sed -e 's@\ \ *@ @g' | cut -d' ' -f2 ; \
-    else \
-      echo "512"; \
-    fi)
-endif
-
-# Machines with 512Mb or less of real memory are considered low memory
-#    build machines and adjustments will be made to prevent excessing
-#    system swapping during the build.
-#    If we don't know, assume 512. Subtract 128 from MB for VM MAX.
-#    Don't set VM max over 1024-128=896.
-ifneq ($(MB_OF_MEMORY),)
-  LOW_MEMORY_MACHINE := $(shell \
-    if [ $(MB_OF_MEMORY) -le 512 ] ; then \
-      echo "true"; \
-    else \
-      echo "false"; \
-    fi)
-  MAX_VM_MEMORY := $(shell \
-    if [ $(MB_OF_MEMORY) -le 1024 ] ; then \
-      expr $(MB_OF_MEMORY) '-' 128 ; \
-    else \
-      echo "896"; \
-    fi)
-  MIN_VM_MEMORY := $(shell \
-    if [ $(MAX_VM_MEMORY) -le 128 ] ; then \
-      expr $(MAX_VM_MEMORY) '-' 8 ; \
-    else \
-      echo "128"; \
-    fi)
-else
-  MB_OF_MEMORY       := unknown
-  LOW_MEMORY_MACHINE := true
-  MAX_VM_MEMORY      := 384
-  MIN_VM_MEMORY      := 128
+  ifeq ($(USING_CYGWIN),true)
+    # CYGWIN has the 'free' utility
+    _MB_OF_MEMORY := \
+	 $(shell free -m | grep Mem: | awk '{print $$2;}' )
+  else
+    # Windows 2000 has the mem utility, but two memory areas
+    #    extended memory is what is beyond 1024M
+    _B_OF_EXT_MEMORY := \
+	 $(shell mem 2> $(DEV_NULL) | grep 'total contiguous extended memory' | awk '{print $$1;}')
+    ifeq ($(_B_OF_EXT_MEMORY),)
+      _B_OF_MEMORY := \
+	 $(shell mem 2> $(DEV_NULL) | grep 'total conventional memory' | awk '{print $$1;}')
+    else
+      _B_OF_MEMORY := \
+         $(shell expr 1048576 '+' $(_B_OF_EXT_MEMORY) 2> $(DEV_NULL))
+    endif
+    ifeq ($(_B_OF_MEMORY),)
+      # Windows 2003 has the systeminfo utility use it if mem doesn't work
+      _MB_OF_MEMORY := \
+	  $(shell systeminfo 2> $(DEV_NULL) | grep 'Total Physical Memory:' | awk '{print $$4;}' | sed -e 's@,@@')
+    else
+      _MB_OF_MEMORY := $(shell expr $(_B_OF_MEMORY) '/' 1024 2> $(DEV_NULL))
+    endif
+  endif
+  ifeq ($(shell expr $(_MB_OF_MEMORY) '+' 0 2> $(DEV_NULL)), $(_MB_OF_MEMORY))
+    MB_OF_MEMORY := $(_MB_OF_MEMORY)
+  else
+    MB_OF_MEMORY := 512
+  endif
 endif
 
 REQUIRED_ZIP_VER = 2.2
@@ -454,6 +442,37 @@
   ARCH_VM_SUBDIR=jre/lib/$(LIBARCH)
 endif
 
+# Machines with 512Mb or less of real memory are considered low memory
+#    build machines and adjustments will be made to prevent excessing
+#    system swapping during the build.
+#    If we don't know, assume 512. Subtract 128 from MB for VM MAX.
+#    Don't set VM max over 1024-128=896.
+ifneq ($(MB_OF_MEMORY),)
+  LOW_MEMORY_MACHINE := $(shell \
+    if [ $(MB_OF_MEMORY) -le 512 ] ; then \
+      echo "true"; \
+    else \
+      echo "false"; \
+    fi)
+  MAX_VM_MEMORY := $(shell \
+    if [ $(MB_OF_MEMORY) -le 1024 ] ; then \
+      expr $(MB_OF_MEMORY) '-' 128 2> $(DEV_NULL) ; \
+    else \
+      echo "896"; \
+    fi)
+  MIN_VM_MEMORY := $(shell \
+    if [ $(MAX_VM_MEMORY) -le 128 ] ; then \
+      expr $(MAX_VM_MEMORY) '-' 8 2> $(DEV_NULL) ; \
+    else \
+      echo "128"; \
+    fi)
+else
+  MB_OF_MEMORY       := unknown
+  LOW_MEMORY_MACHINE := true
+  MAX_VM_MEMORY      := 384
+  MIN_VM_MEMORY      := 128
+endif
+
 # If blanks in the username, use the first 4 words and pack them together
 _USER1:=$(subst ', ,$(_USER))
 _USER2:=$(subst ", ,$(_USER1))
--- a/make/common/shared/Sanity.gmk	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/common/shared/Sanity.gmk	Mon Apr 14 11:34:15 2008 -0700
@@ -105,13 +105,21 @@
 UNZIP_VER  :=$(call GetVersion,"$(_UNZIP_VER)")
 BOOT_VER   :=$(call GetVersion,"$(_BOOT_VER)")
 
-REQUIRED_ANT_VER      := 1.6.3
-_ANT_VER              :=$(shell $(ANT) -version 2>&1 )
-ANT_VER               :=$(call GetVersion,"$(_ANT_VER)")
+REQUIRED_ANT_VER := 1.6.3
+ifeq ($(ANT_HOME),)
+  _ANT_VER:=$(shell JAVACMD="$(BOOTDIR)/bin/java" $(ANT) -version 2>&1 )
+else
+  _ANT_VER:=$(shell JAVACMD="$(BOOTDIR)/bin/java" ANT_HOME="$(ANT_HOME)" $(ANT) -version 2>&1 )
+endif
+ANT_VER:=$(call GetVersion,"$(_ANT_VER)")
 
-REQUIRED_FINDBUGS_VER := 1.1
-_FINDBUGS_VER         :=$(shell $(FINDBUGS) -version 2>&1 )
-FINDBUGS_VER          :=$(call GetVersion,"$(_FINDBUGS_VER)")
+REQUIRED_FINDBUGS_VER := 1.2
+ifeq ($(FINDBUGS_HOME),)
+  _FINDBUGS_VER:=$(shell $(FINDBUGS) -javahome "$(BOOTDIR)" -textui -version 2>&1 )
+else
+  _FINDBUGS_VER:=$(shell FINDBUGS_HOME="$(FINDBUGS_HOME)" $(FINDBUGS) -javahome "$(BOOTDIR)" -textui -version 2>&1 )
+endif
+FINDBUGS_VER:=$(call GetVersion,"$(_FINDBUGS_VER)")
 
 ifdef ALT_BINDIR
   ALT_BINDIR_VERSION := $(shell $(ALT_BINDIR)/java$(EXE_SUFFIX) -version 2>&1  | $(NAWK) -F'"' '{ print $$2 }')
@@ -1564,31 +1572,31 @@
 endif
 
 
-######################################################
-# SECURITY_BASELINE_142 test
-######################################################
-security_baseline_142:
-ifeq ($(PLATFORM), windows)
-	@if [ -z "$(SECURITY_BASELINE_142)" ]; then \
-	    $(ECHO) "WARNING: Your SECURITY_BASELINE_142 setting is empty.\n" \
-		"        Setting it to the default value of 1.4.2_10.\n" \
-		"        It is recommended to set SECURITY_BASELINE_142.\n" \
-		"" >> $(WARNING_FILE) ; \
-	fi
-endif
-
-######################################################
-# SECURITY_BASELINE_150 test
-######################################################
-security_baseline_150:
-ifeq ($(PLATFORM), windows)
-	@if [ -z "$(SECURITY_BASELINE_150)" ]; then \
-	    $(ECHO) "WARNING: Your SECURITY_BASELINE_150 setting is empty.\n" \
-		"        Setting it to the default value of 1.5.0_07.\n" \
-		"        It is recommended to set SECURITY_BASELINE_150.\n" \
-		"" >> $(WARNING_FILE) ; \
-	fi
-endif
+######################################################
+# SECURITY_BASELINE_142 test
+######################################################
+security_baseline_142:
+ifeq ($(PLATFORM), windows)
+	@if [ -z "$(SECURITY_BASELINE_142)" ]; then \
+	    $(ECHO) "WARNING: Your SECURITY_BASELINE_142 setting is empty.\n" \
+		"        Setting it to the default value of 1.4.2_10.\n" \
+		"        It is recommended to set SECURITY_BASELINE_142.\n" \
+		"" >> $(WARNING_FILE) ; \
+	fi
+endif
+
+######################################################
+# SECURITY_BASELINE_150 test
+######################################################
+security_baseline_150:
+ifeq ($(PLATFORM), windows)
+	@if [ -z "$(SECURITY_BASELINE_150)" ]; then \
+	    $(ECHO) "WARNING: Your SECURITY_BASELINE_150 setting is empty.\n" \
+		"        Setting it to the default value of 1.5.0_07.\n" \
+		"        It is recommended to set SECURITY_BASELINE_150.\n" \
+		"" >> $(WARNING_FILE) ; \
+	fi
+endif
 
 
 ######################################################
--- a/make/docs/CORE_PKGS.gmk	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/docs/CORE_PKGS.gmk	Mon Apr 14 11:34:15 2008 -0700
@@ -49,8 +49,8 @@
 # ACTIVE_JSR_PKGS are packages that are part of an active JSR process--
 # one that is doing its own review. These packages are not included when
 # creating diff pages for the platform's JCP process.
-# 
-#       (see /java/pubs/apisrc/jdk/6.0/beta/make/docs/active_jsr_pkgs)
+# 
+#       (see /java/pubs/apisrc/jdk/6.0/beta/make/docs/active_jsr_pkgs)
 # Note:
 # This is a list of regular expressions. So foo.* matches "foo" and "foo.bar".
 #
@@ -72,13 +72,13 @@
 # CORE_PKGS is the list of packages that form the
 # Java API Specification.
 #
-### ***IMPORTANT NOTE***
-### There is also a "REGEXP" variable in the docs/makefile that
-### determines which table the packages go in on the main page.
-### Currently, there is only table ("Platform Packages") and
-### everything goes in it, so REGEXP is "*". But if that policy
-### changes, packages added will need to be reflected in  that
-### list of wildcard expressions, as well.
+### ***IMPORTANT NOTE***
+### There is also a "REGEXP" variable in the docs/makefile that
+### determines which table the packages go in on the main page.
+### Currently, there is only table ("Platform Packages") and
+### everything goes in it, so REGEXP is "*". But if that policy
+### changes, packages added will need to be reflected in  that
+### list of wildcard expressions, as well.
 ###
 CORE_PKGS =                                      \
   java.applet                                    \
--- a/make/java/awt/Makefile	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/java/awt/Makefile	Mon Apr 14 11:34:15 2008 -0700
@@ -28,24 +28,12 @@
 PRODUCT = sun
 include $(BUILDDIR)/common/Defs.gmk
 
-# WARNING: Make sure the OPENJDK plugs are up-to-date, see make/common/internal/BinaryPlugs.gmk
 
 #
 # Files
 #
 AUTO_FILES_JAVA_DIRS = java/awt sun/awt/geom
 
-#
-# Specific to OPENJDK
-#
-ifdef OPENJDK
-
-build: import-binary-plug-awt-classes
-
-include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
-
-endif
-
 build: properties cursors
 
 #
--- a/make/java/java/mapfile-vers	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/java/java/mapfile-vers	Mon Apr 14 11:34:15 2008 -0700
@@ -85,7 +85,6 @@
 		Java_java_io_FileOutputStream_close0;
 		Java_java_io_FileOutputStream_initIDs;
 		Java_java_io_FileOutputStream_open;
-		Java_java_io_FileOutputStream_openAppend;
 		Java_java_io_FileOutputStream_write;
 		Java_java_io_FileOutputStream_writeBytes;
 		Java_java_io_FileSystem_getFileSystem;
--- a/make/java/jli/Makefile	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/java/jli/Makefile	Mon Apr 14 11:34:15 2008 -0700
@@ -107,6 +107,7 @@
 
 ifeq ($(PLATFORM), windows)
 	EXTRA_LIBS = advapi32.lib \
+		     comctl32.lib \
 		     user32.lib
 
 	JAVALIB =
--- a/make/java/main/java/Makefile	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/java/main/java/Makefile	Mon Apr 14 11:34:15 2008 -0700
@@ -43,7 +43,7 @@
 
 # Override the default version info with our own resource file (see 5106536)
 ifeq ($(PLATFORM), windows)
-LDLIBS_COMMON += user32.lib
+LDLIBS_COMMON += user32.lib comctl32.lib
 ifdef OPENJDK
     RC_FLAGS += -i "$(PLATFORM_SRC)/resource/icons"
 else
--- a/make/java/main/javaw/Makefile	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/java/main/javaw/Makefile	Mon Apr 14 11:34:15 2008 -0700
@@ -46,7 +46,7 @@
 include $(BUILDDIR)/common/Defs.gmk
 
 OTHER_CPPFLAGS += -DJAVAW
-LDLIBS_COMMON +=  user32.lib
+LDLIBS_COMMON +=  user32.lib comctl32.lib
 
 # Override the default version info with our own resource file (see 5106536)
 ifeq ($(PLATFORM), windows)
--- a/make/java/nio/Makefile	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/java/nio/Makefile	Mon Apr 14 11:34:15 2008 -0700
@@ -191,7 +191,7 @@
 
 GEN_BUFFER_SH = genBuffer.sh
 
-GEN_BUFFER_CMD = SPP="$(SPP_CMD)" NAWK=$(NAWK) SED=$(SED) \
+GEN_BUFFER_CMD = SPP="$(SPP_CMD)" NAWK=$(NAWK) SED=$(SED) SH=$(SH) \
                  $(SH) $(GEN_BUFFER_SH)
 
 # Public abstract buffer classes
@@ -582,7 +582,7 @@
 
 GEN_CODER_SH = genCoder.sh
 
-GEN_CODER_CMD = SPP="$(SPP_CMD)" SED=$(SED) NAWK=$(NAWK) $(SH) $(GEN_CODER_SH)
+GEN_CODER_CMD = SPP="$(SPP_CMD)" SED=$(SED) NAWK=$(NAWK) SH=$(SH) $(SH) $(GEN_CODER_SH)
 
 $(CS_GEN)/CharsetDecoder.java: $(CS_SRC)/Charset-X-Coder.java $(GEN_CODER_SH)
 	$(prep-target)
@@ -602,7 +602,7 @@
 
 GEN_EX_SH = genExceptions.sh
  
-GEN_EX_CMD = NAWK=$(NAWK) $(SHELL) $(GEN_EX_SH)
+GEN_EX_CMD = NAWK=$(NAWK) SH=$(SH) $(SH) $(GEN_EX_SH)
 
 $(CH_GEN)/%Exception.java: genExceptions.sh $(CH_SRC)/exceptions
 	$(prep-target)
@@ -635,8 +635,8 @@
     $(HASHER_JARFILE) $(SCS_SRC)/standard-charsets
 	$(prep-target)
 	@$(RM) $@.temp
-	NAWK=$(NAWK) TEMPDIR=$(TEMPDIR) \
+	NAWK=$(NAWK) TEMPDIR=$(TEMPDIR) SH=$(SH) \
 	  HASHER="$(BOOT_JAVA_CMD) -jar $(HASHER_JARFILE)" \
-	  $(SHELL) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN)
+	  $(SH) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN)
 
 .PHONY: sources 
--- a/make/java/nio/genCharsetProvider.sh	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/java/nio/genCharsetProvider.sh	Mon Apr 14 11:34:15 2008 -0700
@@ -48,7 +48,7 @@
 # Header
 #
 
-$SHELL addNotices.sh "$COPYRIGHT_YEARS" > $OUT
+$SH ./addNotices.sh "$COPYRIGHT_YEARS" > $OUT
 
 cat <<__END__ >>$OUT
 
--- a/make/java/nio/genExceptions.sh	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/java/nio/genExceptions.sh	Mon Apr 14 11:34:15 2008 -0700
@@ -41,7 +41,7 @@
   echo '-->' $DST/$ID.java
   out=$DST/${ID}.java
 
-  $SHELL addNotices.sh "$COPYRIGHT_YEARS" > $out
+  $SH ./addNotices.sh "$COPYRIGHT_YEARS" > $out
 
 cat >>$out <<__END__
 
--- a/make/sun/splashscreen/Makefile	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/sun/splashscreen/Makefile	Mon Apr 14 11:34:15 2008 -0700
@@ -85,3 +85,13 @@
 CPPFLAGS += -I$(PLATFORM_SRC)/native/$(PKGDIR)/splashscreen -I$(SHARE_SRC)/native/$(PKGDIR)/splashscreen
 CPPFLAGS += -I$(SHARE_SRC)/native/$(PKGDIR)/image/jpeg -I$(SHARE_SRC)/native/java/util/zip/zlib-1.1.3
 
+ifeq ($(PLATFORM), linux)
+  ifeq ($(ARCH_DATA_MODEL), 64)
+    # 64-bit gcc has problems compiling MMX instructions.
+    # Google it for more details. Possibly the newer versions of
+    # the PNG-library and/or the new compiler will not need this
+    # option in the future.
+    CPPFLAGS += -DPNG_NO_MMX_CODE
+  endif
+endif
+
--- a/make/sun/xawt/Makefile	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/sun/xawt/Makefile	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -246,7 +246,7 @@
 	@if [ "$(DOCOMPARE)$(suffix $@)" = "true.64" ]; then \
 	    $(ECHO) COMPARING $@ and $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \
 	    $(DIFF) $@ $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \
-	fi	
+	fi
 
 $(TEMPDIR)/.gen.wrappers: $(SIZES) $(WRAPPER_GENERATOR_CLASS) $(XLIBTYPES)
 	$(BOOT_JAVA_CMD) -cp $(WRAPPER_GENERATOR_TEMPDIR) WrapperGenerator \
@@ -256,10 +256,11 @@
 	$(MKDIR) -p $(TEMPDIR)
 	$(TOUCH) $(TEMPDIR)/.gen.wrappers
 
-generated.clean:	
+generated.clean:
 	$(RM) -r $(WRAPPER_GENERATOR_TEMPDIR)
 	$(RM) -r $(WRAPPER_GENERATOR_DIR)
 	$(RM) -r $(GEN_DIR)/*.java
+	$(RM) -r $(TEMPDIR)/.gen_icons
 
 ifdef OPENJDK
     ICONS_PATH_PREFIX=$(PLATFORM_SRC)
--- a/make/tools/freetypecheck/Makefile	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/tools/freetypecheck/Makefile	Mon Apr 14 11:34:15 2008 -0700
@@ -38,7 +38,14 @@
 
 all: $(FT_TEST_PATH)
 
-FT_OPTIONS  = -I$(FT_HEADERS) -I$(FT_HEADERS)/freetype2
+# Start with CFLAGS (which gets us the required -xarch setting on solaris)
+ifeq ($(PLATFORM), windows)
+  FT_OPTIONS  =
+else
+  FT_OPTIONS  = $(CFLAGS)
+endif
+
+FT_OPTIONS += -I$(FT_HEADERS) -I$(FT_HEADERS)/freetype2
 FT_OPTIONS += $(XARCH)
 
 #add runtime library search path
--- a/make/tools/freetypecheck/freetypecheck.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/tools/freetypecheck/freetypecheck.c	Mon Apr 14 11:34:15 2008 -0700
@@ -26,13 +26,16 @@
 /* Test program for freetype sanity check.
    Prints "Failed" messages to STDOUT if check fails. */
 
+#include <stdio.h>
+#include <string.h>
+
 #include "ft2build.h"
 #include FT_FREETYPE_H
 
 #define QUOTEMACRO(x) QUOTEME(x)
 #define QUOTEME(x) #x
 
-int main(char** argv, int argc) {
+int main(int argc, char** argv) {
    char v[50];
    FT_Int major, minor, patch;
    FT_Library library;
--- a/make/tools/src/build/tools/jdwpgen/CommandNode.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/tools/src/build/tools/jdwpgen/CommandNode.java	Mon Apr 14 11:34:15 2008 -0700
@@ -32,9 +32,9 @@
 
     void constrain(Context ctx) {
         if (components.size() == 3) {
-            Node out = (Node)components.get(0);
-            Node reply = (Node)components.get(1);
-            Node error = (Node)components.get(2);
+            Node out   = components.get(0);
+            Node reply = components.get(1);
+            Node error = components.get(2);
             if (!(out instanceof OutNode)) {
                 error("Expected 'Out' item, got: " + out);
             }
@@ -45,7 +45,7 @@
                 error("Expected 'ErrorSet' item, got: " + error);
             }
         } else if (components.size() == 1) {
-            Node evt = (Node)components.get(0);
+            Node evt = components.get(0);
             if (!(evt instanceof EventNode)) {
                 error("Expected 'Event' item, got: " + evt);
             }
--- a/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java	Mon Apr 14 11:34:15 2008 -0700
@@ -98,7 +98,7 @@
         if (constantMap == null) {
             return "";
         }
-        String com = (String) constantMap.get(key);
+        String com = constantMap.get(key);
         if(com == null){
             return "";
         } else {
--- a/make/tools/src/build/tools/jdwpgen/RepeatNode.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/make/tools/src/build/tools/jdwpgen/RepeatNode.java	Mon Apr 14 11:34:15 2008 -0700
@@ -37,7 +37,7 @@
         if (components.size() != 1) {
             error("Repeat must have exactly one member, use Group for more");
         }
-        member = (Node)(components.get(0));
+        member = components.get(0);
         if (!(member instanceof TypeNode)) {
             error("Repeat member must be type specifier");
         }
--- a/src/share/bin/java.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/bin/java.c	Mon Apr 14 11:34:15 2008 -0700
@@ -205,9 +205,7 @@
     _wc_enabled = cpwildcard;
     _ergo_policy = ergo;
 
-    if (javaw == JNI_TRUE)
-        SetJavaw();
-
+    InitLauncher(javaw);
     DumpState();
 
     /*
--- a/src/share/bin/java.h	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/bin/java.h	Mon Apr 14 11:34:15 2008 -0700
@@ -172,7 +172,6 @@
 const char* GetFullVersion();
 jboolean IsJavaArgs();
 jboolean IsJavaw();
-void SetJavaw();
 jint GetErgoPolicy();
 
 jboolean ServerClassMachine();
@@ -180,5 +179,9 @@
 static int ContinueInNewThread(InvocationFunctions* ifn, int argc, char** argv,
                         char* jarfile, char* classname, int ret);
 
+/*
+ * Initialize platform specific settings
+ */
+void InitLauncher(jboolean javaw);
 
 #endif /* _JAVA_H_ */
--- a/src/share/bin/main.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/bin/main.c	Mon Apr 14 11:34:15 2008 -0700
@@ -64,8 +64,6 @@
     margv = argv;
 #endif /* JAVAW */
 
-    JLI_SetTraceLauncher();
-
     return JLI_Launch(margc, margv,
                    sizeof(const_jargs) / sizeof(char *), const_jargs,
                    sizeof(const_appclasspath) / sizeof(char *), const_appclasspath,
--- a/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -34,6 +34,7 @@
 import java.security.GeneralSecurityException;
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
 import java.security.spec.InvalidKeySpecException;
 import javax.crypto.Mac;
 import javax.crypto.SecretKey;
@@ -107,12 +108,17 @@
             throw new InvalidKeySpecException("Key length is negative");
         }
         try {
-            this.prf = Mac.getInstance(prfAlgo, new SunJCE());
+            this.prf = Mac.getInstance(prfAlgo, "SunJCE");
         } catch (NoSuchAlgorithmException nsae) {
             // not gonna happen; re-throw just in case
             InvalidKeySpecException ike = new InvalidKeySpecException();
             ike.initCause(nsae);
             throw ike;
+        } catch (NoSuchProviderException nspe) {
+            // Again, not gonna happen; re-throw just in case
+            InvalidKeySpecException ike = new InvalidKeySpecException();
+            ike.initCause(nspe);
+            throw ike;
         }
         this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength);
     }
--- a/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames.properties	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames.properties	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,6 @@
-#
-# Default Input method display names for Indic input methods
-#
-
-DisplayName.Devanagari  = Devanagari Input Method
+#
+# Default Input method display names for Indic input methods
+#
+
+DisplayName.Devanagari  = Devanagari Input Method
+
--- a/src/share/classes/com/sun/inputmethods/internal/thaiim/resources/DisplayNames.properties	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/inputmethods/internal/thaiim/resources/DisplayNames.properties	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,6 @@
-#
-# Default Input method display names for Thai input methods
-#
-
-DisplayName.Thai     = Thai Input Method
+#
+# Default Input method display names for Thai input methods
+#
+
+DisplayName.Thai     = Thai Input Method
+
--- a/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Mon Apr 14 11:34:15 2008 -0700
@@ -43,6 +43,13 @@
 import javax.management.NotCompliantMBeanException;
 
 import com.sun.jmx.mbeanserver.Util;
+import com.sun.jmx.remote.util.EnvHelp;
+import java.beans.BeanInfo;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import javax.management.AttributeNotFoundException;
+import javax.management.openmbean.CompositeData;
 
 /**
  * This class contains the methods for performing all the tests needed to verify
@@ -482,4 +489,33 @@
 
         return null;
     }
+
+    public static Object elementFromComplex(Object complex, String element)
+    throws AttributeNotFoundException {
+        try {
+            if (complex.getClass().isArray() && element.equals("length")) {
+                return Array.getLength(complex);
+            } else if (complex instanceof CompositeData) {
+                return ((CompositeData) complex).get(element);
+            } else {
+                // Java Beans introspection
+                //
+                BeanInfo bi = java.beans.Introspector.getBeanInfo(complex.getClass());
+                PropertyDescriptor[] pds = bi.getPropertyDescriptors();
+                for (PropertyDescriptor pd : pds)
+                    if (pd.getName().equals(element))
+                        return pd.getReadMethod().invoke(complex);
+                throw new AttributeNotFoundException(
+                    "Could not find the getter method for the property " +
+                    element + " using the Java Beans introspector");
+            }
+        } catch (InvocationTargetException e) {
+            throw new IllegalArgumentException(e);
+        } catch (AttributeNotFoundException e) {
+            throw e;
+        } catch (Exception e) {
+            throw EnvHelp.initCause(
+                new AttributeNotFoundException(e.getMessage()), e);
+        }
+    }
 }
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.dtd	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.dtd	Mon Apr 14 11:34:15 2008 -0700
@@ -1,73 +1,73 @@
-<?xml version='1.0' encoding='UTF-8' ?>
-
-<!ELEMENT Configuration (CanonicalizationMethods , TransformAlgorithms , JCEAlgorithmMappings , Log4J , ResourceBundles , UnitTests , ResourceResolvers , KeyResolvers)>
-
-<!ATTLIST Configuration  xmlns CDATA  #FIXED 'http://www.xmlsecurity.org/NS/#configuration' 
-target        CDATA  #IMPLIED>
-<!ELEMENT CanonicalizationMethods (CanonicalizationMethod+)>
-
-<!ATTLIST CanonicalizationMethods  JAVACLASS CDATA  #FIXED 'com.sun.org.apache.xml.internal.security.c14n.Canonicalizer' >
-<!ELEMENT CanonicalizationMethod EMPTY>
-
-<!ATTLIST CanonicalizationMethod  URI       CDATA  #REQUIRED
-                                    JAVACLASS CDATA  #REQUIRED >
-<!ELEMENT TransformAlgorithms (TransformAlgorithm+)>
-
-<!ATTLIST TransformAlgorithms  JAVACLASS CDATA  #FIXED 'com.sun.org.apache.xml.internal.security.transforms.Transform' >
-<!ELEMENT TransformAlgorithm EMPTY>
-
-<!ATTLIST TransformAlgorithm  URI       CDATA  #REQUIRED
-                                JAVACLASS CDATA  #REQUIRED >
-<!ELEMENT JCEAlgorithmMappings (Providers , Algorithms)>
-
-<!ELEMENT Providers (Provider+)>
-
-<!ELEMENT Provider EMPTY>
-
-<!ATTLIST Provider  Id          ID     #REQUIRED
-                      Class       CDATA  #REQUIRED
-                      Info        CDATA  #IMPLIED
-                      ProviderURL CDATA  #IMPLIED >
-<!ELEMENT Algorithms (Algorithm+)>
-
-<!ELEMENT Algorithm (ProviderAlgo+)>
-
-<!ATTLIST Algorithm  URI            CDATA  #REQUIRED
-                       Description    CDATA  #IMPLIED
-                       AlgorithmClass CDATA  #IMPLIED >
-<!ELEMENT ProviderAlgo EMPTY>
-
-<!ATTLIST ProviderAlgo  ProviderId IDREF  #REQUIRED
-                          JCEName    CDATA  #REQUIRED
-                          JCEAlias   CDATA  #IMPLIED >
-<!ELEMENT Log4J EMPTY>
-
-<!ATTLIST Log4J  configFile CDATA  'data/log4j.xml' >
-<!ELEMENT ResourceBundles (ResourceBundle+)>
-
-<!ATTLIST ResourceBundles  defaultLanguageCode CDATA  'de'
-                             defaultCountryCode  CDATA  'DE' >
-<!ELEMENT ResourceBundle EMPTY>
-
-<!ATTLIST ResourceBundle  LanguageCode CDATA  #REQUIRED
-                            CountryCode  CDATA  #REQUIRED
-                            LOCATION     CDATA  #REQUIRED >
-<!ELEMENT UnitTests (UnitTest+)>
-
-<!ATTLIST UnitTests  JAVACLASS CDATA  #FIXED 'com.sun.org.apache.xml.internal.security.test.AllTests' >
-<!ELEMENT ResourceResolvers (Resolver+)>
-
-<!ELEMENT Resolver EMPTY>
-
-<!ATTLIST Resolver  JAVACLASS   CDATA  #REQUIRED
-                      DESCRIPTION CDATA  #IMPLIED >
-<!ELEMENT KeyResolvers (KeyResolver+)>
-<!ATTLIST KeyResolvers  JAVACLASS CDATA  #FIXED 'com.sun.org.apache.xml.internal.security.keys.KeyResolver' >
-
-<!ELEMENT KeyResolver EMPTY>
-
-<!ATTLIST KeyResolver  URI       CDATA  #REQUIRED
-                         JAVACLASS CDATA  #REQUIRED >
-<!ELEMENT UnitTest (#PCDATA)>
-
-<!ATTLIST UnitTest  JAVACLASS CDATA  #REQUIRED >
+<?xml version='1.0' encoding='UTF-8' ?>
+
+<!ELEMENT Configuration (CanonicalizationMethods , TransformAlgorithms , JCEAlgorithmMappings , Log4J , ResourceBundles , UnitTests , ResourceResolvers , KeyResolvers)>
+
+<!ATTLIST Configuration  xmlns CDATA  #FIXED 'http://www.xmlsecurity.org/NS/#configuration' 
+target        CDATA  #IMPLIED>
+<!ELEMENT CanonicalizationMethods (CanonicalizationMethod+)>
+
+<!ATTLIST CanonicalizationMethods  JAVACLASS CDATA  #FIXED 'com.sun.org.apache.xml.internal.security.c14n.Canonicalizer' >
+<!ELEMENT CanonicalizationMethod EMPTY>
+
+<!ATTLIST CanonicalizationMethod  URI       CDATA  #REQUIRED
+                                    JAVACLASS CDATA  #REQUIRED >
+<!ELEMENT TransformAlgorithms (TransformAlgorithm+)>
+
+<!ATTLIST TransformAlgorithms  JAVACLASS CDATA  #FIXED 'com.sun.org.apache.xml.internal.security.transforms.Transform' >
+<!ELEMENT TransformAlgorithm EMPTY>
+
+<!ATTLIST TransformAlgorithm  URI       CDATA  #REQUIRED
+                                JAVACLASS CDATA  #REQUIRED >
+<!ELEMENT JCEAlgorithmMappings (Providers , Algorithms)>
+
+<!ELEMENT Providers (Provider+)>
+
+<!ELEMENT Provider EMPTY>
+
+<!ATTLIST Provider  Id          ID     #REQUIRED
+                      Class       CDATA  #REQUIRED
+                      Info        CDATA  #IMPLIED
+                      ProviderURL CDATA  #IMPLIED >
+<!ELEMENT Algorithms (Algorithm+)>
+
+<!ELEMENT Algorithm (ProviderAlgo+)>
+
+<!ATTLIST Algorithm  URI            CDATA  #REQUIRED
+                       Description    CDATA  #IMPLIED
+                       AlgorithmClass CDATA  #IMPLIED >
+<!ELEMENT ProviderAlgo EMPTY>
+
+<!ATTLIST ProviderAlgo  ProviderId IDREF  #REQUIRED
+                          JCEName    CDATA  #REQUIRED
+                          JCEAlias   CDATA  #IMPLIED >
+<!ELEMENT Log4J EMPTY>
+
+<!ATTLIST Log4J  configFile CDATA  'data/log4j.xml' >
+<!ELEMENT ResourceBundles (ResourceBundle+)>
+
+<!ATTLIST ResourceBundles  defaultLanguageCode CDATA  'de'
+                             defaultCountryCode  CDATA  'DE' >
+<!ELEMENT ResourceBundle EMPTY>
+
+<!ATTLIST ResourceBundle  LanguageCode CDATA  #REQUIRED
+                            CountryCode  CDATA  #REQUIRED
+                            LOCATION     CDATA  #REQUIRED >
+<!ELEMENT UnitTests (UnitTest+)>
+
+<!ATTLIST UnitTests  JAVACLASS CDATA  #FIXED 'com.sun.org.apache.xml.internal.security.test.AllTests' >
+<!ELEMENT ResourceResolvers (Resolver+)>
+
+<!ELEMENT Resolver EMPTY>
+
+<!ATTLIST Resolver  JAVACLASS   CDATA  #REQUIRED
+                      DESCRIPTION CDATA  #IMPLIED >
+<!ELEMENT KeyResolvers (KeyResolver+)>
+<!ATTLIST KeyResolvers  JAVACLASS CDATA  #FIXED 'com.sun.org.apache.xml.internal.security.keys.KeyResolver' >
+
+<!ELEMENT KeyResolver EMPTY>
+
+<!ATTLIST KeyResolver  URI       CDATA  #REQUIRED
+                         JAVACLASS CDATA  #REQUIRED >
+<!ELEMENT UnitTest (#PCDATA)>
+
+<!ATTLIST UnitTest  JAVACLASS CDATA  #REQUIRED >
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml	Mon Apr 14 11:34:15 2008 -0700
@@ -1,380 +1,380 @@
-<?xml version="1.0"?>
-<!--
-<!DOCTYPE Configuration SYSTEM "config.dtd">
--->
-<!-- This configuration file is used for configuration of the com.sun.org.apache.xml.internal.security package -->
-<Configuration target="com.sun.org.apache.xml.internal.security" xmlns="http://www.xmlsecurity.org/NS/#configuration">
-   <CanonicalizationMethods>
-      <CanonicalizationMethod URI="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
-                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315OmitComments" />
-      <CanonicalizationMethod URI="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"
-                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315WithComments" />
-
-      <CanonicalizationMethod URI="http://www.w3.org/2001/10/xml-exc-c14n#"
-                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315ExclOmitComments"/>
-      <CanonicalizationMethod URI="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"
-                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315ExclWithComments"/>
-   </CanonicalizationMethods>
-   <TransformAlgorithms>
-      <!-- Base64 -->
-      <TransformAlgorithm URI="http://www.w3.org/2000/09/xmldsig#base64"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformBase64Decode" />
-      <!-- c14n omitting comments -->
-      <TransformAlgorithm URI="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14N" />
-      <!-- c14n with comments -->
-      <TransformAlgorithm URI="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14NWithComments" />
-      <!-- exclusive c14n omitting comments -->
-      <TransformAlgorithm URI="http://www.w3.org/2001/10/xml-exc-c14n#"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14NExclusive" />
-      <!-- exclusive c14n with comments -->
-      <TransformAlgorithm URI="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14NExclusiveWithComments" />
-
-      <!-- XPath transform -->
-      <TransformAlgorithm URI="http://www.w3.org/TR/1999/REC-xpath-19991116"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXPath" />
-      <!-- enveloped signature -->
-      <TransformAlgorithm URI="http://www.w3.org/2000/09/xmldsig#enveloped-signature"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformEnvelopedSignature" />
-      <!-- XSLT -->
-      <TransformAlgorithm URI="http://www.w3.org/TR/1999/REC-xslt-19991116"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT" />
-      <!-- XPath version 2 -->
-      <TransformAlgorithm URI="http://www.w3.org/2002/04/xmldsig-filter2"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXPath2Filter" />
-      <!-- XPath version 2b -->
-      <TransformAlgorithm URI="http://www.w3.org/2002/06/xmldsig-filter2"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXPath2Filter" />
-   </TransformAlgorithms>
-   <SignatureAlgorithms>
-      <SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#dsa-sha1"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureDSA" />
-      <SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#rsa-sha1"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA1" />
-      <SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#hmac-sha1"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacSHA1" />
-
-      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-md5"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSAMD5" />
-      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSARIPEMD160" />
-      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA256" />
-      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA384" />
-      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA512" />
-
-      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-md5"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacMD5" />
-      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacRIPEMD160" />
-      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacSHA256" />
-      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha384"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacSHA384" />
-      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha512"
-                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacSHA512" />
-   </SignatureAlgorithms>
-   <JCEAlgorithmMappings>
-      <Algorithms>
-         <!-- MessageDigest Algorithms -->
-         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#md5"
-                    Description="MD5 message digest from RFC 1321"
-                    AlgorithmClass="MessageDigest"
-                    RequirementLevel="NOT RECOMMENDED"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    JCEName="MD5"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#ripemd160"
-                    Description="RIPEMD-160 message digest"
-                    AlgorithmClass="MessageDigest"
-                    RequirementLevel="OPTIONAL"
-                    JCEName="RIPEMD160"/>
-
-         <Algorithm URI="http://www.w3.org/2000/09/xmldsig#sha1"
-                    Description="SHA-1 message digest"
-                    AlgorithmClass="MessageDigest"
-                    RequirementLevel="REQUIRED"
-                    JCEName="SHA-1"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#sha256"
-                    Description="SHA-1 message digest with 256 bit"
-                    AlgorithmClass="MessageDigest"
-                    RequirementLevel="RECOMMENDED"
-                    JCEName="SHA-256"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#sha384"
-                    Description="SHA message digest with 384 bit"
-                    AlgorithmClass="MessageDigest"
-                    RequirementLevel="OPTIONAL"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    JCEName="SHA-384"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#sha512"
-                    Description="SHA-1 message digest with 512 bit"
-                    AlgorithmClass="MessageDigest"
-                    RequirementLevel="OPTIONAL"
-                    JCEName="SHA-512"/>
-
-         <!-- Signature Algorithms -->
-         <Algorithm URI="http://www.w3.org/2000/09/xmldsig#dsa-sha1"
-                    Description="Digital Signature Algorithm with SHA-1 message digest"
-                    AlgorithmClass="Signature"
-                    RequirementLevel="REQUIRED"
-                    JCEName="SHA1withDSA"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-md5"
-                    Description="RSA Signature with MD5 message digest"
-                    AlgorithmClass="Signature"
-                    RequirementLevel="NOT RECOMMENDED"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    JCEName="MD5withRSA"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160"
-                    Description="RSA Signature with RIPEMD-160 message digest"
-                    AlgorithmClass="Signature"
-                    RequirementLevel="OPTIONAL"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    JCEName="RIPEMD160withRSA"/>
-
-         <Algorithm URI="http://www.w3.org/2000/09/xmldsig#rsa-sha1"
-                    Description="RSA Signature with SHA-1 message digest"
-                    AlgorithmClass="Signature"
-                    RequirementLevel="RECOMMENDED"
-                    JCEName="SHA1withRSA"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
-                    Description="RSA Signature with SHA-256 message digest"
-                    AlgorithmClass="Signature"
-                    RequirementLevel="OPTIONAL"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    JCEName="SHA256withRSA"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
-                    Description="RSA Signature with SHA-384 message digest"
-                    AlgorithmClass="Signature"
-                    RequirementLevel="OPTIONAL"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    JCEName="SHA384withRSA"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
-                    Description="RSA Signature with SHA-512 message digest"
-                    AlgorithmClass="Signature"
-                    RequirementLevel="OPTIONAL"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    JCEName="SHA512withRSA"/>
-
-         <!-- MAC Algorithms -->
-         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-md5"
-                    Description="Message Authentication code using MD5"
-                    AlgorithmClass="Mac"
-                    RequirementLevel="NOT RECOMMENDED"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    JCEName="HmacMD5"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160"
-                    Description="Message Authentication code using RIPEMD-160"
-                    AlgorithmClass="Mac"
-                    RequirementLevel="OPTIONAL"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    JCEName="HMACRIPEMD160"/>
-
-         <Algorithm URI="http://www.w3.org/2000/09/xmldsig#hmac-sha1"
-                    Description="Message Authentication code using SHA1"
-                    AlgorithmClass="Mac"
-                    RequirementLevel="REQUIRED"
-                    JCEName="HmacSHA1"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"
-                    Description="Message Authentication code using SHA-256"
-                    AlgorithmClass="Mac"
-                    RequirementLevel="OPTIONAL"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    JCEName="HmacSHA256"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha384"
-                    Description="Message Authentication code using SHA-384"
-                    AlgorithmClass="Mac"
-                    RequirementLevel="OPTIONAL"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    JCEName="HmacSHA384"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha512"
-                    Description="Message Authentication code using SHA-512"
-                    AlgorithmClass="Mac"
-                    RequirementLevel="OPTIONAL"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    JCEName="HmacSHA512"/>
-
-         <!-- Block encryption Algorithms -->
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"
-                    Description="Block encryption using Triple-DES"
-                    AlgorithmClass="BlockEncryption"
-                    RequirementLevel="REQUIRED"
-                    KeyLength="192"
-                    RequiredKey="DESede"
-                    JCEName="DESede/CBC/ISO10126Padding"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#aes128-cbc"
-                    Description="Block encryption using AES with a key length of 128 bit"
-                    AlgorithmClass="BlockEncryption"
-                    RequirementLevel="REQUIRED"
-                    KeyLength="128"
-                    RequiredKey="AES"
-                    JCEName="AES/CBC/ISO10126Padding"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#aes192-cbc"
-                    Description="Block encryption using AES with a key length of 192 bit"
-                    AlgorithmClass="BlockEncryption"
-                    RequirementLevel="OPTIONAL"
-                    KeyLength="192"
-                    RequiredKey="AES"
-                    JCEName="AES/CBC/ISO10126Padding"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#aes256-cbc"
-                    Description="Block encryption using AES with a key length of 256 bit"
-                    AlgorithmClass="BlockEncryption"
-                    RequirementLevel="REQUIRED"
-                    KeyLength="256"
-                    RequiredKey="AES"
-                    JCEName="AES/CBC/ISO10126Padding"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#rsa-1_5"
-                    Description="Key Transport RSA-v1.5"
-                    AlgorithmClass="KeyTransport"
-                    RequirementLevel="REQUIRED"
-                    RequiredKey="RSA"
-                    JCEName="RSA/ECB/PKCS1Padding"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"
-                    Description="Key Transport RSA-OAEP"
-                    AlgorithmClass="KeyTransport"
-                    RequirementLevel="REQUIRED"
-                    RequiredKey="RSA"
-                    JCEName="RSA/ECB/OAEPWithSHA1AndMGF1Padding"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#dh"
-                    Description="Key Agreement Diffie-Hellman"
-                    AlgorithmClass="KeyAgreement"
-                    RequirementLevel="OPTIONAL"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#kw-tripledes"
-                    Description="Symmetric Key Wrap using Triple DES"
-                    AlgorithmClass="SymmetricKeyWrap"
-                    RequirementLevel="REQUIRED"
-                    KeyLength="192"
-                    RequiredKey="DESede"
-                    JCEName="DESedeWrap"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#kw-aes128"
-                    Description="Symmetric Key Wrap using AES with a key length of 128 bit"
-                    AlgorithmClass="SymmetricKeyWrap"
-                    RequirementLevel="REQUIRED"
-                    KeyLength="128"
-                    RequiredKey="AES"
-                    JCEName="AESWrap"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#kw-aes192"
-                    Description="Symmetric Key Wrap using AES with a key length of 192 bit"
-                    AlgorithmClass="SymmetricKeyWrap"
-                    RequirementLevel="OPTIONAL"
-                    KeyLength="192"
-                    RequiredKey="AES"
-                    JCEName="AESWrap"/>
-
-         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#kw-aes256"
-                    Description="Symmetric Key Wrap using AES with a key length of 256 bit"
-                    AlgorithmClass="SymmetricKeyWrap"
-                    RequirementLevel="REQUIRED"
-                    KeyLength="256"
-                    RequiredKey="AES"
-                    JCEName="AESWrap"/>
-
-      </Algorithms>
-   </JCEAlgorithmMappings>
-   <ResourceBundles defaultLanguageCode="en" defaultCountryCode="US">
-      <ResourceBundle LanguageCode="en"
-                      CountryCode="US"
-                      LOCATION="com.sun.org.apache.xml.internal.security/resource/xmlsecurity_en.properties" />
-      <ResourceBundle LanguageCode="de"
-                      CountryCode="DE"
-                      LOCATION="com.sun.org.apache.xml.internal.security/resource/xmlsecurity_de.properties" />
-   </ResourceBundles>
-   <ResourceResolvers>
-      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverDirectHTTP"
-                DESCRIPTION="A simple resolver for requests to HTTP space" />
-      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverLocalFilesystem"
-                DESCRIPTION="A simple resolver for requests to the local file system" />
-      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment"
-                DESCRIPTION="A simple resolver for requests of same-document URIs" />
-      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverXPointer"
-                DESCRIPTION="A simple resolver for requests of XPointer fragents" />
-   </ResourceResolvers>
-   <!-- <defaultLocale languageCode="en" countryCode="US" /> -->
-   <KeyInfo>
-      <ContentHandler LOCALNAME="KeyName"
-                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
-                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.KeyName" />
-      <ContentHandler LOCALNAME="KeyValue"
-                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
-                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.KeyValue" />
-      <ContentHandler LOCALNAME="RetrievalMethod"
-                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
-                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.RetrievalMethod" />
-      <ContentHandler LOCALNAME="X509Data"
-                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
-                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.X509Data" />
-      <ContentHandler LOCALNAME="PGPData"
-                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
-                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.PGPData" />
-      <ContentHandler LOCALNAME="SPKIData"
-                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
-                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.SPKIData" />
-      <ContentHandler LOCALNAME="MgmtData"
-                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
-                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.MgmtData" />
-   </KeyInfo>
-   <KeyResolver>
-      <!-- This section contains a list of KeyResolvers that are available in
-           every KeyInfo object -->
-      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.RSAKeyValueResolver"
-                DESCRIPTION="Can extract RSA public keys" />
-      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.DSAKeyValueResolver"
-                DESCRIPTION="Can extract DSA public keys" />
-      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509CertificateResolver"
-                DESCRIPTION="Can extract public keys from X509 certificates" />
-      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509SKIResolver"
-                DESCRIPTION="Uses an X509v3 SubjectKeyIdentifier extension to retrieve a certificate from the storages" />
-      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.RetrievalMethodResolver"
-                DESCRIPTION="Resolves keys and certificates using ResourceResolvers" />
-      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509SubjectNameResolver"
-                DESCRIPTION="Uses an X509 SubjectName to retrieve a certificate from the storages" />
-      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509IssuerSerialResolver"
-                DESCRIPTION="Uses an X509 IssuerName and IssuerSerial to retrieve a certificate from the storages" />
-   </KeyResolver>
- 
-   <PrefixMappings>
-      <!-- Many classes create Elements which are in a specific namespace;
-           here, the prefixes for these namespaces are defined. But this
-           can also be overwritten using the ElementProxy#setDefaultPrefix()
-           method. You can even set all prefixes to "" so that the corresponding
-           elements are created using the default namespace -->
-      <PrefixMapping namespace="http://www.w3.org/2000/09/xmldsig#"
-                     prefix="ds" />
-      <PrefixMapping namespace="http://www.w3.org/2001/04/xmlenc#"
-                     prefix="xenc" />
-      <PrefixMapping namespace="http://www.xmlsecurity.org/experimental#"
-                     prefix="experimental" />
-      <PrefixMapping namespace="http://www.w3.org/2002/04/xmldsig-filter2"
-                     prefix="dsig-xpath-old" />
-      <PrefixMapping namespace="http://www.w3.org/2002/06/xmldsig-filter2"
-                     prefix="dsig-xpath" />
-      <PrefixMapping namespace="http://www.w3.org/2001/10/xml-exc-c14n#"
-                     prefix="ec" />
-      <PrefixMapping namespace="http://www.nue.et-inf.uni-siegen.de/~geuer-pollmann/#xpathFilter"
-                     prefix="xx" />
-   </PrefixMappings>
-</Configuration>
+<?xml version="1.0"?>
+<!--
+<!DOCTYPE Configuration SYSTEM "config.dtd">
+-->
+<!-- This configuration file is used for configuration of the com.sun.org.apache.xml.internal.security package -->
+<Configuration target="com.sun.org.apache.xml.internal.security" xmlns="http://www.xmlsecurity.org/NS/#configuration">
+   <CanonicalizationMethods>
+      <CanonicalizationMethod URI="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
+                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315OmitComments" />
+      <CanonicalizationMethod URI="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"
+                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315WithComments" />
+
+      <CanonicalizationMethod URI="http://www.w3.org/2001/10/xml-exc-c14n#"
+                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315ExclOmitComments"/>
+      <CanonicalizationMethod URI="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"
+                              JAVACLASS="com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315ExclWithComments"/>
+   </CanonicalizationMethods>
+   <TransformAlgorithms>
+      <!-- Base64 -->
+      <TransformAlgorithm URI="http://www.w3.org/2000/09/xmldsig#base64"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformBase64Decode" />
+      <!-- c14n omitting comments -->
+      <TransformAlgorithm URI="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14N" />
+      <!-- c14n with comments -->
+      <TransformAlgorithm URI="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14NWithComments" />
+      <!-- exclusive c14n omitting comments -->
+      <TransformAlgorithm URI="http://www.w3.org/2001/10/xml-exc-c14n#"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14NExclusive" />
+      <!-- exclusive c14n with comments -->
+      <TransformAlgorithm URI="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformC14NExclusiveWithComments" />
+
+      <!-- XPath transform -->
+      <TransformAlgorithm URI="http://www.w3.org/TR/1999/REC-xpath-19991116"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXPath" />
+      <!-- enveloped signature -->
+      <TransformAlgorithm URI="http://www.w3.org/2000/09/xmldsig#enveloped-signature"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformEnvelopedSignature" />
+      <!-- XSLT -->
+      <TransformAlgorithm URI="http://www.w3.org/TR/1999/REC-xslt-19991116"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT" />
+      <!-- XPath version 2 -->
+      <TransformAlgorithm URI="http://www.w3.org/2002/04/xmldsig-filter2"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXPath2Filter" />
+      <!-- XPath version 2b -->
+      <TransformAlgorithm URI="http://www.w3.org/2002/06/xmldsig-filter2"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXPath2Filter" />
+   </TransformAlgorithms>
+   <SignatureAlgorithms>
+      <SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#dsa-sha1"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureDSA" />
+      <SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#rsa-sha1"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA1" />
+      <SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#hmac-sha1"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacSHA1" />
+
+      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-md5"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSAMD5" />
+      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSARIPEMD160" />
+      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA256" />
+      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA384" />
+      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA512" />
+
+      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-md5"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacMD5" />
+      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacRIPEMD160" />
+      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacSHA256" />
+      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha384"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacSHA384" />
+      <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha512"
+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacSHA512" />
+   </SignatureAlgorithms>
+   <JCEAlgorithmMappings>
+      <Algorithms>
+         <!-- MessageDigest Algorithms -->
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#md5"
+                    Description="MD5 message digest from RFC 1321"
+                    AlgorithmClass="MessageDigest"
+                    RequirementLevel="NOT RECOMMENDED"
+                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
+                    JCEName="MD5"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#ripemd160"
+                    Description="RIPEMD-160 message digest"
+                    AlgorithmClass="MessageDigest"
+                    RequirementLevel="OPTIONAL"
+                    JCEName="RIPEMD160"/>
+
+         <Algorithm URI="http://www.w3.org/2000/09/xmldsig#sha1"
+                    Description="SHA-1 message digest"
+                    AlgorithmClass="MessageDigest"
+                    RequirementLevel="REQUIRED"
+                    JCEName="SHA-1"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#sha256"
+                    Description="SHA-1 message digest with 256 bit"
+                    AlgorithmClass="MessageDigest"
+                    RequirementLevel="RECOMMENDED"
+                    JCEName="SHA-256"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#sha384"
+                    Description="SHA message digest with 384 bit"
+                    AlgorithmClass="MessageDigest"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
+                    JCEName="SHA-384"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#sha512"
+                    Description="SHA-1 message digest with 512 bit"
+                    AlgorithmClass="MessageDigest"
+                    RequirementLevel="OPTIONAL"
+                    JCEName="SHA-512"/>
+
+         <!-- Signature Algorithms -->
+         <Algorithm URI="http://www.w3.org/2000/09/xmldsig#dsa-sha1"
+                    Description="Digital Signature Algorithm with SHA-1 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="REQUIRED"
+                    JCEName="SHA1withDSA"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-md5"
+                    Description="RSA Signature with MD5 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="NOT RECOMMENDED"
+                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
+                    JCEName="MD5withRSA"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160"
+                    Description="RSA Signature with RIPEMD-160 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
+                    JCEName="RIPEMD160withRSA"/>
+
+         <Algorithm URI="http://www.w3.org/2000/09/xmldsig#rsa-sha1"
+                    Description="RSA Signature with SHA-1 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="RECOMMENDED"
+                    JCEName="SHA1withRSA"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
+                    Description="RSA Signature with SHA-256 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
+                    JCEName="SHA256withRSA"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
+                    Description="RSA Signature with SHA-384 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
+                    JCEName="SHA384withRSA"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
+                    Description="RSA Signature with SHA-512 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
+                    JCEName="SHA512withRSA"/>
+
+         <!-- MAC Algorithms -->
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-md5"
+                    Description="Message Authentication code using MD5"
+                    AlgorithmClass="Mac"
+                    RequirementLevel="NOT RECOMMENDED"
+                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
+                    JCEName="HmacMD5"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160"
+                    Description="Message Authentication code using RIPEMD-160"
+                    AlgorithmClass="Mac"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
+                    JCEName="HMACRIPEMD160"/>
+
+         <Algorithm URI="http://www.w3.org/2000/09/xmldsig#hmac-sha1"
+                    Description="Message Authentication code using SHA1"
+                    AlgorithmClass="Mac"
+                    RequirementLevel="REQUIRED"
+                    JCEName="HmacSHA1"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"
+                    Description="Message Authentication code using SHA-256"
+                    AlgorithmClass="Mac"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
+                    JCEName="HmacSHA256"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha384"
+                    Description="Message Authentication code using SHA-384"
+                    AlgorithmClass="Mac"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
+                    JCEName="HmacSHA384"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-sha512"
+                    Description="Message Authentication code using SHA-512"
+                    AlgorithmClass="Mac"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
+                    JCEName="HmacSHA512"/>
+
+         <!-- Block encryption Algorithms -->
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"
+                    Description="Block encryption using Triple-DES"
+                    AlgorithmClass="BlockEncryption"
+                    RequirementLevel="REQUIRED"
+                    KeyLength="192"
+                    RequiredKey="DESede"
+                    JCEName="DESede/CBC/ISO10126Padding"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#aes128-cbc"
+                    Description="Block encryption using AES with a key length of 128 bit"
+                    AlgorithmClass="BlockEncryption"
+                    RequirementLevel="REQUIRED"
+                    KeyLength="128"
+                    RequiredKey="AES"
+                    JCEName="AES/CBC/ISO10126Padding"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#aes192-cbc"
+                    Description="Block encryption using AES with a key length of 192 bit"
+                    AlgorithmClass="BlockEncryption"
+                    RequirementLevel="OPTIONAL"
+                    KeyLength="192"
+                    RequiredKey="AES"
+                    JCEName="AES/CBC/ISO10126Padding"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#aes256-cbc"
+                    Description="Block encryption using AES with a key length of 256 bit"
+                    AlgorithmClass="BlockEncryption"
+                    RequirementLevel="REQUIRED"
+                    KeyLength="256"
+                    RequiredKey="AES"
+                    JCEName="AES/CBC/ISO10126Padding"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#rsa-1_5"
+                    Description="Key Transport RSA-v1.5"
+                    AlgorithmClass="KeyTransport"
+                    RequirementLevel="REQUIRED"
+                    RequiredKey="RSA"
+                    JCEName="RSA/ECB/PKCS1Padding"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"
+                    Description="Key Transport RSA-OAEP"
+                    AlgorithmClass="KeyTransport"
+                    RequirementLevel="REQUIRED"
+                    RequiredKey="RSA"
+                    JCEName="RSA/ECB/OAEPWithSHA1AndMGF1Padding"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#dh"
+                    Description="Key Agreement Diffie-Hellman"
+                    AlgorithmClass="KeyAgreement"
+                    RequirementLevel="OPTIONAL"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#kw-tripledes"
+                    Description="Symmetric Key Wrap using Triple DES"
+                    AlgorithmClass="SymmetricKeyWrap"
+                    RequirementLevel="REQUIRED"
+                    KeyLength="192"
+                    RequiredKey="DESede"
+                    JCEName="DESedeWrap"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#kw-aes128"
+                    Description="Symmetric Key Wrap using AES with a key length of 128 bit"
+                    AlgorithmClass="SymmetricKeyWrap"
+                    RequirementLevel="REQUIRED"
+                    KeyLength="128"
+                    RequiredKey="AES"
+                    JCEName="AESWrap"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#kw-aes192"
+                    Description="Symmetric Key Wrap using AES with a key length of 192 bit"
+                    AlgorithmClass="SymmetricKeyWrap"
+                    RequirementLevel="OPTIONAL"
+                    KeyLength="192"
+                    RequiredKey="AES"
+                    JCEName="AESWrap"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmlenc#kw-aes256"
+                    Description="Symmetric Key Wrap using AES with a key length of 256 bit"
+                    AlgorithmClass="SymmetricKeyWrap"
+                    RequirementLevel="REQUIRED"
+                    KeyLength="256"
+                    RequiredKey="AES"
+                    JCEName="AESWrap"/>
+
+      </Algorithms>
+   </JCEAlgorithmMappings>
+   <ResourceBundles defaultLanguageCode="en" defaultCountryCode="US">
+      <ResourceBundle LanguageCode="en"
+                      CountryCode="US"
+                      LOCATION="com.sun.org.apache.xml.internal.security/resource/xmlsecurity_en.properties" />
+      <ResourceBundle LanguageCode="de"
+                      CountryCode="DE"
+                      LOCATION="com.sun.org.apache.xml.internal.security/resource/xmlsecurity_de.properties" />
+   </ResourceBundles>
+   <ResourceResolvers>
+      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverDirectHTTP"
+                DESCRIPTION="A simple resolver for requests to HTTP space" />
+      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverLocalFilesystem"
+                DESCRIPTION="A simple resolver for requests to the local file system" />
+      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment"
+                DESCRIPTION="A simple resolver for requests of same-document URIs" />
+      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverXPointer"
+                DESCRIPTION="A simple resolver for requests of XPointer fragents" />
+   </ResourceResolvers>
+   <!-- <defaultLocale languageCode="en" countryCode="US" /> -->
+   <KeyInfo>
+      <ContentHandler LOCALNAME="KeyName"
+                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
+                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.KeyName" />
+      <ContentHandler LOCALNAME="KeyValue"
+                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
+                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.KeyValue" />
+      <ContentHandler LOCALNAME="RetrievalMethod"
+                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
+                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.RetrievalMethod" />
+      <ContentHandler LOCALNAME="X509Data"
+                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
+                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.X509Data" />
+      <ContentHandler LOCALNAME="PGPData"
+                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
+                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.PGPData" />
+      <ContentHandler LOCALNAME="SPKIData"
+                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
+                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.SPKIData" />
+      <ContentHandler LOCALNAME="MgmtData"
+                      NAMESPACE="http://www.w3.org/2000/09/xmldsig#"
+                      JAVACLASS="com.sun.org.apache.xml.internal.security.keys.content.MgmtData" />
+   </KeyInfo>
+   <KeyResolver>
+      <!-- This section contains a list of KeyResolvers that are available in
+           every KeyInfo object -->
+      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.RSAKeyValueResolver"
+                DESCRIPTION="Can extract RSA public keys" />
+      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.DSAKeyValueResolver"
+                DESCRIPTION="Can extract DSA public keys" />
+      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509CertificateResolver"
+                DESCRIPTION="Can extract public keys from X509 certificates" />
+      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509SKIResolver"
+                DESCRIPTION="Uses an X509v3 SubjectKeyIdentifier extension to retrieve a certificate from the storages" />
+      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.RetrievalMethodResolver"
+                DESCRIPTION="Resolves keys and certificates using ResourceResolvers" />
+      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509SubjectNameResolver"
+                DESCRIPTION="Uses an X509 SubjectName to retrieve a certificate from the storages" />
+      <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509IssuerSerialResolver"
+                DESCRIPTION="Uses an X509 IssuerName and IssuerSerial to retrieve a certificate from the storages" />
+   </KeyResolver>
+ 
+   <PrefixMappings>
+      <!-- Many classes create Elements which are in a specific namespace;
+           here, the prefixes for these namespaces are defined. But this
+           can also be overwritten using the ElementProxy#setDefaultPrefix()
+           method. You can even set all prefixes to "" so that the corresponding
+           elements are created using the default namespace -->
+      <PrefixMapping namespace="http://www.w3.org/2000/09/xmldsig#"
+                     prefix="ds" />
+      <PrefixMapping namespace="http://www.w3.org/2001/04/xmlenc#"
+                     prefix="xenc" />
+      <PrefixMapping namespace="http://www.xmlsecurity.org/experimental#"
+                     prefix="experimental" />
+      <PrefixMapping namespace="http://www.w3.org/2002/04/xmldsig-filter2"
+                     prefix="dsig-xpath-old" />
+      <PrefixMapping namespace="http://www.w3.org/2002/06/xmldsig-filter2"
+                     prefix="dsig-xpath" />
+      <PrefixMapping namespace="http://www.w3.org/2001/10/xml-exc-c14n#"
+                     prefix="ec" />
+      <PrefixMapping namespace="http://www.nue.et-inf.uni-siegen.de/~geuer-pollmann/#xpathFilter"
+                     prefix="xx" />
+   </PrefixMappings>
+</Configuration>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd	Mon Apr 14 11:34:15 2008 -0700
@@ -1,347 +1,347 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- edited with XML Spy v4.3 U (http://www.xmlspy.com) by XMLSpy v4 (Altova) -->
-<xsd:schema targetNamespace="http://uri.etsi.org/01903/v1.1.1#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://uri.etsi.org/01903/v1.1.1#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" elementFormDefault="qualified" xsi:schemaLocation="http://www.w3.org/2000/09/xmldsig# xmldsig-core-schema.xsd">
-	<xsd:element name="Any" type="AnyType"/>
-	<xsd:complexType name="AnyType" mixed="true">
-		<xsd:sequence>
-			<xsd:any namespace="##any"/>
-		</xsd:sequence>
-		<xsd:anyAttribute namespace="##any"/>
-	</xsd:complexType>
-	<xsd:element name="ObjectIdentifier" type="ObjectIdentifierType"/>
-	<xsd:complexType name="ObjectIdentifierType">
-		<xsd:sequence>
-			<xsd:element name="Identifier" type="IdentifierType"/>
-			<xsd:element name="Description" type="xsd:string" minOccurs="0"/>
-			<xsd:element name="DocumentationReferences" type="DocumentationReferencesType" minOccurs="0"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="IdentifierType">
-		<xsd:simpleContent>
-			<xsd:extension base="xsd:anyURI">
-				<xsd:attribute name="Qualifier" type="QualifierType" use="optional"/>
-			</xsd:extension>
-		</xsd:simpleContent>
-	</xsd:complexType>
-	<xsd:simpleType name="QualifierType">
-		<xsd:restriction base="xsd:string">
-			<xsd:enumeration value="OIDAsURI"/>
-			<xsd:enumeration value="OIDAsURN"/>
-		</xsd:restriction>
-	</xsd:simpleType>
-	<xsd:complexType name="DocumentationReferencesType">
-		<xsd:sequence maxOccurs="unbounded">
-			<xsd:element name="DocumentationReference" type="xsd:anyURI"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="EncapsulatedPKIData" type="EncapsulatedPKIDataType"/>
-	<xsd:complexType name="EncapsulatedPKIDataType">
-		<xsd:simpleContent>
-			<xsd:extension base="xsd:base64Binary">
-				<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
-			</xsd:extension>
-		</xsd:simpleContent>
-	</xsd:complexType>
-	<xsd:element name="TimeStamp" type="TimeStampType"/>
-	<xsd:complexType name="TimeStampType">
-		<xsd:sequence>
-			<xsd:element name="HashDataInfo" type="HashDataInfoType" maxOccurs="unbounded"/>
-			<xsd:choice>
-				<xsd:element name="EncapsulatedTimeStamp" type="EncapsulatedPKIDataType"/>
-				<xsd:element name="XMLTimeStamp" type="AnyType"/>
-			</xsd:choice>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="HashDataInfoType">
-		<xsd:sequence>
-			<xsd:element name="Transforms" type="ds:TransformsType" minOccurs="0"/>
-		</xsd:sequence>
-		<xsd:attribute name="uri" type="xsd:anyURI" use="required"/>
-	</xsd:complexType>
-	<xsd:element name="QualifyingProperties" type="QualifyingPropertiesType"/>
-	<xsd:complexType name="QualifyingPropertiesType">
-		<xsd:sequence>
-			<xsd:element name="SignedProperties" type="SignedPropertiesType" minOccurs="0"/>
-			<xsd:element name="UnsignedProperties" type="UnsignedPropertiesType" minOccurs="0"/>
-		</xsd:sequence>
-		<xsd:attribute name="Target" type="xsd:anyURI" use="required"/>
-		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
-	</xsd:complexType>
-	<xsd:element name="SignedProperties" type="SignedPropertiesType"/>
-	<xsd:complexType name="SignedPropertiesType">
-		<xsd:sequence>
-			<xsd:element name="SignedSignatureProperties" type="SignedSignaturePropertiesType"/>
-			<xsd:element name="SignedDataObjectProperties" type="SignedDataObjectPropertiesType" minOccurs="0"/>
-		</xsd:sequence>
-		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
-	</xsd:complexType>
-	<xsd:element name="UnsignedProperties" type="UnsignedPropertiesType"/>
-	<xsd:complexType name="UnsignedPropertiesType">
-		<xsd:sequence>
-			<xsd:element name="UnsignedSignatureProperties" type="UnsignedSignaturePropertiesType" minOccurs="0"/>
-			<xsd:element name="UnsignedDataObjectProperties" type="UnsignedDataObjectPropertiesType" minOccurs="0"/>
-		</xsd:sequence>
-		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
-	</xsd:complexType>
-	<xsd:element name="SignedSignatureProperties" type="SignedSignaturePropertiesType"/>
-	<xsd:complexType name="SignedSignaturePropertiesType">
-		<xsd:sequence>
-			<xsd:element name="SigningTime" type="xsd:dateTime"/>
-			<xsd:element name="SigningCertificate" type="CertIDListType"/>
-			<xsd:element name="SignaturePolicyIdentifier" type="SignaturePolicyIdentifierType"/>
-			<xsd:element name="SignatureProductionPlace" type="SignatureProductionPlaceType" minOccurs="0"/>
-			<xsd:element name="SignerRole" type="SignerRoleType" minOccurs="0"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="SignedDataObjectProperties" type="SignedDataObjectPropertiesType"/>
-	<xsd:complexType name="SignedDataObjectPropertiesType">
-		<xsd:sequence>
-			<xsd:element name="DataObjectFormat" type="DataObjectFormatType" minOccurs="0" maxOccurs="unbounded"/>
-			<xsd:element name="CommitmentTypeIndication" type="CommitmentTypeIndicationType" minOccurs="0" maxOccurs="unbounded"/>
-			<xsd:element name="AllDataObjectsTimeStamp" type="TimeStampType" minOccurs="0" maxOccurs="unbounded"/>
-			<xsd:element name="IndividualDataObjectsTimeStamp" type="TimeStampType" minOccurs="0" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="UnsignedSignatureProperties" type="UnsignedSignaturePropertiesType"/>
-	<xsd:complexType name="UnsignedSignaturePropertiesType">
-		<xsd:sequence>
-			<xsd:element name="CounterSignature" type="CounterSignatureType" minOccurs="0" maxOccurs="unbounded"/>
-			<xsd:element name="SignatureTimeStamp" type="TimeStampType" minOccurs="0" maxOccurs="unbounded"/>
-			<xsd:element name="CompleteCertificateRefs" type="CompleteCertificateRefsType" minOccurs="0"/>
-			<xsd:element name="CompleteRevocationRefs" type="CompleteRevocationRefsType" minOccurs="0"/>
-			<xsd:choice>
-				<xsd:element name="SigAndRefsTimeStamp" type="TimeStampType" minOccurs="0" maxOccurs="unbounded"/>
-				<xsd:element name="RefsOnlyTimeStamp" type="TimeStampType" minOccurs="0" maxOccurs="unbounded"/>
-			</xsd:choice>
-			<xsd:element name="CertificateValues" type="CertificateValuesType" minOccurs="0"/>
-			<xsd:element name="RevocationValues" type="RevocationValuesType" minOccurs="0"/>
-			<xsd:element name="ArchiveTimeStamp" type="TimeStampType" minOccurs="0" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="UnsignedDataObjectProperties" type="UnsignedDataObjectPropertiesType"/>
-	<xsd:complexType name="UnsignedDataObjectPropertiesType">
-		<xsd:sequence>
-			<xsd:element name="UnsignedDataObjectProperty" type="AnyType" minOccurs="0" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="QualifyingPropertiesReference" type="QualifyingPropertiesReferenceType"/>
-	<xsd:complexType name="QualifyingPropertiesReferenceType">
-		<xsd:sequence>
-			<xsd:element name="Transforms" type="ds:TransformsType" minOccurs="0"/>
-		</xsd:sequence>
-		<xsd:attribute name="URI" type="xsd:anyURI" use="required"/>
-		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
-	</xsd:complexType>
-	<xsd:element name="SigningTime" type="xsd:dateTime"/>
-	<xsd:element name="SigningCertificate" type="CertIDListType"/>
-	<xsd:complexType name="CertIDListType">
-		<xsd:sequence>
-			<xsd:element name="Cert" type="CertIDType" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="CertIDType">
-		<xsd:sequence>
-			<xsd:element name="CertDigest" type="DigestAlgAndValueType"/>
-			<xsd:element name="IssuerSerial" type="ds:X509IssuerSerialType"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="DigestAlgAndValueType">
-		<xsd:sequence>
-			<xsd:element name="DigestMethod" type="ds:DigestMethodType"/>
-			<xsd:element name="DigestValue" type="ds:DigestValueType"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="SignaturePolicyIdentifier" type="SignaturePolicyIdentifierType"/>
-	<xsd:complexType name="SignaturePolicyIdentifierType">
-		<xsd:choice>
-			<xsd:element name="SignaturePolicyId" type="SignaturePolicyIdType"/>
-			<xsd:element name="SignaturePolicyImplied"/>
-		</xsd:choice>
-	</xsd:complexType>
-	<xsd:complexType name="SignaturePolicyIdType">
-		<xsd:sequence>
-			<xsd:element name="SigPolicyId" type="ObjectIdentifierType"/>
-			<xsd:element ref="ds:Transforms" minOccurs="0"/>
-			<xsd:element name="SigPolicyHash" type="DigestAlgAndValueType"/>
-			<xsd:element name="SigPolicyQualifiers" type="SigPolicyQualifiersListType" minOccurs="0"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="SigPolicyQualifiersListType">
-		<xsd:sequence>
-			<xsd:element name="SigPolicyQualifier" type="AnyType" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="SPURI" type="xsd:anyURI"/>
-	<xsd:element name="SPUserNotice" type="SPUserNoticeType"/>
-	<xsd:complexType name="SPUserNoticeType">
-		<xsd:sequence>
-			<xsd:element name="NoticeRef" type="NoticeReferenceType" minOccurs="0"/>
-			<xsd:element name="ExplicitText" type="xsd:string" minOccurs="0"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="NoticeReferenceType">
-		<xsd:sequence>
-			<xsd:element name="Organization" type="xsd:string"/>
-			<xsd:element name="NoticeNumbers" type="IntegerListType"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="IntegerListType">
-		<xsd:sequence>
-			<xsd:element name="int" type="xsd:integer" minOccurs="0" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="CounterSignature" type="CounterSignatureType"/>
-	<xsd:complexType name="CounterSignatureType">
-		<xsd:sequence>
-			<xsd:element ref="ds:Signature"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="DataObjectFormat" type="DataObjectFormatType"/>
-	<xsd:complexType name="DataObjectFormatType">
-		<xsd:sequence>
-			<xsd:element name="Description" type="xsd:string" minOccurs="0"/>
-			<xsd:element name="ObjectIdentifier" type="ObjectIdentifierType" minOccurs="0"/>
-			<xsd:element name="MimeType" type="xsd:string" minOccurs="0"/>
-			<xsd:element name="Encoding" type="xsd:anyURI" minOccurs="0"/>
-		</xsd:sequence>
-		<xsd:attribute name="ObjectReference" type="xsd:anyURI" use="required"/>
-	</xsd:complexType>
-	<xsd:element name="CommitmentTypeIndication" type="CommitmentTypeIndicationType"/>
-	<xsd:complexType name="CommitmentTypeIndicationType">
-		<xsd:sequence>
-			<xsd:element name="CommitmentTypeId" type="ObjectIdentifierType"/>
-			<xsd:choice>
-				<xsd:element name="ObjectReference" type="xsd:anyURI" minOccurs="0" maxOccurs="unbounded"/>
-				<xsd:element name="AllSignedDataObjects"/>
-			</xsd:choice>
-			<xsd:element name="CommitmentTypeQualifiers" type="CommitmentTypeQualifiersListType" minOccurs="0"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="CommitmentTypeQualifiersListType">
-		<xsd:sequence>
-			<xsd:element name="CommitmentTypeQualifier" type="AnyType" minOccurs="0" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="SignatureProductionPlace" type="SignatureProductionPlaceType"/>
-	<xsd:complexType name="SignatureProductionPlaceType">
-		<xsd:sequence>
-			<xsd:element name="City" type="xsd:string" minOccurs="0"/>
-			<xsd:element name="StateOrProvince" type="xsd:string" minOccurs="0"/>
-			<xsd:element name="PostalCode" type="xsd:string" minOccurs="0"/>
-			<xsd:element name="CountryName" type="xsd:string" minOccurs="0"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="SignerRole" type="SignerRoleType"/>
-	<xsd:complexType name="SignerRoleType">
-		<xsd:sequence>
-			<xsd:element name="ClaimedRoles" type="ClaimedRolesListType" minOccurs="0"/>
-			<xsd:element name="CertifiedRoles" type="CertifiedRolesListType" minOccurs="0"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="ClaimedRolesListType">
-		<xsd:sequence>
-			<xsd:element name="ClaimedRole" type="AnyType" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="CertifiedRolesListType">
-		<xsd:sequence>
-			<xsd:element name="CertifiedRole" type="EncapsulatedPKIDataType" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="AllDataObjectsTimeStamp" type="TimeStampType"/>
-	<xsd:element name="IndividualDataObjectsTimeStamp" type="TimeStampType"/>
-	<xsd:element name="SignatureTimeStamp" type="TimeStampType"/>
-	<xsd:element name="CompleteCertificateRefs" type="CompleteCertificateRefsType"/>
-	<xsd:complexType name="CompleteCertificateRefsType">
-		<xsd:sequence>
-			<xsd:element name="CertRefs" type="CertIDListType"/>
-		</xsd:sequence>
-		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
-	</xsd:complexType>
-	<xsd:element name="CompleteRevocationRefs" type="CompleteRevocationRefsType"/>
-	<xsd:complexType name="CompleteRevocationRefsType">
-		<xsd:sequence>
-			<xsd:element name="CRLRefs" type="CRLRefsType" minOccurs="0"/>
-			<xsd:element name="OCSPRefs" type="OCSPRefsType" minOccurs="0"/>
-			<xsd:element name="OtherRefs" type="OtherCertStatusRefsType" minOccurs="0"/>
-		</xsd:sequence>
-		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
-	</xsd:complexType>
-	<xsd:complexType name="CRLRefsType">
-		<xsd:sequence>
-			<xsd:element name="CRLRef" type="CRLRefType" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="CRLRefType">
-		<xsd:sequence>
-			<xsd:element name="DigestAlgAndValue" type="DigestAlgAndValueType"/>
-			<xsd:element name="CRLIdentifier" type="CRLIdentifierType" minOccurs="0"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="CRLIdentifierType">
-		<xsd:sequence>
-			<xsd:element name="Issuer" type="xsd:string"/>
-			<xsd:element name="IssueTime" type="xsd:dateTime"/>
-			<xsd:element name="Number" type="xsd:integer" minOccurs="0"/>
-		</xsd:sequence>
-		<xsd:attribute name="URI" type="xsd:anyURI" use="optional"/>
-	</xsd:complexType>
-	<xsd:complexType name="OCSPRefsType">
-		<xsd:sequence>
-			<xsd:element name="OCSPRef" type="OCSPRefType" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="OCSPRefType">
-		<xsd:sequence>
-			<xsd:element name="OCSPIdentifier" type="OCSPIdentifierType"/>
-			<xsd:element name="DigestAlgAndValue" type="DigestAlgAndValueType" minOccurs="0"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="OCSPIdentifierType">
-		<xsd:sequence>
-			<xsd:element name="ResponderID" type="xsd:string"/>
-			<xsd:element name="ProducedAt" type="xsd:dateTime"/>
-		</xsd:sequence>
-		<xsd:attribute name="URI" type="xsd:anyURI" use="optional"/>
-	</xsd:complexType>
-	<xsd:complexType name="OtherCertStatusRefsType">
-		<xsd:sequence>
-			<xsd:element name="OtherRef" type="AnyType" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="SigAndRefsTimeStamp" type="TimeStampType"/>
-	<xsd:element name="RefsOnlyTimeStamp" type="TimeStampType"/>
-	<xsd:element name="CertificateValues" type="CertificateValuesType"/>
-	<xsd:complexType name="CertificateValuesType">
-		<xsd:choice minOccurs="0" maxOccurs="unbounded">
-			<xsd:element name="EncapsulatedX509Certificate" type="EncapsulatedPKIDataType"/>
-			<xsd:element name="OtherCertificate" type="AnyType"/>
-		</xsd:choice>
-		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
-	</xsd:complexType>
-	<xsd:element name="RevocationValues" type="RevocationValuesType"/>
-	<xsd:complexType name="RevocationValuesType">
-		<xsd:sequence>
-			<xsd:element name="CRLValues" type="CRLValuesType" minOccurs="0"/>
-			<xsd:element name="OCSPValues" type="OCSPValuesType" minOccurs="0"/>
-			<xsd:element name="OtherValues" type="OtherCertStatusValuesType" minOccurs="0"/>
-		</xsd:sequence>
-		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
-	</xsd:complexType>
-	<xsd:complexType name="CRLValuesType">
-		<xsd:sequence>
-			<xsd:element name="EncapsulatedCRLValue" type="EncapsulatedPKIDataType" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="OCSPValuesType">
-		<xsd:sequence>
-			<xsd:element name="EncapsulatedOCSPValue" type="EncapsulatedPKIDataType" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:complexType name="OtherCertStatusValuesType">
-		<xsd:sequence>
-			<xsd:element name="OtherValue" type="AnyType" maxOccurs="unbounded"/>
-		</xsd:sequence>
-	</xsd:complexType>
-	<xsd:element name="ArchiveTimeStamp" type="TimeStampType"/>
-</xsd:schema>
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- edited with XML Spy v4.3 U (http://www.xmlspy.com) by XMLSpy v4 (Altova) -->
+<xsd:schema targetNamespace="http://uri.etsi.org/01903/v1.1.1#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://uri.etsi.org/01903/v1.1.1#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" elementFormDefault="qualified" xsi:schemaLocation="http://www.w3.org/2000/09/xmldsig# xmldsig-core-schema.xsd">
+	<xsd:element name="Any" type="AnyType"/>
+	<xsd:complexType name="AnyType" mixed="true">
+		<xsd:sequence>
+			<xsd:any namespace="##any"/>
+		</xsd:sequence>
+		<xsd:anyAttribute namespace="##any"/>
+	</xsd:complexType>
+	<xsd:element name="ObjectIdentifier" type="ObjectIdentifierType"/>
+	<xsd:complexType name="ObjectIdentifierType">
+		<xsd:sequence>
+			<xsd:element name="Identifier" type="IdentifierType"/>
+			<xsd:element name="Description" type="xsd:string" minOccurs="0"/>
+			<xsd:element name="DocumentationReferences" type="DocumentationReferencesType" minOccurs="0"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="IdentifierType">
+		<xsd:simpleContent>
+			<xsd:extension base="xsd:anyURI">
+				<xsd:attribute name="Qualifier" type="QualifierType" use="optional"/>
+			</xsd:extension>
+		</xsd:simpleContent>
+	</xsd:complexType>
+	<xsd:simpleType name="QualifierType">
+		<xsd:restriction base="xsd:string">
+			<xsd:enumeration value="OIDAsURI"/>
+			<xsd:enumeration value="OIDAsURN"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+	<xsd:complexType name="DocumentationReferencesType">
+		<xsd:sequence maxOccurs="unbounded">
+			<xsd:element name="DocumentationReference" type="xsd:anyURI"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="EncapsulatedPKIData" type="EncapsulatedPKIDataType"/>
+	<xsd:complexType name="EncapsulatedPKIDataType">
+		<xsd:simpleContent>
+			<xsd:extension base="xsd:base64Binary">
+				<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
+			</xsd:extension>
+		</xsd:simpleContent>
+	</xsd:complexType>
+	<xsd:element name="TimeStamp" type="TimeStampType"/>
+	<xsd:complexType name="TimeStampType">
+		<xsd:sequence>
+			<xsd:element name="HashDataInfo" type="HashDataInfoType" maxOccurs="unbounded"/>
+			<xsd:choice>
+				<xsd:element name="EncapsulatedTimeStamp" type="EncapsulatedPKIDataType"/>
+				<xsd:element name="XMLTimeStamp" type="AnyType"/>
+			</xsd:choice>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="HashDataInfoType">
+		<xsd:sequence>
+			<xsd:element name="Transforms" type="ds:TransformsType" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="uri" type="xsd:anyURI" use="required"/>
+	</xsd:complexType>
+	<xsd:element name="QualifyingProperties" type="QualifyingPropertiesType"/>
+	<xsd:complexType name="QualifyingPropertiesType">
+		<xsd:sequence>
+			<xsd:element name="SignedProperties" type="SignedPropertiesType" minOccurs="0"/>
+			<xsd:element name="UnsignedProperties" type="UnsignedPropertiesType" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="Target" type="xsd:anyURI" use="required"/>
+		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
+	</xsd:complexType>
+	<xsd:element name="SignedProperties" type="SignedPropertiesType"/>
+	<xsd:complexType name="SignedPropertiesType">
+		<xsd:sequence>
+			<xsd:element name="SignedSignatureProperties" type="SignedSignaturePropertiesType"/>
+			<xsd:element name="SignedDataObjectProperties" type="SignedDataObjectPropertiesType" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
+	</xsd:complexType>
+	<xsd:element name="UnsignedProperties" type="UnsignedPropertiesType"/>
+	<xsd:complexType name="UnsignedPropertiesType">
+		<xsd:sequence>
+			<xsd:element name="UnsignedSignatureProperties" type="UnsignedSignaturePropertiesType" minOccurs="0"/>
+			<xsd:element name="UnsignedDataObjectProperties" type="UnsignedDataObjectPropertiesType" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
+	</xsd:complexType>
+	<xsd:element name="SignedSignatureProperties" type="SignedSignaturePropertiesType"/>
+	<xsd:complexType name="SignedSignaturePropertiesType">
+		<xsd:sequence>
+			<xsd:element name="SigningTime" type="xsd:dateTime"/>
+			<xsd:element name="SigningCertificate" type="CertIDListType"/>
+			<xsd:element name="SignaturePolicyIdentifier" type="SignaturePolicyIdentifierType"/>
+			<xsd:element name="SignatureProductionPlace" type="SignatureProductionPlaceType" minOccurs="0"/>
+			<xsd:element name="SignerRole" type="SignerRoleType" minOccurs="0"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="SignedDataObjectProperties" type="SignedDataObjectPropertiesType"/>
+	<xsd:complexType name="SignedDataObjectPropertiesType">
+		<xsd:sequence>
+			<xsd:element name="DataObjectFormat" type="DataObjectFormatType" minOccurs="0" maxOccurs="unbounded"/>
+			<xsd:element name="CommitmentTypeIndication" type="CommitmentTypeIndicationType" minOccurs="0" maxOccurs="unbounded"/>
+			<xsd:element name="AllDataObjectsTimeStamp" type="TimeStampType" minOccurs="0" maxOccurs="unbounded"/>
+			<xsd:element name="IndividualDataObjectsTimeStamp" type="TimeStampType" minOccurs="0" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="UnsignedSignatureProperties" type="UnsignedSignaturePropertiesType"/>
+	<xsd:complexType name="UnsignedSignaturePropertiesType">
+		<xsd:sequence>
+			<xsd:element name="CounterSignature" type="CounterSignatureType" minOccurs="0" maxOccurs="unbounded"/>
+			<xsd:element name="SignatureTimeStamp" type="TimeStampType" minOccurs="0" maxOccurs="unbounded"/>
+			<xsd:element name="CompleteCertificateRefs" type="CompleteCertificateRefsType" minOccurs="0"/>
+			<xsd:element name="CompleteRevocationRefs" type="CompleteRevocationRefsType" minOccurs="0"/>
+			<xsd:choice>
+				<xsd:element name="SigAndRefsTimeStamp" type="TimeStampType" minOccurs="0" maxOccurs="unbounded"/>
+				<xsd:element name="RefsOnlyTimeStamp" type="TimeStampType" minOccurs="0" maxOccurs="unbounded"/>
+			</xsd:choice>
+			<xsd:element name="CertificateValues" type="CertificateValuesType" minOccurs="0"/>
+			<xsd:element name="RevocationValues" type="RevocationValuesType" minOccurs="0"/>
+			<xsd:element name="ArchiveTimeStamp" type="TimeStampType" minOccurs="0" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="UnsignedDataObjectProperties" type="UnsignedDataObjectPropertiesType"/>
+	<xsd:complexType name="UnsignedDataObjectPropertiesType">
+		<xsd:sequence>
+			<xsd:element name="UnsignedDataObjectProperty" type="AnyType" minOccurs="0" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="QualifyingPropertiesReference" type="QualifyingPropertiesReferenceType"/>
+	<xsd:complexType name="QualifyingPropertiesReferenceType">
+		<xsd:sequence>
+			<xsd:element name="Transforms" type="ds:TransformsType" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="URI" type="xsd:anyURI" use="required"/>
+		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
+	</xsd:complexType>
+	<xsd:element name="SigningTime" type="xsd:dateTime"/>
+	<xsd:element name="SigningCertificate" type="CertIDListType"/>
+	<xsd:complexType name="CertIDListType">
+		<xsd:sequence>
+			<xsd:element name="Cert" type="CertIDType" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="CertIDType">
+		<xsd:sequence>
+			<xsd:element name="CertDigest" type="DigestAlgAndValueType"/>
+			<xsd:element name="IssuerSerial" type="ds:X509IssuerSerialType"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="DigestAlgAndValueType">
+		<xsd:sequence>
+			<xsd:element name="DigestMethod" type="ds:DigestMethodType"/>
+			<xsd:element name="DigestValue" type="ds:DigestValueType"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="SignaturePolicyIdentifier" type="SignaturePolicyIdentifierType"/>
+	<xsd:complexType name="SignaturePolicyIdentifierType">
+		<xsd:choice>
+			<xsd:element name="SignaturePolicyId" type="SignaturePolicyIdType"/>
+			<xsd:element name="SignaturePolicyImplied"/>
+		</xsd:choice>
+	</xsd:complexType>
+	<xsd:complexType name="SignaturePolicyIdType">
+		<xsd:sequence>
+			<xsd:element name="SigPolicyId" type="ObjectIdentifierType"/>
+			<xsd:element ref="ds:Transforms" minOccurs="0"/>
+			<xsd:element name="SigPolicyHash" type="DigestAlgAndValueType"/>
+			<xsd:element name="SigPolicyQualifiers" type="SigPolicyQualifiersListType" minOccurs="0"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="SigPolicyQualifiersListType">
+		<xsd:sequence>
+			<xsd:element name="SigPolicyQualifier" type="AnyType" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="SPURI" type="xsd:anyURI"/>
+	<xsd:element name="SPUserNotice" type="SPUserNoticeType"/>
+	<xsd:complexType name="SPUserNoticeType">
+		<xsd:sequence>
+			<xsd:element name="NoticeRef" type="NoticeReferenceType" minOccurs="0"/>
+			<xsd:element name="ExplicitText" type="xsd:string" minOccurs="0"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="NoticeReferenceType">
+		<xsd:sequence>
+			<xsd:element name="Organization" type="xsd:string"/>
+			<xsd:element name="NoticeNumbers" type="IntegerListType"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="IntegerListType">
+		<xsd:sequence>
+			<xsd:element name="int" type="xsd:integer" minOccurs="0" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="CounterSignature" type="CounterSignatureType"/>
+	<xsd:complexType name="CounterSignatureType">
+		<xsd:sequence>
+			<xsd:element ref="ds:Signature"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="DataObjectFormat" type="DataObjectFormatType"/>
+	<xsd:complexType name="DataObjectFormatType">
+		<xsd:sequence>
+			<xsd:element name="Description" type="xsd:string" minOccurs="0"/>
+			<xsd:element name="ObjectIdentifier" type="ObjectIdentifierType" minOccurs="0"/>
+			<xsd:element name="MimeType" type="xsd:string" minOccurs="0"/>
+			<xsd:element name="Encoding" type="xsd:anyURI" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="ObjectReference" type="xsd:anyURI" use="required"/>
+	</xsd:complexType>
+	<xsd:element name="CommitmentTypeIndication" type="CommitmentTypeIndicationType"/>
+	<xsd:complexType name="CommitmentTypeIndicationType">
+		<xsd:sequence>
+			<xsd:element name="CommitmentTypeId" type="ObjectIdentifierType"/>
+			<xsd:choice>
+				<xsd:element name="ObjectReference" type="xsd:anyURI" minOccurs="0" maxOccurs="unbounded"/>
+				<xsd:element name="AllSignedDataObjects"/>
+			</xsd:choice>
+			<xsd:element name="CommitmentTypeQualifiers" type="CommitmentTypeQualifiersListType" minOccurs="0"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="CommitmentTypeQualifiersListType">
+		<xsd:sequence>
+			<xsd:element name="CommitmentTypeQualifier" type="AnyType" minOccurs="0" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="SignatureProductionPlace" type="SignatureProductionPlaceType"/>
+	<xsd:complexType name="SignatureProductionPlaceType">
+		<xsd:sequence>
+			<xsd:element name="City" type="xsd:string" minOccurs="0"/>
+			<xsd:element name="StateOrProvince" type="xsd:string" minOccurs="0"/>
+			<xsd:element name="PostalCode" type="xsd:string" minOccurs="0"/>
+			<xsd:element name="CountryName" type="xsd:string" minOccurs="0"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="SignerRole" type="SignerRoleType"/>
+	<xsd:complexType name="SignerRoleType">
+		<xsd:sequence>
+			<xsd:element name="ClaimedRoles" type="ClaimedRolesListType" minOccurs="0"/>
+			<xsd:element name="CertifiedRoles" type="CertifiedRolesListType" minOccurs="0"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="ClaimedRolesListType">
+		<xsd:sequence>
+			<xsd:element name="ClaimedRole" type="AnyType" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="CertifiedRolesListType">
+		<xsd:sequence>
+			<xsd:element name="CertifiedRole" type="EncapsulatedPKIDataType" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="AllDataObjectsTimeStamp" type="TimeStampType"/>
+	<xsd:element name="IndividualDataObjectsTimeStamp" type="TimeStampType"/>
+	<xsd:element name="SignatureTimeStamp" type="TimeStampType"/>
+	<xsd:element name="CompleteCertificateRefs" type="CompleteCertificateRefsType"/>
+	<xsd:complexType name="CompleteCertificateRefsType">
+		<xsd:sequence>
+			<xsd:element name="CertRefs" type="CertIDListType"/>
+		</xsd:sequence>
+		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
+	</xsd:complexType>
+	<xsd:element name="CompleteRevocationRefs" type="CompleteRevocationRefsType"/>
+	<xsd:complexType name="CompleteRevocationRefsType">
+		<xsd:sequence>
+			<xsd:element name="CRLRefs" type="CRLRefsType" minOccurs="0"/>
+			<xsd:element name="OCSPRefs" type="OCSPRefsType" minOccurs="0"/>
+			<xsd:element name="OtherRefs" type="OtherCertStatusRefsType" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
+	</xsd:complexType>
+	<xsd:complexType name="CRLRefsType">
+		<xsd:sequence>
+			<xsd:element name="CRLRef" type="CRLRefType" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="CRLRefType">
+		<xsd:sequence>
+			<xsd:element name="DigestAlgAndValue" type="DigestAlgAndValueType"/>
+			<xsd:element name="CRLIdentifier" type="CRLIdentifierType" minOccurs="0"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="CRLIdentifierType">
+		<xsd:sequence>
+			<xsd:element name="Issuer" type="xsd:string"/>
+			<xsd:element name="IssueTime" type="xsd:dateTime"/>
+			<xsd:element name="Number" type="xsd:integer" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="URI" type="xsd:anyURI" use="optional"/>
+	</xsd:complexType>
+	<xsd:complexType name="OCSPRefsType">
+		<xsd:sequence>
+			<xsd:element name="OCSPRef" type="OCSPRefType" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="OCSPRefType">
+		<xsd:sequence>
+			<xsd:element name="OCSPIdentifier" type="OCSPIdentifierType"/>
+			<xsd:element name="DigestAlgAndValue" type="DigestAlgAndValueType" minOccurs="0"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="OCSPIdentifierType">
+		<xsd:sequence>
+			<xsd:element name="ResponderID" type="xsd:string"/>
+			<xsd:element name="ProducedAt" type="xsd:dateTime"/>
+		</xsd:sequence>
+		<xsd:attribute name="URI" type="xsd:anyURI" use="optional"/>
+	</xsd:complexType>
+	<xsd:complexType name="OtherCertStatusRefsType">
+		<xsd:sequence>
+			<xsd:element name="OtherRef" type="AnyType" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="SigAndRefsTimeStamp" type="TimeStampType"/>
+	<xsd:element name="RefsOnlyTimeStamp" type="TimeStampType"/>
+	<xsd:element name="CertificateValues" type="CertificateValuesType"/>
+	<xsd:complexType name="CertificateValuesType">
+		<xsd:choice minOccurs="0" maxOccurs="unbounded">
+			<xsd:element name="EncapsulatedX509Certificate" type="EncapsulatedPKIDataType"/>
+			<xsd:element name="OtherCertificate" type="AnyType"/>
+		</xsd:choice>
+		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
+	</xsd:complexType>
+	<xsd:element name="RevocationValues" type="RevocationValuesType"/>
+	<xsd:complexType name="RevocationValuesType">
+		<xsd:sequence>
+			<xsd:element name="CRLValues" type="CRLValuesType" minOccurs="0"/>
+			<xsd:element name="OCSPValues" type="OCSPValuesType" minOccurs="0"/>
+			<xsd:element name="OtherValues" type="OtherCertStatusValuesType" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
+	</xsd:complexType>
+	<xsd:complexType name="CRLValuesType">
+		<xsd:sequence>
+			<xsd:element name="EncapsulatedCRLValue" type="EncapsulatedPKIDataType" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="OCSPValuesType">
+		<xsd:sequence>
+			<xsd:element name="EncapsulatedOCSPValue" type="EncapsulatedPKIDataType" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="OtherCertStatusValuesType">
+		<xsd:sequence>
+			<xsd:element name="OtherValue" type="AnyType" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:element name="ArchiveTimeStamp" type="TimeStampType"/>
+</xsd:schema>
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties	Mon Apr 14 11:34:15 2008 -0700
@@ -1,123 +1,123 @@
-algorithm.alreadyRegistered = URI {0} already assigned to class {1}
-algorithm.classDoesNotExist = Cannot register URI {0} to class {1} because this class does not exist in CLASSPATH
-algorithm.ClassDoesNotExist = Class {0} does not exist
-algorithm.extendsWrongClass = Cannot register URI {0} to class {1} because it does not extend {2}
-algorithms.CannotUseAlgorithmParameterSpecOnDSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating DSA signatures.
-algorithms.CannotUseAlgorithmParameterSpecOnRSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating RSA signatures.
-algorithms.CannotUseSecureRandomOnMAC = Sorry, but you cannot use a SecureRandom object for creating MACs.
-algorithms.HMACOutputLengthOnlyForHMAC = A HMACOutputLength can only be specified for HMAC integrity algorithms
-algorithms.NoSuchAlgorithm = The requested algorithm {0} does not exist. Original Message was: {1}
-algorithms.NoSuchMap = The algorithm URI "{0}" could not be mapped to a JCE algorithm
-algorithms.NoSuchProvider = The specified Provider {0} does not exist. Original Message was: {1}
-algorithms.operationOnlyVerification = A public key can only used for verification of a signature.
-algorithms.WrongKeyForThisOperation = Sorry, you supplied the wrong key type for this operation! You supplied a {0} but a {1} is needed.
-attributeValueIllegal = The attribute {0} has value {1} but must be {2}
-c14n.Canonicalizer.Exception = Exception during Canonicalization:  Original Message was {0}
-c14n.Canonicalizer.IllegalNode = Illegal node type {0}, node name was {1}
-c14n.Canonicalizer.NoSuchCanonicalizer = No canonicalizer found with URI {0}
-c14n.Canonicalizer.ParserConfigurationException = ParserConfigurationException during Canonicalization:  Original Message was {0}
-c14n.Canonicalizer.RelativeNamespace = Element {0} has a relative namespace: {1}="{2}"
-c14n.Canonicalizer.SAXException = SAXException during Canonicalization:  Original Message was {0}
-c14n.Canonicalizer.TraversalNotSupported = This DOM document does not support Traversal {0}
-c14n.Canonicalizer.UnsupportedEncoding = Unsupported encoding {0}
-c14n.Canonicalizer.UnsupportedOperation = This canonicalizer does not support this operation
-c14n.XMLUtils.circumventBug2650forgotten = The tree has not been prepared for canonicalization using XMLUtils#circumventBug2650(Document)
-certificate.noSki.lowVersion = Certificate cannot contain a SubjectKeyIdentifier because it is only X509v{0}
-certificate.noSki.notOctetString = Certificates SubjectKeyIdentifier is not a OctetString
-certificate.noSki.null = Certificate does not contain a SubjectKeyIdentifier
-defaultNamespaceCannotBeSetHere = Default namespace cannot be set here
-ElementProxy.nullElement = Cannot create an ElementProxy from a null argument
-empty = {0}
-encryption.algorithmCannotBeUsedForEncryptedData = encryption.algorithmCannotBeUsedForEncryptedData {0}
-encryption.algorithmCannotEatInitParams = encryption.algorithmCannotEatInitParams
-encryption.algorithmCannotEncryptDecrypt = encryption.algorithmCannotEncryptDecrypt
-encryption.algorithmCannotWrapUnWrap = encryption.algorithmCannotWrapUnWrap
-encryption.ExplicitKeySizeMismatch = The xenc:KeySize element requests a key size of {0} bit but the algorithm implements {1} bit
-encryption.nonceLongerThanDecryptedPlaintext = The given nonce is longer than the available plaintext. I Cannot strip away this.
-encryption.RSAOAEP.dataHashWrong = data hash wrong
-encryption.RSAOAEP.dataStartWrong = data wrong start {0}
-encryption.RSAOAEP.dataTooShort = data too short
-encryption.RSAPKCS15.blockTruncated = block truncated
-encryption.RSAPKCS15.noDataInBlock = no data in block
-encryption.RSAPKCS15.unknownBlockType = unknown block type
-encryption.nokey = No Key Encryption Key loaded and cannot determine using key resolvers
-endorsed.jdk1.4.0 = Since it seems that nobody reads our installation notes, we must do it in the exception messages. Hope you read them. You did NOT use the endorsed mechanism from JDK 1.4 properly; look at <http://xml.apache.org/security/Java/installation.html> how to solve this problem.
-errorMessages.InvalidDigestValueException = INVALID signature -- check reference resolution.
-errorMessages.InvalidSignatureValueException = INVALID signature -- core validation failed.
-errorMessages.IOException = Other file I/O and similar exceptions.
-errorMessages.MissingKeyFailureException = Cannot verify because of missing public key. Provide it via addResource and try again.
-errorMessages.MissingResourceFailureException = Cannot verify because of unresolved references. Provide it via addResource and try again.
-errorMessages.NoSuchAlgorithmException = Unknown Algorithm {0}
-errorMessages.NotYetImplementedException = Functionality not yet there.
-errorMessages.XMLSignatureException = Verification failed for some other reason.
-decoding.divisible.four = It should be divisible by four
-decoding.general = Error while decoding
-FileKeyStorageImpl.addToDefaultFromRemoteNotImplemented = Method addToDefaultFromRemote() not yet implemented.
-FileKeyStorageImpl.NoCert.Context = Not found such a X509Certificate including context {0}
-FileKeyStorageImpl.NoCert.IssNameSerNo = Not found such a X509Certificate with IssuerName {0} and serial number {1}
-FileKeyStorageImpl.NoCert.SubjName = Not found such a X509Certificate including SubjectName {0}
-generic.dontHaveConstructionElement = I do not have a construction Element
-generic.EmptyMessage = {0}
-generic.NotYetImplemented = {0} Not YET implemented ;-((
-java.security.InvalidKeyException = Invalid key
-java.security.NoSuchProviderException = Unknown or unsupported provider
-java.security.UnknownKeyType = Unknown or unsupported key type {0}
-KeyInfo.needKeyResolver = More than one keyResovler have to be registered
-KeyInfo.nokey = Cannot get key from {0}
-KeyInfo.noKey = Cannot get the public key
-KeyInfo.wrongNumberOfObject = Need {0} keyObjects
-KeyInfo.wrongUse = This object was made for getting {0}
-keyResolver.alreadyRegistered = {1} class has already been registered for {0}
-KeyResolver.needStorageResolver = Need a StorageResolver to retrieve a Certificate from a {0}
-KeyResoverSpiImpl.cannotGetCert = Cannot get the Certificate that include or in {1} in implement class {0}
-KeyResoverSpiImpl.elementGeneration = Cannot make {1} element in implement class {0}
-KeyResoverSpiImpl.getPoublicKey = Cannot get the public key from implement class {0}
-KeyResoverSpiImpl.InvalidElement = Cannot set (2) Element in implement class {0}
-KeyResoverSpiImpl.keyStore = KeyStorage error in implement class {0}
-KeyResoverSpiImpl.need.Element = {1} type of Element is needed in implement class {0}
-KeyResoverSpiImpl.wrongCRLElement = Cannot make CRL from {1} in implement class {0}
-KeyResoverSpiImpl.wrongKeyObject =  Need {1} type of KeyObject for generation Element in implement class{0}
-KeyResoverSpiImpl.wrongNumberOfObject = Need {1} keyObject in implement class {0}
-KeyStore.alreadyRegistered = {0} Class has already been registered for {1}
-KeyStore.register = {1} type class register error  in class {0}
-KeyStore.registerStore.register = Registeration error for type {0}
-KeyValue.IllegalArgument = Cannot create a {0} from {1}
-namespacePrefixAlreadyUsedByOtherURI = Namespace prefix {0} already used by other URI {1}
-notYetInitialized = The module {0} is not yet initialized
-prefix.AlreadyAssigned = You want to assign {0} as prefix for namespace {1} but it is already assigned for {2}
-signature.Canonicalizer.UnknownCanonicalizer = Unknown canonicalizer. No handler installed for URI {0}
-signature.DSA.invalidFormat = Invalid ASN.1 encoding of the DSA signature
-signature.Generation.signBeforeGetValue = You have to XMLSignature.sign(java.security.PrivateKey) first
-signature.signaturePropertyHasNoTarget = The Target attribute of the SignatureProperty must be set
-signature.Transform.ErrorDuringTransform = A {1} was thrown during the {0} transform
-signature.Transform.NotYetImplemented = Transform {0} not yet implemented
-signature.Transform.NullPointerTransform = Null pointer as URI. Programming bug?
-signature.Transform.UnknownTransform = Unknown transformation. No handler installed for URI {0}
-signature.Transform.node = Current Node: {0}
-signature.Transform.nodeAndType = Current Node: {0}, type: {1} 
-signature.Util.BignumNonPositive = bigInteger.signum() must be positive
-signature.Util.NonTextNode = Not a text node
-signature.Util.TooManyChilds = Too many childs of Type {0} in {1}
-signature.Verification.certificateError = Certificate error
-signature.Verification.IndexOutOfBounds = Index {0} illegal. We only have {1} References
-signature.Verification.internalError = Internal error
-signature.Verification.InvalidDigestOrReference = Invalid digest of reference {0}
-signature.Verification.keyStore = KeyStore error
-signature.Verification.MissingID = Cannot resolve element with ID {0}
-signature.Verification.MissingResources = Cannot resolve external resource {0}
-signature.Verification.NoSignatureElement = Input document contains no {0} Element in namespace {1}
-signature.Verification.Reference.NoInput = The Reference for URI {0} has no XMLSignatureInput
-signature.Verification.SignatureError = Signature error
-signature.XMLSignatureInput.MissingConstuctor = Cannot construct a XMLSignatureInput from class {0}
-signature.XMLSignatureInput.SerializeDOM = Input initialized with DOM Element. Use Canonicalization to serialize it
-signature.XMLSignatureInput.nodesetReference = Unable to convert to nodeset the reference
-transform.Init.IllegalContextArgument = Invalid context argument of class {0}. Must be String, org.w3c.dom.NodeList or java.io.InputStream.
-transform.init.NotInitialized =
-transform.init.wrongURI = Initialized with wrong URI. How could this happen? We implement {0} but {1} was used during initialization
-utils.Base64.IllegalBitlength = Illegal byte length; Data to be decoded must be a multiple of 4
-Base64Decoding = Error while decoding
-utils.resolver.noClass = Could not find a resolver for URI {0} and Base {1}
-xml.WrongContent = Cannot find {0} in {1}
-xml.WrongElement = Cannot create a {0} from a {1} element
-xpath.funcHere.documentsDiffer = The XPath is not in the same document as the context node
-xpath.funcHere.noXPathContext = Try to evaluate an XPath which uses the here() function but XPath is not inside an ds:XPath Element. XPath was : {0}
+algorithm.alreadyRegistered = URI {0} already assigned to class {1}
+algorithm.classDoesNotExist = Cannot register URI {0} to class {1} because this class does not exist in CLASSPATH
+algorithm.ClassDoesNotExist = Class {0} does not exist
+algorithm.extendsWrongClass = Cannot register URI {0} to class {1} because it does not extend {2}
+algorithms.CannotUseAlgorithmParameterSpecOnDSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating DSA signatures.
+algorithms.CannotUseAlgorithmParameterSpecOnRSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating RSA signatures.
+algorithms.CannotUseSecureRandomOnMAC = Sorry, but you cannot use a SecureRandom object for creating MACs.
+algorithms.HMACOutputLengthOnlyForHMAC = A HMACOutputLength can only be specified for HMAC integrity algorithms
+algorithms.NoSuchAlgorithm = The requested algorithm {0} does not exist. Original Message was: {1}
+algorithms.NoSuchMap = The algorithm URI "{0}" could not be mapped to a JCE algorithm
+algorithms.NoSuchProvider = The specified Provider {0} does not exist. Original Message was: {1}
+algorithms.operationOnlyVerification = A public key can only used for verification of a signature.
+algorithms.WrongKeyForThisOperation = Sorry, you supplied the wrong key type for this operation! You supplied a {0} but a {1} is needed.
+attributeValueIllegal = The attribute {0} has value {1} but must be {2}
+c14n.Canonicalizer.Exception = Exception during Canonicalization:  Original Message was {0}
+c14n.Canonicalizer.IllegalNode = Illegal node type {0}, node name was {1}
+c14n.Canonicalizer.NoSuchCanonicalizer = No canonicalizer found with URI {0}
+c14n.Canonicalizer.ParserConfigurationException = ParserConfigurationException during Canonicalization:  Original Message was {0}
+c14n.Canonicalizer.RelativeNamespace = Element {0} has a relative namespace: {1}="{2}"
+c14n.Canonicalizer.SAXException = SAXException during Canonicalization:  Original Message was {0}
+c14n.Canonicalizer.TraversalNotSupported = This DOM document does not support Traversal {0}
+c14n.Canonicalizer.UnsupportedEncoding = Unsupported encoding {0}
+c14n.Canonicalizer.UnsupportedOperation = This canonicalizer does not support this operation
+c14n.XMLUtils.circumventBug2650forgotten = The tree has not been prepared for canonicalization using XMLUtils#circumventBug2650(Document)
+certificate.noSki.lowVersion = Certificate cannot contain a SubjectKeyIdentifier because it is only X509v{0}
+certificate.noSki.notOctetString = Certificates SubjectKeyIdentifier is not a OctetString
+certificate.noSki.null = Certificate does not contain a SubjectKeyIdentifier
+defaultNamespaceCannotBeSetHere = Default namespace cannot be set here
+ElementProxy.nullElement = Cannot create an ElementProxy from a null argument
+empty = {0}
+encryption.algorithmCannotBeUsedForEncryptedData = encryption.algorithmCannotBeUsedForEncryptedData {0}
+encryption.algorithmCannotEatInitParams = encryption.algorithmCannotEatInitParams
+encryption.algorithmCannotEncryptDecrypt = encryption.algorithmCannotEncryptDecrypt
+encryption.algorithmCannotWrapUnWrap = encryption.algorithmCannotWrapUnWrap
+encryption.ExplicitKeySizeMismatch = The xenc:KeySize element requests a key size of {0} bit but the algorithm implements {1} bit
+encryption.nonceLongerThanDecryptedPlaintext = The given nonce is longer than the available plaintext. I Cannot strip away this.
+encryption.RSAOAEP.dataHashWrong = data hash wrong
+encryption.RSAOAEP.dataStartWrong = data wrong start {0}
+encryption.RSAOAEP.dataTooShort = data too short
+encryption.RSAPKCS15.blockTruncated = block truncated
+encryption.RSAPKCS15.noDataInBlock = no data in block
+encryption.RSAPKCS15.unknownBlockType = unknown block type
+encryption.nokey = No Key Encryption Key loaded and cannot determine using key resolvers
+endorsed.jdk1.4.0 = Since it seems that nobody reads our installation notes, we must do it in the exception messages. Hope you read them. You did NOT use the endorsed mechanism from JDK 1.4 properly; look at <http://xml.apache.org/security/Java/installation.html> how to solve this problem.
+errorMessages.InvalidDigestValueException = INVALID signature -- check reference resolution.
+errorMessages.InvalidSignatureValueException = INVALID signature -- core validation failed.
+errorMessages.IOException = Other file I/O and similar exceptions.
+errorMessages.MissingKeyFailureException = Cannot verify because of missing public key. Provide it via addResource and try again.
+errorMessages.MissingResourceFailureException = Cannot verify because of unresolved references. Provide it via addResource and try again.
+errorMessages.NoSuchAlgorithmException = Unknown Algorithm {0}
+errorMessages.NotYetImplementedException = Functionality not yet there.
+errorMessages.XMLSignatureException = Verification failed for some other reason.
+decoding.divisible.four = It should be divisible by four
+decoding.general = Error while decoding
+FileKeyStorageImpl.addToDefaultFromRemoteNotImplemented = Method addToDefaultFromRemote() not yet implemented.
+FileKeyStorageImpl.NoCert.Context = Not found such a X509Certificate including context {0}
+FileKeyStorageImpl.NoCert.IssNameSerNo = Not found such a X509Certificate with IssuerName {0} and serial number {1}
+FileKeyStorageImpl.NoCert.SubjName = Not found such a X509Certificate including SubjectName {0}
+generic.dontHaveConstructionElement = I do not have a construction Element
+generic.EmptyMessage = {0}
+generic.NotYetImplemented = {0} Not YET implemented ;-((
+java.security.InvalidKeyException = Invalid key
+java.security.NoSuchProviderException = Unknown or unsupported provider
+java.security.UnknownKeyType = Unknown or unsupported key type {0}
+KeyInfo.needKeyResolver = More than one keyResovler have to be registered
+KeyInfo.nokey = Cannot get key from {0}
+KeyInfo.noKey = Cannot get the public key
+KeyInfo.wrongNumberOfObject = Need {0} keyObjects
+KeyInfo.wrongUse = This object was made for getting {0}
+keyResolver.alreadyRegistered = {1} class has already been registered for {0}
+KeyResolver.needStorageResolver = Need a StorageResolver to retrieve a Certificate from a {0}
+KeyResoverSpiImpl.cannotGetCert = Cannot get the Certificate that include or in {1} in implement class {0}
+KeyResoverSpiImpl.elementGeneration = Cannot make {1} element in implement class {0}
+KeyResoverSpiImpl.getPoublicKey = Cannot get the public key from implement class {0}
+KeyResoverSpiImpl.InvalidElement = Cannot set (2) Element in implement class {0}
+KeyResoverSpiImpl.keyStore = KeyStorage error in implement class {0}
+KeyResoverSpiImpl.need.Element = {1} type of Element is needed in implement class {0}
+KeyResoverSpiImpl.wrongCRLElement = Cannot make CRL from {1} in implement class {0}
+KeyResoverSpiImpl.wrongKeyObject =  Need {1} type of KeyObject for generation Element in implement class{0}
+KeyResoverSpiImpl.wrongNumberOfObject = Need {1} keyObject in implement class {0}
+KeyStore.alreadyRegistered = {0} Class has already been registered for {1}
+KeyStore.register = {1} type class register error  in class {0}
+KeyStore.registerStore.register = Registeration error for type {0}
+KeyValue.IllegalArgument = Cannot create a {0} from {1}
+namespacePrefixAlreadyUsedByOtherURI = Namespace prefix {0} already used by other URI {1}
+notYetInitialized = The module {0} is not yet initialized
+prefix.AlreadyAssigned = You want to assign {0} as prefix for namespace {1} but it is already assigned for {2}
+signature.Canonicalizer.UnknownCanonicalizer = Unknown canonicalizer. No handler installed for URI {0}
+signature.DSA.invalidFormat = Invalid ASN.1 encoding of the DSA signature
+signature.Generation.signBeforeGetValue = You have to XMLSignature.sign(java.security.PrivateKey) first
+signature.signaturePropertyHasNoTarget = The Target attribute of the SignatureProperty must be set
+signature.Transform.ErrorDuringTransform = A {1} was thrown during the {0} transform
+signature.Transform.NotYetImplemented = Transform {0} not yet implemented
+signature.Transform.NullPointerTransform = Null pointer as URI. Programming bug?
+signature.Transform.UnknownTransform = Unknown transformation. No handler installed for URI {0}
+signature.Transform.node = Current Node: {0}
+signature.Transform.nodeAndType = Current Node: {0}, type: {1} 
+signature.Util.BignumNonPositive = bigInteger.signum() must be positive
+signature.Util.NonTextNode = Not a text node
+signature.Util.TooManyChilds = Too many childs of Type {0} in {1}
+signature.Verification.certificateError = Certificate error
+signature.Verification.IndexOutOfBounds = Index {0} illegal. We only have {1} References
+signature.Verification.internalError = Internal error
+signature.Verification.InvalidDigestOrReference = Invalid digest of reference {0}
+signature.Verification.keyStore = KeyStore error
+signature.Verification.MissingID = Cannot resolve element with ID {0}
+signature.Verification.MissingResources = Cannot resolve external resource {0}
+signature.Verification.NoSignatureElement = Input document contains no {0} Element in namespace {1}
+signature.Verification.Reference.NoInput = The Reference for URI {0} has no XMLSignatureInput
+signature.Verification.SignatureError = Signature error
+signature.XMLSignatureInput.MissingConstuctor = Cannot construct a XMLSignatureInput from class {0}
+signature.XMLSignatureInput.SerializeDOM = Input initialized with DOM Element. Use Canonicalization to serialize it
+signature.XMLSignatureInput.nodesetReference = Unable to convert to nodeset the reference
+transform.Init.IllegalContextArgument = Invalid context argument of class {0}. Must be String, org.w3c.dom.NodeList or java.io.InputStream.
+transform.init.NotInitialized =
+transform.init.wrongURI = Initialized with wrong URI. How could this happen? We implement {0} but {1} was used during initialization
+utils.Base64.IllegalBitlength = Illegal byte length; Data to be decoded must be a multiple of 4
+Base64Decoding = Error while decoding
+utils.resolver.noClass = Could not find a resolver for URI {0} and Base {1}
+xml.WrongContent = Cannot find {0} in {1}
+xml.WrongElement = Cannot create a {0} from a {1} element
+xpath.funcHere.documentsDiffer = The XPath is not in the same document as the context node
+xpath.funcHere.noXPathContext = Try to evaluate an XPath which uses the here() function but XPath is not inside an ds:XPath Element. XPath was : {0}
--- a/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpec.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpec.java	Mon Apr 14 11:34:15 2008 -0700
@@ -91,9 +91,7 @@
 
     void attemptImmediateResolve(VirtualMachine vm) {
         // try to resolve immediately
-        Iterator iter = vm.allClasses().iterator();
-        while (iter.hasNext()) {
-            ReferenceType refType = (ReferenceType)iter.next();
+        for (ReferenceType refType : vm.allClasses()) {
             if (refSpec.matches(refType)) {
                 try {
                     resolve(refType);
--- a/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpecList.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpecList.java	Mon Apr 14 11:34:15 2008 -0700
@@ -47,9 +47,8 @@
      */
     void resolve(ReferenceType refType) {
         synchronized(eventRequestSpecs) {
-            Iterator iter = eventRequestSpecs.iterator();
-            while (iter.hasNext()) {
-                ((EventRequestSpec)iter.next()).attemptResolve(refType);
+            for (EventRequestSpec spec : eventRequestSpecs) {
+                spec.attemptResolve(refType);
              }
         }
     }
@@ -79,7 +78,7 @@
 
     BreakpointSpec
     createMethodBreakpoint(String classPattern,
-                           String methodId, List methodArgs) {
+                           String methodId, List<String> methodArgs) {
         ReferenceTypeSpec refSpec =
             new PatternReferenceTypeSpec(classPattern);
         return new MethodBreakpointSpec(this, refSpec,
@@ -132,47 +131,48 @@
 
     // --------  notify routines --------------------
 
-    private Vector specListeners() {
-        return (Vector)runtime.specListeners.clone();
+    @SuppressWarnings("unchecked")
+    private Vector<SpecListener> specListeners() {
+        return (Vector<SpecListener>)runtime.specListeners.clone();
     }
 
     void notifySet(EventRequestSpec spec) {
-        Vector l = specListeners();
+        Vector<SpecListener> l = specListeners();
         SpecEvent evt = new SpecEvent(spec);
         for (int i = 0; i < l.size(); i++) {
-            spec.notifySet((SpecListener)l.elementAt(i), evt);
+            spec.notifySet(l.elementAt(i), evt);
         }
     }
 
     void notifyDeferred(EventRequestSpec spec) {
-        Vector l = specListeners();
+        Vector<SpecListener> l = specListeners();
         SpecEvent evt = new SpecEvent(spec);
         for (int i = 0; i < l.size(); i++) {
-            spec.notifyDeferred((SpecListener)l.elementAt(i), evt);
+            spec.notifyDeferred(l.elementAt(i), evt);
         }
     }
 
     void notifyDeleted(EventRequestSpec spec) {
-        Vector l = specListeners();
+        Vector<SpecListener> l = specListeners();
         SpecEvent evt = new SpecEvent(spec);
         for (int i = 0; i < l.size(); i++) {
-            spec.notifyDeleted((SpecListener)l.elementAt(i), evt);
+            spec.notifyDeleted(l.elementAt(i), evt);
         }
     }
 
     void notifyResolved(EventRequestSpec spec) {
-        Vector l = specListeners();
+        Vector<SpecListener> l = specListeners();
         SpecEvent evt = new SpecEvent(spec);
         for (int i = 0; i < l.size(); i++) {
-            spec.notifyResolved((SpecListener)l.elementAt(i), evt);
+            spec.notifyResolved(l.elementAt(i), evt);
         }
     }
 
     void notifyError(EventRequestSpec spec, Exception exc) {
-        Vector l = specListeners();
+        Vector<SpecListener> l = specListeners();
         SpecErrorEvent evt = new SpecErrorEvent(spec, exc);
         for (int i = 0; i < l.size(); i++) {
-            spec.notifyError((SpecListener)l.elementAt(i), evt);
+            spec.notifyError(l.elementAt(i), evt);
         }
     }
 }
--- a/src/share/classes/com/sun/tools/example/debug/bdi/ExecutionManager.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/bdi/ExecutionManager.java	Mon Apr 14 11:34:15 2008 -0700
@@ -232,10 +232,7 @@
         if (pattern.startsWith("*.")) {
             // Wildcard matches any leading package name.
             pattern = pattern.substring(1);
-            List classes = vm().allClasses();
-            Iterator iter = classes.iterator();
-            while (iter.hasNext()) {
-                ReferenceType type = ((ReferenceType)iter.next());
+            for (ReferenceType type : vm().allClasses()) {
                 if (type.name().endsWith(pattern)) {
                     result.add(type);
                 }
@@ -278,7 +275,7 @@
     public ThreadGroupReference systemThreadGroup()
                                                 throws NoSessionException {
         ensureActiveSession();
-        return (ThreadGroupReference)vm().topLevelThreadGroups().get(0);
+        return vm().topLevelThreadGroups().get(0);
     }
 
     /*
@@ -349,10 +346,9 @@
          * attach sessions.
          */
         VirtualMachineManager mgr = Bootstrap.virtualMachineManager();
-        List connectors = mgr.attachingConnectors();
-        AttachingConnector connector = (AttachingConnector)connectors.get(0);
+        AttachingConnector connector = mgr.attachingConnectors().get(0);
         Map<String, Connector.Argument> arguments = connector.defaultArguments();
-        ((Connector.Argument)arguments.get("port")).setValue(portName);
+        arguments.get("port").setValue(portName);
 
         Session newSession = internalAttach(connector, arguments);
         if (newSession != null) {
@@ -504,10 +500,7 @@
          * if so, it gets removed here.
          */
          EventRequestManager mgr = vm().eventRequestManager();
-         List requests = mgr.stepRequests();
-         Iterator iter = requests.iterator();
-         while (iter.hasNext()) {
-             StepRequest request = (StepRequest)iter.next();
+         for (StepRequest request : mgr.stepRequests()) {
              if (request.thread().equals(thread)) {
                  mgr.deleteEventRequest(request);
                  break;
@@ -591,7 +584,7 @@
         if (session == null || thread == null) {
             return null;
         }
-        ThreadInfo info = (ThreadInfo)threadInfoMap.get(thread);
+        ThreadInfo info = threadInfoMap.get(thread);
         if (info == null) {
             //### Should not hardcode initial frame count and prefetch here!
             //info = new ThreadInfo(thread, 10, 10);
@@ -607,24 +600,22 @@
 
      void validateThreadInfo() {
         session.interrupted = true;
-        Iterator iter = threadInfoList.iterator();
-            while (iter.hasNext()) {
-                ((ThreadInfo)iter.next()).validate();
+        for (ThreadInfo threadInfo : threadInfoList) {
+            threadInfo.validate();
             }
     }
 
     private void invalidateThreadInfo() {
         if (session != null) {
             session.interrupted = false;
-            Iterator iter = threadInfoList.iterator();
-            while (iter.hasNext()) {
-                ((ThreadInfo)iter.next()).invalidate();
+            for (ThreadInfo threadInfo : threadInfoList) {
+                threadInfo.invalidate();
             }
         }
     }
 
     void removeThreadInfo(ThreadReference thread) {
-        ThreadInfo info = (ThreadInfo)threadInfoMap.get(thread);
+        ThreadInfo info = threadInfoMap.get(thread);
         if (info != null) {
             info.invalidate();
             threadInfoMap.remove(thread);
@@ -702,7 +693,7 @@
                         while (inputBuffer.size() < 1) {
                             inputLock.wait();
                         }
-                        line = (String)inputBuffer.removeLast();
+                        line = inputBuffer.removeLast();
                     } catch (InterruptedException e) {}
                 }
             }
@@ -774,7 +765,7 @@
 
     public BreakpointSpec
     createMethodBreakpoint(String classPattern,
-                           String methodId, List methodArgs) {
+                           String methodId, List<String> methodArgs) {
         return specList.createMethodBreakpoint(classPattern,
                                                  methodId, methodArgs);
     }
@@ -811,7 +802,7 @@
         specList.install(spec, vm());
     }
 
-    public List eventRequestSpecs() {
+    public List<EventRequestSpec> eventRequestSpecs() {
         return specList.eventRequestSpecs();
     }
 }
--- a/src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java	Mon Apr 14 11:34:15 2008 -0700
@@ -82,9 +82,7 @@
                 boolean interrupted = es.suspendedAll();
                 es.notify(firstListener);
                 boolean wantInterrupt = JDIEventSource.this.wantInterrupt;
-                for (Iterator it = session.runtime.jdiListeners.iterator();
-                     it.hasNext(); ) {
-                    JDIListener jl = (JDIListener)it.next();
+                for (JDIListener jl : session.runtime.jdiListeners) {
                     es.notify(jl);
                 }
                 if (interrupted && !wantInterrupt) {
--- a/src/share/classes/com/sun/tools/example/debug/bdi/LineBreakpointSpec.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/bdi/LineBreakpointSpec.java	Mon Apr 14 11:34:15 2008 -0700
@@ -58,12 +58,12 @@
                                             LineNotFoundException {
         Location location = null;
         try {
-            List locs = clazz.locationsOfLine(lineNumber());
+            List<Location> locs = clazz.locationsOfLine(lineNumber());
             if (locs.size() == 0) {
                 throw new LineNotFoundException();
             }
             // TODO handle multiple locations
-            location = (Location)locs.get(0);
+            location = locs.get(0);
             if (location.method() == null) {
                 throw new LineNotFoundException();
             }
--- a/src/share/classes/com/sun/tools/example/debug/bdi/MethodBreakpointSpec.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/bdi/MethodBreakpointSpec.java	Mon Apr 14 11:34:15 2008 -0700
@@ -34,11 +34,11 @@
 
 public class MethodBreakpointSpec extends BreakpointSpec {
     String methodId;
-    List methodArgs;
+    List<String> methodArgs;
 
     MethodBreakpointSpec(EventRequestSpecList specs,
                          ReferenceTypeSpec refSpec,
-                         String methodId, List methodArgs) {
+                         String methodId, List<String> methodArgs) {
         super(specs, refSpec);
         this.methodId = methodId;
         this.methodArgs = methodArgs;
@@ -76,7 +76,7 @@
         return methodId;
     }
 
-    public List methodArgs() {
+    public List<String> methodArgs() {
         return methodArgs;
     }
 
@@ -120,14 +120,13 @@
         buffer.append('.');
         buffer.append(methodId);
         if (methodArgs != null) {
-            Iterator iter = methodArgs.iterator();
             boolean first = true;
             buffer.append('(');
-            while (iter.hasNext()) {
+            for (String name : methodArgs) {
                 if (!first) {
                     buffer.append(',');
                 }
-                buffer.append((String)iter.next());
+                buffer.append(name);
                 first = false;
             }
             buffer.append(")");
@@ -151,8 +150,8 @@
      * and if the number of arguments in the method matches the
      * number of names passed
      */
-    private boolean compareArgTypes(Method method, List nameList) {
-        List argTypeNames = method.argumentTypeNames();
+    private boolean compareArgTypes(Method method, List<String> nameList) {
+        List<String> argTypeNames = method.argumentTypeNames();
 
         // If argument counts differ, we can stop here
         if (argTypeNames.size() != nameList.size()) {
@@ -162,8 +161,8 @@
         // Compare each argument type's name
         int nTypes = argTypeNames.size();
         for (int i = 0; i < nTypes; ++i) {
-            String comp1 = (String)argTypeNames.get(i);
-            String comp2 = (String)nameList.get(i);
+            String comp1 = argTypeNames.get(i);
+            String comp2 = nameList.get(i);
             if (! comp1.equals(comp2)) {
                 /*
                  * We have to handle varargs.  EG, the
@@ -288,22 +287,17 @@
         List<String> argTypeNames = null;
         if (methodArgs() != null) {
             argTypeNames = new ArrayList<String>(methodArgs().size());
-            Iterator iter = methodArgs().iterator();
-            while (iter.hasNext()) {
-                String name = (String)iter.next();
+            for (String name : methodArgs()) {
                 name = normalizeArgTypeName(name);
                 argTypeNames.add(name);
             }
         }
 
         // Check each method in the class for matches
-        Iterator iter = clazz.methods().iterator();
         Method firstMatch = null;  // first method with matching name
         Method exactMatch = null;  // (only) method with same name & sig
         int matchCount = 0;        // > 1 implies overload
-        while (iter.hasNext()) {
-            Method candidate = (Method)iter.next();
-
+        for (Method candidate : clazz.methods()) {
             if (candidate.name().equals(methodName())) {
                 matchCount++;
 
--- a/src/share/classes/com/sun/tools/example/debug/bdi/ThreadGroupIterator.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/bdi/ThreadGroupIterator.java	Mon Apr 14 11:34:15 2008 -0700
@@ -36,7 +36,7 @@
  * Descend the tree of thread groups.
  * @author Robert G. Field
  */
-public class ThreadGroupIterator implements Iterator {
+public class ThreadGroupIterator implements Iterator<ThreadGroupReference> {
     private final Stack<Iterator<ThreadGroupReference>> stack
                         = new Stack<Iterator<ThreadGroupReference>>();
 
@@ -56,8 +56,8 @@
     }
 */
 
-    private Iterator top() {
-        return (Iterator)stack.peek();
+    private Iterator<ThreadGroupReference> top() {
+        return stack.peek();
     }
 
     /**
@@ -77,12 +77,12 @@
         return !stack.isEmpty();
     }
 
-    public Object next() {
+    public ThreadGroupReference next() {
         return nextThreadGroup();
     }
 
     public ThreadGroupReference nextThreadGroup() {
-        ThreadGroupReference tg = (ThreadGroupReference)top().next();
+        ThreadGroupReference tg = top().next();
         push(tg.threadGroups());
         return tg;
     }
--- a/src/share/classes/com/sun/tools/example/debug/bdi/ThreadIterator.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/bdi/ThreadIterator.java	Mon Apr 14 11:34:15 2008 -0700
@@ -30,8 +30,8 @@
 import java.util.List;
 import java.util.Iterator;
 
-public class ThreadIterator implements Iterator {
-    Iterator it = null;
+public class ThreadIterator implements Iterator<ThreadReference> {
+    Iterator<ThreadReference> it = null;
     ThreadGroupIterator tgi;
 
     public ThreadIterator(ThreadGroupReference tg) {
@@ -53,12 +53,12 @@
         return true;
     }
 
-    public Object next() {
+    public ThreadReference next() {
         return it.next();
     }
 
     public ThreadReference nextThread() {
-        return (ThreadReference)next();
+        return next();
     }
 
     public void remove() {
--- a/src/share/classes/com/sun/tools/example/debug/expr/LValue.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/expr/LValue.java	Mon Apr 14 11:34:15 2008 -0700
@@ -191,11 +191,12 @@
         return field;
     }
 
-    static List methodsByName(ReferenceType refType, String name, int kind) {
-        List list = refType.methodsByName(name);
-        Iterator iter = list.iterator();
+    static List<Method> methodsByName(ReferenceType refType,
+                                      String name, int kind) {
+        List<Method> list = refType.methodsByName(name);
+        Iterator<Method> iter = list.iterator();
         while (iter.hasNext()) {
-            Method method = (Method)iter.next();
+            Method method = iter.next();
             boolean isStatic = method.isStatic();
             if (((kind == STATIC) && !isStatic) ||
                 ((kind == INSTANCE) && isStatic)) {
@@ -231,21 +232,21 @@
      * argType is not assignable from the type of the argument value.
      * IE, one is an Apple and the other is an Orange.
      */
-    static int argumentsMatch(List argTypes, List arguments) {
+    static int argumentsMatch(List<Type> argTypes, List<Value> arguments) {
         if (argTypes.size() != arguments.size()) {
             return DIFFERENT;
         }
 
-        Iterator typeIter = argTypes.iterator();
-        Iterator valIter = arguments.iterator();
+        Iterator<Type> typeIter = argTypes.iterator();
+        Iterator<Value> valIter = arguments.iterator();
         int result = SAME;
 
         // If any pair aren't the same, change the
         // result to ASSIGNABLE.  If any pair aren't
         // assignable, return DIFFERENT
         while (typeIter.hasNext()) {
-            Type argType = (Type)typeIter.next();
-            Value value = (Value)valIter.next();
+            Type argType = typeIter.next();
+            Value value = valIter.next();
             if (value == null) {
                 // Null values can be passed to any non-primitive argument
                 if (primitiveTypeNames.contains(argType.name())) {
@@ -333,7 +334,7 @@
         if (fromType instanceof ArrayType) {
             return isArrayAssignableTo((ArrayType)fromType, toType);
         }
-        List interfaces;
+        List<InterfaceType> interfaces;
         if (fromType instanceof ClassType) {
             ClassType superclazz = ((ClassType)fromType).superclass();
             if ((superclazz != null) && isAssignableTo(superclazz, toType)) {
@@ -344,9 +345,7 @@
             // fromType must be an InterfaceType
             interfaces = ((InterfaceType)fromType).superinterfaces();
         }
-        Iterator iter = interfaces.iterator();
-        while (iter.hasNext()) {
-            InterfaceType interfaze = (InterfaceType)iter.next();
+        for (InterfaceType interfaze : interfaces) {
             if (isAssignableTo(interfaze, toType)) {
                 return true;
             }
@@ -354,7 +353,8 @@
         return false;
     }
 
-    static Method resolveOverload(List overloads, List arguments)
+    static Method resolveOverload(List<Method> overloads,
+                                  List<Value> arguments)
                                        throws ParseException {
 
         // If there is only one method to call, we'll just choose
@@ -362,7 +362,7 @@
         // the invoke will return a better error message than we
         // could generate here.
         if (overloads.size() == 1) {
-            return (Method)overloads.get(0);
+            return overloads.get(0);
         }
 
         // Resolving overloads is beyond the scope of this exercise.
@@ -374,12 +374,10 @@
         // methods to call. And, since casts aren't implemented,
         // the user can't use them to pick a particular overload to call.
         // IE, the user is out of luck in this case.
-        Iterator iter = overloads.iterator();
         Method retVal = null;
         int assignableCount = 0;
-        while (iter.hasNext()) {
-            Method mm = (Method)iter.next();
-            List argTypes;
+        for (Method mm : overloads) {
+            List<Type> argTypes;
             try {
                 argTypes = mm.argumentTypes();
             } catch (ClassNotLoadedException ee) {
@@ -443,7 +441,7 @@
         final ObjectReference obj;
         final ThreadReference thread;
         final Field matchingField;
-        final List overloads;
+        final List<Method> overloads;
         Method matchingMethod = null;
         List<Value> methodArguments = null;
 
@@ -510,7 +508,7 @@
         final ReferenceType refType;
         final ThreadReference thread;
         final Field matchingField;
-        final List overloads;
+        final List<Method> overloads;
         Method matchingMethod = null;
         List<Value> methodArguments = null;
 
@@ -765,7 +763,7 @@
     static LValue makeNewObject(VirtualMachine vm,
                                  ExpressionParser.GetFrame frameGetter,
                                 String className, List<Value> arguments) throws ParseException {
-        List classes = vm.classesByName(className);
+        List<ReferenceType> classes = vm.classesByName(className);
         if (classes.size() == 0) {
             throw new ParseException("No class named: " + className);
         }
@@ -774,7 +772,7 @@
             throw new ParseException("More than one class named: " +
                                      className);
         }
-        ReferenceType refType = (ReferenceType)classes.get(0);
+        ReferenceType refType = classes.get(0);
 
 
         if (!(refType instanceof ClassType)) {
@@ -784,9 +782,9 @@
 
         ClassType classType = (ClassType)refType;
         List<Method> methods = new ArrayList<Method>(classType.methods()); // writable
-        Iterator iter = methods.iterator();
+        Iterator<Method> iter = methods.iterator();
         while (iter.hasNext()) {
-            Method method = (Method)iter.next();
+            Method method = iter.next();
             if (!method.isConstructor()) {
                 iter.remove();
             }
@@ -858,13 +856,13 @@
                 }
                 // check for class name
                 while (izer.hasMoreTokens()) {
-                    List classes = vm.classesByName(first);
+                    List<ReferenceType> classes = vm.classesByName(first);
                     if (classes.size() > 0) {
                         if (classes.size() > 1) {
                             throw new ParseException("More than one class named: " +
                                                      first);
                         } else {
-                            ReferenceType refType = (ReferenceType)classes.get(0);
+                            ReferenceType refType = classes.get(0);
                             LValue lval = new LValueStaticMember(refType,
                                                             izer.nextToken(), thread);
                             return nFields(lval, izer, thread);
--- a/src/share/classes/com/sun/tools/example/debug/gui/ClassTreeTool.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/gui/ClassTreeTool.java	Mon Apr 14 11:34:15 2008 -0700
@@ -124,9 +124,7 @@
         public void sessionStart(EventObject e) {
             // Get system classes and any others loaded before attaching.
             try {
-                Iterator iter = runtime.allClasses().iterator();
-                while (iter.hasNext()) {
-                    ReferenceType type = ((ReferenceType)iter.next());
+                for (ReferenceType type : runtime.allClasses()) {
                     root.addClass(type);
                 }
             } catch (VMDisconnectedException ee) {
--- a/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java	Mon Apr 14 11:34:15 2008 -0700
@@ -77,7 +77,7 @@
             while (ti.hasNext()) {
                 tlist.add(ti.nextThread());
             }
-            threads = (ThreadReference[])tlist.toArray(new ThreadReference[tlist.size()]);
+            threads = tlist.toArray(new ThreadReference[tlist.size()]);
         }
         return threads;
     }
@@ -146,11 +146,9 @@
     // Command: classes
 
     private void commandClasses() throws NoSessionException {
-        List list = runtime.allClasses();
         OutputSink out = env.getOutputSink();
         //out.println("** classes list **");
-        for (int i = 0 ; i < list.size() ; i++) {
-            ReferenceType refType = (ReferenceType)list.get(i);
+        for (ReferenceType refType : runtime.allClasses()) {
             out.println(refType.name());
         }
         out.show();
@@ -167,16 +165,16 @@
         String idClass = t.nextToken();
         ReferenceType cls = findClass(idClass);
         if (cls != null) {
-            List methods = cls.allMethods();
+            List<Method> methods = cls.allMethods();
             OutputSink out = env.getOutputSink();
             for (int i = 0; i < methods.size(); i++) {
-                Method method = (Method)methods.get(i);
+                Method method = methods.get(i);
                 out.print(method.declaringType().name() + " " +
                             method.name() + "(");
-                Iterator it = method.argumentTypeNames().iterator();
+                Iterator<String> it = method.argumentTypeNames().iterator();
                 if (it.hasNext()) {
                     while (true) {
-                        out.print((String)it.next());
+                        out.print(it.next());
                         if (!it.hasNext()) {
                             break;
                         }
@@ -193,10 +191,10 @@
     }
 
     private ReferenceType findClass(String pattern) throws NoSessionException {
-        List results = runtime.findClassesMatchingPattern(pattern);
+        List<ReferenceType> results = runtime.findClassesMatchingPattern(pattern);
         if (results.size() > 0) {
             //### Should handle multiple results sensibly.
-            return (ReferenceType)results.get(0);
+            return results.get(0);
         }
         return null;
     }
@@ -235,11 +233,11 @@
 
     private int printThreadGroup(OutputSink out, ThreadGroupReference tg, int iThread) {
         out.println("Group " + tg.name() + ":");
-        List tlist = tg.threads();
+        List<ThreadReference> tlist = tg.threads();
         int maxId = 0;
         int maxName = 0;
         for (int i = 0 ; i < tlist.size() ; i++) {
-            ThreadReference thr = (ThreadReference)tlist.get(i);
+            ThreadReference thr = tlist.get(i);
             int len = Utils.description(thr).length();
             if (len > maxId)
                 maxId = len;
@@ -254,7 +252,7 @@
         String maxNumString = String.valueOf(iThread + tlist.size());
         int maxNumDigits = maxNumString.length();
         for (int i = 0 ; i < tlist.size() ; i++) {
-            ThreadReference thr = (ThreadReference)tlist.get(i);
+            ThreadReference thr = tlist.get(i);
             char buf[] = new char[80];
             for (int j = 0; j < 79; j++) {
                 buf[j] = ' ';
@@ -283,9 +281,7 @@
             sbOut.setLength(79);
             out.println(sbOut.toString());
         }
-        List tglist = tg.threadGroups();
-        for (int ig = 0; ig < tglist.size(); ig++) {
-            ThreadGroupReference tg0 = (ThreadGroupReference)tglist.get(ig);
+        for (ThreadGroupReference tg0 : tg.threadGroups()) {
             if (!tg.equals(tg0)) {  // TODO ref mgt
                 iThread += printThreadGroup(out, tg0, iThread + tlist.size());
             }
@@ -733,7 +729,7 @@
             if (token.toLowerCase().equals("all")) {
                 ThreadIterator it = allThreads();
                 while (it.hasNext()) {
-                    ThreadReference thread = (ThreadReference)it.next();
+                    ThreadReference thread = it.next();
                     out.println(thread.name() + ": ");
                     dumpStack(thread, showPC);
                 }
@@ -755,7 +751,7 @@
         //env.failure("Target VM must be in interrupted state.");
         //env.failure("Current thread isn't suspended.");
         //### Should handle extremely long stack traces sensibly for user.
-        List stack = null;
+        List<StackFrame> stack = null;
         try {
             stack = thread.frames();
         } catch (IncompatibleThreadStateException e) {
@@ -772,7 +768,7 @@
             OutputSink out = env.getOutputSink();
             int nFrames = stack.size();
             for (int i = frameIndex; i < nFrames; i++) {
-                StackFrame frame = (StackFrame)stack.get(i);
+                StackFrame frame = stack.get(i);
                 Location loc = frame.location();
                 Method meth = loc.method();
                 out.print("  [" + (i + 1) + "] ");
@@ -780,7 +776,7 @@
                 out.print('.');
                 out.print(meth.name());
                 out.print(" (");
-                if (meth instanceof Method && ((Method)meth).isNative()) {
+                if (meth.isNative()) {
                     out.print("native method");
                 } else if (loc.lineNumber() != -1) {
                     try {
@@ -806,14 +802,13 @@
 
     private void listEventRequests() throws NoSessionException {
         // Print set breakpoints
-        Iterator iter = runtime.eventRequestSpecs().iterator();
-        if (!iter.hasNext()) {
+        List<EventRequestSpec> specs = runtime.eventRequestSpecs();
+        if (specs.isEmpty()) {
             env.notice("No breakpoints/watchpoints/exceptions set.");
         } else {
             OutputSink out = env.getOutputSink();
             out.println("Current breakpoints/watchpoints/exceptions set:");
-            while (iter.hasNext()) {
-                EventRequestSpec  bp = (EventRequestSpec)iter.next();
+            for (EventRequestSpec bp : specs) {
                 out.println("\t" + bp);
             }
             out.show();
@@ -926,13 +921,13 @@
         //### need 'clear all'
         BreakpointSpec bpSpec = parseBreakpointSpec(t.nextToken());
         if (bpSpec != null) {
-            Iterator iter = runtime.eventRequestSpecs().iterator();
-            if (!iter.hasNext()) {
+            List<EventRequestSpec> specs = runtime.eventRequestSpecs();
+
+            if (specs.isEmpty()) {
                 env.notice("No breakpoints set.");
             } else {
-                List<BreakpointSpec> toDelete = new ArrayList<BreakpointSpec>();
-                while (iter.hasNext()) {
-                    BreakpointSpec spec = (BreakpointSpec)iter.next();
+                List<EventRequestSpec> toDelete = new ArrayList<EventRequestSpec>();
+                for (EventRequestSpec spec : specs) {
                     if (spec.equals(bpSpec)) {
                         toDelete.add(spec);
                     }
@@ -941,7 +936,7 @@
                 if (toDelete.size() <= 1) {
                     env.notice("No matching breakpoint set.");
                 }
-                for (BreakpointSpec spec : toDelete) {
+                for (EventRequestSpec spec : toDelete) {
                     runtime.delete(spec);
                 }
             }
@@ -988,7 +983,7 @@
                 lineno = Integer.valueOf(id).intValue();
             } catch (NumberFormatException nfe) {
                 // It isn't -- see if it's a method name.
-                List meths = refType.methodsByName(id);
+                List<Method> meths = refType.methodsByName(id);
                 if (meths == null || meths.size() == 0) {
                     env.failure(id +
                                 " is not a valid line number or " +
@@ -1001,7 +996,7 @@
                                 refType.name());
                     return;
                 }
-                loc = ((Method)meths.get(0)).location();
+                loc = meths.get(0).location();
                 lineno = loc.lineNumber();
             }
         }
@@ -1121,7 +1116,7 @@
             return;
         }
 
-        List vars;
+        List<LocalVariable> vars;
         try {
             vars = frame.visibleVariables();
             if (vars == null || vars.size() == 0) {
@@ -1136,15 +1131,13 @@
 
         OutputSink out = env.getOutputSink();
         out.println("Method arguments:");
-        for (Iterator it = vars.iterator(); it.hasNext(); ) {
-            LocalVariable var = (LocalVariable)it.next();
+        for (LocalVariable var : vars) {
             if (var.isArgument()) {
                 printVar(out, var, frame);
             }
         }
         out.println("Local variables:");
-        for (Iterator it = vars.iterator(); it.hasNext(); ) {
-            LocalVariable var = (LocalVariable)it.next();
+        for (LocalVariable var : vars) {
             if (!var.isArgument()) {
                 printVar(out, var, frame);
             }
@@ -1245,8 +1238,7 @@
     private void dump(OutputSink out,
                       ObjectReference obj, ReferenceType refType,
                       ReferenceType refTypeBase) {
-        for (Iterator it = refType.fields().iterator(); it.hasNext(); ) {
-            Field field = (Field)it.next();
+        for (Field field : refType.fields()) {
             out.print("    ");
             if (!refType.equals(refTypeBase)) {
                 out.print(refType.name() + ".");
@@ -1261,9 +1253,8 @@
                 dump(out, obj, sup, refTypeBase);
             }
         } else if (refType instanceof InterfaceType) {
-            List sups = ((InterfaceType)refType).superinterfaces();
-            for (Iterator it = sups.iterator(); it.hasNext(); ) {
-                dump(out, obj, (ReferenceType)it.next(), refTypeBase);
+            for (InterfaceType sup : ((InterfaceType)refType).superinterfaces()) {
+                dump(out, obj, sup, refTypeBase);
             }
         }
     }
--- a/src/share/classes/com/sun/tools/example/debug/gui/JDBFileFilter.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/gui/JDBFileFilter.java	Mon Apr 14 11:34:15 2008 -0700
@@ -201,11 +201,11 @@
             if(description == null || isExtensionListInDescription()) {
                 fullDescription = description==null ? "(" : description + " (";
                 // build the description from the extension list
-                Enumeration extensions = filters.keys();
+                Enumeration<String> extensions = filters.keys();
                 if(extensions != null) {
-                    fullDescription += "." + (String) extensions.nextElement();
+                    fullDescription += "." + extensions.nextElement();
                     while (extensions.hasMoreElements()) {
-                        fullDescription += ", " + (String) extensions.nextElement();
+                        fullDescription += ", " + extensions.nextElement();
                     }
                 }
                 fullDescription += ")";
--- a/src/share/classes/com/sun/tools/example/debug/gui/LaunchTool.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/gui/LaunchTool.java	Mon Apr 14 11:34:15 2008 -0700
@@ -131,14 +131,13 @@
         final JPanel radioPanel = new JPanel();
         final ButtonGroup radioGroup = new ButtonGroup();
         VirtualMachineManager manager = Bootstrap.virtualMachineManager();
-        List all = manager.allConnectors();
+        List<Connector> all = manager.allConnectors();
         Map<ButtonModel, Connector> modelToConnector = new HashMap<ButtonModel, Connector>(all.size(), 0.5f);
 
         dialog.setModal(true);
         dialog.setTitle("Select Connector Type");
         radioPanel.setLayout(new BoxLayout(radioPanel, BoxLayout.Y_AXIS));
-        for (Iterator it = all.iterator(); it.hasNext(); ) {
-            Connector connector = (Connector)it.next();
+        for (Connector connector : all) {
             JRadioButton radio = new JRadioButton(connector.description());
             modelToConnector.put(radio.getModel(), connector);
             radioPanel.add(radio);
@@ -166,7 +165,7 @@
         dialog.show();
 
         return oked[0] ?
-            (Connector)(modelToConnector.get(radioGroup.getSelection())) :
+            modelToConnector.get(radioGroup.getSelection()) :
             null;
     }
 
@@ -188,13 +187,12 @@
         //        guts.add(new JLabel(connector.description()));
 
         final List<ArgRep> argReps = new ArrayList<ArgRep>(args.size());
-        for (Iterator it = args.values().iterator(); it.hasNext(); ) {
-            Object arg = it.next();
+        for (Connector.Argument arg : args.values()) {
             ArgRep ar;
             if (arg instanceof Connector.BooleanArgument) {
                 ar = new BooleanArgRep((Connector.BooleanArgument)arg, guts);
             } else {
-                ar = new StringArgRep((Connector.Argument)arg, guts);
+                ar = new StringArgRep(arg, guts);
             }
             argReps.add(ar);
         }
@@ -202,8 +200,7 @@
 
         JPanel buttonPanel = okCancel( dialog, new ActionListener() {
             public void actionPerformed(ActionEvent event) {
-                for (Iterator it = argReps.iterator(); it.hasNext(); ) {
-                    ArgRep ar = (ArgRep)it.next();
+                for (ArgRep ar : argReps) {
                     if (!ar.isSpecified()) {
                         JOptionPane.showMessageDialog(dialog,
                                     ar.arg.label() +
--- a/src/share/classes/com/sun/tools/example/debug/gui/SearchPath.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/gui/SearchPath.java	Mon Apr 14 11:34:15 2008 -0700
@@ -42,7 +42,7 @@
             dlist.add(st.nextToken());
         }
         pathString = searchPath;
-        pathArray = (String[])dlist.toArray(new String[dlist.size()]);
+        pathArray = dlist.toArray(new String[dlist.size()]);
     }
 
     public boolean isEmpty() {
@@ -54,7 +54,7 @@
     }
 
     public String[] asArray() {
-        return (String[])pathArray.clone();
+        return pathArray.clone();
     }
 
     public File resolve(String relativeFileName) {
@@ -89,7 +89,7 @@
                 }
             }
         }
-        return (String[])s.toArray(new String[s.size()]);
+        return s.toArray(new String[s.size()]);
     }
 
 }
--- a/src/share/classes/com/sun/tools/example/debug/gui/SourceManager.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/gui/SourceManager.java	Mon Apr 14 11:34:15 2008 -0700
@@ -113,7 +113,7 @@
      * Returns null if not available.
      */
     public SourceModel sourceForClass(ReferenceType refType) {
-        SourceModel sm = (SourceModel)classToSource.get(refType);
+        SourceModel sm = classToSource.get(refType);
         if (sm != null) {
             return sm;
         }
@@ -140,10 +140,10 @@
      */
     //### Use hash table for this?
     public SourceModel sourceForFile(File path) {
-        Iterator iter = sourceList.iterator();
+        Iterator<SourceModel> iter = sourceList.iterator();
         SourceModel sm = null;
         while (iter.hasNext()) {
-            SourceModel candidate = (SourceModel)iter.next();
+            SourceModel candidate = iter.next();
             if (candidate.fileName().equals(path)) {
                 sm = candidate;
                 iter.remove();    // Will move to start of list.
--- a/src/share/classes/com/sun/tools/example/debug/gui/SourceModel.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/gui/SourceModel.java	Mon Apr 14 11:34:15 2008 -0700
@@ -187,22 +187,17 @@
      * when sourceLines is set.
      */
     private void markClassLines(ReferenceType refType) {
-        List methods = refType.methods();
-        for (Iterator mit = methods.iterator(); mit.hasNext();) {
-            Method meth = (Method)mit.next();
+        for (Method meth : refType.methods()) {
             try {
-                List lines = meth.allLineLocations();
-                for (Iterator lit = lines.iterator(); lit.hasNext();) {
-                    Location loc = (Location)lit.next();
+                for (Location loc : meth.allLineLocations()) {
                     showExecutable(loc.lineNumber(), refType);
                 }
             } catch (AbsentInformationException exc) {
                 // do nothing
             }
         }
-        List bps = env.getExecutionManager().eventRequestManager().breakpointRequests();
-        for (Iterator it = bps.iterator(); it.hasNext();) {
-            BreakpointRequest bp = (BreakpointRequest)it.next();
+        for (BreakpointRequest bp :
+                 env.getExecutionManager().eventRequestManager().breakpointRequests()) {
             if (bp.location() != null) {
                 Location loc = bp.location();
                 if (loc.declaringType().equals(refType)) {
@@ -224,8 +219,8 @@
         } finally {
             reader.close();
         }
-        for (Iterator it = classes.iterator(); it.hasNext();) {
-            markClassLines((ClassType)it.next());
+        for (ReferenceType refType : classes) {
+            markClassLines(refType);
         }
     }
 
--- a/src/share/classes/com/sun/tools/example/debug/gui/StackTraceTool.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/gui/StackTraceTool.java	Mon Apr 14 11:34:15 2008 -0700
@@ -139,7 +139,7 @@
                 String methName =
                     meth.declaringType().name() + '.' + meth.name();
                 String position = "";
-                if (meth instanceof Method && ((Method)meth).isNative()) {
+                if (meth.isNative()) {
                     position = " (native method)";
                 } else if (loc.lineNumber() != -1) {
                     position = ":" + loc.lineNumber();
--- a/src/share/classes/com/sun/tools/example/debug/gui/ThreadTreeTool.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/gui/ThreadTreeTool.java	Mon Apr 14 11:34:15 2008 -0700
@@ -133,9 +133,7 @@
 
         public void sessionStart(EventObject e) {
             try {
-                Iterator iter = runtime.allThreads().iterator();
-                while (iter.hasNext()) {
-                    ThreadReference thread = ((ThreadReference)iter.next());
+                for (ThreadReference thread : runtime.allThreads()) {
                     root.addThread(thread);
                 }
             } catch (VMDisconnectedException ee) {
@@ -244,16 +242,16 @@
             }
         }
 
-        private void addThread(List threadPath, ThreadReference thread) {
+        private void addThread(List<String> threadPath, ThreadReference thread) {
             int size = threadPath.size();
             if (size == 0) {
                 return;
             } else if (size == 1) {
-                String name = (String)threadPath.get(0);
+                String name = threadPath.get(0);
                 insertNode(name, thread);
             } else {
-                String head = (String)threadPath.get(0);
-                List tail = threadPath.subList(1, size);
+                String head = threadPath.get(0);
+                List<String> tail = threadPath.subList(1, size);
                 ThreadTreeNode child = insertNode(head, null);
                 child.addThread(tail, thread);
             }
@@ -288,17 +286,17 @@
             }
         }
 
-        private void removeThread(List threadPath, ThreadReference thread) {
+        private void removeThread(List<String> threadPath, ThreadReference thread) {
             int size = threadPath.size();
             if (size == 0) {
                 return;
             } else if (size == 1) {
-                String name = (String)threadPath.get(0);
+                String name = threadPath.get(0);
                 ThreadTreeNode child = findLeafNode(thread, name);
                 treeModel.removeNodeFromParent(child);
             } else {
-                String head = (String)threadPath.get(0);
-                List tail = threadPath.subList(1, size);
+                String head = threadPath.get(0);
+                List<String> tail = threadPath.subList(1, size);
                 ThreadTreeNode child = findInternalNode(head);
                 child.removeThread(tail, thread);
                 if (child.isThreadGroup() && child.getChildCount() < 1) {
--- a/src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java	Mon Apr 14 11:34:15 2008 -0700
@@ -34,7 +34,7 @@
 
 class BreakpointSpec extends EventRequestSpec {
     String methodId;
-    List methodArgs;
+    List<String> methodArgs;
     int lineNumber;
 
     BreakpointSpec(ReferenceTypeSpec refSpec, int lineNumber) {
@@ -45,7 +45,7 @@
     }
 
     BreakpointSpec(ReferenceTypeSpec refSpec, String methodId,
-                   List methodArgs) throws MalformedMemberNameException {
+                   List<String> methodArgs) throws MalformedMemberNameException {
         super(refSpec);
         this.methodId = methodId;
         this.methodArgs = methodArgs;
@@ -83,7 +83,7 @@
         return lineNumber;
     }
 
-    List methodArgs() {
+    List<String> methodArgs() {
         return methodArgs;
     }
 
@@ -146,14 +146,13 @@
             buffer.append('.');
             buffer.append(methodId);
             if (methodArgs != null) {
-                Iterator iter = methodArgs.iterator();
                 boolean first = true;
                 buffer.append('(');
-                while (iter.hasNext()) {
+                for (String arg : methodArgs) {
                     if (!first) {
                         buffer.append(',');
                     }
-                    buffer.append((String)iter.next());
+                    buffer.append(arg);
                     first = false;
                 }
                 buffer.append(")");
@@ -176,12 +175,12 @@
             location = method.location();
         } else {
             // let AbsentInformationException be thrown
-            List locs = refType.locationsOfLine(lineNumber());
+            List<Location> locs = refType.locationsOfLine(lineNumber());
             if (locs.size() == 0) {
                 throw new LineNotFoundException();
             }
             // TO DO: handle multiple locations
-            location = (Location)locs.get(0);
+            location = locs.get(0);
             if (location.method() == null) {
                 throw new LineNotFoundException();
             }
@@ -202,8 +201,8 @@
      * and if the number of arguments in the method matches the
      * number of names passed
      */
-    private boolean compareArgTypes(Method method, List nameList) {
-        List argTypeNames = method.argumentTypeNames();
+    private boolean compareArgTypes(Method method, List<String> nameList) {
+        List<String> argTypeNames = method.argumentTypeNames();
 
         // If argument counts differ, we can stop here
         if (argTypeNames.size() != nameList.size()) {
@@ -213,8 +212,8 @@
         // Compare each argument type's name
         int nTypes = argTypeNames.size();
         for (int i = 0; i < nTypes; ++i) {
-            String comp1 = (String)argTypeNames.get(i);
-            String comp2 = (String)nameList.get(i);
+            String comp1 = argTypeNames.get(i);
+            String comp2 = nameList.get(i);
             if (! comp1.equals(comp2)) {
                 /*
                  * We have to handle varargs.  EG, the
@@ -331,22 +330,17 @@
         List<String> argTypeNames = null;
         if (methodArgs() != null) {
             argTypeNames = new ArrayList<String>(methodArgs().size());
-            Iterator iter = methodArgs().iterator();
-            while (iter.hasNext()) {
-                String name = (String)iter.next();
+            for (String name : methodArgs()) {
                 name = normalizeArgTypeName(name);
                 argTypeNames.add(name);
             }
         }
 
         // Check each method in the class for matches
-        Iterator iter = refType.methods().iterator();
         Method firstMatch = null;  // first method with matching name
         Method exactMatch = null;  // (only) method with same name & sig
         int matchCount = 0;        // > 1 implies overload
-        while (iter.hasNext()) {
-            Method candidate = (Method)iter.next();
-
+        for (Method candidate : refType.methods()) {
             if (candidate.name().equals(methodName())) {
                 matchCount++;
 
--- a/src/share/classes/com/sun/tools/example/debug/tty/Commands.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/tty/Commands.java	Mon Apr 14 11:34:15 2008 -0700
@@ -157,16 +157,16 @@
         buf.append(method.name());
         buf.append("(");
 
-        List args = method.argumentTypeNames();
+        List<String> args = method.argumentTypeNames();
         int lastParam = args.size() - 1;
         // output param types except for the last
         for (int ii = 0; ii < lastParam; ii++) {
-            buf.append((String)args.get(ii));
+            buf.append(args.get(ii));
             buf.append(", ");
         }
         if (lastParam >= 0) {
             // output the last param
-            String lastStr = (String)args.get(lastParam);
+            String lastStr = args.get(lastParam);
             if (method.isVarArgs()) {
                 // lastParam is an array.  Replace the [] with ...
                 buf.append(lastStr.substring(0, lastStr.length() - 2));
@@ -180,12 +180,11 @@
     }
 
     void commandConnectors(VirtualMachineManager vmm) {
-        Iterator iter = vmm.allConnectors().iterator();
-        if (iter.hasNext()) {
+        Collection<Connector> ccs = vmm.allConnectors();
+        if (ccs.isEmpty()) {
             MessageOutput.println("Connectors available");
         }
-        while (iter.hasNext()) {
-            Connector cc = (Connector)iter.next();
+        for (Connector cc : ccs) {
             String transportName =
                 cc.transport() == null ? "null" : cc.transport().name();
             MessageOutput.println();
@@ -193,10 +192,7 @@
                                   new Object [] {cc.name(), transportName});
             MessageOutput.println("Connector description", cc.description());
 
-            Iterator argIter = cc.defaultArguments().values().iterator();
-            if (argIter.hasNext()) {
-                while (argIter.hasNext()) {
-                    Connector.Argument aa = (Connector.Argument)argIter.next();
+            for (Connector.Argument aa : cc.defaultArguments().values()) {
                     MessageOutput.println();
 
                     boolean requiredArgument = aa.mustSpecify();
@@ -215,16 +211,12 @@
 
                 }
             }
-        }
 
     }
 
     void commandClasses() {
-        List list = Env.vm().allClasses();
-
         StringBuffer classList = new StringBuffer();
-        for (int i = 0 ; i < list.size() ; i++) {
-            ReferenceType refType = (ReferenceType)list.get(i);
+        for (ReferenceType refType : Env.vm().allClasses()) {
             classList.append(refType.name());
             classList.append("\n");
         }
@@ -232,7 +224,7 @@
     }
 
     void commandClass(StringTokenizer t) {
-        List list = Env.vm().allClasses();
+        List<ReferenceType> list = Env.vm().allClasses();
 
         if (!t.hasMoreTokens()) {
             MessageOutput.println("No class specified.");
@@ -265,51 +257,31 @@
                 superclass = showAll ? superclass.superclass() : null;
             }
 
-            List interfaces = showAll ? clazz.allInterfaces()
-                                      : clazz.interfaces();
-            Iterator iter = interfaces.iterator();
-            while (iter.hasNext()) {
-                InterfaceType interfaze = (InterfaceType)iter.next();
+            List<InterfaceType> interfaces =
+                showAll ? clazz.allInterfaces() : clazz.interfaces();
+            for (InterfaceType interfaze : interfaces) {
                 MessageOutput.println("implements:", interfaze.name());
             }
 
-            List subs = clazz.subclasses();
-            iter = subs.iterator();
-            while (iter.hasNext()) {
-                ClassType sub = (ClassType)iter.next();
+            for (ClassType sub : clazz.subclasses()) {
                 MessageOutput.println("subclass:", sub.name());
             }
-            List nested = clazz.nestedTypes();
-            iter = nested.iterator();
-            while (iter.hasNext()) {
-                ReferenceType nest = (ReferenceType)iter.next();
+            for (ReferenceType nest : clazz.nestedTypes()) {
                 MessageOutput.println("nested:", nest.name());
             }
         } else if (type instanceof InterfaceType) {
             InterfaceType interfaze = (InterfaceType)type;
             MessageOutput.println("Interface:", interfaze.name());
-            List supers = interfaze.superinterfaces();
-            Iterator iter = supers.iterator();
-            while (iter.hasNext()) {
-                InterfaceType superinterface = (InterfaceType)iter.next();
+            for (InterfaceType superinterface : interfaze.superinterfaces()) {
                 MessageOutput.println("extends:", superinterface.name());
             }
-            List subs = interfaze.subinterfaces();
-            iter = subs.iterator();
-            while (iter.hasNext()) {
-                InterfaceType sub = (InterfaceType)iter.next();
+            for (InterfaceType sub : interfaze.subinterfaces()) {
                 MessageOutput.println("subinterface:", sub.name());
             }
-            List implementors = interfaze.implementors();
-            iter = implementors.iterator();
-            while (iter.hasNext()) {
-                ClassType implementor = (ClassType)iter.next();
+            for (ClassType implementor : interfaze.implementors()) {
                 MessageOutput.println("implementor:", implementor.name());
             }
-            List nested = interfaze.nestedTypes();
-            iter = nested.iterator();
-            while (iter.hasNext()) {
-                ReferenceType nest = (ReferenceType)iter.next();
+            for (ReferenceType nest : interfaze.nestedTypes()) {
                 MessageOutput.println("nested:", nest.name());
             }
         } else {  // array type
@@ -327,10 +299,8 @@
         String idClass = t.nextToken();
         ReferenceType cls = Env.getReferenceTypeFromToken(idClass);
         if (cls != null) {
-            List methods = cls.allMethods();
             StringBuffer methodsList = new StringBuffer();
-            for (int i = 0; i < methods.size(); i++) {
-                Method method = (Method)methods.get(i);
+            for (Method method : cls.allMethods()) {
                 methodsList.append(method.declaringType().name());
                 methodsList.append(" ");
                 methodsList.append(typedName(method));
@@ -351,11 +321,10 @@
         String idClass = t.nextToken();
         ReferenceType cls = Env.getReferenceTypeFromToken(idClass);
         if (cls != null) {
-            List fields = cls.allFields();
-            List visible = cls.visibleFields();
+            List<Field> fields = cls.allFields();
+            List<Field> visible = cls.visibleFields();
             StringBuffer fieldsList = new StringBuffer();
-            for (int i = 0; i < fields.size(); i++) {
-                Field field = (Field)fields.get(i);
+            for (Field field : fields) {
                 String s;
                 if (!visible.contains(field)) {
                     s = MessageOutput.format("list field typename and name hidden",
@@ -386,7 +355,7 @@
         int maxIdLength = 0;
         int maxNameLength = 0;
         while (threadIter.hasNext()) {
-            ThreadReference thr = (ThreadReference)threadIter.next();
+            ThreadReference thr = threadIter.next();
             maxIdLength = Math.max(maxIdLength,
                                    Env.description(thr).length());
             maxNameLength = Math.max(maxNameLength,
@@ -395,7 +364,7 @@
 
         threadIter = new ThreadIterator(tg);
         while (threadIter.hasNext()) {
-            ThreadReference thr = (ThreadReference)threadIter.next();
+            ThreadReference thr = threadIter.next();
             if (thr.threadGroup() == null) {
                 continue;
             }
@@ -588,9 +557,7 @@
     private List<ThreadReference> allThreads(ThreadGroupReference group) {
         List<ThreadReference> list = new ArrayList<ThreadReference>();
         list.addAll(group.threads());
-        Iterator iter = group.threadGroups().iterator();
-        while (iter.hasNext()) {
-            ThreadGroupReference child = (ThreadGroupReference)iter.next();
+        for (ThreadGroupReference child : group.threadGroups()) {
             list.addAll(allThreads(child));
         }
         return list;
@@ -641,10 +608,7 @@
          * if so, it gets removed here.
          */
          EventRequestManager mgr = Env.vm().eventRequestManager();
-         List requests = mgr.stepRequests();
-         Iterator iter = requests.iterator();
-         while (iter.hasNext()) {
-             StepRequest request = (StepRequest)iter.next();
+         for (StepRequest request : mgr.stepRequests()) {
              if (request.thread().equals(thread)) {
                  mgr.deleteEventRequest(request);
                  break;
@@ -768,9 +732,7 @@
         boolean noExceptions = true;
 
         // Print a listing of the catch patterns currently in place
-        Iterator iter = Env.specList.eventRequestSpecs().iterator();
-        while (iter.hasNext()) {
-            EventRequestSpec spec = (EventRequestSpec)iter.next();
+        for (EventRequestSpec spec : Env.specList.eventRequestSpecs()) {
             if (spec instanceof ExceptionSpec) {
                 if (noExceptions) {
                     noExceptions = false;
@@ -928,7 +890,7 @@
     }
 
     private void dumpStack(ThreadInfo threadInfo, boolean showPC) {
-        List stack = null;
+        List<StackFrame> stack = null;
         try {
             stack = threadInfo.getStack();
         } catch (IncompatibleThreadStateException e) {
@@ -940,7 +902,7 @@
         } else {
             int nFrames = stack.size();
             for (int i = threadInfo.getCurrentFrameIndex(); i < nFrames; i++) {
-                StackFrame frame = (StackFrame)stack.get(i);
+                StackFrame frame = stack.get(i);
                 dumpFrame (i, showPC, frame);
             }
         }
@@ -956,7 +918,7 @@
 
         long lineNumber = loc.lineNumber();
         String methodInfo = null;
-        if (meth instanceof Method && ((Method)meth).isNative()) {
+        if (meth.isNative()) {
             methodInfo = MessageOutput.format("native method");
         } else if (lineNumber != -1) {
             try {
@@ -994,9 +956,7 @@
         } else {
             String token = t.nextToken();
             if (token.toLowerCase().equals("all")) {
-                Iterator iter = ThreadInfo.threads().iterator();
-                while (iter.hasNext()) {
-                    ThreadInfo threadInfo = (ThreadInfo)iter.next();
+                for (ThreadInfo threadInfo : ThreadInfo.threads()) {
                     MessageOutput.println("Thread:",
                                           threadInfo.getThread().name());
                     dumpStack(threadInfo, showPC);
@@ -1051,9 +1011,7 @@
         boolean noBreakpoints = true;
 
         // Print set breakpoints
-        Iterator iter = Env.specList.eventRequestSpecs().iterator();
-        while (iter.hasNext()) {
-            EventRequestSpec spec = (EventRequestSpec)iter.next();
+        for (EventRequestSpec spec : Env.specList.eventRequestSpecs()) {
             if (spec instanceof BreakpointSpec) {
                 if (noBreakpoints) {
                     noBreakpoints = false;
@@ -1075,7 +1033,7 @@
 
     protected BreakpointSpec parseBreakpointSpec(StringTokenizer t,
                                              String atForm, String inForm) {
-        EventRequestSpec breakpoint = null;
+        BreakpointSpec breakpoint = null;
         try {
             String token = t.nextToken(":( \t\n\r");
 
@@ -1149,7 +1107,7 @@
             printBreakpointCommandUsage(atForm, inForm);
             return null;
         }
-        return (BreakpointSpec)breakpoint;
+        return breakpoint;
     }
 
     private void resolveNow(EventRequestSpec spec) {
@@ -1209,8 +1167,8 @@
         }
     }
 
-    private List<EventRequestSpec> parseWatchpointSpec(StringTokenizer t) {
-        List<EventRequestSpec> list = new ArrayList<EventRequestSpec>();
+    private List<WatchpointSpec> parseWatchpointSpec(StringTokenizer t) {
+        List<WatchpointSpec> list = new ArrayList<WatchpointSpec>();
         boolean access = false;
         boolean modification = false;
         int suspendPolicy = EventRequest.SUSPEND_ALL;
@@ -1242,7 +1200,7 @@
         fieldName = fieldName.substring(dot+1);
 
         try {
-            EventRequestSpec spec;
+            WatchpointSpec spec;
             if (access) {
                 spec = Env.specList.createAccessWatchpoint(className,
                                                            fieldName);
@@ -1269,9 +1227,8 @@
             return;
         }
 
-        Iterator iter = parseWatchpointSpec(t).iterator();
-        while (iter.hasNext()) {
-            resolveNow((WatchpointSpec)iter.next());
+        for (WatchpointSpec spec : parseWatchpointSpec(t)) {
+            resolveNow(spec);
         }
     }
 
@@ -1281,9 +1238,7 @@
             return;
         }
 
-        Iterator iter = parseWatchpointSpec(t).iterator();
-        while (iter.hasNext()) {
-            WatchpointSpec spec = (WatchpointSpec)iter.next();
+        for (WatchpointSpec spec : parseWatchpointSpec(t)) {
             if (Env.specList.delete(spec)) {
                 MessageOutput.println("Removed:", spec.toString());
             } else {
@@ -1482,7 +1437,7 @@
                     lineno = n.intValue();
                 } catch (java.text.ParseException jtpe) {
                     // It isn't -- see if it's a method name.
-                        List meths = refType.methodsByName(id);
+                        List<Method> meths = refType.methodsByName(id);
                         if (meths == null || meths.size() == 0) {
                             MessageOutput.println("is not a valid line number or method name for",
                                                   new Object [] {id, refType.name()});
@@ -1492,7 +1447,7 @@
                                                   new Object [] {id, refType.name()});
                             return;
                         }
-                        loc = ((Method)meths.get(0)).location();
+                        loc = meths.get(0).location();
                         lineno = loc.lineNumber();
                 }
             }
@@ -1539,14 +1494,11 @@
             try {
                 ReferenceType refType = Env.getReferenceTypeFromToken(idClass);
                 if (refType != null) {
-                    List lines = null;
+                    List<Location> lines = null;
                     if (idMethod == null) {
                         lines = refType.allLineLocations();
                     } else {
-                        List methods = refType.allMethods();
-                        Iterator iter = methods.iterator();
-                        while (iter.hasNext()) {
-                            Method method = (Method)iter.next();
+                        for (Method method : refType.allMethods()) {
                             if (method.name().equals(idMethod)) {
                                 lines = method.allLineLocations();
                             }
@@ -1555,9 +1507,7 @@
                             MessageOutput.println("is not a valid method name", idMethod);
                         }
                     }
-                    Iterator iter = lines.iterator();
-                    while (iter.hasNext()) {
-                        Location line = (Location)iter.next();
+                    for (Location line : lines) {
                         MessageOutput.printDirectln(line.toString());// Special case: use printDirectln()
                     }
                 } else {
@@ -1620,21 +1570,19 @@
                 MessageOutput.println("No local variables");
                 return;
             }
-            Map values = frame.getValues(vars);
+            Map<LocalVariable, Value> values = frame.getValues(vars);
 
             MessageOutput.println("Method arguments:");
-            for (Iterator it = vars.iterator(); it.hasNext(); ) {
-                LocalVariable var = (LocalVariable)it.next();
+            for (LocalVariable var : vars) {
                 if (var.isArgument()) {
-                    Value val = (Value)values.get(var);
+                    Value val = values.get(var);
                     printVar(var, val);
                 }
             }
             MessageOutput.println("Local variables:");
-            for (Iterator it = vars.iterator(); it.hasNext(); ) {
-                LocalVariable var = (LocalVariable)it.next();
+            for (LocalVariable var : vars) {
                 if (!var.isArgument()) {
-                    Value val = (Value)values.get(var);
+                    Value val = values.get(var);
                     printVar(var, val);
                 }
             }
@@ -1647,9 +1595,8 @@
 
     private void dump(ObjectReference obj, ReferenceType refType,
                       ReferenceType refTypeBase) {
-        for (Iterator it = refType.fields().iterator(); it.hasNext(); ) {
+        for (Field field : refType.fields()) {
             StringBuffer o = new StringBuffer();
-            Field field = (Field)it.next();
             o.append("    ");
             if (!refType.equals(refTypeBase)) {
                 o.append(refType.name());
@@ -1666,14 +1613,13 @@
                 dump(obj, sup, refTypeBase);
             }
         } else if (refType instanceof InterfaceType) {
-            List sups = ((InterfaceType)refType).superinterfaces();
-            for (Iterator it = sups.iterator(); it.hasNext(); ) {
-                dump(obj, (ReferenceType)it.next(), refTypeBase);
+            for (InterfaceType sup : ((InterfaceType)refType).superinterfaces()) {
+                dump(obj, sup, refTypeBase);
             }
         } else {
             /* else refType is an instanceof ArrayType */
             if (obj instanceof ArrayReference) {
-                for (Iterator it = ((ArrayReference)obj).getValues().iterator();
+                for (Iterator<Value> it = ((ArrayReference)obj).getValues().iterator();
                      it.hasNext(); ) {
                     MessageOutput.printDirect(it.next().toString());// Special case: use printDirect()
                     if (it.hasNext()) {
@@ -1770,13 +1716,11 @@
                                           new Object [] {owner.name(),
                                                          new Integer (object.entryCount())});
                 }
-                List waiters = object.waitingThreads();
+                List<ThreadReference> waiters = object.waitingThreads();
                 if (waiters.size() == 0) {
                     MessageOutput.println("No waiters");
                 } else {
-                    Iterator iter = waiters.iterator();
-                    while (iter.hasNext()) {
-                        ThreadReference waiter = (ThreadReference)iter.next();
+                    for (ThreadReference waiter : waiters) {
                         MessageOutput.println("Waiting thread:", waiter.name());
                     }
                 }
@@ -1800,13 +1744,11 @@
         ThreadReference thread = threadInfo.getThread();
         try {
             MessageOutput.println("Monitor information for thread", thread.name());
-            List owned = thread.ownedMonitors();
+            List<ObjectReference> owned = thread.ownedMonitors();
             if (owned.size() == 0) {
                 MessageOutput.println("No monitors owned");
             } else {
-                Iterator iter = owned.iterator();
-                while (iter.hasNext()) {
-                    ObjectReference monitor = (ObjectReference)iter.next();
+                for (ObjectReference monitor : owned) {
                     MessageOutput.println("Owned monitor:", monitor.toString());
                 }
             }
@@ -1833,9 +1775,7 @@
         }
         String token = t.nextToken();
         if (token.toLowerCase().equals("all")) {
-            Iterator iter = ThreadInfo.threads().iterator();
-            while (iter.hasNext()) {
-                ThreadInfo threadInfo = (ThreadInfo)iter.next();
+            for (ThreadInfo threadInfo : ThreadInfo.threads()) {
                 printThreadLockInfo(threadInfo);
             }
         } else {
@@ -1930,14 +1870,12 @@
 
     void commandSave(final StringTokenizer t) { // Undocumented command: useful for testing.
         if (!t.hasMoreTokens()) {
-            Set keys = Env.getSaveKeys();
-            Iterator iter = keys.iterator();
-            if (!iter.hasNext()) {
+            Set<String> keys = Env.getSaveKeys();
+            if (keys.isEmpty()) {
                 MessageOutput.println("No saved values");
                 return;
             }
-            while (iter.hasNext()) {
-                String key = (String)iter.next();
+            for (String key : keys) {
                 Value value = Env.getSavedValue(key);
                 if ((value instanceof ObjectReference) &&
                     ((ObjectReference)value).isCollected()) {
@@ -1976,7 +1914,7 @@
         // Overloading is not handled here.
         String methodName = t.nextToken();
 
-        List classes = Env.vm().classesByName(className);
+        List<ReferenceType> classes = Env.vm().classesByName(className);
         // TO DO: handle multiple classes found
         if (classes.size() == 0) {
             if (className.indexOf('.') < 0) {
@@ -1987,17 +1925,14 @@
             return;
         }
 
-        ReferenceType rt = (ReferenceType)classes.get(0);
+        ReferenceType rt = classes.get(0);
         if (!(rt instanceof ClassType)) {
             MessageOutput.println("not a class", className);
             return;
         }
 
         byte[] bytecodes = null;
-        List list = rt.methodsByName(methodName);
-        Iterator iter = list.iterator();
-        while (iter.hasNext()) {
-            Method method = (Method)iter.next();
+        for (Method method : rt.methodsByName(methodName)) {
             if (!method.isAbstract()) {
                 bytecodes = method.bytecodes();
                 break;
@@ -2047,7 +1982,7 @@
             MessageOutput.println("Specify classes to redefine");
         } else {
             String className = t.nextToken();
-            List classes = Env.vm().classesByName(className);
+            List<ReferenceType> classes = Env.vm().classesByName(className);
             if (classes.size() == 0) {
                 MessageOutput.println("No class named", className);
                 return;
@@ -2057,7 +1992,7 @@
                 return;
             }
             Env.setSourcePath(Env.getSourcePath());
-            ReferenceType refType = (ReferenceType)classes.get(0);
+            ReferenceType refType = classes.get(0);
             if (!t.hasMoreTokens()) {
                 MessageOutput.println("Specify file name for class", className);
                 return;
@@ -2074,7 +2009,8 @@
                              new Object [] {fileName, exc.toString()});
                 return;
             }
-            Map<ReferenceType, byte[]> map = new HashMap<ReferenceType, byte[]>();
+            Map<ReferenceType, byte[]> map
+                = new HashMap<ReferenceType, byte[]>();
             map.put(refType, bytes);
             try {
                 Env.vm().redefineClasses(map);
--- a/src/share/classes/com/sun/tools/example/debug/tty/Env.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/tty/Env.java	Mon Apr 14 11:34:15 2008 -0700
@@ -89,7 +89,7 @@
         sourceCache.clear();
     }
 
-    static void setSourcePath(List srcList) {
+    static void setSourcePath(List<String> srcList) {
         sourceMapper = new SourceMapper(srcList);
         sourceCache.clear();
     }
@@ -106,10 +106,8 @@
     }
 
     static String excludesString() {
-        Iterator iter = excludes().iterator();
         StringBuffer buffer = new StringBuffer();
-        while (iter.hasNext()) {
-            String pattern = (String)iter.next();
+        for (String pattern : excludes()) {
             buffer.append(pattern);
             buffer.append(",");
         }
@@ -117,25 +115,19 @@
     }
 
     static void addExcludes(StepRequest request) {
-        Iterator iter = excludes().iterator();
-        while (iter.hasNext()) {
-            String pattern = (String)iter.next();
+        for (String pattern : excludes()) {
             request.addClassExclusionFilter(pattern);
         }
     }
 
     static void addExcludes(MethodEntryRequest request) {
-        Iterator iter = excludes().iterator();
-        while (iter.hasNext()) {
-            String pattern = (String)iter.next();
+        for (String pattern : excludes()) {
             request.addClassExclusionFilter(pattern);
         }
     }
 
     static void addExcludes(MethodExitRequest request) {
-        Iterator iter = excludes().iterator();
-        while (iter.hasNext()) {
-            String pattern = (String)iter.next();
+        for (String pattern : excludes()) {
             request.addClassExclusionFilter(pattern);
         }
     }
@@ -175,10 +167,10 @@
         try {
             String fileName = location.sourceName();
 
-            Iterator iter = sourceCache.iterator();
+            Iterator<SourceCode> iter = sourceCache.iterator();
             SourceCode code = null;
             while (iter.hasNext()) {
-                SourceCode candidate = (SourceCode)iter.next();
+                SourceCode candidate = iter.next();
                 if (candidate.fileName().equals(fileName)) {
                     code = candidate;
                     iter.remove();
@@ -269,10 +261,7 @@
         // loaded class whose name matches this limited regular
         // expression is selected.
         idToken = idToken.substring(1);
-        List classes = Env.vm().allClasses();
-        Iterator iter = classes.iterator();
-        while (iter.hasNext()) {
-            ReferenceType type = ((ReferenceType)iter.next());
+        for (ReferenceType type : Env.vm().allClasses()) {
             if (type.name().endsWith(idToken)) {
                 cls = type;
                 break;
@@ -280,21 +269,21 @@
         }
     } else {
             // It's a class name
-            List classes = Env.vm().classesByName(idToken);
+            List<ReferenceType> classes = Env.vm().classesByName(idToken);
             if (classes.size() > 0) {
                 // TO DO: handle multiples
-                cls = (ReferenceType)classes.get(0);
+                cls = classes.get(0);
             }
         }
         return cls;
     }
 
-    static Set getSaveKeys() {
+    static Set<String> getSaveKeys() {
         return savedValues.keySet();
     }
 
     static Value getSavedValue(String key) {
-        return (Value)savedValues.get(key);
+        return savedValues.get(key);
     }
 
     static void setSavedValue(String key, Value value) {
@@ -327,7 +316,7 @@
             if (index >= sourceLines.size()) {
                 return null;
             } else {
-                return (String)sourceLines.get(index);
+                return sourceLines.get(index);
             }
         }
     }
--- a/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java	Mon Apr 14 11:34:15 2008 -0700
@@ -150,7 +150,7 @@
                 EventSet eventSet = queue.remove();
                 EventIterator iter = eventSet.eventIterator();
                 while (iter.hasNext()) {
-                    handleExitEvent((Event)iter.next());
+                    handleExitEvent(iter.next());
                 }
             } catch (InterruptedException exc) {
                 // ignore
@@ -183,7 +183,7 @@
              * If any event in the set has a thread associated with it,
              * they all will, so just grab the first one.
              */
-            Event event = (Event)set.iterator().next(); // Is there a better way?
+            Event event = set.iterator().next(); // Is there a better way?
             thread = eventThread(event);
         } else {
             thread = null;
--- a/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpec.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpec.java	Mon Apr 14 11:34:15 2008 -0700
@@ -101,10 +101,8 @@
                  * so that is all we need to examine.
                  */
                 ArrayList<ExceptionRequest> deleteList = new ArrayList<ExceptionRequest>();
-                Iterator iter =
-                    Env.vm().eventRequestManager().exceptionRequests().iterator();
-                while (iter.hasNext()) {
-                    ExceptionRequest er = (ExceptionRequest)iter.next();
+                for (ExceptionRequest er :
+                         Env.vm().eventRequestManager().exceptionRequests()) {
                     if (prs.matches(er.exception())) {
                         deleteList.add (er);
                     }
@@ -115,9 +113,7 @@
     }
 
     private EventRequest resolveAgainstPreparedClasses() throws Exception {
-        Iterator iter = Env.vm().allClasses().iterator();
-        while (iter.hasNext()) {
-            ReferenceType refType = (ReferenceType)iter.next();
+        for (ReferenceType refType : Env.vm().allClasses()) {
             if (refType.isPrepared() && refSpec.matches(refType)) {
                 resolved = resolveEventRequest(refType);
             }
--- a/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java	Mon Apr 14 11:34:15 2008 -0700
@@ -55,9 +55,7 @@
     boolean resolve(ClassPrepareEvent event) {
         boolean failure = false;
         synchronized(eventRequestSpecs) {
-            Iterator iter = eventRequestSpecs.iterator();
-            while (iter.hasNext()) {
-                EventRequestSpec spec = (EventRequestSpec)iter.next();
+            for (EventRequestSpec spec : eventRequestSpecs) {
                 if (!spec.isResolved()) {
                     try {
                         EventRequest eventRequest = spec.resolve(event);
@@ -77,9 +75,7 @@
     }
 
     void resolveAll() {
-        Iterator iter = eventRequestSpecs.iterator();
-        while (iter.hasNext()) {
-            EventRequestSpec spec = (EventRequestSpec)iter.next();
+        for (EventRequestSpec spec : eventRequestSpecs) {
             try {
                 EventRequest eventRequest = spec.resolveEagerly();
                 if (eventRequest != null) {
@@ -106,16 +102,16 @@
         }
     }
 
-    EventRequestSpec createBreakpoint(String classPattern,
-                                 int line) throws ClassNotFoundException {
+    BreakpointSpec createBreakpoint(String classPattern, int line)
+        throws ClassNotFoundException {
         ReferenceTypeSpec refSpec =
             new PatternReferenceTypeSpec(classPattern);
         return new BreakpointSpec(refSpec, line);
     }
 
-    EventRequestSpec createBreakpoint(String classPattern,
+    BreakpointSpec createBreakpoint(String classPattern,
                                  String methodId,
-                                 List methodArgs)
+                                    List<String> methodArgs)
                                 throws MalformedMemberNameException,
                                        ClassNotFoundException {
         ReferenceTypeSpec refSpec =
@@ -132,7 +128,7 @@
         return new ExceptionSpec(refSpec, notifyCaught, notifyUncaught);
     }
 
-    EventRequestSpec createAccessWatchpoint(String classPattern,
+    WatchpointSpec createAccessWatchpoint(String classPattern,
                                        String fieldId)
                                       throws MalformedMemberNameException,
                                              ClassNotFoundException {
@@ -141,7 +137,7 @@
         return new AccessWatchpointSpec(refSpec, fieldId);
     }
 
-    EventRequestSpec createModificationWatchpoint(String classPattern,
+    WatchpointSpec createModificationWatchpoint(String classPattern,
                                        String fieldId)
                                       throws MalformedMemberNameException,
                                              ClassNotFoundException {
@@ -154,7 +150,7 @@
         synchronized (eventRequestSpecs) {
             int inx = eventRequestSpecs.indexOf(proto);
             if (inx != -1) {
-                EventRequestSpec spec = (EventRequestSpec)eventRequestSpecs.get(inx);
+                EventRequestSpec spec = eventRequestSpecs.get(inx);
                 spec.remove();
                 eventRequestSpecs.remove(inx);
                 return true;
--- a/src/share/classes/com/sun/tools/example/debug/tty/SourceMapper.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/tty/SourceMapper.java	Mon Apr 14 11:34:15 2008 -0700
@@ -39,15 +39,13 @@
 
     private final String[] dirs;
 
-    SourceMapper(List sourcepath) {
+    SourceMapper(List<String> sourcepath) {
         /*
          * sourcepath can arrive from the debugee as a List.
          * (via PathSearchingVirtualMachine.classPath())
          */
         List<String> dirList = new ArrayList<String>();
-        Iterator iter = sourcepath.iterator();
-        while (iter.hasNext()) {
-            String element = (String)iter.next();
+        for (String element : sourcepath) {
             //XXX remove .jar and .zip files; we want only directories on
             //the source path. (Bug ID 4186582)
             if ( ! (element.endsWith(".jar") ||
@@ -55,7 +53,7 @@
                 dirList.add(element);
             }
         }
-        dirs = (String[])dirList.toArray(new String[0]);
+        dirs = dirList.toArray(new String[0]);
     }
 
     SourceMapper(String sourcepath) {
@@ -79,7 +77,7 @@
                 dirList.add(s);
             }
         }
-        dirs = (String[])dirList.toArray(new String[0]);
+        dirs = dirList.toArray(new String[0]);
     }
 
     /*
--- a/src/share/classes/com/sun/tools/example/debug/tty/TTY.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/tty/TTY.java	Mon Apr 14 11:34:15 2008 -0700
@@ -160,9 +160,7 @@
                 // here the next time.
                 Env.setAtExitMethod(null);
                 EventRequestManager erm = Env.vm().eventRequestManager();
-                Iterator it = erm.methodExitRequests().iterator();
-                while (it.hasNext()) {
-                    EventRequest eReq = (EventRequest)it.next();
+                for (EventRequest eReq : erm.methodExitRequests()) {
                     if (eReq.equals(me.request())) {
                         eReq.disable();
                     }
@@ -178,9 +176,8 @@
     public void vmInterrupted() {
         Thread.yield();  // fetch output
         printCurrentLocation();
-        Iterator it = monitorCommands.iterator();
-        while (it.hasNext()) {
-            StringTokenizer t = new StringTokenizer((String)it.next());
+        for (String cmd : monitorCommands) {
+            StringTokenizer t = new StringTokenizer(cmd);
             t.nextToken();  // get rid of monitor number
             executeCommand(t);
         }
@@ -563,9 +560,8 @@
             ++monitorCount;
             monitorCommands.add(monitorCount + ": " + t.nextToken(""));
         } else {
-            Iterator it = monitorCommands.iterator();
-            while (it.hasNext()) {
-                MessageOutput.printDirectln((String)it.next());// Special case: use printDirectln()
+            for (String cmd : monitorCommands) {
+                MessageOutput.printDirectln(cmd);// Special case: use printDirectln()
             }
         }
     }
@@ -581,9 +577,7 @@
                 return;
             }
             String monStr = monTok + ":";
-            Iterator it = monitorCommands.iterator();
-            while (it.hasNext()) {
-                String cmd = (String)it.next();
+            for (String cmd : monitorCommands) {
                 StringTokenizer ct = new StringTokenizer(cmd);
                 if (ct.nextToken().equals(monStr)) {
                     monitorCommands.remove(cmd);
@@ -768,10 +762,8 @@
     }
 
     private static boolean supportsSharedMemory() {
-        List connectors = Bootstrap.virtualMachineManager().allConnectors();
-        Iterator iter = connectors.iterator();
-        while (iter.hasNext()) {
-            Connector connector = (Connector)iter.next();
+        for (Connector connector :
+                 Bootstrap.virtualMachineManager().allConnectors()) {
             if (connector.transport() == null) {
                 continue;
             }
--- a/src/share/classes/com/sun/tools/example/debug/tty/ThreadGroupIterator.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/tty/ThreadGroupIterator.java	Mon Apr 14 11:34:15 2008 -0700
@@ -36,7 +36,7 @@
  * Descend the tree of thread groups.
  * @author Robert G. Field
  */
-class ThreadGroupIterator implements Iterator {
+class ThreadGroupIterator implements Iterator<ThreadGroupReference> {
     private final Stack<Iterator<ThreadGroupReference>> stack = new Stack<Iterator<ThreadGroupReference>>();
 
     ThreadGroupIterator(List<ThreadGroupReference> tgl) {
@@ -53,8 +53,8 @@
         this(Env.vm().topLevelThreadGroups());
     }
 
-    private Iterator top() {
-        return (Iterator)stack.peek();
+    private Iterator<ThreadGroupReference> top() {
+        return stack.peek();
     }
 
     /**
@@ -74,12 +74,12 @@
         return !stack.isEmpty();
     }
 
-    public Object next() {
+    public ThreadGroupReference next() {
         return nextThreadGroup();
     }
 
     public ThreadGroupReference nextThreadGroup() {
-        ThreadGroupReference tg = (ThreadGroupReference)top().next();
+        ThreadGroupReference tg = top().next();
         push(tg.threadGroups());
         return tg;
     }
--- a/src/share/classes/com/sun/tools/example/debug/tty/ThreadInfo.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/tty/ThreadInfo.java	Mon Apr 14 11:34:15 2008 -0700
@@ -56,9 +56,7 @@
 
     private static void initThreads() {
         if (!gotInitialThreads) {
-            Iterator iter = Env.vm().allThreads().iterator();
-            while (iter.hasNext()) {
-                ThreadReference thread = (ThreadReference)iter.next();
+            for (ThreadReference thread : Env.vm().allThreads()) {
                 threads.add(new ThreadInfo(thread));
             }
             gotInitialThreads = true;
@@ -113,9 +111,7 @@
         current = null;
         group = null;
         synchronized (threads) {
-            Iterator iter = threads().iterator();
-            while (iter.hasNext()) {
-                ThreadInfo ti = (ThreadInfo)iter.next();
+            for (ThreadInfo ti : threads()) {
                 ti.invalidate();
             }
         }
@@ -163,8 +159,7 @@
         if (group == null) {
             // Current thread group defaults to the first top level
             // thread group.
-            setThreadGroup((ThreadGroupReference)
-                           Env.vm().topLevelThreadGroups().get(0));
+            setThreadGroup(Env.vm().topLevelThreadGroups().get(0));
         }
         return group;
     }
@@ -173,9 +168,7 @@
         ThreadInfo retInfo = null;
 
         synchronized (threads) {
-            Iterator iter = threads().iterator();
-            while (iter.hasNext()) {
-                ThreadInfo ti  = (ThreadInfo)iter.next();
+            for (ThreadInfo ti : threads()) {
                 if (ti.thread.uniqueID() == id) {
                    retInfo = ti;
                    break;
@@ -208,7 +201,7 @@
      *
      * @return a <code>List</code> of the stack frames.
      */
-    List getStack() throws IncompatibleThreadStateException {
+    List<StackFrame> getStack() throws IncompatibleThreadStateException {
         return thread.frames();
     }
 
--- a/src/share/classes/com/sun/tools/example/debug/tty/ThreadIterator.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/tty/ThreadIterator.java	Mon Apr 14 11:34:15 2008 -0700
@@ -30,8 +30,8 @@
 import java.util.List;
 import java.util.Iterator;
 
-class ThreadIterator implements Iterator {
-    Iterator it = null;
+class ThreadIterator implements Iterator<ThreadReference> {
+    Iterator<ThreadReference> it = null;
     ThreadGroupIterator tgi;
 
     ThreadIterator(ThreadGroupReference tg) {
@@ -56,12 +56,12 @@
         return true;
     }
 
-    public Object next() {
+    public ThreadReference next() {
         return it.next();
     }
 
     public ThreadReference nextThread() {
-        return (ThreadReference)next();
+        return next();
     }
 
     public void remove() {
--- a/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java	Mon Apr 14 11:34:15 2008 -0700
@@ -61,10 +61,8 @@
     }
 
     private Connector findConnector(String name) {
-        List connectors = Bootstrap.virtualMachineManager().allConnectors();
-        Iterator iter = connectors.iterator();
-        while (iter.hasNext()) {
-            Connector connector = (Connector)iter.next();
+        for (Connector connector :
+                 Bootstrap.virtualMachineManager().allConnectors()) {
             if (connector.name().equals(name)) {
                 return connector;
             }
@@ -108,7 +106,7 @@
             String value = token.substring(index + 1,
                                            token.length() - 1); // Remove comma delimiter
 
-            Connector.Argument argument = (Connector.Argument)arguments.get(name);
+            Connector.Argument argument = arguments.get(name);
             if (argument == null) {
                 throw new IllegalArgumentException
                     (MessageOutput.format("Argument is not defined for connector:",
@@ -195,7 +193,7 @@
             return false;
         }
 
-        Connector.Argument argument = (Connector.Argument)connectorArgs.get(name);
+        Connector.Argument argument = connectorArgs.get(name);
         if (argument == null) {
             return false;
         }
@@ -204,7 +202,7 @@
     }
 
     String connectorArg(String name) {
-        Connector.Argument argument = (Connector.Argument)connectorArgs.get(name);
+        Connector.Argument argument = connectorArgs.get(name);
         if (argument == null) {
             return "";
         }
--- a/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java	Mon Apr 14 11:34:15 2008 -0700
@@ -99,8 +99,7 @@
         }
 
         out.println("<h2>Instance Data Members:</h2>");
-        JavaField[] ff = clazz.getFields();
-        ff = (JavaField[]) ff.clone();
+        JavaField[] ff = clazz.getFields().clone();
         ArraySorter.sort(ff, new Comparer() {
             public int compare(Object lhs, Object rhs) {
                 JavaField left = (JavaField) lhs;
--- a/src/share/classes/com/sun/tools/hat/internal/server/PlatformClasses.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/hat/internal/server/PlatformClasses.java	Mon Apr 14 11:34:15 2008 -0700
@@ -90,9 +90,7 @@
                     // is the right thing to do anyway.
                 }
             }
-            int num = list.size();
-            names = new String[num];
-            names = (String[]) list.toArray(names);
+            names = list.toArray(new String[list.size()]);
         }
         return names;
     }
--- a/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java	Mon Apr 14 11:34:15 2008 -0700
@@ -119,7 +119,7 @@
 
         String[] tokenArray = new String[tokenList.size()];
         for (int i = 0; i < tokenList.size(); i++) {
-            tokenArray[i] = (String)tokenList.get(i);
+            tokenArray[i] = tokenList.get(i);
         }
         return tokenArray;
     }
--- a/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -95,11 +95,8 @@
     }
 
     public List<ClassType> subclasses() {
-        List<ReferenceType> all = vm.allClasses();
         List<ClassType> subs = new ArrayList<ClassType>();
-        Iterator iter = all.iterator();
-        while (iter.hasNext()) {
-            ReferenceType refType = (ReferenceType)iter.next();
+        for (ReferenceType refType : vm.allClasses()) {
             if (refType instanceof ClassType) {
                 ClassType clazz = (ClassType)refType;
                 ClassType superclass = clazz.superclass();
@@ -223,7 +220,7 @@
 
         List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
 
-        ValueImpl[] args = (ValueImpl[])arguments.toArray(new ValueImpl[0]);
+        ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
         JDWP.ClassType.InvokeMethod ret;
         try {
             PacketStream stream =
@@ -271,7 +268,7 @@
 
         List<Value> arguments = method.validateAndPrepareArgumentsForInvoke(
                                                        origArguments);
-        ValueImpl[] args = (ValueImpl[])arguments.toArray(new ValueImpl[0]);
+        ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
         JDWP.ClassType.NewInstance ret = null;
         try {
             PacketStream stream =
@@ -301,11 +298,8 @@
     }
 
     public Method concreteMethodByName(String name, String signature)  {
-       List methods = visibleMethods();
        Method method = null;
-       Iterator iter = methods.iterator();
-       while (iter.hasNext()) {
-           Method candidate = (Method)iter.next();
+       for (Method candidate : visibleMethods()) {
            if (candidate.name().equals(name) &&
                candidate.signature().equals(signature) &&
                !candidate.isAbstract()) {
@@ -330,9 +324,7 @@
          * Avoid duplicate checking on each method by iterating through
          * duplicate-free allInterfaces() rather than recursing
          */
-        Iterator iter = allInterfaces().iterator();
-        while (iter.hasNext()) {
-            InterfaceType interfaze = (InterfaceType)iter.next();
+        for (InterfaceType interfaze : allInterfaces()) {
             list.addAll(interfaze.methods());
         }
 
--- a/src/share/classes/com/sun/tools/jdi/ConcreteMethodImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/ConcreteMethodImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -247,7 +247,7 @@
 
     public byte[] bytecodes() {
         byte[] bytecodes = (bytecodesRef == null) ? null :
-                                     (byte[])bytecodesRef.get();
+                                     bytecodesRef.get();
         if (bytecodes == null) {
             try {
                 bytecodes = JDWP.Method.Bytecodes.
@@ -262,7 +262,7 @@
          * to return the cached bytecodes directly; instead, we
          * make a clone at the cost of using more memory.
          */
-        return (byte[])bytecodes.clone();
+        return bytecodes.clone();
     }
 
     int argSlotCount() throws AbsentInformationException {
@@ -279,7 +279,7 @@
         String stratumID = stratum.id();
         SoftLocationXRefs info =
             (softOtherLocationXRefsRef == null) ? null :
-               (SoftLocationXRefs)softOtherLocationXRefsRef.get();
+               softOtherLocationXRefsRef.get();
         if (info != null && info.stratumID.equals(stratumID)) {
             return info;
         }
@@ -348,7 +348,7 @@
 
     private SoftLocationXRefs getBaseLocations() {
         SoftLocationXRefs info = (softBaseLocationXRefsRef == null) ? null :
-                                     (SoftLocationXRefs)softBaseLocationXRefsRef.get();
+                                     softBaseLocationXRefsRef.get();
         if (info != null) {
             return info;
         }
--- a/src/share/classes/com/sun/tools/jdi/EventSetImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/EventSetImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -56,10 +56,8 @@
     public String toString() {
         String string = "event set, policy:" + suspendPolicy +
                         ", count:" + this.size() + " = {";
-        Iterator iter = this.iterator();
         boolean first = true;
-        while (iter.hasNext()) {
-            Event event = (Event)iter.next();
+        for (Event event : this) {
             if (!first) {
                 string += ", ";
             }
@@ -787,9 +785,7 @@
     }
 
     private ThreadReference eventThread() {
-        Iterator iter = this.iterator();
-        while (iter.hasNext()) {
-            Event event = (Event)iter.next();
+        for (Event event : this) {
             if (event instanceof ThreadedEventImpl) {
                 return ((ThreadedEventImpl)event).thread();
             }
@@ -846,7 +842,7 @@
         }
 
         public Event nextEvent() {
-            return (Event)next();
+            return next();
         }
 
         public void remove() {
--- a/src/share/classes/com/sun/tools/jdi/JNITypeParser.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/JNITypeParser.java	Mon Apr 14 11:34:15 2008 -0700
@@ -82,7 +82,7 @@
     }
 
     String typeName() {
-        return (String)typeNameList().get(typeNameList().size()-1);
+        return typeNameList().get(typeNameList().size()-1);
     }
 
     List<String> argumentTypeNames() {
@@ -90,7 +90,7 @@
     }
 
     String signature() {
-        return (String)signatureList().get(signatureList().size()-1);
+        return signatureList().get(signatureList().size()-1);
     }
 
     List<String> argumentSignatures() {
--- a/src/share/classes/com/sun/tools/jdi/MethodImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/MethodImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -158,7 +158,7 @@
 
     Type argumentType(int index) throws ClassNotLoadedException {
         ReferenceTypeImpl enclosing = (ReferenceTypeImpl)declaringType();
-        String signature = (String)argumentSignatures().get(index);
+        String signature = argumentSignatures().get(index);
         return enclosing.findType(signature);
     }
 
@@ -263,10 +263,10 @@
             return argumentType(index);
         }
         public String typeName(){
-            return (String)argumentTypeNames().get(index);
+            return argumentTypeNames().get(index);
         }
         public String signature() {
-            return (String)argumentSignatures().get(index);
+            return argumentSignatures().get(index);
         }
         public Type findType(String signature) throws ClassNotLoadedException {
             return MethodImpl.this.findType(signature);
@@ -307,7 +307,7 @@
             arguments.add(argArray);
             return;
         }
-        Value nthArgValue = (Value)arguments.get(paramCount - 1);
+        Value nthArgValue = arguments.get(paramCount - 1);
         if (nthArgValue == null) {
             return;
         }
@@ -371,7 +371,7 @@
         }
 
         for (int i = 0; i < argSize; i++) {
-            Value value = (Value)arguments.get(i);
+            Value value = arguments.get(i);
             value = ValueImpl.prepareForAssignment(value,
                                                    new ArgumentContainer(i));
             arguments.set(i, value);
@@ -386,11 +386,11 @@
         sb.append(name());
         sb.append("(");
         boolean first = true;
-        for (Iterator it = argumentTypeNames().iterator(); it.hasNext();) {
+        for (String name : argumentTypeNames()) {
             if (!first) {
                 sb.append(", ");
             }
-            sb.append((String)it.next());
+            sb.append(name);
             first = false;
         }
         sb.append(")");
--- a/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -383,7 +383,7 @@
         List<Value> arguments = method.validateAndPrepareArgumentsForInvoke(
                                                   origArguments);
 
-        ValueImpl[] args = (ValueImpl[])arguments.toArray(new ValueImpl[0]);
+        ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
         JDWP.ObjectReference.InvokeMethod ret;
         try {
             PacketStream stream =
@@ -583,7 +583,7 @@
         // Validate assignment
         ReferenceType destType = (ReferenceTypeImpl)destination.type();
         ReferenceTypeImpl myType = (ReferenceTypeImpl)referenceType();
-        if (!myType.isAssignableTo((ReferenceType)destType)) {
+        if (!myType.isAssignableTo(destType)) {
             JNITypeParser parser = new JNITypeParser(destType.signature());
             String destTypeName = parser.typeName();
             throw new InvalidTypeException("Can't assign " +
--- a/src/share/classes/com/sun/tools/jdi/PacketStream.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/PacketStream.java	Mon Apr 14 11:34:15 2008 -0700
@@ -485,7 +485,7 @@
      * Read field represented as vm specific byte sequence.
      */
     Field readField() {
-        ReferenceTypeImpl refType = (ReferenceTypeImpl)readReferenceType();
+        ReferenceTypeImpl refType = readReferenceType();
         long fieldRef = readFieldRef();
         return refType.getFieldMirror(fieldRef);
     }
--- a/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -59,7 +59,7 @@
     private boolean constantPoolInfoGotten = false;
     private int constanPoolCount;
     private byte[] constantPoolBytes;
-    private SoftReference constantPoolBytesRef = null;
+    private SoftReference<byte[]> constantPoolBytesRef = null;
 
     /* to mark a SourceFile request that returned a genuine JDWP.Error.ABSENT_INFORMATION */
     private static final String ABSENT_BASE_SOURCE_NAME = "**ABSENT_BASE_SOURCE_NAME**";
@@ -352,13 +352,10 @@
     abstract List<? extends ReferenceType> inheritedTypes();
 
     void addVisibleFields(List<Field> visibleList, Map<String, Field> visibleTable, List<String> ambiguousNames) {
-        List<Field> list = visibleFields();
-        Iterator iter = list.iterator();
-        while (iter.hasNext()) {
-            Field field = (Field)iter.next();
+        for (Field field : visibleFields()) {
             String name = field.name();
             if (!ambiguousNames.contains(name)) {
-                Field duplicate = (Field)visibleTable.get(name);
+                Field duplicate = visibleTable.get(name);
                 if (duplicate == null) {
                     visibleList.add(field);
                     visibleTable.put(name, field);
@@ -402,10 +399,8 @@
          * hide.
          */
         List<Field> retList = new ArrayList<Field>(fields());
-        iter = retList.iterator();
-        while (iter.hasNext()) {
-            Field field = (Field)iter.next();
-            Field hidden = (Field)visibleTable.get(field.name());
+        for (Field field : retList) {
+            Field hidden = visibleTable.get(field.name());
             if (hidden != null) {
                 visibleList.remove(hidden);
             }
@@ -515,12 +510,9 @@
      * methods.
      */
     void addToMethodMap(Map<String, Method> methodMap, List<Method> methodList) {
-        Iterator iter = methodList.iterator();
-        while (iter.hasNext()) {
-            Method method = (Method)iter.next();
+        for (Method method : methodList)
             methodMap.put(method.name().concat(method.signature()), method);
         }
-    }
 
     abstract void addVisibleMethods(Map<String, Method> methodMap);
 
@@ -549,9 +541,7 @@
     public List<Method> methodsByName(String name) {
         List<Method> methods = visibleMethods();
         ArrayList<Method> retList = new ArrayList<Method>(methods.size());
-        Iterator iter = methods.iterator();
-        while (iter.hasNext()) {
-            Method candidate = (Method)iter.next();
+        for (Method candidate : methods) {
             if (candidate.name().equals(name)) {
                 retList.add(candidate);
             }
@@ -563,9 +553,7 @@
     public List<Method> methodsByName(String name, String signature) {
         List<Method> methods = visibleMethods();
         ArrayList<Method> retList = new ArrayList<Method>(methods.size());
-        Iterator iter = methods.iterator();
-        while (iter.hasNext()) {
-            Method candidate = (Method)iter.next();
+        for (Method candidate : methods) {
             if (candidate.name().equals(name) &&
                 candidate.signature().equals(signature)) {
                 retList.add(candidate);
@@ -706,7 +694,7 @@
     }
 
     public String sourceName() throws AbsentInformationException {
-        return (String)(sourceNames(vm.getDefaultStratum()).get(0));
+        return sourceNames(vm.getDefaultStratum()).get(0);
     }
 
     public List<String> sourceNames(String stratumID)
@@ -796,7 +784,7 @@
         if (!vm.canGetSourceDebugExtension()) {
             return NO_SDE_INFO_MARK;
         }
-        SDE sde = (sdeRef == null) ?  null : (SDE)sdeRef.get();
+        SDE sde = (sdeRef == null) ?  null : sdeRef.get();
         if (sde == null) {
             String extension = null;
             try {
@@ -1034,13 +1022,13 @@
             throw exc;
         }
         if (constantPoolBytesRef != null) {
-            byte[] cpbytes = (byte[])constantPoolBytesRef.get();
+            byte[] cpbytes = constantPoolBytesRef.get();
             /*
              * Arrays are always modifiable, so it is a little unsafe
              * to return the cached bytecodes directly; instead, we
              * make a clone at the cost of using more memory.
              */
-            return (byte[])cpbytes.clone();
+            return cpbytes.clone();
         } else {
             return null;
         }
--- a/src/share/classes/com/sun/tools/jdi/SDE.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/SDE.java	Mon Apr 14 11:34:15 2008 -0700
@@ -327,7 +327,7 @@
 
         ignoreWhite();
         while (((ch = sdeRead()) != '\n') && (ch != '\r')) {
-            sb.append((char)ch);
+            sb.append(ch);
         }
         // check for CR LF
         if ((ch == '\r') && (sdePeek() == '\n')) {
--- a/src/share/classes/com/sun/tools/jdi/StackFrameImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/StackFrameImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -162,7 +162,7 @@
             for (LocalVariable variable : allVariables) {
                 String name = variable.name();
                 if (variable.isVisible(this)) {
-                    LocalVariable existing = (LocalVariable)map.get(name);
+                    LocalVariable existing = map.get(name);
                     if ((existing == null) ||
                         ((LocalVariableImpl)variable).hides(existing)) {
                         map.put(name, variable);
@@ -330,7 +330,7 @@
             slot = 1;
         }
         for (int ii = 0; ii < count; ++ii) {
-            char sigChar =  (char)argSigs.get(ii).charAt(0);
+            char sigChar = argSigs.get(ii).charAt(0);
             slots[ii] = new JDWP.StackFrame.GetValues.SlotInfo(slot++,(byte)sigChar);
             if (sigChar == 'J' || sigChar == 'D') {
                 slot++;
--- a/src/share/classes/com/sun/tools/jdi/TargetVM.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/TargetVM.java	Mon Apr 14 11:34:15 2008 -0700
@@ -148,7 +148,7 @@
                 idString = String.valueOf(p.id);
 
                 synchronized(waitingQueue) {
-                    p2 = (Packet)waitingQueue.get(idString);
+                    p2 = waitingQueue.get(idString);
 
                     if (p2 != null)
                         waitingQueue.remove(idString);
--- a/src/share/classes/com/sun/tools/jdi/ThreadGroupReferenceImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/ThreadGroupReferenceImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -86,30 +86,22 @@
     }
 
     public void suspend() {
-        List threads = threads();
-        Iterator iter = threads.iterator();
-        while (iter.hasNext()) {
-                ((ThreadReference)iter.next()).suspend();
+        for (ThreadReference thread : threads()) {
+            thread.suspend();
         }
 
-        List groups = threadGroups();
-        iter = groups.iterator();
-        while (iter.hasNext()) {
-                ((ThreadGroupReference)iter.next()).suspend();
+        for (ThreadGroupReference threadGroup : threadGroups()) {
+            threadGroup.suspend();
         }
     }
 
     public void resume() {
-        List threads = threads();
-        Iterator iter = threads.iterator();
-        while (iter.hasNext()) {
-                ((ThreadReference)iter.next()).resume();
+        for (ThreadReference thread : threads()) {
+            thread.resume();
         }
 
-        List groups = threadGroups();
-        iter = groups.iterator();
-        while (iter.hasNext()) {
-                ((ThreadGroupReference)iter.next()).resume();
+        for (ThreadGroupReference threadGroup : threadGroups()) {
+            threadGroup.resume();
         }
     }
 
--- a/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1191,8 +1191,7 @@
                 }
                 requests = new JDWP.VirtualMachine.DisposeObjects.Request[size];
                 for (int i = 0; i < requests.length; i++) {
-                    SoftObjectReference ref =
-                        (SoftObjectReference)batchedDisposeRequests.get(i);
+                    SoftObjectReference ref = batchedDisposeRequests.get(i);
                     if ((traceFlags & TRACE_OBJREFS) != 0) {
                         printTrace("Disposing object " + ref.key().longValue() +
                                    " (ref count = " + ref.count() + ")");
@@ -1436,7 +1435,7 @@
        }
 
        ObjectReferenceImpl object() {
-           return (ObjectReferenceImpl)get();
+           return get();
        }
    }
 }
--- a/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -92,7 +92,7 @@
             Connector connector;
 
             try {
-                connector = (Connector)connectors.next();
+                connector = connectors.next();
             } catch (ThreadDeath x) {
                 throw x;
             } catch (Exception x) {
@@ -121,7 +121,7 @@
             TransportService transportService;
 
             try {
-                transportService = (TransportService)transportServices.next();
+                transportService = transportServices.next();
             } catch (ThreadDeath x) {
                 throw x;
             } catch (Exception x) {
--- a/src/share/classes/java/awt/Component.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/awt/Component.java	Mon Apr 14 11:34:15 2008 -0700
@@ -634,6 +634,11 @@
      */
     private PropertyChangeSupport changeSupport;
 
+    private transient final Object changeSupportLock = new Object();
+    private Object getChangeSupportLock() {
+        return changeSupportLock;
+    }
+
     boolean isPacked = false;
 
     /**
@@ -935,24 +940,26 @@
      */
     public GraphicsConfiguration getGraphicsConfiguration() {
         synchronized(getTreeLock()) {
-            GraphicsConfiguration gc = graphicsConfig;
-            Component parent = getParent();
-            while ((gc == null) && (parent != null)) {
-                gc = parent.getGraphicsConfiguration();
-                parent = parent.getParent();
-            }
-            return gc;
+            if (graphicsConfig != null) {
+                return graphicsConfig;
+            } else if (getParent() != null) {
+                return getParent().getGraphicsConfiguration();
+            } else {
+                return null;
+            }
         }
     }
 
     final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() {
-        GraphicsConfiguration gc = this.graphicsConfig;
-        Component par = this.parent;
-        while ((gc == null) && (par != null)) {
-            gc = par.getGraphicsConfiguration_NoClientCode();
-            par = par.parent;
-        }
-        return gc;
+        GraphicsConfiguration graphicsConfig = this.graphicsConfig;
+        Container parent = this.parent;
+        if (graphicsConfig != null) {
+            return graphicsConfig;
+        } else if (parent != null) {
+            return parent.getGraphicsConfiguration_NoClientCode();
+        } else {
+            return null;
+        }
     }
 
     /**
@@ -4602,7 +4609,8 @@
                                              e.isPopupTrigger(),
                                              e.getScrollType(),
                                              e.getScrollAmount(),
-                                             e.getWheelRotation());
+                                             e.getWheelRotation(),
+                                             e.getPreciseWheelRotation());
                 ((AWTEvent)e).copyPrivateDataInto(newMWE);
                 // When dispatching a wheel event to
                 // ancestor, there is no need trying to find descendant
@@ -6484,7 +6492,7 @@
                 // will need some help.
                 Container parent = this.parent;
                 if (parent != null && parent.peer instanceof LightweightPeer) {
-                    nativeInLightFixer = new NativeInLightFixer();
+                    relocateComponent();
                 }
             }
             invalidate();
@@ -6595,10 +6603,6 @@
                 }
             }
 
-            if (nativeInLightFixer != null) {
-                nativeInLightFixer.uninstall();
-            }
-
             ComponentPeer p = peer;
             if (p != null) {
                 boolean isLightweight = isLightweight();
@@ -7836,15 +7840,17 @@
      * @see #getPropertyChangeListeners
      * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
      */
-    public synchronized void addPropertyChangeListener(
+    public void addPropertyChangeListener(
                                                        PropertyChangeListener listener) {
-        if (listener == null) {
-            return;
-        }
-        if (changeSupport == null) {
-            changeSupport = new PropertyChangeSupport(this);
-        }
-        changeSupport.addPropertyChangeListener(listener);
+        synchronized (getChangeSupportLock()) {
+            if (listener == null) {
+                return;
+            }
+            if (changeSupport == null) {
+                changeSupport = new PropertyChangeSupport(this);
+            }
+            changeSupport.addPropertyChangeListener(listener);
+        }
     }
 
     /**
@@ -7860,12 +7866,14 @@
      * @see #getPropertyChangeListeners
      * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
      */
-    public synchronized void removePropertyChangeListener(
+    public void removePropertyChangeListener(
                                                           PropertyChangeListener listener) {
-        if (listener == null || changeSupport == null) {
-            return;
-        }
-        changeSupport.removePropertyChangeListener(listener);
+        synchronized (getChangeSupportLock()) {
+            if (listener == null || changeSupport == null) {
+                return;
+            }
+            changeSupport.removePropertyChangeListener(listener);
+        }
     }
 
     /**
@@ -7882,11 +7890,13 @@
      * @see      java.beans.PropertyChangeSupport#getPropertyChangeListeners
      * @since    1.4
      */
-    public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
-        if (changeSupport == null) {
-            return new PropertyChangeListener[0];
-        }
-        return changeSupport.getPropertyChangeListeners();
+    public PropertyChangeListener[] getPropertyChangeListeners() {
+        synchronized (getChangeSupportLock()) {
+            if (changeSupport == null) {
+                return new PropertyChangeListener[0];
+            }
+            return changeSupport.getPropertyChangeListeners();
+        }
     }
 
     /**
@@ -7920,16 +7930,18 @@
      * @see #getPropertyChangeListeners(java.lang.String)
      * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
      */
-    public synchronized void addPropertyChangeListener(
+    public void addPropertyChangeListener(
                                                        String propertyName,
                                                        PropertyChangeListener listener) {
-        if (listener == null) {
-            return;
-        }
-        if (changeSupport == null) {
-            changeSupport = new PropertyChangeSupport(this);
-        }
-        changeSupport.addPropertyChangeListener(propertyName, listener);
+        synchronized (getChangeSupportLock()) {
+            if (listener == null) {
+                return;
+            }
+            if (changeSupport == null) {
+                changeSupport = new PropertyChangeSupport(this);
+            }
+            changeSupport.addPropertyChangeListener(propertyName, listener);
+        }
     }
 
     /**
@@ -7948,13 +7960,15 @@
      * @see #getPropertyChangeListeners(java.lang.String)
      * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
      */
-    public synchronized void removePropertyChangeListener(
+    public void removePropertyChangeListener(
                                                           String propertyName,
                                                           PropertyChangeListener listener) {
-        if (listener == null || changeSupport == null) {
-            return;
-        }
-        changeSupport.removePropertyChangeListener(propertyName, listener);
+        synchronized (getChangeSupportLock()) {
+            if (listener == null || changeSupport == null) {
+                return;
+            }
+            changeSupport.removePropertyChangeListener(propertyName, listener);
+        }
     }
 
     /**
@@ -7971,12 +7985,14 @@
      * @see #getPropertyChangeListeners
      * @since 1.4
      */
-    public synchronized PropertyChangeListener[] getPropertyChangeListeners(
+    public PropertyChangeListener[] getPropertyChangeListeners(
                                                                             String propertyName) {
-        if (changeSupport == null) {
-            return new PropertyChangeListener[0];
-        }
-        return changeSupport.getPropertyChangeListeners(propertyName);
+        synchronized (getChangeSupportLock()) {
+            if (changeSupport == null) {
+                return new PropertyChangeListener[0];
+            }
+            return changeSupport.getPropertyChangeListeners(propertyName);
+        }
     }
 
     /**
@@ -7991,7 +8007,10 @@
      */
     protected void firePropertyChange(String propertyName,
                                       Object oldValue, Object newValue) {
-        PropertyChangeSupport changeSupport = this.changeSupport;
+        PropertyChangeSupport changeSupport;
+        synchronized (getChangeSupportLock()) {
+            changeSupport = this.changeSupport;
+        }
         if (changeSupport == null ||
             (oldValue != null && newValue != null && oldValue.equals(newValue))) {
             return;
@@ -8491,8 +8510,6 @@
         setComponentOrientation(orientation);
     }
 
-    transient NativeInLightFixer nativeInLightFixer;
-
     /**
      * Checks that this component meets the prerequesites to be focus owner:
      * - it is enabled, visible, focusable
@@ -8518,188 +8535,25 @@
     }
 
     /**
-     * This odd class is to help out a native component that has been
-     * embedded in a lightweight component.  Moving lightweight
-     * components around and changing their visibility is not seen
-     * by the native window system.  This is a feature for lightweights,
-     * but a problem for native components that depend upon the
-     * lightweights.  An instance of this class listens to the lightweight
-     * parents of an associated native component (the outer class).
-     *
-     * @author  Timothy Prinzing
-     */
-    final class NativeInLightFixer implements ComponentListener, ContainerListener {
-
-        NativeInLightFixer() {
-            lightParents = new Vector();
-            install(parent);
-        }
-
-        void install(Container parent) {
-            lightParents.clear();
-            Container p = parent;
-            boolean isLwParentsVisible = true;
-            // stash a reference to the components that are being observed so that
-            // we can reliably remove ourself as a listener later.
-            for (; p.peer instanceof LightweightPeer; p = p.parent) {
-
-                // register listeners and stash a reference
-                p.addComponentListener(this);
-                p.addContainerListener(this);
-                lightParents.addElement(p);
-                isLwParentsVisible &= p.isVisible();
-            }
-            // register with the native host (native parent of associated native)
-            // to get notified if the top-level lightweight is removed.
-            nativeHost = p;
-            p.addContainerListener(this);
-
-            // kick start the fixup.  Since the event isn't looked at
-            // we can simulate movement notification.
-            componentMoved(null);
-            if (!isLwParentsVisible) {
-                synchronized (getTreeLock()) {
-                    if (peer != null) {
-                        peer.hide();
-                    }
-                }
-            }
-        }
-
-        void uninstall() {
-            if (nativeHost != null) {
-                removeReferences();
-            }
-        }
-
-        // --- ComponentListener -------------------------------------------
-
-        /**
-         * Invoked when one of the lightweight parents has been resized.
-         * This doesn't change the position of the native child so it
-         * is ignored.
-         */
-        public void componentResized(ComponentEvent e) {
-        }
-
-        /**
-         * Invoked when one of the lightweight parents has been moved.
-         * The native peer must be told of the new position which is
-         * relative to the native container that is hosting the
-         * lightweight components.
-         */
-        public void componentMoved(ComponentEvent e) {
-            synchronized (getTreeLock()) {
-                int nativeX = x;
-                int nativeY = y;
-                for(Component c = parent; (c != null) &&
-                        (c.peer instanceof LightweightPeer);
-                    c = c.parent) {
-
-                    nativeX += c.x;
-                    nativeY += c.y;
-                }
-                if (peer != null) {
-                    peer.setBounds(nativeX, nativeY, width, height,
-                                   ComponentPeer.SET_LOCATION);
-                }
-            }
-        }
-
-        /**
-         * Invoked when a lightweight parent component has been
-         * shown.  The associated native component must also be
-         * shown if it hasn't had an overriding hide done on it.
-         */
-        public void componentShown(ComponentEvent e) {
-            if (shouldShow()) {
-                synchronized (getTreeLock()) {
-                    if (peer != null) {
-                        peer.show();
-                    }
-                }
-            }
-        }
-
-        /**
-         * Invoked when one of the lightweight parents become visible.
-         * Returns true if component and all its lightweight
-         * parents are visible.
-         */
-        private boolean shouldShow() {
-            boolean isLwParentsVisible = visible;
-            for (int i = lightParents.size() - 1;
-                 i >= 0 && isLwParentsVisible;
-                 i--)
+     * Fix the location of the HW component in a LW container hierarchy.
+     */
+    final void relocateComponent() {
+        synchronized (getTreeLock()) {
+            if (peer == null) {
+                return;
+            }
+            int nativeX = x;
+            int nativeY = y;
+            for (Component cont = getContainer();
+                    cont != null && cont.isLightweight();
+                    cont = cont.getContainer())
             {
-                isLwParentsVisible &=
-                    ((Container) lightParents.elementAt(i)).isVisible();
-            }
-            return isLwParentsVisible;
-        }
-
-        /**
-         * Invoked when component has been hidden.
-         */
-        public void componentHidden(ComponentEvent e) {
-            if (visible) {
-                synchronized (getTreeLock()) {
-                    if (peer != null) {
-                        peer.hide();
-                    }
-                }
-            }
-        }
-
-        // --- ContainerListener ------------------------------------
-
-        /**
-         * Invoked when a component has been added to a lightweight
-         * parent.  This doesn't effect the native component.
-         */
-        public void componentAdded(ContainerEvent e) {
-        }
-
-        /**
-         * Invoked when a lightweight parent has been removed.
-         * This means the services of this listener are no longer
-         * required and it should remove all references (ie
-         * registered listeners).
-         */
-        public void componentRemoved(ContainerEvent e) {
-            Component c = e.getChild();
-            if (c == Component.this) {
-                removeReferences();
-            } else {
-                int n = lightParents.size();
-                for (int i = 0; i < n; i++) {
-                    Container p = (Container) lightParents.elementAt(i);
-                    if (p == c) {
-                        removeReferences();
-                        break;
-                    }
-                }
-            }
-        }
-
-        /**
-         * Removes references to this object so it can be
-         * garbage collected.
-         */
-        void removeReferences() {
-            int n = lightParents.size();
-            for (int i = 0; i < n; i++) {
-                Container c = (Container) lightParents.elementAt(i);
-                c.removeComponentListener(this);
-                c.removeContainerListener(this);
-            }
-            nativeHost.removeContainerListener(this);
-            lightParents.clear();
-            nativeHost = null;
-        }
-
-        Vector lightParents;
-        Container nativeHost;
+                nativeX += cont.x;
+                nativeY += cont.y;
+            }
+            peer.setBounds(nativeX, nativeY, width, height,
+                    ComponentPeer.SET_LOCATION);
+        }
     }
 
     /**
@@ -9453,6 +9307,19 @@
     // ************************** MIXING CODE *******************************
 
     /**
+     * Check whether we can trust the current bounds of the component.
+     * The return value of false indicates that the container of the
+     * component is invalid, and therefore needs to be layed out, which would
+     * probably mean changing the bounds of its children.
+     * Null-layout of the container or absence of the container mean
+     * the bounds of the component are final and can be trusted.
+     */
+    private boolean areBoundsValid() {
+        Container cont = getContainer();
+        return cont == null || cont.isValid() || cont.getLayout() == null;
+    }
+
+    /**
      * Applies the shape to the component
      * @param shape Shape to be applied to the component
      */
@@ -9475,7 +9342,7 @@
                 // to modify the object outside of the mixing code.
                 this.compoundShape = shape;
 
-                if (isValid()) {
+                if (areBoundsValid()) {
                     Point compAbsolute = getLocationOnWindow();
 
                     if (mixingLog.isLoggable(Level.FINER)) {
@@ -9602,7 +9469,7 @@
 
     void applyCurrentShape() {
         checkTreeLock();
-        if (!isValid()) {
+        if (!areBoundsValid()) {
             return; // Because applyCompoundShape() ignores such components anyway
         }
         if (mixingLog.isLoggable(Level.FINE)) {
--- a/src/share/classes/java/awt/Container.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/awt/Container.java	Mon Apr 14 11:34:15 2008 -0700
@@ -832,16 +832,8 @@
                 }
                 if (!comp.isLightweight() && isLightweight()) {
                     // If component is heavyweight and one of the containers is lightweight
-                    // some NativeInLightFixer activity should be performed
-                    if (!curParent.isLightweight()) {
-                        // Moving from heavyweight container to lightweight container - should create NativeInLightFixer
-                        // since addNotify does this
-                        comp.nativeInLightFixer = new NativeInLightFixer();
-                    } else {
-                        // Component already has NativeInLightFixer - just reinstall it
-                        // because hierarchy changed and he needs to rebuild list of parents to listen.
-                        comp.nativeInLightFixer.install(this);
-                    }
+                    // the location of the component should be fixed.
+                    comp.relocateComponent();
                 }
             }
         }
@@ -2267,53 +2259,56 @@
                                          EventTargetFilter filter,
                                          boolean searchHeavyweightChildren,
                                          boolean searchHeavyweightDescendants) {
-        int ncomponents = this.ncomponents;
-        Component component[] = this.component;
-
-        for (int i = 0 ; i < ncomponents ; i++) {
-            Component comp = component[i];
-            if (comp != null && comp.visible &&
-                ((!searchHeavyweightChildren &&
-                  comp.peer instanceof LightweightPeer) ||
-                 (searchHeavyweightChildren &&
-                  !(comp.peer instanceof LightweightPeer))) &&
-                comp.contains(x - comp.x, y - comp.y)) {
-
-                // found a component that intersects the point, see if there is
-                // a deeper possibility.
-                if (comp instanceof Container) {
-                    Container child = (Container) comp;
-                    Component deeper = child.getMouseEventTarget(x - child.x,
-                                                                 y - child.y,
-                                                                 includeSelf,
-                                                                 filter,
-                                                                 searchHeavyweightDescendants);
-                    if (deeper != null) {
-                        return deeper;
-                    }
-                } else {
-                    if (filter.accept(comp)) {
-                        // there isn't a deeper target, but this component is a
-                        // target
-                        return comp;
+        synchronized (getTreeLock()) {
+            int ncomponents = this.ncomponents;
+            Component component[] = this.component;
+
+            for (int i = 0 ; i < ncomponents ; i++) {
+                Component comp = component[i];
+                if (comp != null && comp.visible &&
+                    ((!searchHeavyweightChildren &&
+                      comp.peer instanceof LightweightPeer) ||
+                     (searchHeavyweightChildren &&
+                      !(comp.peer instanceof LightweightPeer))) &&
+                    comp.contains(x - comp.x, y - comp.y)) {
+
+                    // found a component that intersects the point, see if there
+                    // is a deeper possibility.
+                    if (comp instanceof Container) {
+                        Container child = (Container) comp;
+                        Component deeper = child.getMouseEventTarget(
+                                x - child.x,
+                                y - child.y,
+                                includeSelf,
+                                filter,
+                                searchHeavyweightDescendants);
+                        if (deeper != null) {
+                            return deeper;
+                        }
+                    } else {
+                        if (filter.accept(comp)) {
+                            // there isn't a deeper target, but this component
+                            // is a target
+                            return comp;
+                        }
                     }
                 }
             }
+
+            boolean isPeerOK;
+            boolean isMouseOverMe;
+
+            isPeerOK = (peer instanceof LightweightPeer) || includeSelf;
+            isMouseOverMe = contains(x,y);
+
+            // didn't find a child target, return this component if it's
+            // a possible target
+            if (isMouseOverMe && isPeerOK && filter.accept(this)) {
+                return this;
+            }
+            // no possible target
+            return null;
         }
-
-        boolean isPeerOK;
-        boolean isMouseOverMe;
-
-        isPeerOK = (peer instanceof LightweightPeer) || includeSelf;
-        isMouseOverMe = contains(x,y);
-
-        // didn't find a child target, return this component if it's a possible
-        // target
-        if (isMouseOverMe && isPeerOK && filter.accept(this)) {
-            return this;
-        }
-        // no possible target
-        return null;
     }
 
     static interface EventTargetFilter {
@@ -3950,6 +3945,83 @@
         }
     }
 
+    private void recursiveShowHeavyweightChildren() {
+        if (!hasHeavyweightDescendants() || !isVisible()) {
+            return;
+        }
+        for (int index = 0; index < getComponentCount(); index++) {
+            Component comp = getComponent(index);
+            if (comp.isLightweight()) {
+                if  (comp instanceof Container) {
+                    ((Container)comp).recursiveShowHeavyweightChildren();
+                }
+            } else {
+                if (comp.isVisible()) {
+                    ComponentPeer peer = comp.getPeer();
+                    if (peer != null) {
+                        peer.show();
+                    }
+                }
+            }
+        }
+    }
+
+    private void recursiveHideHeavyweightChildren() {
+        if (!hasHeavyweightDescendants()) {
+            return;
+        }
+        for (int index = 0; index < getComponentCount(); index++) {
+            Component comp = getComponent(index);
+            if (comp.isLightweight()) {
+                if  (comp instanceof Container) {
+                    ((Container)comp).recursiveHideHeavyweightChildren();
+                }
+            } else {
+                if (comp.isVisible()) {
+                    ComponentPeer peer = comp.getPeer();
+                    if (peer != null) {
+                        peer.hide();
+                    }
+                }
+            }
+        }
+    }
+
+    private void recursiveRelocateHeavyweightChildren(Point origin) {
+        for (int index = 0; index < getComponentCount(); index++) {
+            Component comp = getComponent(index);
+            if (comp.isLightweight()) {
+                if  (comp instanceof Container &&
+                        ((Container)comp).hasHeavyweightDescendants())
+                {
+                    final Point newOrigin = new Point(origin);
+                    newOrigin.translate(comp.getX(), comp.getY());
+                    ((Container)comp).recursiveRelocateHeavyweightChildren(newOrigin);
+                }
+            } else {
+                ComponentPeer peer = comp.getPeer();
+                if (peer != null) {
+                    peer.setBounds(origin.x + comp.getX(), origin.y + comp.getY(),
+                            comp.getWidth(), comp.getHeight(),
+                            ComponentPeer.SET_LOCATION);
+                }
+            }
+        }
+    }
+
+    /*
+     * Consider the heavyweight container hides or shows the HW descendants
+     * automatically. Therefore we care of LW containers' visibility only.
+     */
+    private boolean isRecursivelyVisibleUpToHeavyweightContainer() {
+        if (!isLightweight()) {
+            return true;
+        }
+        return isVisible() && (getContainer() == null ||
+             getContainer().isRecursivelyVisibleUpToHeavyweightContainer());
+    }
+
+    @Override
     void mixOnShowing() {
         synchronized (getTreeLock()) {
             if (mixingLog.isLoggable(Level.FINE)) {
@@ -3958,6 +4030,10 @@
 
             boolean isLightweight = isLightweight();
 
+            if (isLightweight && isRecursivelyVisibleUpToHeavyweightContainer()) {
+                recursiveShowHeavyweightChildren();
+            }
+
             if (!isLightweight || (isLightweight && hasHeavyweightDescendants())) {
                 recursiveApplyCurrentShape();
             }
@@ -3966,6 +4042,42 @@
         }
     }
 
+    @Override
+    void mixOnHiding(boolean isLightweight) {
+        synchronized (getTreeLock()) {
+            if (mixingLog.isLoggable(Level.FINE)) {
+                mixingLog.fine("this = " + this +
+                        "; isLightweight=" + isLightweight);
+            }
+            if (isLightweight) {
+                recursiveHideHeavyweightChildren();
+            }
+            super.mixOnHiding(isLightweight);
+        }
+    }
+
+    @Override
+    void mixOnReshaping() {
+        synchronized (getTreeLock()) {
+            if (mixingLog.isLoggable(Level.FINE)) {
+                mixingLog.fine("this = " + this);
+            }
+            if (isLightweight() && hasHeavyweightDescendants()) {
+                final Point origin = new Point(getX(), getY());
+                for (Container cont = getContainer();
+                        cont != null && cont.isLightweight();
+                        cont = cont.getContainer())
+                {
+                    origin.translate(cont.getX(), cont.getY());
+                }
+
+                recursiveRelocateHeavyweightChildren(origin);
+            }
+            super.mixOnReshaping();
+        }
+    }
+
+    @Override
     void mixOnZOrderChanging(int oldZorder, int newZorder) {
         synchronized (getTreeLock()) {
             if (mixingLog.isLoggable(Level.FINE)) {
@@ -4431,7 +4543,8 @@
                                        e.isPopupTrigger(),
                                        ((MouseWheelEvent)e).getScrollType(),
                                        ((MouseWheelEvent)e).getScrollAmount(),
-                                       ((MouseWheelEvent)e).getWheelRotation());
+                                       ((MouseWheelEvent)e).getWheelRotation(),
+                                       ((MouseWheelEvent)e).getPreciseWheelRotation());
             }
             else {
                 retargeted = new MouseEvent(target,
--- a/src/share/classes/java/awt/DefaultKeyboardFocusManager.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/awt/DefaultKeyboardFocusManager.java	Mon Apr 14 11:34:15 2008 -0700
@@ -154,7 +154,7 @@
     private boolean doRestoreFocus(Component toFocus, Component vetoedComponent,
                                    boolean clearOnFailure)
     {
-        if (toFocus.isShowing() && toFocus.isFocusable() &&
+        if (toFocus != vetoedComponent && toFocus.isShowing() && toFocus.isFocusable() &&
             toFocus.requestFocus(false, CausedFocusEvent.Cause.ROLLBACK)) {
             return true;
         } else {
--- a/src/share/classes/java/awt/Window.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/awt/Window.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1995-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,6 @@
  */
 package java.awt;
 
-import java.applet.Applet;
 import java.awt.event.*;
 import java.awt.im.InputContext;
 import java.awt.image.BufferStrategy;
@@ -355,18 +354,21 @@
     static class WindowDisposerRecord implements sun.java2d.DisposerRecord {
         final WeakReference<Window> owner;
         final WeakReference weakThis;
-        final AppContext context;
+        final WeakReference<AppContext> context;
         WindowDisposerRecord(AppContext context, Window victim) {
             owner = new WeakReference<Window>(victim.getOwner());
             weakThis = victim.weakThis;
-            this.context = context;
+            this.context = new WeakReference<AppContext>(context);
         }
         public void dispose() {
             Window parent = owner.get();
             if (parent != null) {
                 parent.removeOwnedWindow(weakThis);
             }
-            Window.removeFromWindowList(context, weakThis);
+            AppContext ac = context.get();
+            if (null != ac) {
+                Window.removeFromWindowList(ac, weakThis);
+            }
         }
     }
 
@@ -824,7 +826,10 @@
     static private final AtomicBoolean
         beforeFirstWindowShown = new AtomicBoolean(true);
 
-    static final void closeSplashScreen() {
+    final void closeSplashScreen() {
+        if (isTrayIconWindow) {
+            return;
+        }
         if (beforeFirstWindowShown.getAndSet(false)) {
             SunToolkit.closeSplashScreen();
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/color/CMMException.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,57 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+    Created by gbp, October 25, 1997
+
+ *
+ */
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+
+package java.awt.color;
+
+
+/**
+ * This exception is thrown if the native CMM returns an error.
+ */
+
+public class CMMException extends java.lang.RuntimeException {
+
+    /**
+     *  Constructs a CMMException with the specified detail message.
+     *  @param s the specified detail message
+     */
+    public CMMException (String s) {
+        super (s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/color/ColorSpace.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,611 @@
+/*
+ * Portions Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+package java.awt.color;
+
+import sun.java2d.cmm.PCMM;
+import sun.java2d.cmm.CMSManager;
+
+
+/**
+ * This abstract class is used to serve as a color space tag to identify the
+ * specific color space of a Color object or, via a ColorModel object,
+ * of an Image, a BufferedImage, or a GraphicsDevice.  It contains
+ * methods that transform colors in a specific color space to/from sRGB
+ * and to/from a well-defined CIEXYZ color space.
+ * <p>
+ * For purposes of the methods in this class, colors are represented as
+ * arrays of color components represented as floats in a normalized range
+ * defined by each ColorSpace.  For many ColorSpaces (e.g. sRGB), this
+ * range is 0.0 to 1.0.  However, some ColorSpaces have components whose
+ * values have a different range.  Methods are provided to inquire per
+ * component minimum and maximum normalized values.
+ * <p>
+ * Several variables are defined for purposes of referring to color
+ * space types (e.g. TYPE_RGB, TYPE_XYZ, etc.) and to refer to specific
+ * color spaces (e.g. CS_sRGB and CS_CIEXYZ).
+ * sRGB is a proposed standard RGB color space.  For more information,
+ * see <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
+ * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
+ * </A>.
+ * <p>
+ * The purpose of the methods to transform to/from the well-defined
+ * CIEXYZ color space is to support conversions between any two color
+ * spaces at a reasonably high degree of accuracy.  It is expected that
+ * particular implementations of subclasses of ColorSpace (e.g.
+ * ICC_ColorSpace) will support high performance conversion based on
+ * underlying platform color management systems.
+ * <p>
+ * The CS_CIEXYZ space used by the toCIEXYZ/fromCIEXYZ methods can be
+ * described as follows:
+<pre>
+
+&nbsp;     CIEXYZ
+&nbsp;     viewing illuminance: 200 lux
+&nbsp;     viewing white point: CIE D50
+&nbsp;     media white point: "that of a perfectly reflecting diffuser" -- D50
+&nbsp;     media black point: 0 lux or 0 Reflectance
+&nbsp;     flare: 1 percent
+&nbsp;     surround: 20percent of the media white point
+&nbsp;     media description: reflection print (i.e., RLAB, Hunt viewing media)
+&nbsp;     note: For developers creating an ICC profile for this conversion
+&nbsp;           space, the following is applicable.  Use a simple Von Kries
+&nbsp;           white point adaptation folded into the 3X3 matrix parameters
+&nbsp;           and fold the flare and surround effects into the three
+&nbsp;           one-dimensional lookup tables (assuming one uses the minimal
+&nbsp;           model for monitors).
+
+</pre>
+ *
+ * <p>
+ * @see ICC_ColorSpace
+ */
+
+
+
+public abstract class ColorSpace implements java.io.Serializable {
+
+    static final long serialVersionUID = -409452704308689724L;
+
+    private int type;
+    private int numComponents;
+    private transient String [] compName = null;
+
+    // Cache of singletons for the predefined color spaces.
+    private static ColorSpace sRGBspace;
+    private static ColorSpace XYZspace;
+    private static ColorSpace PYCCspace;
+    private static ColorSpace GRAYspace;
+    private static ColorSpace LINEAR_RGBspace;
+
+    /**
+     * Any of the family of XYZ color spaces.
+     */
+    public static final int TYPE_XYZ = 0;
+
+    /**
+     * Any of the family of Lab color spaces.
+     */
+    public static final int TYPE_Lab = 1;
+
+    /**
+     * Any of the family of Luv color spaces.
+     */
+    public static final int TYPE_Luv = 2;
+
+    /**
+     * Any of the family of YCbCr color spaces.
+     */
+    public static final int TYPE_YCbCr = 3;
+
+    /**
+     * Any of the family of Yxy color spaces.
+     */
+    public static final int TYPE_Yxy = 4;
+
+    /**
+     * Any of the family of RGB color spaces.
+     */
+    public static final int TYPE_RGB = 5;
+
+    /**
+     * Any of the family of GRAY color spaces.
+     */
+    public static final int TYPE_GRAY = 6;
+
+    /**
+     * Any of the family of HSV color spaces.
+     */
+    public static final int TYPE_HSV = 7;
+
+    /**
+     * Any of the family of HLS color spaces.
+     */
+    public static final int TYPE_HLS = 8;
+
+    /**
+     * Any of the family of CMYK color spaces.
+     */
+    public static final int TYPE_CMYK = 9;
+
+    /**
+     * Any of the family of CMY color spaces.
+     */
+    public static final int TYPE_CMY = 11;
+
+    /**
+     * Generic 2 component color spaces.
+     */
+    public static final int TYPE_2CLR = 12;
+
+    /**
+     * Generic 3 component color spaces.
+     */
+    public static final int TYPE_3CLR = 13;
+
+    /**
+     * Generic 4 component color spaces.
+     */
+    public static final int TYPE_4CLR = 14;
+
+    /**
+     * Generic 5 component color spaces.
+     */
+    public static final int TYPE_5CLR = 15;
+
+    /**
+     * Generic 6 component color spaces.
+     */
+    public static final int TYPE_6CLR = 16;
+
+    /**
+     * Generic 7 component color spaces.
+     */
+    public static final int TYPE_7CLR = 17;
+
+    /**
+     * Generic 8 component color spaces.
+     */
+    public static final int TYPE_8CLR = 18;
+
+    /**
+     * Generic 9 component color spaces.
+     */
+    public static final int TYPE_9CLR = 19;
+
+    /**
+     * Generic 10 component color spaces.
+     */
+    public static final int TYPE_ACLR = 20;
+
+    /**
+     * Generic 11 component color spaces.
+     */
+    public static final int TYPE_BCLR = 21;
+
+    /**
+     * Generic 12 component color spaces.
+     */
+    public static final int TYPE_CCLR = 22;
+
+    /**
+     * Generic 13 component color spaces.
+     */
+    public static final int TYPE_DCLR = 23;
+
+    /**
+     * Generic 14 component color spaces.
+     */
+    public static final int TYPE_ECLR = 24;
+
+    /**
+     * Generic 15 component color spaces.
+     */
+    public static final int TYPE_FCLR = 25;
+
+    /**
+     * The sRGB color space defined at
+     * <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
+     * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
+     * </A>.
+     */
+    public static final int CS_sRGB = 1000;
+
+    /**
+     * A built-in linear RGB color space.  This space is based on the
+     * same RGB primaries as CS_sRGB, but has a linear tone reproduction curve.
+     */
+    public static final int CS_LINEAR_RGB = 1004;
+
+    /**
+     * The CIEXYZ conversion color space defined above.
+     */
+    public static final int CS_CIEXYZ = 1001;
+
+    /**
+     * The Photo YCC conversion color space.
+     */
+    public static final int CS_PYCC = 1002;
+
+    /**
+     * The built-in linear gray scale color space.
+     */
+    public static final int CS_GRAY = 1003;
+
+
+    /**
+     * Constructs a ColorSpace object given a color space type
+     * and the number of components.
+     * @param type one of the <CODE>ColorSpace</CODE> type constants
+     * @param numcomponents the number of components in the color space
+     */
+    protected ColorSpace (int type, int numcomponents) {
+        this.type = type;
+        this.numComponents = numcomponents;
+    }
+
+
+    /**
+     * Returns a ColorSpace representing one of the specific
+     * predefined color spaces.
+     * @param colorspace a specific color space identified by one of
+     *        the predefined class constants (e.g. CS_sRGB, CS_LINEAR_RGB,
+     *        CS_CIEXYZ, CS_GRAY, or CS_PYCC)
+     * @return the requested <CODE>ColorSpace</CODE> object
+     */
+    // NOTE: This method may be called by privileged threads.
+    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
+    public static ColorSpace getInstance (int colorspace)
+    {
+    ColorSpace    theColorSpace;
+
+        switch (colorspace) {
+        case CS_sRGB:
+            synchronized(ColorSpace.class) {
+                if (sRGBspace == null) {
+                    ICC_Profile theProfile = ICC_Profile.getInstance (CS_sRGB);
+                    sRGBspace = new ICC_ColorSpace (theProfile);
+                }
+
+                theColorSpace = sRGBspace;
+            }
+            break;
+
+        case CS_CIEXYZ:
+            synchronized(ColorSpace.class) {
+                if (XYZspace == null) {
+                    ICC_Profile theProfile =
+                        ICC_Profile.getInstance (CS_CIEXYZ);
+                    XYZspace = new ICC_ColorSpace (theProfile);
+                }
+
+                theColorSpace = XYZspace;
+            }
+            break;
+
+        case CS_PYCC:
+            synchronized(ColorSpace.class) {
+                if (PYCCspace == null) {
+                    ICC_Profile theProfile = ICC_Profile.getInstance (CS_PYCC);
+                    PYCCspace = new ICC_ColorSpace (theProfile);
+                }
+
+                theColorSpace = PYCCspace;
+            }
+            break;
+
+
+        case CS_GRAY:
+            synchronized(ColorSpace.class) {
+                if (GRAYspace == null) {
+                    ICC_Profile theProfile = ICC_Profile.getInstance (CS_GRAY);
+                    GRAYspace = new ICC_ColorSpace (theProfile);
+                    /* to allow access from java.awt.ColorModel */
+                    CMSManager.GRAYspace = GRAYspace;
+                }
+
+                theColorSpace = GRAYspace;
+            }
+            break;
+
+
+        case CS_LINEAR_RGB:
+            synchronized(ColorSpace.class) {
+                if (LINEAR_RGBspace == null) {
+                    ICC_Profile theProfile =
+                        ICC_Profile.getInstance(CS_LINEAR_RGB);
+                    LINEAR_RGBspace = new ICC_ColorSpace (theProfile);
+                    /* to allow access from java.awt.ColorModel */
+                    CMSManager.LINEAR_RGBspace = LINEAR_RGBspace;
+                }
+
+                theColorSpace = LINEAR_RGBspace;
+            }
+            break;
+
+
+        default:
+            throw new IllegalArgumentException ("Unknown color space");
+        }
+
+        return theColorSpace;
+    }
+
+
+    /**
+     * Returns true if the ColorSpace is CS_sRGB.
+     * @return <CODE>true</CODE> if this is a <CODE>CS_sRGB</CODE> color
+     *         space, <code>false</code> if it is not
+     */
+    public boolean isCS_sRGB () {
+        /* REMIND - make sure we know sRGBspace exists already */
+        return (this == sRGBspace);
+    }
+
+    /**
+     * Transforms a color value assumed to be in this ColorSpace
+     * into a value in the default CS_sRGB color space.
+     * <p>
+     * This method transforms color values using algorithms designed
+     * to produce the best perceptual match between input and output
+     * colors.  In order to do colorimetric conversion of color values,
+     * you should use the <code>toCIEXYZ</code>
+     * method of this color space to first convert from the input
+     * color space to the CS_CIEXYZ color space, and then use the
+     * <code>fromCIEXYZ</code> method of the CS_sRGB color space to
+     * convert from CS_CIEXYZ to the output color space.
+     * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
+     * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
+     * <p>
+     * @param colorvalue a float array with length of at least the number
+     *        of components in this ColorSpace
+     * @return a float array of length 3
+     * @throws ArrayIndexOutOfBoundsException if array length is not
+     *         at least the number of components in this ColorSpace
+     */
+    public abstract float[] toRGB(float[] colorvalue);
+
+
+    /**
+     * Transforms a color value assumed to be in the default CS_sRGB
+     * color space into this ColorSpace.
+     * <p>
+     * This method transforms color values using algorithms designed
+     * to produce the best perceptual match between input and output
+     * colors.  In order to do colorimetric conversion of color values,
+     * you should use the <code>toCIEXYZ</code>
+     * method of the CS_sRGB color space to first convert from the input
+     * color space to the CS_CIEXYZ color space, and then use the
+     * <code>fromCIEXYZ</code> method of this color space to
+     * convert from CS_CIEXYZ to the output color space.
+     * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
+     * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
+     * <p>
+     * @param rgbvalue a float array with length of at least 3
+     * @return a float array with length equal to the number of
+     *         components in this ColorSpace
+     * @throws ArrayIndexOutOfBoundsException if array length is not
+     *         at least 3
+     */
+    public abstract float[] fromRGB(float[] rgbvalue);
+
+
+    /**
+     * Transforms a color value assumed to be in this ColorSpace
+     * into the CS_CIEXYZ conversion color space.
+     * <p>
+     * This method transforms color values using relative colorimetry,
+     * as defined by the International Color Consortium standard.  This
+     * means that the XYZ values returned by this method are represented
+     * relative to the D50 white point of the CS_CIEXYZ color space.
+     * This representation is useful in a two-step color conversion
+     * process in which colors are transformed from an input color
+     * space to CS_CIEXYZ and then to an output color space.  This
+     * representation is not the same as the XYZ values that would
+     * be measured from the given color value by a colorimeter.
+     * A further transformation is necessary to compute the XYZ values
+     * that would be measured using current CIE recommended practices.
+     * See the {@link ICC_ColorSpace#toCIEXYZ(float[]) toCIEXYZ} method of
+     * <code>ICC_ColorSpace</code> for further information.
+     * <p>
+     * @param colorvalue a float array with length of at least the number
+     *        of components in this ColorSpace
+     * @return a float array of length 3
+     * @throws ArrayIndexOutOfBoundsException if array length is not
+     *         at least the number of components in this ColorSpace.
+     */
+    public abstract float[] toCIEXYZ(float[] colorvalue);
+
+
+    /**
+     * Transforms a color value assumed to be in the CS_CIEXYZ conversion
+     * color space into this ColorSpace.
+     * <p>
+     * This method transforms color values using relative colorimetry,
+     * as defined by the International Color Consortium standard.  This
+     * means that the XYZ argument values taken by this method are represented
+     * relative to the D50 white point of the CS_CIEXYZ color space.
+     * This representation is useful in a two-step color conversion
+     * process in which colors are transformed from an input color
+     * space to CS_CIEXYZ and then to an output color space.  The color
+     * values returned by this method are not those that would produce
+     * the XYZ value passed to the method when measured by a colorimeter.
+     * If you have XYZ values corresponding to measurements made using
+     * current CIE recommended practices, they must be converted to D50
+     * relative values before being passed to this method.
+     * See the {@link ICC_ColorSpace#fromCIEXYZ(float[]) fromCIEXYZ} method of
+     * <code>ICC_ColorSpace</code> for further information.
+     * <p>
+     * @param colorvalue a float array with length of at least 3
+     * @return a float array with length equal to the number of
+     *         components in this ColorSpace
+     * @throws ArrayIndexOutOfBoundsException if array length is not
+     *         at least 3
+     */
+    public abstract float[] fromCIEXYZ(float[] colorvalue);
+
+    /**
+     * Returns the color space type of this ColorSpace (for example
+     * TYPE_RGB, TYPE_XYZ, ...).  The type defines the
+     * number of components of the color space and the interpretation,
+     * e.g. TYPE_RGB identifies a color space with three components - red,
+     * green, and blue.  It does not define the particular color
+     * characteristics of the space, e.g. the chromaticities of the
+     * primaries.
+     *
+     * @return the type constant that represents the type of this
+     *         <CODE>ColorSpace</CODE>
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Returns the number of components of this ColorSpace.
+     * @return The number of components in this <CODE>ColorSpace</CODE>.
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+    /**
+     * Returns the name of the component given the component index.
+     *
+     * @param idx the component index
+     * @return the name of the component at the specified index
+     * @throws IllegalArgumentException if <code>idx</code> is
+     *         less than 0 or greater than numComponents - 1
+     */
+    public String getName (int idx) {
+        /* REMIND - handle common cases here */
+        if ((idx < 0) || (idx > numComponents - 1)) {
+            throw new IllegalArgumentException(
+                "Component index out of range: " + idx);
+        }
+
+        if (compName == null) {
+            switch (type) {
+                case ColorSpace.TYPE_XYZ:
+                    compName = new String[] {"X", "Y", "Z"};
+                    break;
+                case ColorSpace.TYPE_Lab:
+                    compName = new String[] {"L", "a", "b"};
+                    break;
+                case ColorSpace.TYPE_Luv:
+                    compName = new String[] {"L", "u", "v"};
+                    break;
+                case ColorSpace.TYPE_YCbCr:
+                    compName = new String[] {"Y", "Cb", "Cr"};
+                    break;
+                case ColorSpace.TYPE_Yxy:
+                    compName = new String[] {"Y", "x", "y"};
+                    break;
+                case ColorSpace.TYPE_RGB:
+                    compName = new String[] {"Red", "Green", "Blue"};
+                    break;
+                case ColorSpace.TYPE_GRAY:
+                    compName = new String[] {"Gray"};
+                    break;
+                case ColorSpace.TYPE_HSV:
+                    compName = new String[] {"Hue", "Saturation", "Value"};
+                    break;
+                case ColorSpace.TYPE_HLS:
+                    compName = new String[] {"Hue", "Lightness",
+                                             "Saturation"};
+                    break;
+                case ColorSpace.TYPE_CMYK:
+                    compName = new String[] {"Cyan", "Magenta", "Yellow",
+                                             "Black"};
+                    break;
+                case ColorSpace.TYPE_CMY:
+                    compName = new String[] {"Cyan", "Magenta", "Yellow"};
+                    break;
+                default:
+                    String [] tmp = new String[numComponents];
+                    for (int i = 0; i < tmp.length; i++) {
+                        tmp[i] = "Unnamed color component(" + i + ")";
+                    }
+                    compName = tmp;
+            }
+        }
+        return compName[idx];
+    }
+
+    /**
+     * Returns the minimum normalized color component value for the
+     * specified component.  The default implementation in this abstract
+     * class returns 0.0 for all components.  Subclasses should override
+     * this method if necessary.
+     *
+     * @param component the component index
+     * @return the minimum normalized component value
+     * @throws IllegalArgumentException if component is less than 0 or
+     *         greater than numComponents - 1
+     * @since 1.4
+     */
+    public float getMinValue(int component) {
+        if ((component < 0) || (component > numComponents - 1)) {
+            throw new IllegalArgumentException(
+                "Component index out of range: " + component);
+        }
+        return 0.0f;
+    }
+
+    /**
+     * Returns the maximum normalized color component value for the
+     * specified component.  The default implementation in this abstract
+     * class returns 1.0 for all components.  Subclasses should override
+     * this method if necessary.
+     *
+     * @param component the component index
+     * @return the maximum normalized component value
+     * @throws IllegalArgumentException if component is less than 0 or
+     *         greater than numComponents - 1
+     * @since 1.4
+     */
+    public float getMaxValue(int component) {
+        if ((component < 0) || (component > numComponents - 1)) {
+            throw new IllegalArgumentException(
+                "Component index out of range: " + component);
+        }
+        return 1.0f;
+    }
+
+    /* Returns true if cspace is the XYZspace.
+     */
+    static boolean isCS_CIEXYZ(ColorSpace cspace) {
+        return (cspace == XYZspace);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/color/ICC_ColorSpace.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,616 @@
+/*
+ * Portions Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+package java.awt.color;
+
+import sun.java2d.cmm.ColorTransform;
+import sun.java2d.cmm.CMSManager;
+import sun.java2d.cmm.PCMM;
+
+
+/**
+ *
+ * The ICC_ColorSpace class is an implementation of the abstract
+ * ColorSpace class.  This representation of
+ * device independent and device dependent color spaces is based on the
+ * International Color Consortium Specification ICC.1:2001-12, File Format for
+ * Color Profiles (see <A href="http://www.color.org">http://www.color.org</A>).
+ * <p>
+ * Typically, a Color or ColorModel would be associated with an ICC
+ * Profile which is either an input, display, or output profile (see
+ * the ICC specification).  There are other types of ICC Profiles, e.g.
+ * abstract profiles, device link profiles, and named color profiles,
+ * which do not contain information appropriate for representing the color
+ * space of a color, image, or device (see ICC_Profile).
+ * Attempting to create an ICC_ColorSpace object from an inappropriate ICC
+ * Profile is an error.
+ * <p>
+ * ICC Profiles represent transformations from the color space of
+ * the profile (e.g. a monitor) to a Profile Connection Space (PCS).
+ * Profiles of interest for tagging images or colors have a
+ * PCS which is one of the device independent
+ * spaces (one CIEXYZ space and two CIELab spaces) defined in the
+ * ICC Profile Format Specification.  Most profiles of interest
+ * either have invertible transformations or explicitly specify
+ * transformations going both directions.  Should an ICC_ColorSpace
+ * object be used in a way requiring a conversion from PCS to
+ * the profile's native space and there is inadequate data to
+ * correctly perform the conversion, the ICC_ColorSpace object will
+ * produce output in the specified type of color space (e.g. TYPE_RGB,
+ * TYPE_CMYK, etc.), but the specific color values of the output data
+ * will be undefined.
+ * <p>
+ * The details of this class are not important for simple applets,
+ * which draw in a default color space or manipulate and display
+ * imported images with a known color space.  At most, such applets
+ * would need to get one of the default color spaces via
+ * ColorSpace.getInstance().
+ * <p>
+ * @see ColorSpace
+ * @see ICC_Profile
+ */
+
+
+
+public class ICC_ColorSpace extends ColorSpace {
+
+    static final long serialVersionUID = 3455889114070431483L;
+
+    private ICC_Profile    thisProfile;
+    private float[] minVal;
+    private float[] maxVal;
+    private float[] diffMinMax;
+    private float[] invDiffMinMax;
+    private boolean needScaleInit = true;
+
+    // {to,from}{RGB,CIEXYZ} methods create and cache these when needed
+    private transient ColorTransform this2srgb;
+    private transient ColorTransform srgb2this;
+    private transient ColorTransform this2xyz;
+    private transient ColorTransform xyz2this;
+
+
+    /**
+    * Constructs a new ICC_ColorSpace from an ICC_Profile object.
+    * @param profile the specified ICC_Profile object
+    * @exception IllegalArgumentException if profile is inappropriate for
+    *            representing a ColorSpace.
+    */
+    public ICC_ColorSpace (ICC_Profile profile) {
+        super (profile.getColorSpaceType(), profile.getNumComponents());
+
+        int profileClass = profile.getProfileClass();
+
+        /* REMIND - is NAMEDCOLOR OK? */
+        if ((profileClass != ICC_Profile.CLASS_INPUT) &&
+            (profileClass != ICC_Profile.CLASS_DISPLAY) &&
+            (profileClass != ICC_Profile.CLASS_OUTPUT) &&
+            (profileClass != ICC_Profile.CLASS_COLORSPACECONVERSION) &&
+            (profileClass != ICC_Profile.CLASS_NAMEDCOLOR) &&
+            (profileClass != ICC_Profile.CLASS_ABSTRACT)) {
+            throw new IllegalArgumentException("Invalid profile type");
+        }
+
+        thisProfile = profile;
+        setMinMax();
+    }
+
+    /**
+    * Returns the ICC_Profile for this ICC_ColorSpace.
+    * @return the ICC_Profile for this ICC_ColorSpace.
+    */
+    public ICC_Profile getProfile() {
+        return thisProfile;
+    }
+
+    /**
+     * Transforms a color value assumed to be in this ColorSpace
+     * into a value in the default CS_sRGB color space.
+     * <p>
+     * This method transforms color values using algorithms designed
+     * to produce the best perceptual match between input and output
+     * colors.  In order to do colorimetric conversion of color values,
+     * you should use the <code>toCIEXYZ</code>
+     * method of this color space to first convert from the input
+     * color space to the CS_CIEXYZ color space, and then use the
+     * <code>fromCIEXYZ</code> method of the CS_sRGB color space to
+     * convert from CS_CIEXYZ to the output color space.
+     * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
+     * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
+     * <p>
+     * @param colorvalue a float array with length of at least the number
+     *      of components in this ColorSpace.
+     * @return a float array of length 3.
+     * @throws ArrayIndexOutOfBoundsException if array length is not
+     * at least the number of components in this ColorSpace.
+     */
+    public float[]    toRGB (float[] colorvalue) {
+
+        if (this2srgb == null) {
+            ColorTransform[] transformList = new ColorTransform [2];
+            ICC_ColorSpace srgbCS =
+                (ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
+            PCMM mdl = CMSManager.getModule();
+            transformList[0] = mdl.createTransform(
+                thisProfile, ColorTransform.Any, ColorTransform.In);
+            transformList[1] = mdl.createTransform(
+                srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
+            this2srgb = mdl.createTransform(transformList);
+            if (needScaleInit) {
+                setComponentScaling();
+            }
+        }
+
+        int nc = this.getNumComponents();
+        short tmp[] = new short[nc];
+        for (int i = 0; i < nc; i++) {
+            tmp[i] = (short)
+                ((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
+        }
+        tmp = this2srgb.colorConvert(tmp, null);
+        float[] result = new float [3];
+        for (int i = 0; i < 3; i++) {
+            result[i] = ((float) (tmp[i] & 0xffff)) / 65535.0f;
+        }
+        return result;
+    }
+
+    /**
+     * Transforms a color value assumed to be in the default CS_sRGB
+     * color space into this ColorSpace.
+     * <p>
+     * This method transforms color values using algorithms designed
+     * to produce the best perceptual match between input and output
+     * colors.  In order to do colorimetric conversion of color values,
+     * you should use the <code>toCIEXYZ</code>
+     * method of the CS_sRGB color space to first convert from the input
+     * color space to the CS_CIEXYZ color space, and then use the
+     * <code>fromCIEXYZ</code> method of this color space to
+     * convert from CS_CIEXYZ to the output color space.
+     * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
+     * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
+     * <p>
+     * @param rgbvalue a float array with length of at least 3.
+     * @return a float array with length equal to the number of
+     *       components in this ColorSpace.
+     * @throws ArrayIndexOutOfBoundsException if array length is not
+     * at least 3.
+     */
+    public float[]    fromRGB(float[] rgbvalue) {
+
+        if (srgb2this == null) {
+            ColorTransform[] transformList = new ColorTransform [2];
+            ICC_ColorSpace srgbCS =
+                (ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
+            PCMM mdl = CMSManager.getModule();
+            transformList[0] = mdl.createTransform(
+                srgbCS.getProfile(), ColorTransform.Any, ColorTransform.In);
+            transformList[1] = mdl.createTransform(
+                thisProfile, ColorTransform.Any, ColorTransform.Out);
+            srgb2this = mdl.createTransform(transformList);
+            if (needScaleInit) {
+                setComponentScaling();
+            }
+        }
+
+        short tmp[] = new short[3];
+        for (int i = 0; i < 3; i++) {
+            tmp[i] = (short) ((rgbvalue[i] * 65535.0f) + 0.5f);
+        }
+        tmp = srgb2this.colorConvert(tmp, null);
+        int nc = this.getNumComponents();
+        float[] result = new float [nc];
+        for (int i = 0; i < nc; i++) {
+            result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
+                        diffMinMax[i] + minVal[i];
+        }
+        return result;
+    }
+
+
+    /**
+     * Transforms a color value assumed to be in this ColorSpace
+     * into the CS_CIEXYZ conversion color space.
+     * <p>
+     * This method transforms color values using relative colorimetry,
+     * as defined by the ICC Specification.  This
+     * means that the XYZ values returned by this method are represented
+     * relative to the D50 white point of the CS_CIEXYZ color space.
+     * This representation is useful in a two-step color conversion
+     * process in which colors are transformed from an input color
+     * space to CS_CIEXYZ and then to an output color space.  This
+     * representation is not the same as the XYZ values that would
+     * be measured from the given color value by a colorimeter.
+     * A further transformation is necessary to compute the XYZ values
+     * that would be measured using current CIE recommended practices.
+     * The paragraphs below explain this in more detail.
+     * <p>
+     * The ICC standard uses a device independent color space (DICS) as the
+     * mechanism for converting color from one device to another device.  In
+     * this architecture, colors are converted from the source device's color
+     * space to the ICC DICS and then from the ICC DICS to the destination
+     * device's color space.  The ICC standard defines device profiles which
+     * contain transforms which will convert between a device's color space
+     * and the ICC DICS.  The overall conversion of colors from a source
+     * device to colors of a destination device is done by connecting the
+     * device-to-DICS transform of the profile for the source device to the
+     * DICS-to-device transform of the profile for the destination device.
+     * For this reason, the ICC DICS is commonly referred to as the profile
+     * connection space (PCS).  The color space used in the methods
+     * toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
+     * Specification.  This is also the color space represented by
+     * ColorSpace.CS_CIEXYZ.
+     * <p>
+     * The XYZ values of a color are often represented as relative to some
+     * white point, so the actual meaning of the XYZ values cannot be known
+     * without knowing the white point of those values.  This is known as
+     * relative colorimetry.  The PCS uses a white point of D50, so the XYZ
+     * values of the PCS are relative to D50.  For example, white in the PCS
+     * will have the XYZ values of D50, which is defined to be X=.9642,
+     * Y=1.000, and Z=0.8249.  This white point is commonly used for graphic
+     * arts applications, but others are often used in other applications.
+     * <p>
+     * To quantify the color characteristics of a device such as a printer
+     * or monitor, measurements of XYZ values for particular device colors
+     * are typically made.  For purposes of this discussion, the term
+     * device XYZ values is used to mean the XYZ values that would be
+     * measured from device colors using current CIE recommended practices.
+     * <p>
+     * Converting between device XYZ values and the PCS XYZ values returned
+     * by this method corresponds to converting between the device's color
+     * space, as represented by CIE colorimetric values, and the PCS.  There
+     * are many factors involved in this process, some of which are quite
+     * subtle.  The most important, however, is the adjustment made to account
+     * for differences between the device's white point and the white point of
+     * the PCS.  There are many techniques for doing this and it is the
+     * subject of much current research and controversy.  Some commonly used
+     * methods are XYZ scaling, the von Kries transform, and the Bradford
+     * transform.  The proper method to use depends upon each particular
+     * application.
+     * <p>
+     * The simplest method is XYZ scaling.  In this method each device XYZ
+     * value is  converted to a PCS XYZ value by multiplying it by the ratio
+     * of the PCS white point (D50) to the device white point.
+     * <pre>
+     *
+     * Xd, Yd, Zd are the device XYZ values
+     * Xdw, Ydw, Zdw are the device XYZ white point values
+     * Xp, Yp, Zp are the PCS XYZ values
+     * Xd50, Yd50, Zd50 are the PCS XYZ white point values
+     *
+     * Xp = Xd * (Xd50 / Xdw)
+     * Yp = Yd * (Yd50 / Ydw)
+     * Zp = Zd * (Zd50 / Zdw)
+     *
+     * </pre>
+     * <p>
+     * Conversion from the PCS to the device would be done by inverting these
+     * equations:
+     * <pre>
+     *
+     * Xd = Xp * (Xdw / Xd50)
+     * Yd = Yp * (Ydw / Yd50)
+     * Zd = Zp * (Zdw / Zd50)
+     *
+     * </pre>
+     * <p>
+     * Note that the media white point tag in an ICC profile is not the same
+     * as the device white point.  The media white point tag is expressed in
+     * PCS values and is used to represent the difference between the XYZ of
+     * device illuminant and the XYZ of the device media when measured under
+     * that illuminant.  The device white point is expressed as the device
+     * XYZ values corresponding to white displayed on the device.  For
+     * example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
+     * will result in a measured device XYZ value of D65.  This will not
+     * be the same as the media white point tag XYZ value in the ICC
+     * profile for an sRGB device.
+     * <p>
+     * @param colorvalue a float array with length of at least the number
+     *        of components in this ColorSpace.
+     * @return a float array of length 3.
+     * @throws ArrayIndexOutOfBoundsException if array length is not
+     * at least the number of components in this ColorSpace.
+     */
+    public float[]    toCIEXYZ(float[] colorvalue) {
+
+        if (this2xyz == null) {
+            ColorTransform[] transformList = new ColorTransform [2];
+            ICC_ColorSpace xyzCS =
+                (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
+            PCMM mdl = CMSManager.getModule();
+            try {
+                transformList[0] = mdl.createTransform(
+                    thisProfile, ICC_Profile.icRelativeColorimetric,
+                    ColorTransform.In);
+            } catch (CMMException e) {
+                transformList[0] = mdl.createTransform(
+                    thisProfile, ColorTransform.Any, ColorTransform.In);
+            }
+            transformList[1] = mdl.createTransform(
+                xyzCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
+            this2xyz = mdl.createTransform (transformList);
+            if (needScaleInit) {
+                setComponentScaling();
+            }
+        }
+
+        int nc = this.getNumComponents();
+        short tmp[] = new short[nc];
+        for (int i = 0; i < nc; i++) {
+            tmp[i] = (short)
+                ((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
+        }
+        tmp = this2xyz.colorConvert(tmp, null);
+        float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
+        // For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
+        float[] result = new float [3];
+        for (int i = 0; i < 3; i++) {
+            result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) * ALMOST_TWO;
+        }
+        return result;
+    }
+
+
+    /**
+     * Transforms a color value assumed to be in the CS_CIEXYZ conversion
+     * color space into this ColorSpace.
+     * <p>
+     * This method transforms color values using relative colorimetry,
+     * as defined by the ICC Specification.  This
+     * means that the XYZ argument values taken by this method are represented
+     * relative to the D50 white point of the CS_CIEXYZ color space.
+     * This representation is useful in a two-step color conversion
+     * process in which colors are transformed from an input color
+     * space to CS_CIEXYZ and then to an output color space.  The color
+     * values returned by this method are not those that would produce
+     * the XYZ value passed to the method when measured by a colorimeter.
+     * If you have XYZ values corresponding to measurements made using
+     * current CIE recommended practices, they must be converted to D50
+     * relative values before being passed to this method.
+     * The paragraphs below explain this in more detail.
+     * <p>
+     * The ICC standard uses a device independent color space (DICS) as the
+     * mechanism for converting color from one device to another device.  In
+     * this architecture, colors are converted from the source device's color
+     * space to the ICC DICS and then from the ICC DICS to the destination
+     * device's color space.  The ICC standard defines device profiles which
+     * contain transforms which will convert between a device's color space
+     * and the ICC DICS.  The overall conversion of colors from a source
+     * device to colors of a destination device is done by connecting the
+     * device-to-DICS transform of the profile for the source device to the
+     * DICS-to-device transform of the profile for the destination device.
+     * For this reason, the ICC DICS is commonly referred to as the profile
+     * connection space (PCS).  The color space used in the methods
+     * toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
+     * Specification.  This is also the color space represented by
+     * ColorSpace.CS_CIEXYZ.
+     * <p>
+     * The XYZ values of a color are often represented as relative to some
+     * white point, so the actual meaning of the XYZ values cannot be known
+     * without knowing the white point of those values.  This is known as
+     * relative colorimetry.  The PCS uses a white point of D50, so the XYZ
+     * values of the PCS are relative to D50.  For example, white in the PCS
+     * will have the XYZ values of D50, which is defined to be X=.9642,
+     * Y=1.000, and Z=0.8249.  This white point is commonly used for graphic
+     * arts applications, but others are often used in other applications.
+     * <p>
+     * To quantify the color characteristics of a device such as a printer
+     * or monitor, measurements of XYZ values for particular device colors
+     * are typically made.  For purposes of this discussion, the term
+     * device XYZ values is used to mean the XYZ values that would be
+     * measured from device colors using current CIE recommended practices.
+     * <p>
+     * Converting between device XYZ values and the PCS XYZ values taken as
+     * arguments by this method corresponds to converting between the device's
+     * color space, as represented by CIE colorimetric values, and the PCS.
+     * There are many factors involved in this process, some of which are quite
+     * subtle.  The most important, however, is the adjustment made to account
+     * for differences between the device's white point and the white point of
+     * the PCS.  There are many techniques for doing this and it is the
+     * subject of much current research and controversy.  Some commonly used
+     * methods are XYZ scaling, the von Kries transform, and the Bradford
+     * transform.  The proper method to use depends upon each particular
+     * application.
+     * <p>
+     * The simplest method is XYZ scaling.  In this method each device XYZ
+     * value is  converted to a PCS XYZ value by multiplying it by the ratio
+     * of the PCS white point (D50) to the device white point.
+     * <pre>
+     *
+     * Xd, Yd, Zd are the device XYZ values
+     * Xdw, Ydw, Zdw are the device XYZ white point values
+     * Xp, Yp, Zp are the PCS XYZ values
+     * Xd50, Yd50, Zd50 are the PCS XYZ white point values
+     *
+     * Xp = Xd * (Xd50 / Xdw)
+     * Yp = Yd * (Yd50 / Ydw)
+     * Zp = Zd * (Zd50 / Zdw)
+     *
+     * </pre>
+     * <p>
+     * Conversion from the PCS to the device would be done by inverting these
+     * equations:
+     * <pre>
+     *
+     * Xd = Xp * (Xdw / Xd50)
+     * Yd = Yp * (Ydw / Yd50)
+     * Zd = Zp * (Zdw / Zd50)
+     *
+     * </pre>
+     * <p>
+     * Note that the media white point tag in an ICC profile is not the same
+     * as the device white point.  The media white point tag is expressed in
+     * PCS values and is used to represent the difference between the XYZ of
+     * device illuminant and the XYZ of the device media when measured under
+     * that illuminant.  The device white point is expressed as the device
+     * XYZ values corresponding to white displayed on the device.  For
+     * example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
+     * will result in a measured device XYZ value of D65.  This will not
+     * be the same as the media white point tag XYZ value in the ICC
+     * profile for an sRGB device.
+     * <p>
+     * <p>
+     * @param colorvalue a float array with length of at least 3.
+     * @return a float array with length equal to the number of
+     *         components in this ColorSpace.
+     * @throws ArrayIndexOutOfBoundsException if array length is not
+     * at least 3.
+     */
+    public float[]    fromCIEXYZ(float[] colorvalue) {
+
+        if (xyz2this == null) {
+            ColorTransform[] transformList = new ColorTransform [2];
+            ICC_ColorSpace xyzCS =
+                (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
+            PCMM mdl = CMSManager.getModule();
+            transformList[0] = mdl.createTransform (
+                xyzCS.getProfile(), ColorTransform.Any, ColorTransform.In);
+            try {
+                transformList[1] = mdl.createTransform(
+                    thisProfile, ICC_Profile.icRelativeColorimetric,
+                    ColorTransform.Out);
+            } catch (CMMException e) {
+                transformList[1] = CMSManager.getModule().createTransform(
+                thisProfile, ColorTransform.Any, ColorTransform.Out);
+            }
+            xyz2this = mdl.createTransform(transformList);
+            if (needScaleInit) {
+                setComponentScaling();
+            }
+        }
+
+        short tmp[] = new short[3];
+        float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
+        float factor = 65535.0f / ALMOST_TWO;
+        // For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
+        for (int i = 0; i < 3; i++) {
+            tmp[i] = (short) ((colorvalue[i] * factor) + 0.5f);
+        }
+        tmp = xyz2this.colorConvert(tmp, null);
+        int nc = this.getNumComponents();
+        float[] result = new float [nc];
+        for (int i = 0; i < nc; i++) {
+            result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
+                        diffMinMax[i] + minVal[i];
+        }
+        return result;
+    }
+
+    /**
+     * Returns the minimum normalized color component value for the
+     * specified component.  For TYPE_XYZ spaces, this method returns
+     * minimum values of 0.0 for all components.  For TYPE_Lab spaces,
+     * this method returns 0.0 for L and -128.0 for a and b components.
+     * This is consistent with the encoding of the XYZ and Lab Profile
+     * Connection Spaces in the ICC specification.  For all other types, this
+     * method returns 0.0 for all components.  When using an ICC_ColorSpace
+     * with a profile that requires different minimum component values,
+     * it is necessary to subclass this class and override this method.
+     * @param component The component index.
+     * @return The minimum normalized component value.
+     * @throws IllegalArgumentException if component is less than 0 or
+     *         greater than numComponents - 1.
+     * @since 1.4
+     */
+    public float getMinValue(int component) {
+        if ((component < 0) || (component > this.getNumComponents() - 1)) {
+            throw new IllegalArgumentException(
+                "Component index out of range: + component");
+        }
+        return minVal[component];
+    }
+
+    /**
+     * Returns the maximum normalized color component value for the
+     * specified component.  For TYPE_XYZ spaces, this method returns
+     * maximum values of 1.0 + (32767.0 / 32768.0) for all components.
+     * For TYPE_Lab spaces,
+     * this method returns 100.0 for L and 127.0 for a and b components.
+     * This is consistent with the encoding of the XYZ and Lab Profile
+     * Connection Spaces in the ICC specification.  For all other types, this
+     * method returns 1.0 for all components.  When using an ICC_ColorSpace
+     * with a profile that requires different maximum component values,
+     * it is necessary to subclass this class and override this method.
+     * @param component The component index.
+     * @return The maximum normalized component value.
+     * @throws IllegalArgumentException if component is less than 0 or
+     *         greater than numComponents - 1.
+     * @since 1.4
+     */
+    public float getMaxValue(int component) {
+        if ((component < 0) || (component > this.getNumComponents() - 1)) {
+            throw new IllegalArgumentException(
+                "Component index out of range: + component");
+        }
+        return maxVal[component];
+    }
+
+    private void setMinMax() {
+        int nc = this.getNumComponents();
+        int type = this.getType();
+        minVal = new float[nc];
+        maxVal = new float[nc];
+        if (type == ColorSpace.TYPE_Lab) {
+            minVal[0] = 0.0f;    // L
+            maxVal[0] = 100.0f;
+            minVal[1] = -128.0f; // a
+            maxVal[1] = 127.0f;
+            minVal[2] = -128.0f; // b
+            maxVal[2] = 127.0f;
+        } else if (type == ColorSpace.TYPE_XYZ) {
+            minVal[0] = minVal[1] = minVal[2] = 0.0f; // X, Y, Z
+            maxVal[0] = maxVal[1] = maxVal[2] = 1.0f + (32767.0f/ 32768.0f);
+        } else {
+            for (int i = 0; i < nc; i++) {
+                minVal[i] = 0.0f;
+                maxVal[i] = 1.0f;
+            }
+        }
+    }
+
+    private void setComponentScaling() {
+        int nc = this.getNumComponents();
+        diffMinMax = new float[nc];
+        invDiffMinMax = new float[nc];
+        for (int i = 0; i < nc; i++) {
+            minVal[i] = this.getMinValue(i); // in case getMinVal is overridden
+            maxVal[i] = this.getMaxValue(i); // in case getMaxVal is overridden
+            diffMinMax[i] = maxVal[i] - minVal[i];
+            invDiffMinMax[i] = 65535.0f / diffMinMax[i];
+        }
+        needScaleInit = false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/color/ICC_Profile.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,2003 @@
+/*
+ * Portions Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+package java.awt.color;
+
+import sun.java2d.cmm.PCMM;
+import sun.java2d.cmm.CMSManager;
+import sun.java2d.cmm.ProfileDeferralMgr;
+import sun.java2d.cmm.ProfileDeferralInfo;
+import sun.java2d.cmm.ProfileActivator;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+import java.util.StringTokenizer;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * A representation of color profile data for device independent and
+ * device dependent color spaces based on the International Color
+ * Consortium Specification ICC.1:2001-12, File Format for Color Profiles,
+ * (see <A href="http://www.color.org"> http://www.color.org</A>).
+ * <p>
+ * An ICC_ColorSpace object can be constructed from an appropriate
+ * ICC_Profile.
+ * Typically, an ICC_ColorSpace would be associated with an ICC
+ * Profile which is either an input, display, or output profile (see
+ * the ICC specification).  There are also device link, abstract,
+ * color space conversion, and named color profiles.  These are less
+ * useful for tagging a color or image, but are useful for other
+ * purposes (in particular device link profiles can provide improved
+ * performance for converting from one device's color space to
+ * another's).
+ * <p>
+ * ICC Profiles represent transformations from the color space of
+ * the profile (e.g. a monitor) to a Profile Connection Space (PCS).
+ * Profiles of interest for tagging images or colors have a PCS
+ * which is one of the two specific device independent
+ * spaces (one CIEXYZ space and one CIELab space) defined in the
+ * ICC Profile Format Specification.  Most profiles of interest
+ * either have invertible transformations or explicitly specify
+ * transformations going both directions.
+ * <p>
+ * @see ICC_ColorSpace
+ */
+
+
+public class ICC_Profile implements Serializable {
+
+    private static final long serialVersionUID = -3938515861990936766L;
+
+    transient long ID;
+
+    private transient ProfileDeferralInfo deferralInfo;
+    private transient ProfileActivator profileActivator;
+
+    // Registry of singleton profile objects for specific color spaces
+    // defined in the ColorSpace class (e.g. CS_sRGB), see
+    // getInstance(int cspace) factory method.
+    private static ICC_Profile sRGBprofile;
+    private static ICC_Profile XYZprofile;
+    private static ICC_Profile PYCCprofile;
+    private static ICC_Profile GRAYprofile;
+    private static ICC_Profile LINEAR_RGBprofile;
+
+
+    /**
+     * Profile class is input.
+     */
+    public static final int CLASS_INPUT = 0;
+
+    /**
+     * Profile class is display.
+     */
+    public static final int CLASS_DISPLAY = 1;
+
+    /**
+     * Profile class is output.
+     */
+    public static final int CLASS_OUTPUT = 2;
+
+    /**
+     * Profile class is device link.
+     */
+    public static final int CLASS_DEVICELINK = 3;
+
+    /**
+     * Profile class is color space conversion.
+     */
+    public static final int CLASS_COLORSPACECONVERSION = 4;
+
+    /**
+     * Profile class is abstract.
+     */
+    public static final int CLASS_ABSTRACT = 5;
+
+    /**
+     * Profile class is named color.
+     */
+    public static final int CLASS_NAMEDCOLOR = 6;
+
+
+    /**
+     * ICC Profile Color Space Type Signature: 'XYZ '.
+     */
+    public static final int icSigXYZData        = 0x58595A20;    /* 'XYZ ' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'Lab '.
+     */
+    public static final int icSigLabData        = 0x4C616220;    /* 'Lab ' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'Luv '.
+     */
+    public static final int icSigLuvData        = 0x4C757620;    /* 'Luv ' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'YCbr'.
+     */
+    public static final int icSigYCbCrData        = 0x59436272;    /* 'YCbr' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'Yxy '.
+     */
+    public static final int icSigYxyData        = 0x59787920;    /* 'Yxy ' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'RGB '.
+     */
+    public static final int icSigRgbData        = 0x52474220;    /* 'RGB ' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'GRAY'.
+     */
+    public static final int icSigGrayData        = 0x47524159;    /* 'GRAY' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'HSV'.
+     */
+    public static final int icSigHsvData        = 0x48535620;    /* 'HSV ' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'HLS'.
+     */
+    public static final int icSigHlsData        = 0x484C5320;    /* 'HLS ' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'CMYK'.
+     */
+    public static final int icSigCmykData        = 0x434D594B;    /* 'CMYK' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'CMY '.
+     */
+    public static final int icSigCmyData        = 0x434D5920;    /* 'CMY ' */
+
+    /**
+     * ICC Profile Color Space Type Signature: '2CLR'.
+     */
+    public static final int icSigSpace2CLR        = 0x32434C52;    /* '2CLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: '3CLR'.
+     */
+    public static final int icSigSpace3CLR        = 0x33434C52;    /* '3CLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: '4CLR'.
+     */
+    public static final int icSigSpace4CLR        = 0x34434C52;    /* '4CLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: '5CLR'.
+     */
+    public static final int icSigSpace5CLR        = 0x35434C52;    /* '5CLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: '6CLR'.
+     */
+    public static final int icSigSpace6CLR        = 0x36434C52;    /* '6CLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: '7CLR'.
+     */
+    public static final int icSigSpace7CLR        = 0x37434C52;    /* '7CLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: '8CLR'.
+     */
+    public static final int icSigSpace8CLR        = 0x38434C52;    /* '8CLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: '9CLR'.
+     */
+    public static final int icSigSpace9CLR        = 0x39434C52;    /* '9CLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'ACLR'.
+     */
+    public static final int icSigSpaceACLR        = 0x41434C52;    /* 'ACLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'BCLR'.
+     */
+    public static final int icSigSpaceBCLR        = 0x42434C52;    /* 'BCLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'CCLR'.
+     */
+    public static final int icSigSpaceCCLR        = 0x43434C52;    /* 'CCLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'DCLR'.
+     */
+    public static final int icSigSpaceDCLR        = 0x44434C52;    /* 'DCLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'ECLR'.
+     */
+    public static final int icSigSpaceECLR        = 0x45434C52;    /* 'ECLR' */
+
+    /**
+     * ICC Profile Color Space Type Signature: 'FCLR'.
+     */
+    public static final int icSigSpaceFCLR        = 0x46434C52;    /* 'FCLR' */
+
+
+    /**
+     * ICC Profile Class Signature: 'scnr'.
+     */
+    public static final int icSigInputClass       = 0x73636E72;    /* 'scnr' */
+
+    /**
+     * ICC Profile Class Signature: 'mntr'.
+     */
+    public static final int icSigDisplayClass     = 0x6D6E7472;    /* 'mntr' */
+
+    /**
+     * ICC Profile Class Signature: 'prtr'.
+     */
+    public static final int icSigOutputClass      = 0x70727472;    /* 'prtr' */
+
+    /**
+     * ICC Profile Class Signature: 'link'.
+     */
+    public static final int icSigLinkClass        = 0x6C696E6B;    /* 'link' */
+
+    /**
+     * ICC Profile Class Signature: 'abst'.
+     */
+    public static final int icSigAbstractClass    = 0x61627374;    /* 'abst' */
+
+    /**
+     * ICC Profile Class Signature: 'spac'.
+     */
+    public static final int icSigColorSpaceClass  = 0x73706163;    /* 'spac' */
+
+    /**
+     * ICC Profile Class Signature: 'nmcl'.
+     */
+    public static final int icSigNamedColorClass  = 0x6e6d636c;    /* 'nmcl' */
+
+
+    /**
+     * ICC Profile Rendering Intent: Perceptual.
+     */
+    public static final int icPerceptual            = 0;
+
+    /**
+     * ICC Profile Rendering Intent: RelativeColorimetric.
+     */
+    public static final int icRelativeColorimetric    = 1;
+
+    /**
+     * ICC Profile Rendering Intent: Media-RelativeColorimetric.
+     * @since 1.5
+     */
+    public static final int icMediaRelativeColorimetric = 1;
+
+    /**
+     * ICC Profile Rendering Intent: Saturation.
+     */
+    public static final int icSaturation            = 2;
+
+    /**
+     * ICC Profile Rendering Intent: AbsoluteColorimetric.
+     */
+    public static final int icAbsoluteColorimetric    = 3;
+
+    /**
+     * ICC Profile Rendering Intent: ICC-AbsoluteColorimetric.
+     * @since 1.5
+     */
+    public static final int icICCAbsoluteColorimetric = 3;
+
+
+    /**
+     * ICC Profile Tag Signature: 'head' - special.
+     */
+    public static final int icSigHead      = 0x68656164; /* 'head' - special */
+
+    /**
+     * ICC Profile Tag Signature: 'A2B0'.
+     */
+    public static final int icSigAToB0Tag         = 0x41324230;    /* 'A2B0' */
+
+    /**
+     * ICC Profile Tag Signature: 'A2B1'.
+     */
+    public static final int icSigAToB1Tag         = 0x41324231;    /* 'A2B1' */
+
+    /**
+     * ICC Profile Tag Signature: 'A2B2'.
+     */
+    public static final int icSigAToB2Tag         = 0x41324232;    /* 'A2B2' */
+
+    /**
+     * ICC Profile Tag Signature: 'bXYZ'.
+     */
+    public static final int icSigBlueColorantTag  = 0x6258595A;    /* 'bXYZ' */
+
+    /**
+     * ICC Profile Tag Signature: 'bXYZ'.
+     * @since 1.5
+     */
+    public static final int icSigBlueMatrixColumnTag = 0x6258595A; /* 'bXYZ' */
+
+    /**
+     * ICC Profile Tag Signature: 'bTRC'.
+     */
+    public static final int icSigBlueTRCTag       = 0x62545243;    /* 'bTRC' */
+
+    /**
+     * ICC Profile Tag Signature: 'B2A0'.
+     */
+    public static final int icSigBToA0Tag         = 0x42324130;    /* 'B2A0' */
+
+    /**
+     * ICC Profile Tag Signature: 'B2A1'.
+     */
+    public static final int icSigBToA1Tag         = 0x42324131;    /* 'B2A1' */
+
+    /**
+     * ICC Profile Tag Signature: 'B2A2'.
+     */
+    public static final int icSigBToA2Tag         = 0x42324132;    /* 'B2A2' */
+
+    /**
+     * ICC Profile Tag Signature: 'calt'.
+     */
+    public static final int icSigCalibrationDateTimeTag = 0x63616C74;
+                                                                   /* 'calt' */
+
+    /**
+     * ICC Profile Tag Signature: 'targ'.
+     */
+    public static final int icSigCharTargetTag    = 0x74617267;    /* 'targ' */
+
+    /**
+     * ICC Profile Tag Signature: 'cprt'.
+     */
+    public static final int icSigCopyrightTag     = 0x63707274;    /* 'cprt' */
+
+    /**
+     * ICC Profile Tag Signature: 'crdi'.
+     */
+    public static final int icSigCrdInfoTag       = 0x63726469;    /* 'crdi' */
+
+    /**
+     * ICC Profile Tag Signature: 'dmnd'.
+     */
+    public static final int icSigDeviceMfgDescTag = 0x646D6E64;    /* 'dmnd' */
+
+    /**
+     * ICC Profile Tag Signature: 'dmdd'.
+     */
+    public static final int icSigDeviceModelDescTag = 0x646D6464;  /* 'dmdd' */
+
+    /**
+     * ICC Profile Tag Signature: 'devs'.
+     */
+    public static final int icSigDeviceSettingsTag =  0x64657673;  /* 'devs' */
+
+    /**
+     * ICC Profile Tag Signature: 'gamt'.
+     */
+    public static final int icSigGamutTag         = 0x67616D74;    /* 'gamt' */
+
+    /**
+     * ICC Profile Tag Signature: 'kTRC'.
+     */
+    public static final int icSigGrayTRCTag       = 0x6b545243;    /* 'kTRC' */
+
+    /**
+     * ICC Profile Tag Signature: 'gXYZ'.
+     */
+    public static final int icSigGreenColorantTag = 0x6758595A;    /* 'gXYZ' */
+
+    /**
+     * ICC Profile Tag Signature: 'gXYZ'.
+     * @since 1.5
+     */
+    public static final int icSigGreenMatrixColumnTag = 0x6758595A;/* 'gXYZ' */
+
+    /**
+     * ICC Profile Tag Signature: 'gTRC'.
+     */
+    public static final int icSigGreenTRCTag      = 0x67545243;    /* 'gTRC' */
+
+    /**
+     * ICC Profile Tag Signature: 'lumi'.
+     */
+    public static final int icSigLuminanceTag     = 0x6C756d69;    /* 'lumi' */
+
+    /**
+     * ICC Profile Tag Signature: 'meas'.
+     */
+    public static final int icSigMeasurementTag   = 0x6D656173;    /* 'meas' */
+
+    /**
+     * ICC Profile Tag Signature: 'bkpt'.
+     */
+    public static final int icSigMediaBlackPointTag = 0x626B7074;  /* 'bkpt' */
+
+    /**
+     * ICC Profile Tag Signature: 'wtpt'.
+     */
+    public static final int icSigMediaWhitePointTag = 0x77747074;  /* 'wtpt' */
+
+    /**
+     * ICC Profile Tag Signature: 'ncl2'.
+     */
+    public static final int icSigNamedColor2Tag   = 0x6E636C32;    /* 'ncl2' */
+
+    /**
+     * ICC Profile Tag Signature: 'resp'.
+     */
+    public static final int icSigOutputResponseTag = 0x72657370;   /* 'resp' */
+
+    /**
+     * ICC Profile Tag Signature: 'pre0'.
+     */
+    public static final int icSigPreview0Tag      = 0x70726530;    /* 'pre0' */
+
+    /**
+     * ICC Profile Tag Signature: 'pre1'.
+     */
+    public static final int icSigPreview1Tag      = 0x70726531;    /* 'pre1' */
+
+    /**
+     * ICC Profile Tag Signature: 'pre2'.
+     */
+    public static final int icSigPreview2Tag      = 0x70726532;    /* 'pre2' */
+
+    /**
+     * ICC Profile Tag Signature: 'desc'.
+     */
+    public static final int icSigProfileDescriptionTag = 0x64657363;
+                                                                   /* 'desc' */
+
+    /**
+     * ICC Profile Tag Signature: 'pseq'.
+     */
+    public static final int icSigProfileSequenceDescTag = 0x70736571;
+                                                                   /* 'pseq' */
+
+    /**
+     * ICC Profile Tag Signature: 'psd0'.
+     */
+    public static final int icSigPs2CRD0Tag       = 0x70736430;    /* 'psd0' */
+
+    /**
+     * ICC Profile Tag Signature: 'psd1'.
+     */
+    public static final int icSigPs2CRD1Tag       = 0x70736431;    /* 'psd1' */
+
+    /**
+     * ICC Profile Tag Signature: 'psd2'.
+     */
+    public static final int icSigPs2CRD2Tag       = 0x70736432;    /* 'psd2' */
+
+    /**
+     * ICC Profile Tag Signature: 'psd3'.
+     */
+    public static final int icSigPs2CRD3Tag       = 0x70736433;    /* 'psd3' */
+
+    /**
+     * ICC Profile Tag Signature: 'ps2s'.
+     */
+    public static final int icSigPs2CSATag        = 0x70733273;    /* 'ps2s' */
+
+    /**
+     * ICC Profile Tag Signature: 'ps2i'.
+     */
+    public static final int icSigPs2RenderingIntentTag = 0x70733269;
+                                                                   /* 'ps2i' */
+
+    /**
+     * ICC Profile Tag Signature: 'rXYZ'.
+     */
+    public static final int icSigRedColorantTag   = 0x7258595A;    /* 'rXYZ' */
+
+    /**
+     * ICC Profile Tag Signature: 'rXYZ'.
+     * @since 1.5
+     */
+    public static final int icSigRedMatrixColumnTag = 0x7258595A;  /* 'rXYZ' */
+
+    /**
+     * ICC Profile Tag Signature: 'rTRC'.
+     */
+    public static final int icSigRedTRCTag        = 0x72545243;    /* 'rTRC' */
+
+    /**
+     * ICC Profile Tag Signature: 'scrd'.
+     */
+    public static final int icSigScreeningDescTag = 0x73637264;    /* 'scrd' */
+
+    /**
+     * ICC Profile Tag Signature: 'scrn'.
+     */
+    public static final int icSigScreeningTag     = 0x7363726E;    /* 'scrn' */
+
+    /**
+     * ICC Profile Tag Signature: 'tech'.
+     */
+    public static final int icSigTechnologyTag    = 0x74656368;    /* 'tech' */
+
+    /**
+     * ICC Profile Tag Signature: 'bfd '.
+     */
+    public static final int icSigUcrBgTag         = 0x62666420;    /* 'bfd ' */
+
+    /**
+     * ICC Profile Tag Signature: 'vued'.
+     */
+    public static final int icSigViewingCondDescTag = 0x76756564;  /* 'vued' */
+
+    /**
+     * ICC Profile Tag Signature: 'view'.
+     */
+    public static final int icSigViewingConditionsTag = 0x76696577;/* 'view' */
+
+    /**
+     * ICC Profile Tag Signature: 'chrm'.
+     */
+    public static final int icSigChromaticityTag  = 0x6368726d;    /* 'chrm' */
+
+    /**
+     * ICC Profile Tag Signature: 'chad'.
+     * @since 1.5
+     */
+    public static final int icSigChromaticAdaptationTag = 0x63686164;/* 'chad' */
+
+    /**
+     * ICC Profile Tag Signature: 'clro'.
+     * @since 1.5
+     */
+    public static final int icSigColorantOrderTag = 0x636C726F;    /* 'clro' */
+
+    /**
+     * ICC Profile Tag Signature: 'clrt'.
+     * @since 1.5
+     */
+    public static final int icSigColorantTableTag = 0x636C7274;    /* 'clrt' */
+
+
+    /**
+     * ICC Profile Header Location: profile size in bytes.
+     */
+    public static final int icHdrSize         = 0;  /* Profile size in bytes */
+
+    /**
+     * ICC Profile Header Location: CMM for this profile.
+     */
+    public static final int icHdrCmmId        = 4;  /* CMM for this profile */
+
+    /**
+     * ICC Profile Header Location: format version number.
+     */
+    public static final int icHdrVersion      = 8;  /* Format version number */
+
+    /**
+     * ICC Profile Header Location: type of profile.
+     */
+    public static final int icHdrDeviceClass  = 12; /* Type of profile */
+
+    /**
+     * ICC Profile Header Location: color space of data.
+     */
+    public static final int icHdrColorSpace   = 16; /* Color space of data */
+
+    /**
+     * ICC Profile Header Location: PCS - XYZ or Lab only.
+     */
+    public static final int icHdrPcs          = 20; /* PCS - XYZ or Lab only */
+
+    /**
+     * ICC Profile Header Location: date profile was created.
+     */
+    public static final int icHdrDate       = 24; /* Date profile was created */
+
+    /**
+     * ICC Profile Header Location: icMagicNumber.
+     */
+    public static final int icHdrMagic        = 36; /* icMagicNumber */
+
+    /**
+     * ICC Profile Header Location: primary platform.
+     */
+    public static final int icHdrPlatform     = 40; /* Primary Platform */
+
+    /**
+     * ICC Profile Header Location: various bit settings.
+     */
+    public static final int icHdrFlags        = 44; /* Various bit settings */
+
+    /**
+     * ICC Profile Header Location: device manufacturer.
+     */
+    public static final int icHdrManufacturer = 48; /* Device manufacturer */
+
+    /**
+     * ICC Profile Header Location: device model number.
+     */
+    public static final int icHdrModel        = 52; /* Device model number */
+
+    /**
+     * ICC Profile Header Location: device attributes.
+     */
+    public static final int icHdrAttributes   = 56; /* Device attributes */
+
+    /**
+     * ICC Profile Header Location: rendering intent.
+     */
+    public static final int icHdrRenderingIntent = 64; /* Rendering intent */
+
+    /**
+     * ICC Profile Header Location: profile illuminant.
+     */
+    public static final int icHdrIlluminant   = 68; /* Profile illuminant */
+
+    /**
+     * ICC Profile Header Location: profile creator.
+     */
+    public static final int icHdrCreator      = 80; /* Profile creator */
+
+    /**
+     * ICC Profile Header Location: profile's ID.
+     * @since 1.5
+     */
+    public static final int icHdrProfileID = 84; /* Profile's ID */
+
+
+    /**
+     * ICC Profile Constant: tag type signaturE.
+     */
+    public static final int icTagType          = 0;    /* tag type signature */
+
+    /**
+     * ICC Profile Constant: reserved.
+     */
+    public static final int icTagReserved      = 4;    /* reserved */
+
+    /**
+     * ICC Profile Constant: curveType count.
+     */
+    public static final int icCurveCount       = 8;    /* curveType count */
+
+    /**
+     * ICC Profile Constant: curveType data.
+     */
+    public static final int icCurveData        = 12;   /* curveType data */
+
+    /**
+     * ICC Profile Constant: XYZNumber X.
+     */
+    public static final int icXYZNumberX       = 8;    /* XYZNumber X */
+
+
+    /**
+     * Constructs an ICC_Profile object with a given ID.
+     */
+    ICC_Profile(long ID) {
+        this.ID = ID;
+    }
+
+
+    /**
+     * Constructs an ICC_Profile object whose loading will be deferred.
+     * The ID will be 0 until the profile is loaded.
+     */
+    ICC_Profile(ProfileDeferralInfo pdi) {
+        this.deferralInfo = pdi;
+        this.profileActivator = new ProfileActivator() {
+            public void activate() {
+                activateDeferredProfile();
+            }
+        };
+        ProfileDeferralMgr.registerDeferral(this.profileActivator);
+    }
+
+
+    /**
+     * Frees the resources associated with an ICC_Profile object.
+     */
+    protected void finalize () {
+        if (ID != 0) {
+            CMSManager.getModule().freeProfile(ID);
+        } else if (profileActivator != null) {
+            ProfileDeferralMgr.unregisterDeferral(profileActivator);
+        }
+    }
+
+
+    /**
+     * Constructs an ICC_Profile object corresponding to the data in
+     * a byte array.  Throws an IllegalArgumentException if the data
+     * does not correspond to a valid ICC Profile.
+     * @param data the specified ICC Profile data
+     * @return an <code>ICC_Profile</code> object corresponding to
+     *          the data in the specified <code>data</code> array.
+     */
+    public static ICC_Profile getInstance(byte[] data) {
+    ICC_Profile thisProfile;
+
+        long theID;
+
+        if (ProfileDeferralMgr.deferring) {
+            ProfileDeferralMgr.activateProfiles();
+        }
+
+        try {
+            theID = CMSManager.getModule().loadProfile(data);
+        } catch (CMMException c) {
+            throw new IllegalArgumentException("Invalid ICC Profile Data");
+        }
+
+        try {
+            if ((getColorSpaceType (theID) == ColorSpace.TYPE_GRAY) &&
+                (getData (theID, icSigMediaWhitePointTag) != null) &&
+                (getData (theID, icSigGrayTRCTag) != null)) {
+                thisProfile = new ICC_ProfileGray (theID);
+            }
+            else if ((getColorSpaceType (theID) == ColorSpace.TYPE_RGB) &&
+                (getData (theID, icSigMediaWhitePointTag) != null) &&
+                (getData (theID, icSigRedColorantTag) != null) &&
+                (getData (theID, icSigGreenColorantTag) != null) &&
+                (getData (theID, icSigBlueColorantTag) != null) &&
+                (getData (theID, icSigRedTRCTag) != null) &&
+                (getData (theID, icSigGreenTRCTag) != null) &&
+                (getData (theID, icSigBlueTRCTag) != null)) {
+                thisProfile = new ICC_ProfileRGB (theID);
+            }
+            else {
+                thisProfile = new ICC_Profile (theID);
+            }
+        } catch (CMMException c) {
+            thisProfile = new ICC_Profile (theID);
+        }
+        return thisProfile;
+    }
+
+
+
+    /**
+     * Constructs an ICC_Profile corresponding to one of the specific color
+     * spaces defined by the ColorSpace class (for example CS_sRGB).
+     * Throws an IllegalArgumentException if cspace is not one of the
+     * defined color spaces.
+     *
+     * @param cspace the type of color space to create a profile for.
+     * The specified type is one of the color
+     * space constants defined in the  <CODE>ColorSpace</CODE> class.
+     *
+     * @return an <code>ICC_Profile</code> object corresponding to
+     *          the specified <code>ColorSpace</code> type.
+     * @exception IllegalArgumentException If <CODE>cspace</CODE> is not
+     * one of the predefined color space types.
+     */
+    public static ICC_Profile getInstance (int cspace) {
+        ICC_Profile thisProfile = null;
+        String fileName;
+
+        switch (cspace) {
+        case ColorSpace.CS_sRGB:
+            synchronized(ICC_Profile.class) {
+                if (sRGBprofile == null) {
+                    try {
+                        /*
+                         * Deferral is only used for standard profiles.
+                         * Enabling the appropriate access privileges is handled
+                         * at a lower level.
+                         */
+                        sRGBprofile = getDeferredInstance(
+                            new ProfileDeferralInfo("sRGB.pf",
+                                                    ColorSpace.TYPE_RGB,
+                                                    3, CLASS_DISPLAY));
+                    } catch (IOException e) {
+                        throw new IllegalArgumentException(
+                              "Can't load standard profile: sRGB.pf");
+                    }
+                }
+                thisProfile = sRGBprofile;
+            }
+
+            break;
+
+        case ColorSpace.CS_CIEXYZ:
+            synchronized(ICC_Profile.class) {
+                if (XYZprofile == null) {
+                    XYZprofile = getStandardProfile("CIEXYZ.pf");
+                }
+                thisProfile = XYZprofile;
+            }
+
+            break;
+
+        case ColorSpace.CS_PYCC:
+            synchronized(ICC_Profile.class) {
+                if (PYCCprofile == null) {
+                    PYCCprofile = getStandardProfile("PYCC.pf");
+                }
+                thisProfile = PYCCprofile;
+            }
+
+            break;
+
+        case ColorSpace.CS_GRAY:
+            synchronized(ICC_Profile.class) {
+                if (GRAYprofile == null) {
+                    GRAYprofile = getStandardProfile("GRAY.pf");
+                }
+                thisProfile = GRAYprofile;
+            }
+
+            break;
+
+        case ColorSpace.CS_LINEAR_RGB:
+            synchronized(ICC_Profile.class) {
+                if (LINEAR_RGBprofile == null) {
+                    LINEAR_RGBprofile = getStandardProfile("LINEAR_RGB.pf");
+                }
+                thisProfile = LINEAR_RGBprofile;
+            }
+
+            break;
+
+        default:
+            throw new IllegalArgumentException("Unknown color space");
+        }
+
+        return thisProfile;
+    }
+
+    /* This asserts system privileges, so is used only for the
+     * standard profiles.
+     */
+    private static ICC_Profile getStandardProfile(final String name) {
+
+        return (ICC_Profile) AccessController.doPrivileged(
+            new PrivilegedAction() {
+                 public Object run() {
+                     ICC_Profile p = null;
+                     try {
+                         p = getInstance (name);
+                     } catch (IOException ex) {
+                         throw new IllegalArgumentException(
+                               "Can't load standard profile: " + name);
+                     }
+                     return p;
+                 }
+             });
+    }
+
+    /**
+     * Constructs an ICC_Profile corresponding to the data in a file.
+     * fileName may be an absolute or a relative file specification.
+     * Relative file names are looked for in several places: first, relative
+     * to any directories specified by the java.iccprofile.path property;
+     * second, relative to any directories specified by the java.class.path
+     * property; finally, in a directory used to store profiles always
+     * available, such as the profile for sRGB.  Built-in profiles use .pf as
+     * the file name extension for profiles, e.g. sRGB.pf.
+     * This method throws an IOException if the specified file cannot be
+     * opened or if an I/O error occurs while reading the file.  It throws
+     * an IllegalArgumentException if the file does not contain valid ICC
+     * Profile data.
+     * @param fileName The file that contains the data for the profile.
+     *
+     * @return an <code>ICC_Profile</code> object corresponding to
+     *          the data in the specified file.
+     * @exception IOException If the specified file cannot be opened or
+     * an I/O error occurs while reading the file.
+     *
+     * @exception IllegalArgumentException If the file does not
+     * contain valid ICC Profile data.
+     *
+     * @exception SecurityException If a security manager is installed
+     * and it does not permit read access to the given file.
+     */
+    public static ICC_Profile getInstance(String fileName) throws IOException {
+    ICC_Profile thisProfile;
+    FileInputStream fis;
+
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkRead(fileName);
+        }
+
+        if ((fis = openProfile(fileName)) == null) {
+            throw new IOException("Cannot open file " + fileName);
+        }
+
+        thisProfile = getInstance(fis);
+
+        fis.close();    /* close the file */
+
+        return thisProfile;
+    }
+
+
+    /**
+     * Constructs an ICC_Profile corresponding to the data in an InputStream.
+     * This method throws an IllegalArgumentException if the stream does not
+     * contain valid ICC Profile data.  It throws an IOException if an I/O
+     * error occurs while reading the stream.
+     * @param s The input stream from which to read the profile data.
+     *
+     * @return an <CODE>ICC_Profile</CODE> object corresponding to the
+     *     data in the specified <code>InputStream</code>.
+     *
+     * @exception IOException If an I/O error occurs while reading the stream.
+     *
+     * @exception IllegalArgumentException If the stream does not
+     * contain valid ICC Profile data.
+     */
+    public static ICC_Profile getInstance(InputStream s) throws IOException {
+    byte profileData[];
+
+        if (s instanceof ProfileDeferralInfo) {
+            /* hack to detect profiles whose loading can be deferred */
+            return getDeferredInstance((ProfileDeferralInfo) s);
+        }
+
+        if ((profileData = getProfileDataFromStream(s)) == null) {
+            throw new IllegalArgumentException("Invalid ICC Profile Data");
+        }
+
+        return getInstance(profileData);
+    }
+
+
+    static byte[] getProfileDataFromStream(InputStream s) throws IOException {
+    byte profileData[];
+    int profileSize;
+
+        byte header[] = new byte[128];
+        int bytestoread = 128;
+        int bytesread = 0;
+        int n;
+
+        while (bytestoread != 0) {
+            if ((n = s.read(header, bytesread, bytestoread)) < 0) {
+                return null;
+            }
+            bytesread += n;
+            bytestoread -= n;
+        }
+        if (header[36] != 0x61 || header[37] != 0x63 ||
+            header[38] != 0x73 || header[39] != 0x70) {
+            return null;   /* not a valid profile */
+        }
+        profileSize = ((header[0] & 0xff) << 24) |
+                      ((header[1] & 0xff) << 16) |
+                      ((header[2] & 0xff) <<  8) |
+                       (header[3] & 0xff);
+        profileData = new byte[profileSize];
+        System.arraycopy(header, 0, profileData, 0, 128);
+        bytestoread = profileSize - 128;
+        bytesread = 128;
+        while (bytestoread != 0) {
+            if ((n = s.read(profileData, bytesread, bytestoread)) < 0) {
+                return null;
+            }
+            bytesread += n;
+            bytestoread -= n;
+        }
+
+        return profileData;
+    }
+
+
+    /**
+     * Constructs an ICC_Profile for which the actual loading of the
+     * profile data from a file and the initialization of the CMM should
+     * be deferred as long as possible.
+     * Deferral is only used for standard profiles.
+     * If deferring is disabled, then getStandardProfile() ensures
+     * that all of the appropriate access privileges are granted
+     * when loading this profile.
+     * If deferring is enabled, then the deferred activation
+     * code will take care of access privileges.
+     * @see activateDeferredProfile()
+     */
+    static ICC_Profile getDeferredInstance(ProfileDeferralInfo pdi)
+        throws IOException {
+
+        if (!ProfileDeferralMgr.deferring) {
+            return getStandardProfile(pdi.filename);
+        }
+        if (pdi.colorSpaceType == ColorSpace.TYPE_RGB) {
+            return new ICC_ProfileRGB(pdi);
+        } else if (pdi.colorSpaceType == ColorSpace.TYPE_GRAY) {
+            return new ICC_ProfileGray(pdi);
+        } else {
+            return new ICC_Profile(pdi);
+        }
+    }
+
+
+    void activateDeferredProfile() {
+    byte profileData[];
+    FileInputStream fis;
+    String fileName = deferralInfo.filename;
+
+        profileActivator = null;
+        deferralInfo = null;
+        if ((fis = openProfile(fileName)) == null) {
+            throw new IllegalArgumentException("Cannot open file " + fileName);
+        }
+        try {
+            profileData = getProfileDataFromStream(fis);
+            fis.close();    /* close the file */
+        }
+        catch (IOException e) {
+            throw new IllegalArgumentException("Invalid ICC Profile Data" +
+                fileName);
+        }
+        if (profileData == null) {
+            throw new IllegalArgumentException("Invalid ICC Profile Data" +
+                fileName);
+        }
+        try {
+            ID = CMSManager.getModule().loadProfile(profileData);
+        } catch (CMMException c) {
+            throw new IllegalArgumentException("Invalid ICC Profile Data" +
+                fileName);
+        }
+    }
+
+
+    /**
+     * Returns profile major version.
+     * @return  The major version of the profile.
+     */
+    public int getMajorVersion() {
+    byte[] theHeader;
+
+        theHeader = getData(icSigHead); /* getData will activate deferred
+                                           profiles if necessary */
+
+        return (int) theHeader[8];
+    }
+
+    /**
+     * Returns profile minor version.
+     * @return The minor version of the profile.
+     */
+    public int getMinorVersion() {
+    byte[] theHeader;
+
+        theHeader = getData(icSigHead); /* getData will activate deferred
+                                           profiles if necessary */
+
+        return (int) theHeader[9];
+    }
+
+    /**
+     * Returns the profile class.
+     * @return One of the predefined profile class constants.
+     */
+    public int getProfileClass() {
+    byte[] theHeader;
+    int theClassSig, theClass;
+
+        if (deferralInfo != null) {
+            return deferralInfo.profileClass; /* Need to have this info for
+                                                 ICC_ColorSpace without
+                                                 causing a deferred profile
+                                                 to be loaded */
+        }
+
+        theHeader = getData(icSigHead);
+
+        theClassSig = intFromBigEndian (theHeader, icHdrDeviceClass);
+
+        switch (theClassSig) {
+        case icSigInputClass:
+            theClass = CLASS_INPUT;
+            break;
+
+        case icSigDisplayClass:
+            theClass = CLASS_DISPLAY;
+            break;
+
+        case icSigOutputClass:
+            theClass = CLASS_OUTPUT;
+            break;
+
+        case icSigLinkClass:
+            theClass = CLASS_DEVICELINK;
+            break;
+
+        case icSigColorSpaceClass:
+            theClass = CLASS_COLORSPACECONVERSION;
+            break;
+
+        case icSigAbstractClass:
+            theClass = CLASS_ABSTRACT;
+            break;
+
+        case icSigNamedColorClass:
+            theClass = CLASS_NAMEDCOLOR;
+            break;
+
+        default:
+            throw new IllegalArgumentException("Unknown profile class");
+        }
+
+        return theClass;
+    }
+
+    /**
+     * Returns the color space type.  Returns one of the color space type
+     * constants defined by the ColorSpace class.  This is the
+     * "input" color space of the profile.  The type defines the
+     * number of components of the color space and the interpretation,
+     * e.g. TYPE_RGB identifies a color space with three components - red,
+     * green, and blue.  It does not define the particular color
+     * characteristics of the space, e.g. the chromaticities of the
+     * primaries.
+     * @return One of the color space type constants defined in the
+     * <CODE>ColorSpace</CODE> class.
+     */
+    public int getColorSpaceType() {
+        if (deferralInfo != null) {
+            return deferralInfo.colorSpaceType; /* Need to have this info for
+                                                   ICC_ColorSpace without
+                                                   causing a deferred profile
+                                                   to be loaded */
+        }
+        return    getColorSpaceType(ID);
+    }
+
+    static int getColorSpaceType(long profileID) {
+    byte[] theHeader;
+    int theColorSpaceSig, theColorSpace;
+
+        theHeader = getData(profileID, icSigHead);
+        theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace);
+        theColorSpace = iccCStoJCS (theColorSpaceSig);
+        return theColorSpace;
+    }
+
+    /**
+     * Returns the color space type of the Profile Connection Space (PCS).
+     * Returns one of the color space type constants defined by the
+     * ColorSpace class.  This is the "output" color space of the
+     * profile.  For an input, display, or output profile useful
+     * for tagging colors or images, this will be either TYPE_XYZ or
+     * TYPE_Lab and should be interpreted as the corresponding specific
+     * color space defined in the ICC specification.  For a device
+     * link profile, this could be any of the color space type constants.
+     * @return One of the color space type constants defined in the
+     * <CODE>ColorSpace</CODE> class.
+     */
+    public int getPCSType() {
+        if (ProfileDeferralMgr.deferring) {
+            ProfileDeferralMgr.activateProfiles();
+        }
+        return getPCSType(ID);
+    }
+
+
+    static int getPCSType(long profileID) {
+    byte[] theHeader;
+    int thePCSSig, thePCS;
+
+        theHeader = getData(profileID, icSigHead);
+        thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
+        thePCS = iccCStoJCS(thePCSSig);
+        return thePCS;
+    }
+
+
+    /**
+     * Write this ICC_Profile to a file.
+     *
+     * @param fileName The file to write the profile data to.
+     *
+     * @exception IOException If the file cannot be opened for writing
+     * or an I/O error occurs while writing to the file.
+     */
+    public void write(String fileName) throws IOException {
+    FileOutputStream outputFile;
+    byte profileData[];
+
+        profileData = getData(); /* this will activate deferred
+                                    profiles if necessary */
+        outputFile = new FileOutputStream(fileName);
+        outputFile.write(profileData);
+        outputFile.close ();
+    }
+
+
+    /**
+     * Write this ICC_Profile to an OutputStream.
+     *
+     * @param s The stream to write the profile data to.
+     *
+     * @exception IOException If an I/O error occurs while writing to the
+     * stream.
+     */
+    public void write(OutputStream s) throws IOException {
+    byte profileData[];
+
+        profileData = getData(); /* this will activate deferred
+                                    profiles if necessary */
+        s.write(profileData);
+    }
+
+
+    /**
+     * Returns a byte array corresponding to the data of this ICC_Profile.
+     * @return A byte array that contains the profile data.
+     * @see #setData(int, byte[])
+     */
+    public byte[] getData() {
+    int profileSize;
+    byte[] profileData;
+
+        if (ProfileDeferralMgr.deferring) {
+            ProfileDeferralMgr.activateProfiles();
+        }
+
+        PCMM mdl = CMSManager.getModule();
+
+        /* get the number of bytes needed for this profile */
+        profileSize = mdl.getProfileSize(ID);
+
+        profileData = new byte [profileSize];
+
+        /* get the data for the profile */
+        mdl.getProfileData(ID, profileData);
+
+        return profileData;
+    }
+
+
+    /**
+     * Returns a particular tagged data element from the profile as
+     * a byte array.  Elements are identified by signatures
+     * as defined in the ICC specification.  The signature
+     * icSigHead can be used to get the header.  This method is useful
+     * for advanced applets or applications which need to access
+     * profile data directly.
+     *
+     * @param tagSignature The ICC tag signature for the data element you
+     * want to get.
+     *
+     * @return A byte array that contains the tagged data element. Returns
+     * <code>null</code> if the specified tag doesn't exist.
+     * @see #setData(int, byte[])
+     */
+    public byte[] getData(int tagSignature) {
+
+        if (ProfileDeferralMgr.deferring) {
+            ProfileDeferralMgr.activateProfiles();
+        }
+
+        return getData(ID, tagSignature);
+    }
+
+
+    static byte[] getData(long profileID, int tagSignature) {
+    int tagSize;
+    byte[] tagData;
+
+        try {
+            PCMM mdl = CMSManager.getModule();
+
+            /* get the number of bytes needed for this tag */
+            tagSize = mdl.getTagSize(profileID, tagSignature);
+
+            tagData = new byte[tagSize]; /* get an array for the tag */
+
+            /* get the tag's data */
+            mdl.getTagData(profileID, tagSignature, tagData);
+        } catch(CMMException c) {
+            tagData = null;
+        }
+
+        return tagData;
+    }
+
+    /**
+     * Sets a particular tagged data element in the profile from
+     * a byte array.  This method is useful
+     * for advanced applets or applications which need to access
+     * profile data directly.
+     *
+     * @param tagSignature The ICC tag signature for the data element
+     * you want to set.
+     * @param tagData the data to set for the specified tag signature
+     * @see #getData
+     */
+    public void setData(int tagSignature, byte[] tagData) {
+
+        if (ProfileDeferralMgr.deferring) {
+            ProfileDeferralMgr.activateProfiles();
+        }
+
+        CMSManager.getModule().setTagData(ID, tagSignature, tagData);
+    }
+
+    /**
+     * Sets the rendering intent of the profile.
+     * This is used to select the proper transform from a profile that
+     * has multiple transforms.
+     */
+    void setRenderingIntent(int renderingIntent) {
+        byte[] theHeader = getData(icSigHead);/* getData will activate deferred
+                                                 profiles if necessary */
+        intToBigEndian (renderingIntent, theHeader, icHdrRenderingIntent);
+                                                 /* set the rendering intent */
+        setData (icSigHead, theHeader);
+    }
+
+
+    /**
+     * Returns the rendering intent of the profile.
+     * This is used to select the proper transform from a profile that
+     * has multiple transforms.  It is typically set in a source profile
+     * to select a transform from an output profile.
+     */
+    int getRenderingIntent() {
+        byte[] theHeader = getData(icSigHead);/* getData will activate deferred
+                                                 profiles if necessary */
+
+        int renderingIntent = intFromBigEndian(theHeader, icHdrRenderingIntent);
+                                                 /* set the rendering intent */
+        return renderingIntent;
+    }
+
+
+    /**
+     * Returns the number of color components in the "input" color
+     * space of this profile.  For example if the color space type
+     * of this profile is TYPE_RGB, then this method will return 3.
+     *
+     * @return The number of color components in the profile's input
+     * color space.
+     *
+     * @throws ProfileDataException if color space is in the profile
+     *         is invalid
+     */
+    public int getNumComponents() {
+    byte[]    theHeader;
+    int    theColorSpaceSig, theNumComponents;
+
+        if (deferralInfo != null) {
+            return deferralInfo.numComponents; /* Need to have this info for
+                                                  ICC_ColorSpace without
+                                                  causing a deferred profile
+                                                  to be loaded */
+        }
+        theHeader = getData(icSigHead);
+
+        theColorSpaceSig = intFromBigEndian (theHeader, icHdrColorSpace);
+
+        switch (theColorSpaceSig) {
+        case icSigGrayData:
+            theNumComponents = 1;
+            break;
+
+        case icSigSpace2CLR:
+            theNumComponents = 2;
+            break;
+
+        case icSigXYZData:
+        case icSigLabData:
+        case icSigLuvData:
+        case icSigYCbCrData:
+        case icSigYxyData:
+        case icSigRgbData:
+        case icSigHsvData:
+        case icSigHlsData:
+        case icSigCmyData:
+        case icSigSpace3CLR:
+            theNumComponents = 3;
+            break;
+
+        case icSigCmykData:
+        case icSigSpace4CLR:
+            theNumComponents = 4;
+            break;
+
+        case icSigSpace5CLR:
+            theNumComponents = 5;
+            break;
+
+        case icSigSpace6CLR:
+            theNumComponents = 6;
+            break;
+
+        case icSigSpace7CLR:
+            theNumComponents = 7;
+            break;
+
+        case icSigSpace8CLR:
+            theNumComponents = 8;
+            break;
+
+        case icSigSpace9CLR:
+            theNumComponents = 9;
+            break;
+
+        case icSigSpaceACLR:
+            theNumComponents = 10;
+            break;
+
+        case icSigSpaceBCLR:
+            theNumComponents = 11;
+            break;
+
+        case icSigSpaceCCLR:
+            theNumComponents = 12;
+            break;
+
+        case icSigSpaceDCLR:
+            theNumComponents = 13;
+            break;
+
+        case icSigSpaceECLR:
+            theNumComponents = 14;
+            break;
+
+        case icSigSpaceFCLR:
+            theNumComponents = 15;
+            break;
+
+        default:
+            throw new ProfileDataException ("invalid ICC color space");
+        }
+
+        return theNumComponents;
+    }
+
+
+    /**
+     * Returns a float array of length 3 containing the X, Y, and Z
+     * components of the mediaWhitePointTag in the ICC profile.
+     */
+    float[] getMediaWhitePoint() {
+        return getXYZTag(icSigMediaWhitePointTag);
+                                           /* get the media white point tag */
+    }
+
+
+    /**
+     * Returns a float array of length 3 containing the X, Y, and Z
+     * components encoded in an XYZType tag.
+     */
+    float[] getXYZTag(int theTagSignature) {
+    byte[] theData;
+    float[] theXYZNumber;
+    int i1, i2, theS15Fixed16;
+
+        theData = getData(theTagSignature); /* get the tag data */
+                                            /* getData will activate deferred
+                                               profiles if necessary */
+
+        theXYZNumber = new float [3];        /* array to return */
+
+        /* convert s15Fixed16Number to float */
+        for (i1 = 0, i2 = icXYZNumberX; i1 < 3; i1++, i2 += 4) {
+            theS15Fixed16 = intFromBigEndian(theData, i2);
+            theXYZNumber [i1] = ((float) theS15Fixed16) / 65536.0f;
+        }
+        return theXYZNumber;
+    }
+
+
+    /**
+     * Returns a gamma value representing a tone reproduction
+     * curve (TRC).  If the profile represents the TRC as a table rather
+     * than a single gamma value, then an exception is thrown.  In this
+     * case the actual table can be obtained via getTRC().
+     * theTagSignature should be one of icSigGrayTRCTag, icSigRedTRCTag,
+     * icSigGreenTRCTag, or icSigBlueTRCTag.
+     * @return the gamma value as a float.
+     * @exception ProfileDataException if the profile does not specify
+     *            the TRC as a single gamma value.
+     */
+    float getGamma(int theTagSignature) {
+    byte[] theTRCData;
+    float theGamma;
+    int theU8Fixed8;
+
+        theTRCData = getData(theTagSignature); /* get the TRC */
+                                               /* getData will activate deferred
+                                                  profiles if necessary */
+
+        if (intFromBigEndian (theTRCData, icCurveCount) != 1) {
+            throw new ProfileDataException ("TRC is not a gamma");
+        }
+
+        /* convert u8Fixed8 to float */
+        theU8Fixed8 = (shortFromBigEndian(theTRCData, icCurveData)) & 0xffff;
+
+        theGamma = ((float) theU8Fixed8) / 256.0f;
+
+        return theGamma;
+    }
+
+
+    /**
+     * Returns the TRC as an array of shorts.  If the profile has
+     * specified the TRC as linear (gamma = 1.0) or as a simple gamma
+     * value, this method throws an exception, and the getGamma() method
+     * should be used to get the gamma value.  Otherwise the short array
+     * returned here represents a lookup table where the input Gray value
+     * is conceptually in the range [0.0, 1.0].  Value 0.0 maps
+     * to array index 0 and value 1.0 maps to array index length-1.
+     * Interpolation may be used to generate output values for
+     * input values which do not map exactly to an index in the
+     * array.  Output values also map linearly to the range [0.0, 1.0].
+     * Value 0.0 is represented by an array value of 0x0000 and
+     * value 1.0 by 0xFFFF, i.e. the values are really unsigned
+     * short values, although they are returned in a short array.
+     * theTagSignature should be one of icSigGrayTRCTag, icSigRedTRCTag,
+     * icSigGreenTRCTag, or icSigBlueTRCTag.
+     * @return a short array representing the TRC.
+     * @exception ProfileDataException if the profile does not specify
+     *            the TRC as a table.
+     */
+    short[] getTRC(int theTagSignature) {
+    byte[] theTRCData;
+    short[] theTRC;
+    int i1, i2, nElements, theU8Fixed8;
+
+        theTRCData = getData(theTagSignature); /* get the TRC */
+                                               /* getData will activate deferred
+                                                  profiles if necessary */
+
+        nElements = intFromBigEndian(theTRCData, icCurveCount);
+
+        if (nElements == 1) {
+            throw new ProfileDataException("TRC is not a table");
+        }
+
+        /* make the short array */
+        theTRC = new short [nElements];
+
+        for (i1 = 0, i2 = icCurveData; i1 < nElements; i1++, i2 += 2) {
+            theTRC[i1] = shortFromBigEndian(theTRCData, i2);
+        }
+
+        return theTRC;
+    }
+
+
+    /* convert an ICC color space signature into a Java color space type */
+    static int iccCStoJCS(int theColorSpaceSig) {
+    int theColorSpace;
+
+        switch (theColorSpaceSig) {
+        case icSigXYZData:
+            theColorSpace = ColorSpace.TYPE_XYZ;
+            break;
+
+        case icSigLabData:
+            theColorSpace = ColorSpace.TYPE_Lab;
+            break;
+
+        case icSigLuvData:
+            theColorSpace = ColorSpace.TYPE_Luv;
+            break;
+
+        case icSigYCbCrData:
+            theColorSpace = ColorSpace.TYPE_YCbCr;
+            break;
+
+        case icSigYxyData:
+            theColorSpace = ColorSpace.TYPE_Yxy;
+            break;
+
+        case icSigRgbData:
+            theColorSpace = ColorSpace.TYPE_RGB;
+            break;
+
+        case icSigGrayData:
+            theColorSpace = ColorSpace.TYPE_GRAY;
+            break;
+
+        case icSigHsvData:
+            theColorSpace = ColorSpace.TYPE_HSV;
+            break;
+
+        case icSigHlsData:
+            theColorSpace = ColorSpace.TYPE_HLS;
+            break;
+
+        case icSigCmykData:
+            theColorSpace = ColorSpace.TYPE_CMYK;
+            break;
+
+        case icSigCmyData:
+            theColorSpace = ColorSpace.TYPE_CMY;
+            break;
+
+        case icSigSpace2CLR:
+            theColorSpace = ColorSpace.TYPE_2CLR;
+            break;
+
+        case icSigSpace3CLR:
+            theColorSpace = ColorSpace.TYPE_3CLR;
+            break;
+
+        case icSigSpace4CLR:
+            theColorSpace = ColorSpace.TYPE_4CLR;
+            break;
+
+        case icSigSpace5CLR:
+            theColorSpace = ColorSpace.TYPE_5CLR;
+            break;
+
+        case icSigSpace6CLR:
+            theColorSpace = ColorSpace.TYPE_6CLR;
+            break;
+
+        case icSigSpace7CLR:
+            theColorSpace = ColorSpace.TYPE_7CLR;
+            break;
+
+        case icSigSpace8CLR:
+            theColorSpace = ColorSpace.TYPE_8CLR;
+            break;
+
+        case icSigSpace9CLR:
+            theColorSpace = ColorSpace.TYPE_9CLR;
+            break;
+
+        case icSigSpaceACLR:
+            theColorSpace = ColorSpace.TYPE_ACLR;
+            break;
+
+        case icSigSpaceBCLR:
+            theColorSpace = ColorSpace.TYPE_BCLR;
+            break;
+
+        case icSigSpaceCCLR:
+            theColorSpace = ColorSpace.TYPE_CCLR;
+            break;
+
+        case icSigSpaceDCLR:
+            theColorSpace = ColorSpace.TYPE_DCLR;
+            break;
+
+        case icSigSpaceECLR:
+            theColorSpace = ColorSpace.TYPE_ECLR;
+            break;
+
+        case icSigSpaceFCLR:
+            theColorSpace = ColorSpace.TYPE_FCLR;
+            break;
+
+        default:
+            throw new IllegalArgumentException ("Unknown color space");
+        }
+
+        return theColorSpace;
+    }
+
+
+    static int intFromBigEndian(byte[] array, int index) {
+        return (((array[index]   & 0xff) << 24) |
+                ((array[index+1] & 0xff) << 16) |
+                ((array[index+2] & 0xff) <<  8) |
+                 (array[index+3] & 0xff));
+    }
+
+
+    static void intToBigEndian(int value, byte[] array, int index) {
+            array[index]   = (byte) (value >> 24);
+            array[index+1] = (byte) (value >> 16);
+            array[index+2] = (byte) (value >>  8);
+            array[index+3] = (byte) (value);
+    }
+
+
+    static short shortFromBigEndian(byte[] array, int index) {
+        return (short) (((array[index]   & 0xff) << 8) |
+                         (array[index+1] & 0xff));
+    }
+
+
+    static void shortToBigEndian(short value, byte[] array, int index) {
+            array[index]   = (byte) (value >> 8);
+            array[index+1] = (byte) (value);
+    }
+
+
+    /*
+     * fileName may be an absolute or a relative file specification.
+     * Relative file names are looked for in several places: first, relative
+     * to any directories specified by the java.iccprofile.path property;
+     * second, relative to any directories specified by the java.class.path
+     * property; finally, in a directory used to store profiles always
+     * available, such as a profile for sRGB.  Built-in profiles use .pf as
+     * the file name extension for profiles, e.g. sRGB.pf.
+     */
+    private static FileInputStream openProfile(final String fileName) {
+        return (FileInputStream)java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction() {
+            public Object run() {
+                return privilegedOpenProfile(fileName);
+            }
+        });
+    }
+
+    /*
+     * this version is called from doPrivileged in privilegedOpenProfile.
+     * the whole method is privileged!
+     */
+    private static FileInputStream privilegedOpenProfile(String fileName) {
+        FileInputStream fis = null;
+        String path, dir, fullPath;
+
+        File f = new File(fileName); /* try absolute file name */
+
+        if ((!f.isFile()) &&
+                ((path = System.getProperty("java.iccprofile.path")) != null)){
+                                    /* try relative to java.iccprofile.path */
+                StringTokenizer st =
+                    new StringTokenizer(path, File.pathSeparator);
+                while (st.hasMoreTokens() && (!f.isFile())) {
+                    dir = st.nextToken();
+                        fullPath = dir + File.separatorChar + fileName;
+                    f = new File(fullPath);
+                }
+            }
+
+        if ((!f.isFile()) &&
+                ((path = System.getProperty("java.class.path")) != null)) {
+                                    /* try relative to java.class.path */
+                StringTokenizer st =
+                    new StringTokenizer(path, File.pathSeparator);
+                while (st.hasMoreTokens() && (!f.isFile())) {
+                    dir = st.nextToken();
+                        fullPath = dir + File.separatorChar + fileName;
+                    f = new File(fullPath);
+                }
+            }
+
+        if (!f.isFile()) { /* try the directory of built-in profiles */
+                dir = System.getProperty("java.home") +
+                    File.separatorChar + "lib" + File.separatorChar + "cmm";
+                fullPath = dir + File.separatorChar + fileName;
+                f = new File(fullPath);
+            }
+
+        if (f.isFile()) {
+            try {
+                fis = new FileInputStream(f);
+            } catch (FileNotFoundException e) {
+            }
+        }
+        return fis;
+    }
+
+
+    /*
+     * Serialization support.
+     *
+     * Directly deserialized profiles are useless since they are not
+     * registered with CMM.  We don't allow constructor to be called
+     * directly and instead have clients to call one of getInstance
+     * factory methods that will register the profile with CMM.  For
+     * deserialization we implement readResolve method that will
+     * resolve the bogus deserialized profile object with one obtained
+     * with getInstance as well.
+     *
+     * There're two primary factory methods for construction of ICC
+     * profiles: getInstance(int cspace) and getInstance(byte[] data).
+     * This implementation of ICC_Profile uses the former to return a
+     * cached singleton profile object, other implementations will
+     * likely use this technique too.  To preserve the singleton
+     * pattern across serialization we serialize cached singleton
+     * profiles in such a way that deserializing VM could call
+     * getInstance(int cspace) method that will resolve deserialized
+     * object into the corresponding singleton as well.
+     *
+     * Since the singletons are private to ICC_Profile the readResolve
+     * method have to be `protected' instead of `private' so that
+     * singletons that are instances of subclasses of ICC_Profile
+     * could be correctly deserialized.
+     */
+
+
+    /**
+     * Version of the format of additional serialized data in the
+     * stream.  Version&nbsp;<code>1</code> corresponds to Java&nbsp;2
+     * Platform,&nbsp;v1.3.
+     * @since 1.3
+     * @serial
+     */
+    private int iccProfileSerializedDataVersion = 1;
+
+
+    /**
+     * Writes default serializable fields to the stream.  Writes a
+     * string and an array of bytes to the stream as additional data.
+     *
+     * @param s stream used for serialization.
+     * @throws IOException
+     *     thrown by <code>ObjectInputStream</code>.
+     * @serialData
+     *     The <code>String</code> is the name of one of
+     *     <code>CS_<var>*</var></code> constants defined in the
+     *     {@link ColorSpace} class if the profile object is a profile
+     *     for a predefined color space (for example
+     *     <code>"CS_sRGB"</code>).  The string is <code>null</code>
+     *     otherwise.
+     *     <p>
+     *     The <code>byte[]</code> array is the profile data for the
+     *     profile.  For predefined color spaces <code>null</code> is
+     *     written instead of the profile data.  If in the future
+     *     versions of Java API new predefined color spaces will be
+     *     added, future versions of this class may choose to write
+     *     for new predefined color spaces not only the color space
+     *     name, but the profile data as well so that older versions
+     *     could still deserialize the object.
+     */
+    private void writeObject(ObjectOutputStream s)
+      throws IOException
+    {
+        s.defaultWriteObject();
+
+        String csName = null;
+        if (this == sRGBprofile) {
+            csName = "CS_sRGB";
+        } else if (this == XYZprofile) {
+            csName = "CS_CIEXYZ";
+        } else if (this == PYCCprofile) {
+            csName = "CS_PYCC";
+        } else if (this == GRAYprofile) {
+            csName = "CS_GRAY";
+        } else if (this == LINEAR_RGBprofile) {
+            csName = "CS_LINEAR_RGB";
+        }
+
+        // Future versions may choose to write profile data for new
+        // predefined color spaces as well, if any will be introduced,
+        // so that old versions that don't recognize the new CS name
+        // may fall back to constructing profile from the data.
+        byte[] data = null;
+        if (csName == null) {
+            // getData will activate deferred profile if necessary
+            data = getData();
+        }
+
+        s.writeObject(csName);
+        s.writeObject(data);
+    }
+
+    // Temporary storage used by readObject to store resolved profile
+    // (obtained with getInstance) for readResolve to return.
+    private transient ICC_Profile resolvedDeserializedProfile;
+
+    /**
+     * Reads default serializable fields from the stream.  Reads from
+     * the stream a string and an array of bytes as additional data.
+     *
+     * @param s stream used for deserialization.
+     * @throws IOException
+     *     thrown by <code>ObjectInputStream</code>.
+     * @throws ClassNotFoundException
+     *     thrown by <code>ObjectInputStream</code>.
+     * @serialData
+     *     The <code>String</code> is the name of one of
+     *     <code>CS_<var>*</var></code> constants defined in the
+     *     {@link ColorSpace} class if the profile object is a profile
+     *     for a predefined color space (for example
+     *     <code>"CS_sRGB"</code>).  The string is <code>null</code>
+     *     otherwise.
+     *     <p>
+     *     The <code>byte[]</code> array is the profile data for the
+     *     profile.  It will usually be <code>null</code> for the
+     *     predefined profiles.
+     *     <p>
+     *     If the string is recognized as a constant name for
+     *     predefined color space the object will be resolved into
+     *     profile obtained with
+     *     <code>getInstance(int&nbsp;cspace)</code> and the profile
+     *     data are ignored.  Otherwise the object will be resolved
+     *     into profile obtained with
+     *     <code>getInstance(byte[]&nbsp;data)</code>.
+     * @see #readResolve()
+     * @see #getInstance(int)
+     * @see #getInstance(byte[])
+     */
+    private void readObject(ObjectInputStream s)
+      throws IOException, ClassNotFoundException
+    {
+        s.defaultReadObject();
+
+        String csName = (String)s.readObject();
+        byte[] data = (byte[])s.readObject();
+
+        int cspace = 0;         // ColorSpace.CS_* constant if known
+        boolean isKnownPredefinedCS = false;
+        if (csName != null) {
+            isKnownPredefinedCS = true;
+            if (csName.equals("CS_sRGB")) {
+                cspace = ColorSpace.CS_sRGB;
+            } else if (csName.equals("CS_CIEXYZ")) {
+                cspace = ColorSpace.CS_CIEXYZ;
+            } else if (csName.equals("CS_PYCC")) {
+                cspace = ColorSpace.CS_PYCC;
+            } else if (csName.equals("CS_GRAY")) {
+                cspace = ColorSpace.CS_GRAY;
+            } else if (csName.equals("CS_LINEAR_RGB")) {
+                cspace = ColorSpace.CS_LINEAR_RGB;
+            } else {
+                isKnownPredefinedCS = false;
+            }
+        }
+
+        if (isKnownPredefinedCS) {
+            resolvedDeserializedProfile = getInstance(cspace);
+        } else {
+            resolvedDeserializedProfile = getInstance(data);
+        }
+    }
+
+    /**
+     * Resolves instances being deserialized into instances registered
+     * with CMM.
+     * @return ICC_Profile object for profile registered with CMM.
+     * @throws ObjectStreamException
+     *     never thrown, but mandated by the serialization spec.
+     * @since 1.3
+     */
+    protected Object readResolve() throws ObjectStreamException {
+        return resolvedDeserializedProfile;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/color/ICC_ProfileGray.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,150 @@
+/*
+ * Portions Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+package java.awt.color;
+
+import java.awt.image.LookupTable;
+import sun.java2d.cmm.ProfileDeferralInfo;
+
+/**
+ *
+ * A subclass of the ICC_Profile class which represents profiles
+ * which meet the following criteria: the color space type of the
+ * profile is TYPE_GRAY and the profile includes the grayTRCTag and
+ * mediaWhitePointTag tags.  Examples of this kind of profile are
+ * monochrome input profiles, monochrome display profiles, and
+ * monochrome output profiles.  The getInstance methods in the
+ * ICC_Profile class will
+ * return an ICC_ProfileGray object when the above conditions are
+ * met.  The advantage of this class is that it provides a lookup
+ * table that Java or native methods may be able to use directly to
+ * optimize color conversion in some cases.
+ * <p>
+ * To transform from a GRAY device profile color space to the CIEXYZ Profile
+ * Connection Space, the device gray component is transformed by
+ * a lookup through the tone reproduction curve (TRC).  The result is
+ * treated as the achromatic component of the PCS.
+<pre>
+
+&nbsp;               PCSY = grayTRC[deviceGray]
+
+</pre>
+ * The inverse transform is done by converting the PCS Y components to
+ * device Gray via the inverse of the grayTRC.
+ * <p>
+ */
+
+
+
+public class ICC_ProfileGray
+extends ICC_Profile {
+
+    static final long serialVersionUID = -1124721290732002649L;
+
+    /**
+     * Constructs a new ICC_ProfileGray from a CMM ID.
+     */
+    ICC_ProfileGray(long ID) {
+        super(ID);
+    }
+
+    /**
+     * Constructs a new ICC_ProfileGray from a ProfileDeferralInfo object.
+     */
+    ICC_ProfileGray(ProfileDeferralInfo pdi) {
+        super(pdi);
+    }
+
+
+    /**
+     * Returns a float array of length 3 containing the X, Y, and Z
+     * components of the mediaWhitePointTag in the ICC profile.
+     * @return an array containing the components of the
+     * mediaWhitePointTag in the ICC profile.
+     */
+    public float[] getMediaWhitePoint() {
+        return super.getMediaWhitePoint();
+    }
+
+
+    /**
+     * Returns a gamma value representing the tone reproduction
+     * curve (TRC).  If the profile represents the TRC as a table rather
+     * than a single gamma value, then an exception is thrown.  In this
+     * case the actual table can be obtained via getTRC().  When
+     * using a gamma value, the PCS Y component is computed as follows:
+<pre>
+
+&nbsp;                         gamma
+&nbsp;        PCSY = deviceGray
+
+</pre>
+     * @return the gamma value as a float.
+     * @exception ProfileDataException if the profile does not specify
+     *            the TRC as a single gamma value.
+     */
+    public float getGamma() {
+    float theGamma;
+
+        theGamma = super.getGamma(ICC_Profile.icSigGrayTRCTag);
+        return theGamma;
+    }
+
+    /**
+     * Returns the TRC as an array of shorts.  If the profile has
+     * specified the TRC as linear (gamma = 1.0) or as a simple gamma
+     * value, this method throws an exception, and the getGamma() method
+     * should be used to get the gamma value.  Otherwise the short array
+     * returned here represents a lookup table where the input Gray value
+     * is conceptually in the range [0.0, 1.0].  Value 0.0 maps
+     * to array index 0 and value 1.0 maps to array index length-1.
+     * Interpolation may be used to generate output values for
+     * input values which do not map exactly to an index in the
+     * array.  Output values also map linearly to the range [0.0, 1.0].
+     * Value 0.0 is represented by an array value of 0x0000 and
+     * value 1.0 by 0xFFFF, i.e. the values are really unsigned
+     * short values, although they are returned in a short array.
+     * @return a short array representing the TRC.
+     * @exception ProfileDataException if the profile does not specify
+     *            the TRC as a table.
+     */
+    public short[] getTRC() {
+    short[]    theTRC;
+
+        theTRC = super.getTRC(ICC_Profile.icSigGrayTRCTag);
+        return theTRC;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/color/ICC_ProfileRGB.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,282 @@
+/*
+ * Portions Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+package java.awt.color;
+
+import java.awt.image.LookupTable;
+import sun.java2d.cmm.ProfileDeferralInfo;
+
+/**
+ *
+ * The ICC_ProfileRGB class is a subclass of the ICC_Profile class
+ * that represents profiles which meet the following criteria:
+ * <ul>
+ * <li>The profile's color space type is RGB.</li>
+ * <li>The profile includes the <code>redColorantTag</code>,
+ * <code>greenColorantTag</code>, <code>blueColorantTag</code>,
+ * <code>redTRCTag</code>, <code>greenTRCTag</code>,
+ * <code>blueTRCTag</code>, and <code>mediaWhitePointTag</code> tags.</li>
+ * </ul>
+ * The <code>ICC_Profile</code> <code>getInstance</code> method will
+ * return an <code>ICC_ProfileRGB</code> object when these conditions are met.
+ * Three-component, matrix-based input profiles and RGB display profiles are
+ * examples of this type of profile.
+ * <p>
+ * This profile class provides color transform matrices and lookup tables
+ * that Java or native methods can use directly to
+ * optimize color conversion in some cases.
+ * <p>
+ * To transform from a device profile color space to the CIEXYZ Profile
+ * Connection Space, each device color component is first linearized by
+ * a lookup through the corresponding tone reproduction curve (TRC).
+ * The resulting linear RGB components are converted to the CIEXYZ PCS
+ * using a a 3x3 matrix constructed from the RGB colorants.
+ * <pre>
+ *
+ * &nbsp;               linearR = redTRC[deviceR]
+ *
+ * &nbsp;               linearG = greenTRC[deviceG]
+ *
+ * &nbsp;               linearB = blueTRC[deviceB]
+ *
+ * &nbsp; _      _       _                                             _   _         _
+ * &nbsp;[  PCSX  ]     [  redColorantX  greenColorantX  blueColorantX  ] [  linearR  ]
+ * &nbsp;[        ]     [                                               ] [           ]
+ * &nbsp;[  PCSY  ]  =  [  redColorantY  greenColorantY  blueColorantY  ] [  linearG  ]
+ * &nbsp;[        ]     [                                               ] [           ]
+ * &nbsp;[_ PCSZ _]     [_ redColorantZ  greenColorantZ  blueColorantZ _] [_ linearB _]
+ *
+ * </pre>
+ * The inverse transform is performed by converting PCS XYZ components to linear
+ * RGB components through the inverse of the above 3x3 matrix, and then converting
+ * linear RGB to device RGB through inverses of the TRCs.
+ * <p>
+ */
+
+
+
+public class ICC_ProfileRGB
+extends ICC_Profile {
+
+    static final long serialVersionUID = 8505067385152579334L;
+
+    /**
+     * Used to get a gamma value or TRC for the red component.
+     */
+    public static final int REDCOMPONENT = 0;
+
+    /**
+     * Used to get a gamma value or TRC for the green component.
+     */
+    public static final int GREENCOMPONENT = 1;
+
+    /**
+     * Used to get a gamma value or TRC for the blue component.
+     */
+    public static final int BLUECOMPONENT = 2;
+
+
+    /**
+     * Constructs an new <code>ICC_ProfileRGB</code> from a CMM ID.
+     *
+     * @param ID The CMM ID for the profile.
+     *
+     */
+    ICC_ProfileRGB(long ID) {
+        super(ID);
+    }
+
+    /**
+     * Constructs a new <code>ICC_ProfileRGB</code> from a
+     * ProfileDeferralInfo object.
+     *
+     * @param pdi
+     */
+    ICC_ProfileRGB(ProfileDeferralInfo pdi) {
+        super(pdi);
+    }
+
+
+    /**
+     * Returns an array that contains the components of the profile's
+     * <CODE>mediaWhitePointTag</CODE>.
+     *
+     * @return A 3-element <CODE>float</CODE> array containing the x, y,
+     * and z components of the profile's <CODE>mediaWhitePointTag</CODE>.
+     */
+    public float[] getMediaWhitePoint() {
+        return super.getMediaWhitePoint();
+    }
+
+
+    /**
+     * Returns a 3x3 <CODE>float</CODE> matrix constructed from the
+     * X, Y, and Z components of the profile's <CODE>redColorantTag</CODE>,
+     * <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>.
+     * <p>
+     * This matrix can be used for color transforms in the forward
+     * direction of the profile--from the profile color space
+     * to the CIEXYZ PCS.
+     *
+     * @return A 3x3 <CODE>float</CODE> array that contains the x, y, and z
+     * components of the profile's <CODE>redColorantTag</CODE>,
+     * <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>.
+     */
+    public float[][] getMatrix() {
+        float[][] theMatrix = new float[3][3];
+        float[] tmpMatrix;
+
+        tmpMatrix = getXYZTag(ICC_Profile.icSigRedColorantTag);
+        theMatrix[0][0] = tmpMatrix[0];
+        theMatrix[1][0] = tmpMatrix[1];
+        theMatrix[2][0] = tmpMatrix[2];
+        tmpMatrix = getXYZTag(ICC_Profile.icSigGreenColorantTag);
+        theMatrix[0][1] = tmpMatrix[0];
+        theMatrix[1][1] = tmpMatrix[1];
+        theMatrix[2][1] = tmpMatrix[2];
+        tmpMatrix = getXYZTag(ICC_Profile.icSigBlueColorantTag);
+        theMatrix[0][2] = tmpMatrix[0];
+        theMatrix[1][2] = tmpMatrix[1];
+        theMatrix[2][2] = tmpMatrix[2];
+        return theMatrix;
+    }
+
+    /**
+     * Returns a gamma value representing the tone reproduction curve
+     * (TRC) for a particular component.  The component parameter
+     * must be one of REDCOMPONENT, GREENCOMPONENT, or BLUECOMPONENT.
+     * <p>
+     * If the profile
+     * represents the TRC for the corresponding component
+     * as a table rather than a single gamma value, an
+     * exception is thrown.  In this case the actual table
+     * can be obtained through the {@link #getTRC(int)} method.
+     * When using a gamma value,
+     * the linear component (R, G, or B) is computed as follows:
+     * <pre>
+     *
+     * &nbsp;                                         gamma
+     * &nbsp;        linearComponent = deviceComponent
+     *
+     *</pre>
+     * @param component The <CODE>ICC_ProfileRGB</CODE> constant that
+     * represents the component whose TRC you want to retrieve
+     * @return the gamma value as a float.
+     * @exception ProfileDataException if the profile does not specify
+     *            the corresponding TRC as a single gamma value.
+     */
+    public float getGamma(int component) {
+    float theGamma;
+    int theSignature;
+
+        switch (component) {
+        case REDCOMPONENT:
+            theSignature = ICC_Profile.icSigRedTRCTag;
+            break;
+
+        case GREENCOMPONENT:
+            theSignature = ICC_Profile.icSigGreenTRCTag;
+            break;
+
+        case BLUECOMPONENT:
+            theSignature = ICC_Profile.icSigBlueTRCTag;
+            break;
+
+        default:
+            throw new IllegalArgumentException("Must be Red, Green, or Blue");
+        }
+
+        theGamma = super.getGamma(theSignature);
+
+        return theGamma;
+    }
+
+    /**
+     * Returns the TRC for a particular component as an array.
+     * Component must be <code>REDCOMPONENT</code>,
+     * <code>GREENCOMPONENT</code>, or <code>BLUECOMPONENT</code>.
+     * Otherwise the returned array
+     * represents a lookup table where the input component value
+     * is conceptually in the range [0.0, 1.0].  Value 0.0 maps
+     * to array index 0 and value 1.0 maps to array index length-1.
+     * Interpolation might be used to generate output values for
+     * input values that do not map exactly to an index in the
+     * array.  Output values also map linearly to the range [0.0, 1.0].
+     * Value 0.0 is represented by an array value of 0x0000 and
+     * value 1.0 by 0xFFFF.  In other words, the values are really unsigned
+     * <code>short</code> values even though they are returned in a
+     * <code>short</code> array.
+     *
+     * If the profile has specified the corresponding TRC
+     * as linear (gamma = 1.0) or as a simple gamma value, this method
+     * throws an exception.  In this case, the {@link #getGamma(int)}
+     * method should be used to get the gamma value.
+     *
+     * @param component The <CODE>ICC_ProfileRGB</CODE> constant that
+     * represents the component whose TRC you want to retrieve:
+     * <CODE>REDCOMPONENT</CODE>, <CODE>GREENCOMPONENT</CODE>, or
+     * <CODE>BLUECOMPONENT</CODE>.
+     *
+     * @return a short array representing the TRC.
+     * @exception ProfileDataException if the profile does not specify
+     *            the corresponding TRC as a table.
+     */
+    public short[] getTRC(int component) {
+    short[] theTRC;
+    int theSignature;
+
+        switch (component) {
+        case REDCOMPONENT:
+            theSignature = ICC_Profile.icSigRedTRCTag;
+            break;
+
+        case GREENCOMPONENT:
+            theSignature = ICC_Profile.icSigGreenTRCTag;
+            break;
+
+        case BLUECOMPONENT:
+            theSignature = ICC_Profile.icSigBlueTRCTag;
+            break;
+
+        default:
+            throw new IllegalArgumentException("Must be Red, Green, or Blue");
+        }
+
+        theTRC = super.getTRC(theSignature);
+
+        return theTRC;
+    }
+
+}
--- a/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,7 +49,6 @@
 
 import sun.awt.datatransfer.DataTransferer;
 
-
 /**
  * The SystemFlavorMap is a configurable map between "natives" (Strings), which
  * correspond to platform-specific data formats, and "flavors" (DataFlavors),
@@ -117,16 +116,51 @@
     /**
      * Maps native Strings to Lists of DataFlavors (or base type Strings for
      * text DataFlavors).
+     * Do not use the field directly, use getNativeToFlavor() instead.
      */
     private Map nativeToFlavor = new HashMap();
 
     /**
+     * Accessor to nativeToFlavor map.  Since we use lazy initialization we must
+     * use this accessor instead of direct access to the field which may not be
+     * initialized yet.  This method will initialize the field if needed.
+     *
+     * @return nativeToFlavor
+     */
+    private Map getNativeToFlavor() {
+        if (!isMapInitialized) {
+            initSystemFlavorMap();
+        }
+        return nativeToFlavor;
+    }
+
+    /**
      * Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
      * native Strings.
+     * Do not use the field directly, use getFlavorToNative() instead.
      */
     private Map flavorToNative = new HashMap();
 
     /**
+     * Accessor to flavorToNative map.  Since we use lazy initialization we must
+     * use this accessor instead of direct access to the field which may not be
+     * initialized yet.  This method will initialize the field if needed.
+     *
+     * @return flavorToNative
+     */
+    private synchronized Map getFlavorToNative() {
+        if (!isMapInitialized) {
+            initSystemFlavorMap();
+        }
+        return flavorToNative;
+    }
+
+    /**
+     * Shows if the object has been initialized.
+     */
+    private boolean isMapInitialized = false;
+
+    /**
      * Caches the result of getNativesForFlavor(). Maps DataFlavors to
      * SoftReferences which reference Lists of String natives.
      */
@@ -169,15 +203,24 @@
         return fm;
     }
 
+    private SystemFlavorMap() {
+    }
+
     /**
-     * Constructs a SystemFlavorMap by reading flavormap.properties and
+     * Initializes a SystemFlavorMap by reading flavormap.properties and
      * AWT.DnD.flavorMapFileURL.
+     * For thread-safety must be called under lock on this.
      */
-    private SystemFlavorMap() {
-        BufferedReader flavormapDotProperties = (BufferedReader)
+    private void initSystemFlavorMap() {
+        if (isMapInitialized) {
+            return;
+        }
+
+        isMapInitialized = true;
+        BufferedReader flavormapDotProperties =
             java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction() {
-                    public Object run() {
+                new java.security.PrivilegedAction<BufferedReader>() {
+                    public BufferedReader run() {
                         String fileName =
                             System.getProperty("java.home") +
                             File.separator +
@@ -197,12 +240,11 @@
                     }
                 });
 
-        BufferedReader flavormapURL = (BufferedReader)
+        BufferedReader flavormapURL =
             java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction() {
-                    public Object run() {
-                        String url = Toolkit.getDefaultToolkit().getProperty
-                            ("AWT.DnD.flavorMapFileURL", null);
+                new java.security.PrivilegedAction<BufferedReader>() {
+                    public BufferedReader run() {
+                        String url = Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null);
 
                         if (url == null) {
                             return null;
@@ -237,7 +279,6 @@
             }
         }
     }
-
     /**
      * Copied code from java.util.Properties. Parsing the data ourselves is the
      * only way to handle duplicate keys and values.
@@ -388,11 +429,11 @@
                     // For text/* flavors, store mappings in separate maps to
                     // enable dynamic mapping generation at a run-time.
                     if ("text".equals(flavor.getPrimaryType())) {
-                        store(value, key, flavorToNative);
-                        store(key, value, nativeToFlavor);
+                        store(value, key, getFlavorToNative());
+                        store(key, value, getNativeToFlavor());
                     } else {
-                        store(flavor, key, flavorToNative);
-                        store(key, flavor, nativeToFlavor);
+                        store(flavor, key, getFlavorToNative());
+                        store(key, flavor, getNativeToFlavor());
                     }
                 }
             }
@@ -494,7 +535,7 @@
      * only if the specified native is encoded as a Java MIME type.
      */
     private List nativeToFlavorLookup(String nat) {
-        List flavors = (List)nativeToFlavor.get(nat);
+        List flavors = (List)getNativeToFlavor().get(nat);
 
         if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
             DataTransferer transferer = DataTransferer.getInstance();
@@ -530,15 +571,15 @@
 
             if (flavor != null) {
                 flavors = new ArrayList(1);
-                nativeToFlavor.put(nat, flavors);
+                getNativeToFlavor().put(nat, flavors);
                 flavors.add(flavor);
                 getFlavorsForNativeCache.remove(nat);
                 getFlavorsForNativeCache.remove(null);
 
-                List natives = (List)flavorToNative.get(flavor);
+                List natives = (List)getFlavorToNative().get(flavor);
                 if (natives == null) {
                     natives = new ArrayList(1);
-                    flavorToNative.put(flavor, natives);
+                    getFlavorToNative().put(flavor, natives);
                 }
                 natives.add(nat);
                 getNativesForFlavorCache.remove(flavor);
@@ -559,7 +600,7 @@
      */
     private List flavorToNativeLookup(final DataFlavor flav,
                                       final boolean synthesize) {
-        List natives = (List)flavorToNative.get(flav);
+        List natives = (List)getFlavorToNative().get(flav);
 
         if (flav != null && !disabledMappingGenerationKeys.contains(flav)) {
             DataTransferer transferer = DataTransferer.getInstance();
@@ -584,15 +625,15 @@
             if (synthesize) {
                 String encoded = encodeDataFlavor(flav);
                 natives = new ArrayList(1);
-                flavorToNative.put(flav, natives);
+                getFlavorToNative().put(flav, natives);
                 natives.add(encoded);
                 getNativesForFlavorCache.remove(flav);
                 getNativesForFlavorCache.remove(null);
 
-                List flavors = (List)nativeToFlavor.get(encoded);
+                List flavors = (List)getNativeToFlavor().get(encoded);
                 if (flavors == null) {
                     flavors = new ArrayList(1);
-                    nativeToFlavor.put(encoded, flavors);
+                    getNativeToFlavor().put(encoded, flavors);
                 }
                 flavors.add(flav);
                 getFlavorsForNativeCache.remove(encoded);
@@ -645,7 +686,7 @@
         }
 
         if (flav == null) {
-            retval = new ArrayList(nativeToFlavor.keySet());
+            retval = new ArrayList(getNativeToFlavor().keySet());
         } else if (disabledMappingGenerationKeys.contains(flav)) {
             // In this case we shouldn't synthesize a native for this flavor,
             // since its mappings were explicitly specified.
@@ -655,7 +696,7 @@
             // For text/* flavors, flavor-to-native mappings specified in
             // flavormap.properties are stored per flavor's base type.
             if ("text".equals(flav.getPrimaryType())) {
-                retval = (List)flavorToNative.get(flav.mimeType.getBaseType());
+                retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
                 if (retval != null) {
                     // To prevent the List stored in the map from modification.
                     retval = new ArrayList(retval);
@@ -663,7 +704,7 @@
             }
 
             // Also include text/plain natives, but don't duplicate Strings
-            List textPlainList = (List)flavorToNative.get(TEXT_PLAIN_BASE_TYPE);
+            List textPlainList = (List)getFlavorToNative().get(TEXT_PLAIN_BASE_TYPE);
 
             if (textPlainList != null && !textPlainList.isEmpty()) {
                 // To prevent the List stored in the map from modification.
@@ -699,7 +740,7 @@
                 }
             }
         } else if (DataTransferer.isFlavorNoncharsetTextType(flav)) {
-            retval = (List)flavorToNative.get(flav.mimeType.getBaseType());
+            retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
 
             if (retval == null || retval.isEmpty()) {
                 retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
@@ -1025,10 +1066,10 @@
             throw new NullPointerException("null arguments not permitted");
         }
 
-        List natives = (List)flavorToNative.get(flav);
+        List natives = (List)getFlavorToNative().get(flav);
         if (natives == null) {
             natives = new ArrayList(1);
-            flavorToNative.put(flav, natives);
+            getFlavorToNative().put(flav, natives);
         } else if (natives.contains(nat)) {
             return;
         }
@@ -1071,7 +1112,7 @@
             throw new NullPointerException("null arguments not permitted");
         }
 
-        flavorToNative.remove(flav);
+        getFlavorToNative().remove(flav);
         for (int i = 0; i < natives.length; i++) {
             addUnencodedNativeForFlavor(flav, natives[i]);
         }
@@ -1105,10 +1146,10 @@
             throw new NullPointerException("null arguments not permitted");
         }
 
-        List flavors = (List)nativeToFlavor.get(nat);
+        List flavors = (List)getNativeToFlavor().get(nat);
         if (flavors == null) {
             flavors = new ArrayList(1);
-            nativeToFlavor.put(nat, flavors);
+            getNativeToFlavor().put(nat, flavors);
         } else if (flavors.contains(flav)) {
             return;
         }
@@ -1150,7 +1191,7 @@
             throw new NullPointerException("null arguments not permitted");
         }
 
-        nativeToFlavor.remove(nat);
+        getNativeToFlavor().remove(nat);
         for (int i = 0; i < flavors.length; i++) {
             addFlavorForUnencodedNative(nat, flavors[i]);
         }
--- a/src/share/classes/java/awt/dnd/DropTarget.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/awt/dnd/DropTarget.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -110,7 +110,11 @@
             setActive(act);
         }
 
-        if (fm != null) flavorMap = fm;
+        if (fm != null) {
+            flavorMap = fm;
+        } else {
+            flavorMap = SystemFlavorMap.getDefaultFlavorMap();
+        }
     }
 
     /**
@@ -850,5 +854,5 @@
      * The FlavorMap
      */
 
-    private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap();
+    private transient FlavorMap flavorMap;
 }
--- a/src/share/classes/java/awt/event/MouseWheelEvent.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/awt/event/MouseWheelEvent.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -74,6 +74,19 @@
  * methods for conforming to the underlying platform settings.  These
  * platform settings can be changed at any time by the user.  MouseWheelEvents
  * reflect the most recent settings.
+ * <P>
+ * The <code>MouseWheelEvent</code> class includes methods for
+ * getting the number of "clicks" by which the mouse wheel is rotated.
+ * The {@link #getWheelRotation} method returns the integer number
+ * of "clicks" corresponding to the number of notches by which the wheel was
+ * rotated. In addition to this method, the <code>MouseWheelEvent</code>
+ * class provides the {@link #getPreciseWheelRotation} method which returns
+ * a double number of "clicks" in case a partial rotation occurred.
+ * The {@link #getPreciseWheelRotation} method is useful if a mouse supports
+ * a high-resolution wheel, such as a freely rotating wheel with no
+ * notches. Applications can benefit by using this method to process
+ * mouse wheel events more precisely, and thus, making visual perception
+ * smoother.
  *
  * @author Brent Christian
  * @see MouseWheelListener
@@ -131,6 +144,13 @@
      */
     int wheelRotation;
 
+    /**
+     * Indicates how far the mouse wheel was rotated.
+     *
+     * @see #getPreciseWheelRotation
+     */
+    double preciseWheelRotation;
+
     /*
      * serialVersionUID
      */
@@ -165,8 +185,8 @@
      *                       <code>WHEEL_BLOCK_SCROLL</code>
      * @param  scrollAmount  for scrollType <code>WHEEL_UNIT_SCROLL</code>,
      *                       the number of units to be scrolled
-     * @param wheelRotation  the amount that the mouse wheel was rotated (the
-     *                       number of "clicks")
+     * @param wheelRotation  the integer number of "clicks" by which the mouse
+     *                       wheel was rotated
      *
      * @throws IllegalArgumentException if <code>source</code> is null
      * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
@@ -211,8 +231,8 @@
      *                       <code>WHEEL_BLOCK_SCROLL</code>
      * @param  scrollAmount  for scrollType <code>WHEEL_UNIT_SCROLL</code>,
      *                       the number of units to be scrolled
-     * @param wheelRotation  the amount that the mouse wheel was rotated (the
-     *                       number of "clicks")
+     * @param wheelRotation  the integer number of "clicks" by which the mouse
+     *                       wheel was rotated
      *
      * @throws IllegalArgumentException if <code>source</code> is null
      * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
@@ -223,12 +243,68 @@
                             int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
                             int scrollType, int scrollAmount, int wheelRotation) {
 
+        this(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount, popupTrigger,
+             scrollType, scrollAmount, wheelRotation, wheelRotation);
+
+    }
+
+
+    /**
+     * Constructs a <code>MouseWheelEvent</code> object with the specified
+     * source component, type, modifiers, coordinates, absolute coordinates,
+     * scroll type, scroll amount, and wheel rotation.
+     * <p>Note that passing in an invalid <code>id</code> parameter results
+     * in unspecified behavior. This method throws an
+     * <code>IllegalArgumentException</code> if <code>source</code> equals
+     * <code>null</code>.
+     * <p>Even if inconsistent values for relative and absolute coordinates
+     * are passed to the constructor, a <code>MouseWheelEvent</code> instance
+     * is still created and no exception is thrown.
+     *
+     * @param source         the <code>Component</code> that originated the event
+     * @param id             the integer value that identifies the event
+     * @param when           a long value that gives the time when the event occurred
+     * @param modifiers      the modifier keys down during event
+     *                       (shift, ctrl, alt, meta)
+     * @param x              the horizontal <code>x</code> coordinate for the
+     *                       mouse location
+     * @param y              the vertical <code>y</code> coordinate for the
+     *                       mouse location
+     * @param xAbs           the absolute horizontal <code>x</code> coordinate for
+     *                       the mouse location
+     * @param yAbs           the absolute vertical <code>y</code> coordinate for
+     *                       the mouse location
+     * @param clickCount     the number of mouse clicks associated with the event
+     * @param popupTrigger   a boolean value, <code>true</code> if this event is a trigger
+     *                       for a popup-menu
+     * @param scrollType     the type of scrolling which should take place in
+     *                       response to this event;  valid values are
+     *                       <code>WHEEL_UNIT_SCROLL</code> and
+     *                       <code>WHEEL_BLOCK_SCROLL</code>
+     * @param  scrollAmount  for scrollType <code>WHEEL_UNIT_SCROLL</code>,
+     *                       the number of units to be scrolled
+     * @param wheelRotation  the integer number of "clicks" by which the mouse wheel
+     *                       was rotated
+     * @param preciseWheelRotation the double number of "clicks" by which the mouse wheel
+     *                       was rotated
+     *
+     * @throws IllegalArgumentException if <code>source</code> is null
+     * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
+     * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, int, int, boolean, int)
+     * @since 1.7
+     */
+    public MouseWheelEvent (Component source, int id, long when, int modifiers,
+                            int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
+                            int scrollType, int scrollAmount, int wheelRotation, double preciseWheelRotation) {
+
         super(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount,
               popupTrigger, MouseEvent.NOBUTTON);
 
         this.scrollType = scrollType;
         this.scrollAmount = scrollAmount;
         this.wheelRotation = wheelRotation;
+        this.preciseWheelRotation = preciseWheelRotation;
+
     }
 
     /**
@@ -267,17 +343,35 @@
     }
 
     /**
-     * Returns the number of "clicks" the mouse wheel was rotated.
+     * Returns the number of "clicks" the mouse wheel was rotated, as an integer.
+     * A partial rotation may occur if the mouse supports a high-resolution wheel.
+     * In this case, the method returns zero until a full "click" has been accumulated.
      *
      * @return negative values if the mouse wheel was rotated up/away from
      * the user, and positive values if the mouse wheel was rotated down/
      * towards the user
+     * @see #getPreciseWheelRotation
      */
     public int getWheelRotation() {
         return wheelRotation;
     }
 
     /**
+     * Returns the number of "clicks" the mouse wheel was rotated, as a double.
+     * A partial rotation may occur if the mouse supports a high-resolution wheel.
+     * In this case, the return value will include a fractional "click".
+     *
+     * @return negative values if the mouse wheel was rotated up or away from
+     * the user, and positive values if the mouse wheel was rotated down or
+     * towards the user
+     * @see #getWheelRotation
+     * @since 1.7
+     */
+    public double getPreciseWheelRotation() {
+        return preciseWheelRotation;
+    }
+
+    /**
      * This is a convenience method to aid in the implementation of
      * the common-case MouseWheelListener - to scroll a ScrollPane or
      * JScrollPane by an amount which conforms to the platform settings.
@@ -348,6 +442,6 @@
         }
         return super.paramString()+",scrollType="+scrollTypeStr+
          ",scrollAmount="+getScrollAmount()+",wheelRotation="+
-         getWheelRotation();
+         getWheelRotation()+",preciseWheelRotation="+getPreciseWheelRotation();
     }
 }
--- a/src/share/classes/java/awt/font/OpenType.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/awt/font/OpenType.java	Mon Apr 14 11:34:15 2008 -0700
@@ -31,9 +31,9 @@
  * <i>sfnt</i> tables from the font.  A particular
  * <code>Font</code> object can implement this interface.
  * <p>
- * For more information on TrueType fonts, see the
- * Apple TrueType Reference Manual
- * ( <a href="http://fonts.apple.com/TTRefMan/index.html">http://fonts.apple.com/TTRefMan/index.html</a> ).
+ * For more information on TrueType and OpenType fonts, see the
+ * OpenType specification.
+ * ( <a href=http://www.microsoft.com/typography/otspec/">http://www.microsoft.com/typography/otspec/l</a> ).
  */
 public interface OpenType {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/BandedSampleModel.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,839 @@
+/*
+ * Portions Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+
+/**
+ *  This class represents image data which is stored in a band interleaved
+ *  fashion and for
+ *  which each sample of a pixel occupies one data element of the DataBuffer.
+ *  It subclasses ComponentSampleModel but provides a more efficent
+ *  implementation for accessing band interleaved image data than is provided
+ *  by ComponentSampleModel.  This class should typically be used when working
+ *  with images which store sample data for each band in a different bank of the
+ *  DataBuffer. Accessor methods are provided so that image data can be
+ *  manipulated directly. Pixel stride is the number of
+ *  data array elements between two samples for the same band on the same
+ *  scanline. The pixel stride for a BandedSampleModel is one.
+ *  Scanline stride is the number of data array elements between
+ *  a given sample and the corresponding sample in the same column of the next
+ *  scanline.  Band offsets denote the number
+ *  of data array elements from the first data array element of the bank
+ *  of the DataBuffer holding each band to the first sample of the band.
+ *  The bands are numbered from 0 to N-1.
+ *  Bank indices denote the correspondence between a bank of the data buffer
+ *  and a band of image data.  This class supports
+ *  {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
+ *  {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
+ *  {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
+ *  {@link DataBuffer#TYPE_INT TYPE_INT},
+ *  {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT}, and
+ *  {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE} datatypes
+ */
+
+
+public final class BandedSampleModel extends ComponentSampleModel
+{
+
+    /**
+     * Constructs a BandedSampleModel with the specified parameters.
+     * The pixel stride will be one data element.  The scanline stride
+     * will be the same as the width.  Each band will be stored in
+     * a separate bank and all band offsets will be zero.
+     * @param dataType  The data type for storing samples.
+     * @param w         The width (in pixels) of the region of
+     *                  image data described.
+     * @param h         The height (in pixels) of the region of image
+     *                  data described.
+     * @param numBands  The number of bands for the image data.
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types
+     */
+    public BandedSampleModel(int dataType, int w, int h, int numBands) {
+        super(dataType, w, h, 1, w,
+              BandedSampleModel.createIndicesArray(numBands),
+              BandedSampleModel.createOffsetArray(numBands));
+    }
+
+    /**
+     * Constructs a BandedSampleModel with the specified parameters.
+     * The number of bands will be inferred from the lengths of the
+     * bandOffsets bankIndices arrays, which must be equal.  The pixel
+     * stride will be one data element.
+     * @param dataType  The data type for storing samples.
+     * @param w         The width (in pixels) of the region of
+     *                  image data described.
+     * @param h         The height (in pixels) of the region of
+     *                  image data described.
+     * @param scanlineStride The line stride of the of the image data.
+     * @param bankIndices The bank index for each band.
+     * @param bandOffsets The band offset for each band.
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types
+     */
+    public BandedSampleModel(int dataType,
+                             int w, int h,
+                             int scanlineStride,
+                             int bankIndices[],
+                             int bandOffsets[]) {
+
+        super(dataType, w, h, 1,scanlineStride, bankIndices, bandOffsets);
+    }
+
+    /**
+     * Creates a new BandedSampleModel with the specified
+     * width and height.  The new BandedSampleModel will have the same
+     * number of bands, storage data type, and bank indices
+     * as this BandedSampleModel.  The band offsets will be compressed
+     * such that the offset between bands will be w*pixelStride and
+     * the minimum of all of the band offsets is zero.
+     * @param w the width of the resulting <code>BandedSampleModel</code>
+     * @param h the height of the resulting <code>BandedSampleModel</code>
+     * @return a new <code>BandedSampleModel</code> with the specified
+     *         width and height.
+     * @throws IllegalArgumentException if <code>w</code> or
+     *         <code>h</code> equals either
+     *         <code>Integer.MAX_VALUE</code> or
+     *         <code>Integer.MIN_VALUE</code>
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types
+     */
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        int[] bandOffs;
+
+        if (numBanks == 1) {
+            bandOffs = orderBands(bandOffsets, w*h);
+        }
+        else {
+            bandOffs = new int[bandOffsets.length];
+        }
+
+        SampleModel sampleModel =
+            new BandedSampleModel(dataType, w, h, w, bankIndices, bandOffs);
+        return sampleModel;
+    }
+
+    /**
+     * Creates a new BandedSampleModel with a subset of the bands of this
+     * BandedSampleModel.  The new BandedSampleModel can be
+     * used with any DataBuffer that the existing BandedSampleModel
+     * can be used with.  The new BandedSampleModel/DataBuffer
+     * combination will represent an image with a subset of the bands
+     * of the original BandedSampleModel/DataBuffer combination.
+     * @throws RasterFormatException if the number of bands is greater than
+     *                               the number of banks in this sample model.
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types
+     */
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands.length > bankIndices.length)
+            throw new RasterFormatException("There are only " +
+                                            bankIndices.length +
+                                            " bands");
+        int newBankIndices[] = new int[bands.length];
+        int newBandOffsets[] = new int[bands.length];
+
+        for (int i=0; i<bands.length; i++) {
+            newBankIndices[i] = bankIndices[bands[i]];
+            newBandOffsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new BandedSampleModel(this.dataType, width, height,
+                                     this.scanlineStride,
+                                     newBankIndices, newBandOffsets);
+    }
+
+    /**
+     * Creates a DataBuffer that corresponds to this BandedSampleModel,
+     * The DataBuffer's data type, number of banks, and size
+     * will be consistent with this BandedSampleModel.
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported types.
+     */
+    public DataBuffer createDataBuffer() {
+        DataBuffer dataBuffer = null;
+
+        int size = scanlineStride * height;
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            dataBuffer = new DataBufferByte(size, numBanks);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            dataBuffer = new DataBufferUShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_SHORT:
+            dataBuffer = new DataBufferShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_INT:
+            dataBuffer = new DataBufferInt(size, numBanks);
+            break;
+        case DataBuffer.TYPE_FLOAT:
+            dataBuffer = new DataBufferFloat(size, numBanks);
+            break;
+        case DataBuffer.TYPE_DOUBLE:
+            dataBuffer = new DataBufferDouble(size, numBanks);
+            break;
+        default:
+            throw new IllegalArgumentException("dataType is not one " +
+                "of the supported types.");
+        }
+
+        return dataBuffer;
+    }
+
+
+    /**
+     * Returns data for a single pixel in a primitive array of type
+     * TransferType.  For a BandedSampleModel, this will be the same
+     * as the data type, and samples will be returned one per array
+     * element.  Generally, obj
+     * should be passed in as null, so that the Object will be created
+     * automatically and will be of the right primitive data type.
+     * <p>
+     * The following code illustrates transferring data for one pixel from
+     * DataBuffer <code>db1</code>, whose storage layout is described by
+     * BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
+     * whose storage layout is described by
+     * BandedSampleModel <code>bsm2</code>.
+     * The transfer will generally be more efficient than using
+     * getPixel/setPixel.
+     * <pre>
+     *       BandedSampleModel bsm1, bsm2;
+     *       DataBufferInt db1, db2;
+     *       bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
+     *                            db2);
+     * </pre>
+     * Using getDataElements/setDataElements to transfer between two
+     * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
+     * the same number of bands, corresponding bands have the same number of
+     * bits per sample, and the TransferTypes are the same.
+     * <p>
+     * If obj is non-null, it should be a primitive array of type TransferType.
+     * Otherwise, a ClassCastException is thrown.  An
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds, or if obj is non-null and is not large enough to hold
+     * the pixel data.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param obj       If non-null, a primitive array in which to return
+     *                  the pixel data.
+     * @param data      The DataBuffer containing the image data.
+     * @return the data for the specified pixel.
+     * @see #setDataElements(int, int, Object, DataBuffer)
+     */
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int type = getTransferType();
+        int numDataElems = getNumDataElements();
+        int pixelOffset = y*scanlineStride + x;
+
+        switch(type) {
+
+        case DataBuffer.TYPE_BYTE:
+
+            byte[] bdata;
+
+            if (obj == null) {
+                bdata = new byte[numDataElems];
+            } else {
+                bdata = (byte[])obj;
+            }
+
+            for (int i=0; i<numDataElems; i++) {
+                bdata[i] = (byte)data.getElem(bankIndices[i],
+                                              pixelOffset + bandOffsets[i]);
+            }
+
+            obj = (Object)bdata;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_SHORT:
+
+            short[] sdata;
+
+            if (obj == null) {
+                sdata = new short[numDataElems];
+            } else {
+                sdata = (short[])obj;
+            }
+
+            for (int i=0; i<numDataElems; i++) {
+                sdata[i] = (short)data.getElem(bankIndices[i],
+                                               pixelOffset + bandOffsets[i]);
+            }
+
+            obj = (Object)sdata;
+            break;
+
+        case DataBuffer.TYPE_INT:
+
+            int[] idata;
+
+            if (obj == null) {
+                idata = new int[numDataElems];
+            } else {
+                idata = (int[])obj;
+            }
+
+            for (int i=0; i<numDataElems; i++) {
+                idata[i] = data.getElem(bankIndices[i],
+                                        pixelOffset + bandOffsets[i]);
+            }
+
+            obj = (Object)idata;
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+
+            float[] fdata;
+
+            if (obj == null) {
+                fdata = new float[numDataElems];
+            } else {
+                fdata = (float[])obj;
+            }
+
+            for (int i=0; i<numDataElems; i++) {
+                fdata[i] = data.getElemFloat(bankIndices[i],
+                                             pixelOffset + bandOffsets[i]);
+            }
+
+            obj = (Object)fdata;
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+
+            double[] ddata;
+
+            if (obj == null) {
+                ddata = new double[numDataElems];
+            } else {
+                ddata = (double[])obj;
+            }
+
+            for (int i=0; i<numDataElems; i++) {
+                ddata[i] = data.getElemDouble(bankIndices[i],
+                                              pixelOffset + bandOffsets[i]);
+            }
+
+            obj = (Object)ddata;
+            break;
+        }
+
+        return obj;
+    }
+
+    /**
+     * Returns all samples for the specified pixel in an int array.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param iArray    If non-null, returns the samples in this array
+     * @param data      The DataBuffer containing the image data
+     * @return the samples for the specified pixel.
+     * @see #setPixel(int, int, int[], DataBuffer)
+     */
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        int[] pixels;
+
+        if (iArray != null) {
+           pixels = iArray;
+        } else {
+           pixels = new int [numBands];
+        }
+
+        int pixelOffset = y*scanlineStride + x;
+        for (int i=0; i<numBands; i++) {
+            pixels[i] = data.getElem(bankIndices[i],
+                                     pixelOffset + bandOffsets[i]);
+        }
+        return pixels;
+    }
+
+    /**
+     * Returns all samples for the specified rectangle of pixels in
+     * an int array, one sample per data array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location
+     * @param y         The Y coordinate of the upper left pixel location
+     * @param w         The width of the pixel rectangle
+     * @param h         The height of the pixel rectangle
+     * @param iArray    If non-null, returns the samples in this array
+     * @param data      The DataBuffer containing the image data
+     * @return the samples for the pixels within the specified region.
+     * @see #setPixels(int, int, int, int, int[], DataBuffer)
+     */
+    public int[] getPixels(int x, int y, int w, int h,
+                           int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int[] pixels;
+
+        if (iArray != null) {
+           pixels = iArray;
+        } else {
+           pixels = new int[w*h*numBands];
+        }
+
+        for (int k = 0; k < numBands; k++) {
+            int lineOffset = y*scanlineStride + x + bandOffsets[k];
+            int srcOffset = k;
+            int bank = bankIndices[k];
+
+            for (int i = 0; i < h; i++) {
+                int pixelOffset = lineOffset;
+                for (int j = 0; j < w; j++) {
+                    pixels[srcOffset] = data.getElem(bank, pixelOffset++);
+                    srcOffset += numBands;
+                }
+                lineOffset += scanlineStride;
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Returns as int the sample in a specified band for the pixel
+     * located at (x,y).
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param b         The band to return
+     * @param data      The DataBuffer containing the image data
+     * @return the sample in the specified band for the specified pixel.
+     * @see #setSample(int, int, int, int, DataBuffer)
+     */
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int sample =
+            data.getElem(bankIndices[b],
+                         y*scanlineStride + x + bandOffsets[b]);
+        return sample;
+    }
+
+    /**
+     * Returns the sample in a specified band
+     * for the pixel located at (x,y) as a float.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param b         The band to return
+     * @param data      The DataBuffer containing the image data
+     * @return a float value that represents the sample in the specified
+     * band for the specified pixel.
+     */
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        float sample = data.getElemFloat(bankIndices[b],
+                                    y*scanlineStride + x + bandOffsets[b]);
+        return sample;
+    }
+
+    /**
+     * Returns the sample in a specified band
+     * for a pixel located at (x,y) as a double.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param b         The band to return
+     * @param data      The DataBuffer containing the image data
+     * @return a double value that represents the sample in the specified
+     * band for the specified pixel.
+     */
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        double sample = data.getElemDouble(bankIndices[b],
+                                       y*scanlineStride + x + bandOffsets[b]);
+        return sample;
+    }
+
+    /**
+     * Returns the samples in a specified band for the specified rectangle
+     * of pixels in an int array, one sample per data array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location
+     * @param y         The Y coordinate of the upper left pixel location
+     * @param w         The width of the pixel rectangle
+     * @param h         The height of the pixel rectangle
+     * @param b         The band to return
+     * @param iArray    If non-null, returns the samples in this array
+     * @param data      The DataBuffer containing the image data
+     * @return the samples in the specified band for the pixels within
+     * the specified region.
+     * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b,
+                            int iArray[], DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int samples[];
+        if (iArray != null) {
+           samples = iArray;
+        } else {
+           samples = new int [w*h];
+        }
+
+        int lineOffset = y*scanlineStride + x + bandOffsets[b];
+        int srcOffset = 0;
+        int bank = bankIndices[b];
+
+        for (int i = 0; i < h; i++) {
+           int sampleOffset = lineOffset;
+           for (int j = 0; j < w; j++) {
+               samples[srcOffset++] = data.getElem(bank, sampleOffset++);
+           }
+           lineOffset += scanlineStride;
+        }
+        return samples;
+    }
+
+    /**
+     * Sets the data for a single pixel in the specified DataBuffer from a
+     * primitive array of type TransferType.  For a BandedSampleModel,
+     * this will be the same as the data type, and samples are transferred
+     * one per array element.
+     * <p>
+     * The following code illustrates transferring data for one pixel from
+     * DataBuffer <code>db1</code>, whose storage layout is described by
+     * BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
+     * whose storage layout is described by
+     * BandedSampleModel <code>bsm2</code>.
+     * The transfer will generally be more efficient than using
+     * getPixel/setPixel.
+     * <pre>
+     *       BandedSampleModel bsm1, bsm2;
+     *       DataBufferInt db1, db2;
+     *       bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
+     *                            db2);
+     * </pre>
+     * Using getDataElements/setDataElements to transfer between two
+     * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
+     * the same number of bands, corresponding bands have the same number of
+     * bits per sample, and the TransferTypes are the same.
+     * <p>
+     * obj must be a primitive array of type TransferType.  Otherwise,
+     * a ClassCastException is thrown.  An
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds, or if obj is not large enough to hold the pixel data.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param obj       If non-null, returns the primitive array in this
+     *                  object
+     * @param data      The DataBuffer containing the image data
+     * @see #getDataElements(int, int, Object, DataBuffer)
+     */
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int type = getTransferType();
+        int numDataElems = getNumDataElements();
+        int pixelOffset = y*scanlineStride + x;
+
+        switch(type) {
+
+        case DataBuffer.TYPE_BYTE:
+
+            byte[] barray = (byte[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
+                             barray[i] & 0xff);
+            }
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_SHORT:
+
+            short[] sarray = (short[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
+                             sarray[i] & 0xffff);
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+
+            int[] iarray = (int[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
+                             iarray[i]);
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+
+            float[] farray = (float[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                data.setElemFloat(bankIndices[i], pixelOffset + bandOffsets[i],
+                                  farray[i]);
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+
+            double[] darray = (double[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                data.setElemDouble(bankIndices[i], pixelOffset + bandOffsets[i],
+                                   darray[i]);
+            }
+            break;
+
+        }
+    }
+
+    /**
+     * Sets a pixel in the DataBuffer using an int array of samples for input.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param iArray    The input samples in an int array
+     * @param data      The DataBuffer containing the image data
+     * @see #getPixel(int, int, int[], DataBuffer)
+     */
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+       int pixelOffset = y*scanlineStride + x;
+       for (int i=0; i<numBands; i++) {
+           data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
+                        iArray[i]);
+       }
+    }
+
+    /**
+     * Sets all samples for a rectangle of pixels from an int array containing
+     * one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location
+     * @param y         The Y coordinate of the upper left pixel location
+     * @param w         The width of the pixel rectangle
+     * @param h         The height of the pixel rectangle
+     * @param iArray    The input samples in an int array
+     * @param data      The DataBuffer containing the image data
+     * @see #getPixels(int, int, int, int, int[], DataBuffer)
+     */
+    public void setPixels(int x, int y, int w, int h,
+                          int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        for (int k = 0; k < numBands; k++) {
+            int lineOffset = y*scanlineStride + x + bandOffsets[k];
+            int srcOffset = k;
+            int bank = bankIndices[k];
+
+            for (int i = 0; i < h; i++) {
+                int pixelOffset = lineOffset;
+                for (int j = 0; j < w; j++) {
+                    data.setElem(bank, pixelOffset++, iArray[srcOffset]);
+                    srcOffset += numBands;
+                }
+                lineOffset += scanlineStride;
+           }
+        }
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the DataBuffer using an int for input.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param b         The band to set
+     * @param s         The input sample as an int
+     * @param data      The DataBuffer containing the image data
+     * @see #getSample(int, int, int, DataBuffer)
+     */
+    public void setSample(int x, int y, int b, int s,
+                          DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        data.setElem(bankIndices[b],
+                     y*scanlineStride + x + bandOffsets[b], s);
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the DataBuffer using a float for input.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param b         The band to set
+     * @param s         The input sample as a float
+     * @param data      The DataBuffer containing the image data
+     * @see #getSample(int, int, int, DataBuffer)
+     */
+    public void setSample(int x, int y, int b,
+                          float s ,
+                          DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        data.setElemFloat(bankIndices[b],
+                          y*scanlineStride + x + bandOffsets[b], s);
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the DataBuffer using a double for input.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param b         The band to set
+     * @param s         The input sample as a double
+     * @param data      The DataBuffer containing the image data
+     * @see #getSample(int, int, int, DataBuffer)
+     */
+    public void setSample(int x, int y, int b,
+                          double s,
+                          DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        data.setElemDouble(bankIndices[b],
+                          y*scanlineStride + x + bandOffsets[b], s);
+    }
+
+    /**
+     * Sets the samples in the specified band for the specified rectangle
+     * of pixels from an int array containing one sample per data array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location
+     * @param y         The Y coordinate of the upper left pixel location
+     * @param w         The width of the pixel rectangle
+     * @param h         The height of the pixel rectangle
+     * @param b         The band to set
+     * @param iArray    The input sample array
+     * @param data      The DataBuffer containing the image data
+     * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
+     */
+    public void setSamples(int x, int y, int w, int h, int b,
+                           int iArray[], DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int lineOffset = y*scanlineStride + x + bandOffsets[b];
+        int srcOffset = 0;
+        int bank = bankIndices[b];
+
+        for (int i = 0; i < h; i++) {
+           int sampleOffset = lineOffset;
+           for (int j = 0; j < w; j++) {
+              data.setElem(bank, sampleOffset++, iArray[srcOffset++]);
+           }
+           lineOffset += scanlineStride;
+        }
+    }
+
+    private static int[] createOffsetArray(int numBands) {
+        int[] bandOffsets = new int[numBands];
+        for (int i=0; i < numBands; i++) {
+            bandOffsets[i] = 0;
+        }
+        return bandOffsets;
+    }
+
+    private static int[] createIndicesArray(int numBands) {
+        int[] bankIndices = new int[numBands];
+        for (int i=0; i < numBands; i++) {
+            bankIndices[i] = i;
+        }
+        return bankIndices;
+    }
+
+    // Differentiate hash code from other ComponentSampleModel subclasses
+    public int hashCode() {
+        return super.hashCode() ^ 0x2;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/ColorConvertOp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,1109 @@
+/*
+ * Portions Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+package java.awt.image;
+
+import java.awt.Point;
+import java.awt.Graphics2D;
+import java.awt.color.*;
+import sun.java2d.cmm.ColorTransform;
+import sun.java2d.cmm.CMSManager;
+import sun.java2d.cmm.ProfileDeferralMgr;
+import sun.java2d.cmm.PCMM;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Point2D;
+import java.awt.RenderingHints;
+
+/**
+ * This class performs a pixel-by-pixel color conversion of the data in
+ * the source image.  The resulting color values are scaled to the precision
+ * of the destination image.  Color conversion can be specified
+ * via an array of ColorSpace objects or an array of ICC_Profile objects.
+ * <p>
+ * If the source is a BufferedImage with premultiplied alpha, the
+ * color components are divided by the alpha component before color conversion.
+ * If the destination is a BufferedImage with premultiplied alpha, the
+ * color components are multiplied by the alpha component after conversion.
+ * Rasters are treated as having no alpha channel, i.e. all bands are
+ * color bands.
+ * <p>
+ * If a RenderingHints object is specified in the constructor, the
+ * color rendering hint and the dithering hint may be used to control
+ * color conversion.
+ * <p>
+ * Note that Source and Destination may be the same object.
+ * <p>
+ * @see java.awt.RenderingHints#KEY_COLOR_RENDERING
+ * @see java.awt.RenderingHints#KEY_DITHERING
+ */
+public class ColorConvertOp implements BufferedImageOp, RasterOp {
+    ICC_Profile[]    profileList;
+    ColorSpace[]     CSList;
+    ColorTransform    thisTransform, thisRasterTransform;
+    ICC_Profile      thisSrcProfile, thisDestProfile;
+    RenderingHints   hints;
+    boolean          gotProfiles;
+    float[]          srcMinVals, srcMaxVals, dstMinVals, dstMaxVals;
+
+    /* the class initializer */
+    static {
+        if (ProfileDeferralMgr.deferring) {
+            ProfileDeferralMgr.activateProfiles();
+        }
+    }
+
+    /**
+     * Constructs a new ColorConvertOp which will convert
+     * from a source color space to a destination color space.
+     * The RenderingHints argument may be null.
+     * This Op can be used only with BufferedImages, and will convert
+     * directly from the ColorSpace of the source image to that of the
+     * destination.  The destination argument of the filter method
+     * cannot be specified as null.
+     * @param hints the <code>RenderingHints</code> object used to control
+     *        the color conversion, or <code>null</code>
+     */
+    public ColorConvertOp (RenderingHints hints)
+    {
+        profileList = new ICC_Profile [0];    /* 0 length list */
+        this.hints  = hints;
+    }
+
+    /**
+     * Constructs a new ColorConvertOp from a ColorSpace object.
+     * The RenderingHints argument may be null.  This
+     * Op can be used only with BufferedImages, and is primarily useful
+     * when the {@link #filter(BufferedImage, BufferedImage) filter}
+     * method is invoked with a destination argument of null.
+     * In that case, the ColorSpace defines the destination color space
+     * for the destination created by the filter method.  Otherwise, the
+     * ColorSpace defines an intermediate space to which the source is
+     * converted before being converted to the destination space.
+     * @param cspace defines the destination <code>ColorSpace</code> or an
+     *        intermediate <code>ColorSpace</code>
+     * @param hints the <code>RenderingHints</code> object used to control
+     *        the color conversion, or <code>null</code>
+     * @throws NullPointerException if cspace is null
+     */
+    public ColorConvertOp (ColorSpace cspace, RenderingHints hints)
+    {
+        if (cspace == null) {
+            throw new NullPointerException("ColorSpace cannot be null");
+        }
+        if (cspace instanceof ICC_ColorSpace) {
+            profileList = new ICC_Profile [1];    /* 1 profile in the list */
+
+            profileList [0] = ((ICC_ColorSpace) cspace).getProfile();
+        }
+        else {
+            CSList = new ColorSpace[1]; /* non-ICC case: 1 ColorSpace in list */
+            CSList[0] = cspace;
+        }
+        this.hints  = hints;
+    }
+
+
+    /**
+     * Constructs a new ColorConvertOp from two ColorSpace objects.
+     * The RenderingHints argument may be null.
+     * This Op is primarily useful for calling the filter method on
+     * Rasters, in which case the two ColorSpaces define the operation
+     * to be performed on the Rasters.  In that case, the number of bands
+     * in the source Raster must match the number of components in
+     * srcCspace, and the number of bands in the destination Raster
+     * must match the number of components in dstCspace.  For BufferedImages,
+     * the two ColorSpaces define intermediate spaces through which the
+     * source is converted before being converted to the destination space.
+     * @param srcCspace the source <code>ColorSpace</code>
+     * @param dstCspace the destination <code>ColorSpace</code>
+     * @param hints the <code>RenderingHints</code> object used to control
+     *        the color conversion, or <code>null</code>
+     * @throws NullPointerException if either srcCspace or dstCspace is null
+     */
+    public ColorConvertOp(ColorSpace srcCspace, ColorSpace dstCspace,
+                           RenderingHints hints)
+    {
+        if ((srcCspace == null) || (dstCspace == null)) {
+            throw new NullPointerException("ColorSpaces cannot be null");
+        }
+        if ((srcCspace instanceof ICC_ColorSpace) &&
+            (dstCspace instanceof ICC_ColorSpace)) {
+            profileList = new ICC_Profile [2];    /* 2 profiles in the list */
+
+            profileList [0] = ((ICC_ColorSpace) srcCspace).getProfile();
+            profileList [1] = ((ICC_ColorSpace) dstCspace).getProfile();
+
+            getMinMaxValsFromColorSpaces(srcCspace, dstCspace);
+        } else {
+            /* non-ICC case: 2 ColorSpaces in list */
+            CSList = new ColorSpace[2];
+            CSList[0] = srcCspace;
+            CSList[1] = dstCspace;
+        }
+        this.hints  = hints;
+    }
+
+
+     /**
+     * Constructs a new ColorConvertOp from an array of ICC_Profiles.
+     * The RenderingHints argument may be null.
+     * The sequence of profiles may include profiles that represent color
+     * spaces, profiles that represent effects, etc.  If the whole sequence
+     * does not represent a well-defined color conversion, an exception is
+     * thrown.
+     * <p>For BufferedImages, if the ColorSpace
+     * of the source BufferedImage does not match the requirements of the
+     * first profile in the array,
+     * the first conversion is to an appropriate ColorSpace.
+     * If the requirements of the last profile in the array are not met
+     * by the ColorSpace of the destination BufferedImage,
+     * the last conversion is to the destination's ColorSpace.
+     * <p>For Rasters, the number of bands in the source Raster must match
+     * the requirements of the first profile in the array, and the
+     * number of bands in the destination Raster must match the requirements
+     * of the last profile in the array.  The array must have at least two
+     * elements or calling the filter method for Rasters will throw an
+     * IllegalArgumentException.
+     * @param profiles the array of <code>ICC_Profile</code> objects
+     * @param hints the <code>RenderingHints</code> object used to control
+     *        the color conversion, or <code>null</code>
+     * @exception IllegalArgumentException when the profile sequence does not
+     *             specify a well-defined color conversion
+     * @exception NullPointerException if profiles is null
+     */
+    public ColorConvertOp (ICC_Profile[] profiles, RenderingHints hints)
+    {
+        if (profiles == null) {
+            throw new NullPointerException("Profiles cannot be null");
+        }
+        gotProfiles = true;
+        profileList = new ICC_Profile[profiles.length];
+        for (int i1 = 0; i1 < profiles.length; i1++) {
+            profileList[i1] = profiles[i1];
+        }
+        this.hints  = hints;
+    }
+
+
+    /**
+     * Returns the array of ICC_Profiles used to construct this ColorConvertOp.
+     * Returns null if the ColorConvertOp was not constructed from such an
+     * array.
+     * @return the array of <code>ICC_Profile</code> objects of this
+     *         <code>ColorConvertOp</code>, or <code>null</code> if this
+     *         <code>ColorConvertOp</code> was not constructed with an
+     *         array of <code>ICC_Profile</code> objects.
+     */
+    public final ICC_Profile[] getICC_Profiles() {
+        if (gotProfiles) {
+            ICC_Profile[] profiles = new ICC_Profile[profileList.length];
+            for (int i1 = 0; i1 < profileList.length; i1++) {
+                profiles[i1] = profileList[i1];
+            }
+            return profiles;
+        }
+        return null;
+    }
+
+    /**
+     * ColorConverts the source BufferedImage.
+     * If the destination image is null,
+     * a BufferedImage will be created with an appropriate ColorModel.
+     * @param src the source <code>BufferedImage</code> to be converted
+     * @param dest the destination <code>BufferedImage</code>,
+     *        or <code>null</code>
+     * @return <code>dest</code> color converted from <code>src</code>
+     *         or a new, converted <code>BufferedImage</code>
+     *         if <code>dest</code> is <code>null</code>
+     * @exception IllegalArgumentException if dest is null and this op was
+     *             constructed using the constructor which takes only a
+     *             RenderingHints argument, since the operation is ill defined.
+     */
+    public final BufferedImage filter(BufferedImage src, BufferedImage dest) {
+        ColorSpace srcColorSpace, destColorSpace;
+        BufferedImage savdest = null;
+
+        if (src.getColorModel() instanceof IndexColorModel) {
+            IndexColorModel icm = (IndexColorModel) src.getColorModel();
+            src = icm.convertToIntDiscrete(src.getRaster(), true);
+        }
+        srcColorSpace = src.getColorModel().getColorSpace();
+        if (dest != null) {
+            if (dest.getColorModel() instanceof IndexColorModel) {
+                savdest = dest;
+                dest = null;
+                destColorSpace = null;
+            } else {
+                destColorSpace = dest.getColorModel().getColorSpace();
+            }
+        } else {
+            destColorSpace = null;
+        }
+
+        if ((CSList != null) ||
+            (!(srcColorSpace instanceof ICC_ColorSpace)) ||
+            ((dest != null) &&
+             (!(destColorSpace instanceof ICC_ColorSpace)))) {
+            /* non-ICC case */
+            dest = nonICCBIFilter(src, srcColorSpace, dest, destColorSpace);
+        } else {
+            dest = ICCBIFilter(src, srcColorSpace, dest, destColorSpace);
+        }
+
+        if (savdest != null) {
+            Graphics2D big = savdest.createGraphics();
+            try {
+                big.drawImage(dest, 0, 0, null);
+            } finally {
+                big.dispose();
+            }
+            return savdest;
+        } else {
+            return dest;
+        }
+    }
+
+    private final BufferedImage ICCBIFilter(BufferedImage src,
+                                            ColorSpace srcColorSpace,
+                                            BufferedImage dest,
+                                            ColorSpace destColorSpace) {
+    int              nProfiles = profileList.length;
+    ICC_Profile      srcProfile = null, destProfile = null;
+
+        srcProfile = ((ICC_ColorSpace) srcColorSpace).getProfile();
+
+        if (dest == null) {        /* last profile in the list defines
+                                      the output color space */
+            if (nProfiles == 0) {
+                throw new IllegalArgumentException(
+                    "Destination ColorSpace is undefined");
+            }
+            destProfile = profileList [nProfiles - 1];
+            dest = createCompatibleDestImage(src, null);
+        }
+        else {
+            if (src.getHeight() != dest.getHeight() ||
+                src.getWidth() != dest.getWidth()) {
+                throw new IllegalArgumentException(
+                    "Width or height of BufferedImages do not match");
+            }
+            destProfile = ((ICC_ColorSpace) destColorSpace).getProfile();
+        }
+
+        /* Checking if all profiles in the transform sequence are the same.
+         * If so, performing just copying the data.
+         */
+        if (srcProfile == destProfile) {
+            boolean noTrans = true;
+            for (int i = 0; i < nProfiles; i++) {
+                if (srcProfile != profileList[i]) {
+                    noTrans = false;
+                    break;
+                }
+            }
+            if (noTrans) {
+                Graphics2D g = dest.createGraphics();
+                try {
+                    g.drawImage(src, 0, 0, null);
+                } finally {
+                    g.dispose();
+                }
+
+                return dest;
+            }
+        }
+
+        /* make a new transform if needed */
+        if ((thisTransform == null) || (thisSrcProfile != srcProfile) ||
+            (thisDestProfile != destProfile) ) {
+            updateBITransform(srcProfile, destProfile);
+        }
+
+        /* color convert the image */
+        thisTransform.colorConvert(src, dest);
+
+        return dest;
+    }
+
+    private void updateBITransform(ICC_Profile srcProfile,
+                                   ICC_Profile destProfile) {
+        ICC_Profile[]    theProfiles;
+        int              i1, nProfiles, nTransforms, whichTrans, renderState;
+        ColorTransform[]  theTransforms;
+        boolean          useSrc = false, useDest = false;
+
+        nProfiles = profileList.length;
+        nTransforms = nProfiles;
+        if ((nProfiles == 0) || (srcProfile != profileList[0])) {
+            nTransforms += 1;
+            useSrc = true;
+        }
+        if ((nProfiles == 0) || (destProfile != profileList[nProfiles - 1]) ||
+            (nTransforms < 2)) {
+            nTransforms += 1;
+            useDest = true;
+        }
+
+        /* make the profile list */
+        theProfiles = new ICC_Profile[nTransforms]; /* the list of profiles
+                                                       for this Op */
+
+        int idx = 0;
+        if (useSrc) {
+            /* insert source as first profile */
+            theProfiles[idx++] = srcProfile;
+        }
+
+        for (i1 = 0; i1 < nProfiles; i1++) {
+                                   /* insert profiles defined in this Op */
+            theProfiles[idx++] = profileList [i1];
+        }
+
+        if (useDest) {
+            /* insert dest as last profile */
+            theProfiles[idx] = destProfile;
+        }
+
+        /* make the transform list */
+        theTransforms = new ColorTransform [nTransforms];
+
+        /* initialize transform get loop */
+        if (theProfiles[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) {
+                                        /* if first profile is a printer
+                                           render as colorimetric */
+            renderState = ICC_Profile.icRelativeColorimetric;
+        }
+        else {
+            renderState = ICC_Profile.icPerceptual; /* render any other
+                                                       class perceptually */
+        }
+
+        whichTrans = ColorTransform.In;
+
+        PCMM mdl = CMSManager.getModule();
+
+        /* get the transforms from each profile */
+        for (i1 = 0; i1 < nTransforms; i1++) {
+            if (i1 == nTransforms -1) {         /* last profile? */
+                whichTrans = ColorTransform.Out; /* get output transform */
+            }
+            else {      /* check for abstract profile */
+                if ((whichTrans == ColorTransform.Simulation) &&
+                    (theProfiles[i1].getProfileClass () ==
+                     ICC_Profile.CLASS_ABSTRACT)) {
+                renderState = ICC_Profile.icPerceptual;
+                    whichTrans = ColorTransform.In;
+                }
+            }
+
+            theTransforms[i1] = mdl.createTransform (
+                theProfiles[i1], renderState, whichTrans);
+
+            /* get this profile's rendering intent to select transform
+               from next profile */
+            renderState = getRenderingIntent(theProfiles[i1]);
+
+            /* "middle" profiles use simulation transform */
+            whichTrans = ColorTransform.Simulation;
+        }
+
+        /* make the net transform */
+        thisTransform = mdl.createTransform(theTransforms);
+
+        /* update corresponding source and dest profiles */
+        thisSrcProfile = srcProfile;
+        thisDestProfile = destProfile;
+    }
+
+    /**
+     * ColorConverts the image data in the source Raster.
+     * If the destination Raster is null, a new Raster will be created.
+     * The number of bands in the source and destination Rasters must
+     * meet the requirements explained above.  The constructor used to
+     * create this ColorConvertOp must have provided enough information
+     * to define both source and destination color spaces.  See above.
+     * Otherwise, an exception is thrown.
+     * @param src the source <code>Raster</code> to be converted
+     * @param dest the destination <code>WritableRaster</code>,
+     *        or <code>null</code>
+     * @return <code>dest</code> color converted from <code>src</code>
+     *         or a new, converted <code>WritableRaster</code>
+     *         if <code>dest</code> is <code>null</code>
+     * @exception IllegalArgumentException if the number of source or
+     *             destination bands is incorrect, the source or destination
+     *             color spaces are undefined, or this op was constructed
+     *             with one of the constructors that applies only to
+     *             operations on BufferedImages.
+     */
+    public final WritableRaster filter (Raster src, WritableRaster dest)  {
+
+        if (CSList != null) {
+            /* non-ICC case */
+            return nonICCRasterFilter(src, dest);
+        }
+        int nProfiles = profileList.length;
+        if (nProfiles < 2) {
+            throw new IllegalArgumentException(
+                "Source or Destination ColorSpace is undefined");
+        }
+        if (src.getNumBands() != profileList[0].getNumComponents()) {
+            throw new IllegalArgumentException(
+                "Numbers of source Raster bands and source color space " +
+                "components do not match");
+        }
+        if (dest == null) {
+            dest = createCompatibleDestRaster(src);
+        }
+        else {
+            if (src.getHeight() != dest.getHeight() ||
+                src.getWidth() != dest.getWidth()) {
+                throw new IllegalArgumentException(
+                    "Width or height of Rasters do not match");
+            }
+            if (dest.getNumBands() !=
+                profileList[nProfiles-1].getNumComponents()) {
+                throw new IllegalArgumentException(
+                    "Numbers of destination Raster bands and destination " +
+                    "color space components do not match");
+            }
+        }
+
+        /* make a new transform if needed */
+        if (thisRasterTransform == null) {
+            int              i1, whichTrans, renderState;
+            ColorTransform[]  theTransforms;
+
+            /* make the transform list */
+            theTransforms = new ColorTransform [nProfiles];
+
+            /* initialize transform get loop */
+            if (profileList[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) {
+                                            /* if first profile is a printer
+                                               render as colorimetric */
+                renderState = ICC_Profile.icRelativeColorimetric;
+            }
+            else {
+                renderState = ICC_Profile.icPerceptual; /* render any other
+                                                           class perceptually */
+            }
+
+            whichTrans = ColorTransform.In;
+
+            PCMM mdl = CMSManager.getModule();
+
+            /* get the transforms from each profile */
+            for (i1 = 0; i1 < nProfiles; i1++) {
+                if (i1 == nProfiles -1) {         /* last profile? */
+                    whichTrans = ColorTransform.Out; /* get output transform */
+                }
+                else {  /* check for abstract profile */
+                    if ((whichTrans == ColorTransform.Simulation) &&
+                        (profileList[i1].getProfileClass () ==
+                         ICC_Profile.CLASS_ABSTRACT)) {
+                        renderState = ICC_Profile.icPerceptual;
+                        whichTrans = ColorTransform.In;
+                    }
+                }
+
+                theTransforms[i1] = mdl.createTransform (
+                    profileList[i1], renderState, whichTrans);
+
+                /* get this profile's rendering intent to select transform
+                   from next profile */
+                renderState = getRenderingIntent(profileList[i1]);
+
+                /* "middle" profiles use simulation transform */
+                whichTrans = ColorTransform.Simulation;
+            }
+
+            /* make the net transform */
+            thisRasterTransform = mdl.createTransform(theTransforms);
+        }
+
+        int srcTransferType = src.getTransferType();
+        int dstTransferType = dest.getTransferType();
+        if ((srcTransferType == DataBuffer.TYPE_FLOAT) ||
+            (srcTransferType == DataBuffer.TYPE_DOUBLE) ||
+            (dstTransferType == DataBuffer.TYPE_FLOAT) ||
+            (dstTransferType == DataBuffer.TYPE_DOUBLE)) {
+            if (srcMinVals == null) {
+                getMinMaxValsFromProfiles(profileList[0],
+                                          profileList[nProfiles-1]);
+            }
+            /* color convert the raster */
+            thisRasterTransform.colorConvert(src, dest,
+                                             srcMinVals, srcMaxVals,
+                                             dstMinVals, dstMaxVals);
+        } else {
+            /* color convert the raster */
+            thisRasterTransform.colorConvert(src, dest);
+        }
+
+
+        return dest;
+    }
+
+    /**
+     * Returns the bounding box of the destination, given this source.
+     * Note that this will be the same as the the bounding box of the
+     * source.
+     * @param src the source <code>BufferedImage</code>
+     * @return a <code>Rectangle2D</code> that is the bounding box
+     *         of the destination, given the specified <code>src</code>
+     */
+    public final Rectangle2D getBounds2D (BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    /**
+     * Returns the bounding box of the destination, given this source.
+     * Note that this will be the same as the the bounding box of the
+     * source.
+     * @param src the source <code>Raster</code>
+     * @return a <code>Rectangle2D</code> that is the bounding box
+     *         of the destination, given the specified <code>src</code>
+     */
+    public final Rectangle2D getBounds2D (Raster src) {
+        /*        return new Rectangle (src.getXOffset(),
+                              src.getYOffset(),
+                              src.getWidth(), src.getHeight()); */
+        return src.getBounds();
+    }
+
+    /**
+     * Creates a zeroed destination image with the correct size and number of
+     * bands, given this source.
+     * @param src       Source image for the filter operation.
+     * @param destCM    ColorModel of the destination.  If null, an
+     *                  appropriate ColorModel will be used.
+     * @return a <code>BufferedImage</code> with the correct size and
+     * number of bands from the specified <code>src</code>.
+     * @throws IllegalArgumentException if <code>destCM</code> is
+     *         <code>null</code> and this <code>ColorConvertOp</code> was
+     *         created without any <code>ICC_Profile</code> or
+     *         <code>ColorSpace</code> defined for the destination
+     */
+    public BufferedImage createCompatibleDestImage (BufferedImage src,
+                                                    ColorModel destCM) {
+        ColorSpace cs = null;;
+        if (destCM == null) {
+            if (CSList == null) {
+                /* ICC case */
+                int nProfiles = profileList.length;
+                if (nProfiles == 0) {
+                    throw new IllegalArgumentException(
+                        "Destination ColorSpace is undefined");
+                }
+                ICC_Profile destProfile = profileList[nProfiles - 1];
+                cs = new ICC_ColorSpace(destProfile);
+            } else {
+                /* non-ICC case */
+                int nSpaces = CSList.length;
+                cs = CSList[nSpaces - 1];
+            }
+        }
+        return createCompatibleDestImage(src, destCM, cs);
+    }
+
+    private BufferedImage createCompatibleDestImage(BufferedImage src,
+                                                    ColorModel destCM,
+                                                    ColorSpace destCS) {
+        BufferedImage image;
+        if (destCM == null) {
+            ColorModel srcCM = src.getColorModel();
+            int nbands = destCS.getNumComponents();
+            boolean hasAlpha = srcCM.hasAlpha();
+            if (hasAlpha) {
+               nbands += 1;
+            }
+            int[] nbits = new int[nbands];
+            for (int i = 0; i < nbands; i++) {
+                nbits[i] = 8;
+            }
+            destCM = new ComponentColorModel(destCS, nbits, hasAlpha,
+                                             srcCM.isAlphaPremultiplied(),
+                                             srcCM.getTransparency(),
+                                             DataBuffer.TYPE_BYTE);
+        }
+        int w = src.getWidth();
+        int h = src.getHeight();
+        image = new BufferedImage(destCM,
+                                  destCM.createCompatibleWritableRaster(w, h),
+                                  destCM.isAlphaPremultiplied(), null);
+        return image;
+    }
+
+
+    /**
+     * Creates a zeroed destination Raster with the correct size and number of
+     * bands, given this source.
+     * @param src the specified <code>Raster</code>
+     * @return a <code>WritableRaster</code> with the correct size and number
+     *         of bands from the specified <code>src</code>
+     * @throws IllegalArgumentException if this <code>ColorConvertOp</code>
+     *         was created without sufficient information to define the
+     *         <code>dst</code> and <code>src</code> color spaces
+     */
+    public WritableRaster createCompatibleDestRaster (Raster src) {
+        int ncomponents;
+
+        if (CSList != null) {
+            /* non-ICC case */
+            if (CSList.length != 2) {
+                throw new IllegalArgumentException(
+                    "Destination ColorSpace is undefined");
+            }
+            ncomponents = CSList[1].getNumComponents();
+        } else {
+            /* ICC case */
+            int nProfiles = profileList.length;
+            if (nProfiles < 2) {
+                throw new IllegalArgumentException(
+                    "Destination ColorSpace is undefined");
+            }
+            ncomponents = profileList[nProfiles-1].getNumComponents();
+        }
+
+        WritableRaster dest =
+            Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                                  src.getWidth(),
+                                  src.getHeight(),
+                                  ncomponents,
+                                  new Point(src.getMinX(), src.getMinY()));
+        return dest;
+    }
+
+    /**
+     * Returns the location of the destination point given a
+     * point in the source.  If <code>dstPt</code> is non-null,
+     * it will be used to hold the return value.  Note that
+     * for this class, the destination point will be the same
+     * as the source point.
+     * @param srcPt the specified source <code>Point2D</code>
+     * @param dstPt the destination <code>Point2D</code>
+     * @return <code>dstPt</code> after setting its location to be
+     *         the same as <code>srcPt</code>
+     */
+    public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+        dstPt.setLocation(srcPt.getX(), srcPt.getY());
+
+        return dstPt;
+    }
+
+
+    /**
+     * Returns the RenderingIntent from the specified ICC Profile.
+     */
+    private int getRenderingIntent (ICC_Profile profile) {
+        byte[] header = profile.getData(ICC_Profile.icSigHead);
+        int index = ICC_Profile.icHdrRenderingIntent;
+        return (((header[index]   & 0xff) << 24) |
+                ((header[index+1] & 0xff) << 16) |
+                ((header[index+2] & 0xff) <<  8) |
+                 (header[index+3] & 0xff));
+    }
+
+    /**
+     * Returns the rendering hints used by this op.
+     * @return the <code>RenderingHints</code> object of this
+     *         <code>ColorConvertOp</code>
+     */
+    public final RenderingHints getRenderingHints() {
+        return hints;
+    }
+
+    private final BufferedImage nonICCBIFilter(BufferedImage src,
+                                               ColorSpace srcColorSpace,
+                                               BufferedImage dst,
+                                               ColorSpace dstColorSpace) {
+
+        int w = src.getWidth();
+        int h = src.getHeight();
+        ICC_ColorSpace ciespace =
+            (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
+        if (dst == null) {
+            dst = createCompatibleDestImage(src, null);
+            dstColorSpace = dst.getColorModel().getColorSpace();
+        } else {
+            if ((h != dst.getHeight()) || (w != dst.getWidth())) {
+                throw new IllegalArgumentException(
+                    "Width or height of BufferedImages do not match");
+            }
+        }
+        Raster srcRas = src.getRaster();
+        WritableRaster dstRas = dst.getRaster();
+        ColorModel srcCM = src.getColorModel();
+        ColorModel dstCM = dst.getColorModel();
+        int srcNumComp = srcCM.getNumColorComponents();
+        int dstNumComp = dstCM.getNumColorComponents();
+        boolean dstHasAlpha = dstCM.hasAlpha();
+        boolean needSrcAlpha = srcCM.hasAlpha() && dstHasAlpha;
+        ColorSpace[] list;
+        if ((CSList == null) && (profileList.length != 0)) {
+            /* possible non-ICC src, some profiles, possible non-ICC dst */
+            boolean nonICCSrc, nonICCDst;
+            ICC_Profile srcProfile, dstProfile;
+            if (!(srcColorSpace instanceof ICC_ColorSpace)) {
+                nonICCSrc = true;
+                srcProfile = ciespace.getProfile();
+            } else {
+                nonICCSrc = false;
+                srcProfile = ((ICC_ColorSpace) srcColorSpace).getProfile();
+            }
+            if (!(dstColorSpace instanceof ICC_ColorSpace)) {
+                nonICCDst = true;
+                dstProfile = ciespace.getProfile();
+            } else {
+                nonICCDst = false;
+                dstProfile = ((ICC_ColorSpace) dstColorSpace).getProfile();
+            }
+            /* make a new transform if needed */
+            if ((thisTransform == null) || (thisSrcProfile != srcProfile) ||
+                (thisDestProfile != dstProfile) ) {
+                updateBITransform(srcProfile, dstProfile);
+            }
+            // process per scanline
+            float maxNum = 65535.0f; // use 16-bit precision in CMM
+            ColorSpace cs;
+            int iccSrcNumComp;
+            if (nonICCSrc) {
+                cs = ciespace;
+                iccSrcNumComp = 3;
+            } else {
+                cs = srcColorSpace;
+                iccSrcNumComp = srcNumComp;
+            }
+            float[] srcMinVal = new float[iccSrcNumComp];
+            float[] srcInvDiffMinMax = new float[iccSrcNumComp];
+            for (int i = 0; i < srcNumComp; i++) {
+                srcMinVal[i] = cs.getMinValue(i);
+                srcInvDiffMinMax[i] = maxNum / (cs.getMaxValue(i) - srcMinVal[i]);
+            }
+            int iccDstNumComp;
+            if (nonICCDst) {
+                cs = ciespace;
+                iccDstNumComp = 3;
+            } else {
+                cs = dstColorSpace;
+                iccDstNumComp = dstNumComp;
+            }
+            float[] dstMinVal = new float[iccDstNumComp];
+            float[] dstDiffMinMax = new float[iccDstNumComp];
+            for (int i = 0; i < dstNumComp; i++) {
+                dstMinVal[i] = cs.getMinValue(i);
+                dstDiffMinMax[i] = (cs.getMaxValue(i) - dstMinVal[i]) / maxNum;
+            }
+            float[] dstColor;
+            if (dstHasAlpha) {
+                int size = ((dstNumComp + 1) > 3) ? (dstNumComp + 1) : 3;
+                dstColor = new float[size];
+            } else {
+                int size = (dstNumComp  > 3) ? dstNumComp : 3;
+                dstColor = new float[size];
+            }
+            short[] srcLine = new short[w * iccSrcNumComp];
+            short[] dstLine = new short[w * iccDstNumComp];
+            Object pixel;
+            float[] color;
+            float[] alpha = null;
+            if (needSrcAlpha) {
+                alpha = new float[w];
+            }
+            int idx;
+            // process each scanline
+            for (int y = 0; y < h; y++) {
+                // convert src scanline
+                pixel = null;
+                color = null;
+                idx = 0;
+                for (int x = 0; x < w; x++) {
+                    pixel = srcRas.getDataElements(x, y, pixel);
+                    color = srcCM.getNormalizedComponents(pixel, color, 0);
+                    if (needSrcAlpha) {
+                        alpha[x] = color[srcNumComp];
+                    }
+                    if (nonICCSrc) {
+                        color = srcColorSpace.toCIEXYZ(color);
+                    }
+                    for (int i = 0; i < iccSrcNumComp; i++) {
+                        srcLine[idx++] = (short)
+                            ((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] +
+                             0.5f);
+                    }
+                }
+                // color convert srcLine to dstLine
+                thisTransform.colorConvert(srcLine, dstLine);
+                // convert dst scanline
+                pixel = null;
+                idx = 0;
+                for (int x = 0; x < w; x++) {
+                    for (int i = 0; i < iccDstNumComp; i++) {
+                        dstColor[i] = ((float) (dstLine[idx++] & 0xffff)) *
+                                      dstDiffMinMax[i] + dstMinVal[i];
+                    }
+                    if (nonICCDst) {
+                        color = srcColorSpace.fromCIEXYZ(dstColor);
+                        for (int i = 0; i < dstNumComp; i++) {
+                            dstColor[i] = color[i];
+                        }
+                    }
+                    if (needSrcAlpha) {
+                        dstColor[dstNumComp] = alpha[x];
+                    } else if (dstHasAlpha) {
+                        dstColor[dstNumComp] = 1.0f;
+                    }
+                    pixel = dstCM.getDataElements(dstColor, 0, pixel);
+                    dstRas.setDataElements(x, y, pixel);
+                }
+            }
+        } else {
+            /* possible non-ICC src, possible CSList, possible non-ICC dst */
+            // process per pixel
+            int numCS;
+            if (CSList == null) {
+                numCS = 0;
+            } else {
+                numCS = CSList.length;
+            }
+            float[] dstColor;
+            if (dstHasAlpha) {
+                dstColor = new float[dstNumComp + 1];
+            } else {
+                dstColor = new float[dstNumComp];
+            }
+            Object spixel = null;
+            Object dpixel = null;
+            float[] color = null;
+            float[] tmpColor;
+            // process each pixel
+            for (int y = 0; y < h; y++) {
+                for (int x = 0; x < w; x++) {
+                    spixel = srcRas.getDataElements(x, y, spixel);
+                    color = srcCM.getNormalizedComponents(spixel, color, 0);
+                    tmpColor = srcColorSpace.toCIEXYZ(color);
+                    for (int i = 0; i < numCS; i++) {
+                        tmpColor = CSList[i].fromCIEXYZ(tmpColor);
+                        tmpColor = CSList[i].toCIEXYZ(tmpColor);
+                    }
+                    tmpColor = dstColorSpace.fromCIEXYZ(tmpColor);
+                    for (int i = 0; i < dstNumComp; i++) {
+                        dstColor[i] = tmpColor[i];
+                    }
+                    if (needSrcAlpha) {
+                        dstColor[dstNumComp] = color[srcNumComp];
+                    } else if (dstHasAlpha) {
+                        dstColor[dstNumComp] = 1.0f;
+                    }
+                    dpixel = dstCM.getDataElements(dstColor, 0, dpixel);
+                    dstRas.setDataElements(x, y, dpixel);
+
+                }
+            }
+        }
+
+        return dst;
+    }
+
+    /* color convert a Raster - handles byte, ushort, int, short, float,
+       or double transferTypes */
+    private final WritableRaster nonICCRasterFilter(Raster src,
+                                                    WritableRaster dst)  {
+
+        if (CSList.length != 2) {
+            throw new IllegalArgumentException(
+                "Destination ColorSpace is undefined");
+        }
+        if (src.getNumBands() != CSList[0].getNumComponents()) {
+            throw new IllegalArgumentException(
+                "Numbers of source Raster bands and source color space " +
+                "components do not match");
+        }
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else {
+            if (src.getHeight() != dst.getHeight() ||
+                src.getWidth() != dst.getWidth()) {
+                throw new IllegalArgumentException(
+                    "Width or height of Rasters do not match");
+            }
+            if (dst.getNumBands() != CSList[1].getNumComponents()) {
+                throw new IllegalArgumentException(
+                    "Numbers of destination Raster bands and destination " +
+                    "color space components do not match");
+            }
+        }
+
+        if (srcMinVals == null) {
+            getMinMaxValsFromColorSpaces(CSList[0], CSList[1]);
+        }
+
+        SampleModel srcSM = src.getSampleModel();
+        SampleModel dstSM = dst.getSampleModel();
+        boolean srcIsFloat, dstIsFloat;
+        int srcTransferType = src.getTransferType();
+        int dstTransferType = dst.getTransferType();
+        if ((srcTransferType == DataBuffer.TYPE_FLOAT) ||
+            (srcTransferType == DataBuffer.TYPE_DOUBLE)) {
+            srcIsFloat = true;
+        } else {
+            srcIsFloat = false;
+        }
+        if ((dstTransferType == DataBuffer.TYPE_FLOAT) ||
+            (dstTransferType == DataBuffer.TYPE_DOUBLE)) {
+            dstIsFloat = true;
+        } else {
+            dstIsFloat = false;
+        }
+        int w = src.getWidth();
+        int h = src.getHeight();
+        int srcNumBands = src.getNumBands();
+        int dstNumBands = dst.getNumBands();
+        float[] srcScaleFactor = null;
+        float[] dstScaleFactor = null;
+        if (!srcIsFloat) {
+            srcScaleFactor = new float[srcNumBands];
+            for (int i = 0; i < srcNumBands; i++) {
+                if (srcTransferType == DataBuffer.TYPE_SHORT) {
+                    srcScaleFactor[i] = (srcMaxVals[i] - srcMinVals[i]) /
+                                        32767.0f;
+                } else {
+                    srcScaleFactor[i] = (srcMaxVals[i] - srcMinVals[i]) /
+                        ((float) ((1 << srcSM.getSampleSize(i)) - 1));
+                }
+            }
+        }
+        if (!dstIsFloat) {
+            dstScaleFactor = new float[dstNumBands];
+            for (int i = 0; i < dstNumBands; i++) {
+                if (dstTransferType == DataBuffer.TYPE_SHORT) {
+                    dstScaleFactor[i] = 32767.0f /
+                                        (dstMaxVals[i] - dstMinVals[i]);
+                } else {
+                    dstScaleFactor[i] =
+                        ((float) ((1 << dstSM.getSampleSize(i)) - 1)) /
+                        (dstMaxVals[i] - dstMinVals[i]);
+                }
+            }
+        }
+        int ys = src.getMinY();
+        int yd = dst.getMinY();
+        int xs, xd;
+        float sample;
+        float[] color = new float[srcNumBands];
+        float[] tmpColor;
+        ColorSpace srcColorSpace = CSList[0];
+        ColorSpace dstColorSpace = CSList[1];
+        // process each pixel
+        for (int y = 0; y < h; y++, ys++, yd++) {
+            // get src scanline
+            xs = src.getMinX();
+            xd = dst.getMinX();
+            for (int x = 0; x < w; x++, xs++, xd++) {
+                for (int i = 0; i < srcNumBands; i++) {
+                    sample = src.getSampleFloat(xs, ys, i);
+                    if (!srcIsFloat) {
+                        sample = sample * srcScaleFactor[i] + srcMinVals[i];
+                    }
+                    color[i] = sample;
+                }
+                tmpColor = srcColorSpace.toCIEXYZ(color);
+                tmpColor = dstColorSpace.fromCIEXYZ(tmpColor);
+                for (int i = 0; i < dstNumBands; i++) {
+                    sample = tmpColor[i];
+                    if (!dstIsFloat) {
+                        sample = (sample - dstMinVals[i]) * dstScaleFactor[i];
+                    }
+                    dst.setSample(xd, yd, i, sample);
+                }
+            }
+        }
+        return dst;
+    }
+
+    private void getMinMaxValsFromProfiles(ICC_Profile srcProfile,
+                                           ICC_Profile dstProfile) {
+        int type = srcProfile.getColorSpaceType();
+        int nc = srcProfile.getNumComponents();
+        srcMinVals = new float[nc];
+        srcMaxVals = new float[nc];
+        setMinMax(type, nc, srcMinVals, srcMaxVals);
+        type = dstProfile.getColorSpaceType();
+        nc = dstProfile.getNumComponents();
+        dstMinVals = new float[nc];
+        dstMaxVals = new float[nc];
+        setMinMax(type, nc, dstMinVals, dstMaxVals);
+    }
+
+    private void setMinMax(int type, int nc, float[] minVals, float[] maxVals) {
+        if (type == ColorSpace.TYPE_Lab) {
+            minVals[0] = 0.0f;    // L
+            maxVals[0] = 100.0f;
+            minVals[1] = -128.0f; // a
+            maxVals[1] = 127.0f;
+            minVals[2] = -128.0f; // b
+            maxVals[2] = 127.0f;
+        } else if (type == ColorSpace.TYPE_XYZ) {
+            minVals[0] = minVals[1] = minVals[2] = 0.0f; // X, Y, Z
+            maxVals[0] = maxVals[1] = maxVals[2] = 1.0f + (32767.0f/ 32768.0f);
+        } else {
+            for (int i = 0; i < nc; i++) {
+                minVals[i] = 0.0f;
+                maxVals[i] = 1.0f;
+            }
+        }
+    }
+
+    private void getMinMaxValsFromColorSpaces(ColorSpace srcCspace,
+                                              ColorSpace dstCspace) {
+        int nc = srcCspace.getNumComponents();
+        srcMinVals = new float[nc];
+        srcMaxVals = new float[nc];
+        for (int i = 0; i < nc; i++) {
+            srcMinVals[i] = srcCspace.getMinValue(i);
+            srcMaxVals[i] = srcCspace.getMaxValue(i);
+        }
+        nc = dstCspace.getNumComponents();
+        dstMinVals = new float[nc];
+        dstMaxVals = new float[nc];
+        for (int i = 0; i < nc; i++) {
+            dstMinVals[i] = dstCspace.getMinValue(i);
+            dstMaxVals[i] = dstCspace.getMaxValue(i);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/ComponentSampleModel.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,1202 @@
+/*
+ * Portions Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+
+import java.util.Arrays;
+
+/**
+ *  This class represents image data which is stored such that each sample
+ *  of a pixel occupies one data element of the DataBuffer.  It stores the
+ *  N samples which make up a pixel in N separate data array elements.
+ *  Different bands may be in different banks of the DataBuffer.
+ *  Accessor methods are provided so that image data can be manipulated
+ *  directly. This class can support different kinds of interleaving, e.g.
+ *  band interleaving, scanline interleaving, and pixel interleaving.
+ *  Pixel stride is the number of data array elements between two samples
+ *  for the same band on the same scanline. Scanline stride is the number
+ *  of data array elements between a given sample and the corresponding sample
+ *  in the same column of the next scanline.  Band offsets denote the number
+ *  of data array elements from the first data array element of the bank
+ *  of the DataBuffer holding each band to the first sample of the band.
+ *  The bands are numbered from 0 to N-1.  This class can represent image
+ *  data for which each sample is an unsigned integral number which can be
+ *  stored in 8, 16, or 32 bits (using <code>DataBuffer.TYPE_BYTE</code>,
+ *  <code>DataBuffer.TYPE_USHORT</code>, or <code>DataBuffer.TYPE_INT</code>,
+ *  respectively), data for which each sample is a signed integral number
+ *  which can be stored in 16 bits (using <code>DataBuffer.TYPE_SHORT</code>),
+ *  or data for which each sample is a signed float or double quantity
+ *  (using <code>DataBuffer.TYPE_FLOAT</code> or
+ *  <code>DataBuffer.TYPE_DOUBLE</code>, respectively).
+ *  All samples of a given ComponentSampleModel
+ *  are stored with the same precision.  All strides and offsets must be
+ *  non-negative.  This class supports
+ *  {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
+ *  {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
+ *  {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
+ *  {@link DataBuffer#TYPE_INT TYPE_INT},
+ *  {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT},
+ *  {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE},
+ *  @see java.awt.image.PixelInterleavedSampleModel
+ *  @see java.awt.image.BandedSampleModel
+ */
+
+public class ComponentSampleModel extends SampleModel
+{
+    /** Offsets for all bands in data array elements. */
+    protected int bandOffsets[];
+
+    /** Index for each bank storing a band of image data. */
+    protected int[] bankIndices;
+
+    /**
+     * The number of bands in this
+     * <code>ComponentSampleModel</code>.
+     */
+    protected int numBands = 1;
+
+    /**
+     * The number of banks in this
+     * <code>ComponentSampleModel</code>.
+     */
+    protected int numBanks = 1;
+
+    /**
+     *  Line stride (in data array elements) of the region of image
+     *  data described by this ComponentSampleModel.
+     */
+    protected int scanlineStride;
+
+    /** Pixel stride (in data array elements) of the region of image
+     *  data described by this ComponentSampleModel.
+     */
+    protected int pixelStride;
+
+    static private native void initIDs();
+    static {
+        ColorModel.loadLibraries();
+        initIDs();
+    }
+
+    /**
+     * Constructs a ComponentSampleModel with the specified parameters.
+     * The number of bands will be given by the length of the bandOffsets array.
+     * All bands will be stored in the first bank of the DataBuffer.
+     * @param dataType  the data type for storing samples
+     * @param w         the width (in pixels) of the region of
+     *     image data described
+     * @param h         the height (in pixels) of the region of
+     *     image data described
+     * @param pixelStride the pixel stride of the region of image
+     *     data described
+     * @param scanlineStride the line stride of the region of image
+     *     data described
+     * @param bandOffsets the offsets of all bands
+     * @throws IllegalArgumentException if <code>w</code> or
+     *         <code>h</code> is not greater than 0
+     * @throws IllegalArgumentException if <code>pixelStride</code>
+     *         is less than 0
+     * @throws IllegalArgumentException if <code>scanlineStride</code>
+     *         is less than 0
+     * @throws IllegalArgumentException if <code>numBands</code>
+     *         is less than 1
+     * @throws IllegalArgumentException if the product of <code>w</code>
+     *         and <code>h</code> is greater than
+     *         <code>Integer.MAX_VALUE</code>
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types
+     */
+    public ComponentSampleModel(int dataType,
+                                int w, int h,
+                                int pixelStride,
+                                int scanlineStride,
+                                int bandOffsets[]) {
+        super(dataType, w, h, bandOffsets.length);
+        this.dataType = dataType;
+        this.pixelStride = pixelStride;
+        this.scanlineStride  = scanlineStride;
+        this.bandOffsets = (int[])bandOffsets.clone();
+        numBands = bandOffsets.length;
+        if (pixelStride < 0) {
+            throw new IllegalArgumentException("Pixel stride must be >= 0");
+        }
+        // TODO - bug 4296691 - remove this check
+        if (scanlineStride < 0) {
+            throw new IllegalArgumentException("Scanline stride must be >= 0");
+        }
+        if (numBands < 1) {
+            throw new IllegalArgumentException("Must have at least one band.");
+        }
+        if ((dataType < DataBuffer.TYPE_BYTE) ||
+            (dataType > DataBuffer.TYPE_DOUBLE)) {
+            throw new IllegalArgumentException("Unsupported dataType.");
+        }
+        bankIndices = new int[numBands];
+        for (int i=0; i<numBands; i++) {
+            bankIndices[i] = 0;
+        }
+    }
+
+
+    /**
+     * Constructs a ComponentSampleModel with the specified parameters.
+     * The number of bands will be given by the length of the bandOffsets array.
+     * Different bands may be stored in different banks of the DataBuffer.
+     *
+     * @param dataType  the data type for storing samples
+     * @param w         the width (in pixels) of the region of
+     *     image data described
+     * @param h         the height (in pixels) of the region of
+     *     image data described
+     * @param pixelStride the pixel stride of the region of image
+     *     data described
+     * @param scanlineStride The line stride of the region of image
+     *     data described
+     * @param bankIndices the bank indices of all bands
+     * @param bandOffsets the band offsets of all bands
+     * @throws IllegalArgumentException if <code>w</code> or
+     *         <code>h</code> is not greater than 0
+     * @throws IllegalArgumentException if <code>pixelStride</code>
+     *         is less than 0
+     * @throws IllegalArgumentException if <code>scanlineStride</code>
+     *         is less than 0
+     * @throws IllegalArgumentException if the length of
+     *         <code>bankIndices</code> does not equal the length of
+     *         <code>bankOffsets</code>
+     * @throws IllegalArgumentException if any of the bank indices
+     *         of <code>bandIndices</code> is less than 0
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types
+     */
+    public ComponentSampleModel(int dataType,
+                                int w, int h,
+                                int pixelStride,
+                                int scanlineStride,
+                                int bankIndices[],
+                                int bandOffsets[]) {
+        super(dataType, w, h, bandOffsets.length);
+        this.dataType = dataType;
+        this.pixelStride = pixelStride;
+        this.scanlineStride  = scanlineStride;
+        this.bandOffsets = (int[])bandOffsets.clone();
+        this.bankIndices = (int[]) bankIndices.clone();
+        if (pixelStride < 0) {
+            throw new IllegalArgumentException("Pixel stride must be >= 0");
+        }
+        // TODO - bug 4296691 - remove this check
+        if (scanlineStride < 0) {
+            throw new IllegalArgumentException("Scanline stride must be >= 0");
+        }
+        if ((dataType < DataBuffer.TYPE_BYTE) ||
+            (dataType > DataBuffer.TYPE_DOUBLE)) {
+            throw new IllegalArgumentException("Unsupported dataType.");
+        }
+        int maxBank = bankIndices[0];
+        if (maxBank < 0) {
+            throw new IllegalArgumentException("Index of bank 0 is less than "+
+                                               "0 ("+maxBank+")");
+        }
+        for (int i=1; i < bankIndices.length; i++) {
+            if (bankIndices[i] > maxBank) {
+                maxBank = bankIndices[i];
+            }
+            else if (bankIndices[i] < 0) {
+                throw new IllegalArgumentException("Index of bank "+i+
+                                                   " is less than 0 ("+
+                                                   maxBank+")");
+            }
+        }
+        numBanks         = maxBank+1;
+        numBands         = bandOffsets.length;
+        if (bandOffsets.length != bankIndices.length) {
+            throw new IllegalArgumentException("Length of bandOffsets must "+
+                                               "equal length of bankIndices.");
+        }
+    }
+
+    /**
+     * Returns the size of the data buffer (in data elements) needed
+     * for a data buffer that matches this ComponentSampleModel.
+     */
+     private long getBufferSize() {
+         int maxBandOff=bandOffsets[0];
+         for (int i=1; i<bandOffsets.length; i++)
+             maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
+
+         long size = 0;
+         if (maxBandOff >= 0)
+             size += maxBandOff+1;
+         if (pixelStride > 0)
+             size += pixelStride * (width-1);
+         if (scanlineStride > 0)
+             size += scanlineStride*(height-1);
+         return size;
+     }
+
+     /**
+      * Preserves band ordering with new step factor...
+      */
+    int []orderBands(int orig[], int step) {
+        int map[] = new int[orig.length];
+        int ret[] = new int[orig.length];
+
+        for (int i=0; i<map.length; i++) map[i] = i;
+
+        for (int i = 0; i < ret.length; i++) {
+            int index = i;
+            for (int j = i+1; j < ret.length; j++) {
+                if (orig[map[index]] > orig[map[j]]) {
+                    index = j;
+                }
+            }
+            ret[map[index]] = i*step;
+            map[index]  = map[i];
+        }
+        return ret;
+    }
+
+    /**
+     * Creates a new <code>ComponentSampleModel</code> with the specified
+     * width and height.  The new <code>SampleModel</code> will have the same
+     * number of bands, storage data type, interleaving scheme, and
+     * pixel stride as this <code>SampleModel</code>.
+     * @param w the width of the resulting <code>SampleModel</code>
+     * @param h the height of the resulting <code>SampleModel</code>
+     * @return a new <code>ComponentSampleModel</code> with the specified size
+     * @throws IllegalArgumentException if <code>w</code> or
+     *         <code>h</code> is not greater than 0
+     */
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        SampleModel ret=null;
+        long size;
+        int minBandOff=bandOffsets[0];
+        int maxBandOff=bandOffsets[0];
+        for (int i=1; i<bandOffsets.length; i++) {
+            minBandOff = Math.min(minBandOff,bandOffsets[i]);
+            maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
+        }
+        maxBandOff -= minBandOff;
+
+        int bands   = bandOffsets.length;
+        int bandOff[];
+        int pStride = Math.abs(pixelStride);
+        int lStride = Math.abs(scanlineStride);
+        int bStride = Math.abs(maxBandOff);
+
+        if (pStride > lStride) {
+            if (pStride > bStride) {
+                if (lStride > bStride) { // pix > line > band
+                    bandOff = new int[bandOffsets.length];
+                    for (int i=0; i<bands; i++)
+                        bandOff[i] = bandOffsets[i]-minBandOff;
+                    lStride = bStride+1;
+                    pStride = lStride*h;
+                } else { // pix > band > line
+                    bandOff = orderBands(bandOffsets,lStride*h);
+                    pStride = bands*lStride*h;
+                }
+            } else { // band > pix > line
+                pStride = lStride*h;
+                bandOff = orderBands(bandOffsets,pStride*w);
+            }
+        } else {
+            if (pStride > bStride) { // line > pix > band
+                bandOff = new int[bandOffsets.length];
+                for (int i=0; i<bands; i++)
+                    bandOff[i] = bandOffsets[i]-minBandOff;
+                pStride = bStride+1;
+                lStride = pStride*w;
+            } else {
+                if (lStride > bStride) { // line > band > pix
+                    bandOff = orderBands(bandOffsets,pStride*w);
+                    lStride = bands*pStride*w;
+                } else { // band > line > pix
+                    lStride = pStride*w;
+                    bandOff = orderBands(bandOffsets,lStride*h);
+                }
+            }
+        }
+
+        // make sure we make room for negative offsets...
+        int base = 0;
+        if (scanlineStride < 0) {
+            base += lStride*h;
+            lStride *= -1;
+        }
+        if (pixelStride    < 0) {
+            base += pStride*w;
+            pStride *= -1;
+        }
+
+        for (int i=0; i<bands; i++)
+            bandOff[i] += base;
+        return new ComponentSampleModel(dataType, w, h, pStride,
+                                        lStride, bankIndices, bandOff);
+    }
+
+    /**
+     * Creates a new ComponentSampleModel with a subset of the bands
+     * of this ComponentSampleModel.  The new ComponentSampleModel can be
+     * used with any DataBuffer that the existing ComponentSampleModel
+     * can be used with.  The new ComponentSampleModel/DataBuffer
+     * combination will represent an image with a subset of the bands
+     * of the original ComponentSampleModel/DataBuffer combination.
+     * @param bands a subset of bands from this
+     *              <code>ComponentSampleModel</code>
+     * @return a <code>ComponentSampleModel</code> created with a subset
+     *          of bands from this <code>ComponentSampleModel</code>.
+     */
+    public SampleModel createSubsetSampleModel(int bands[]) {
+       if (bands.length > bankIndices.length)
+            throw new RasterFormatException("There are only " +
+                                            bankIndices.length +
+                                            " bands");
+        int newBankIndices[] = new int[bands.length];
+        int newBandOffsets[] = new int[bands.length];
+
+        for (int i=0; i<bands.length; i++) {
+            newBankIndices[i] = bankIndices[bands[i]];
+            newBandOffsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new ComponentSampleModel(this.dataType, width, height,
+                                        this.pixelStride,
+                                        this.scanlineStride,
+                                        newBankIndices, newBandOffsets);
+    }
+
+    /**
+     * Creates a <code>DataBuffer</code> that corresponds to this
+     * <code>ComponentSampleModel</code>.
+     * The <code>DataBuffer</code> object's data type, number of banks,
+     * and size are be consistent with this <code>ComponentSampleModel</code>.
+     * @return a <code>DataBuffer</code> whose data type, number of banks
+     *         and size are consistent with this
+     *         <code>ComponentSampleModel</code>.
+     */
+    public DataBuffer createDataBuffer() {
+        DataBuffer dataBuffer = null;
+
+        int size = (int)getBufferSize();
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            dataBuffer = new DataBufferByte(size, numBanks);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            dataBuffer = new DataBufferUShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_SHORT:
+            dataBuffer = new DataBufferShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_INT:
+            dataBuffer = new DataBufferInt(size, numBanks);
+            break;
+        case DataBuffer.TYPE_FLOAT:
+            dataBuffer = new DataBufferFloat(size, numBanks);
+            break;
+        case DataBuffer.TYPE_DOUBLE:
+            dataBuffer = new DataBufferDouble(size, numBanks);
+            break;
+        }
+
+        return dataBuffer;
+    }
+
+
+    /** Gets the offset for the first band of pixel (x,y).
+     *  A sample of the first band can be retrieved from a
+     * <code>DataBuffer</code>
+     *  <code>data</code> with a <code>ComponentSampleModel</code>
+     * <code>csm</code> as
+     * <pre>
+     *        data.getElem(csm.getOffset(x, y));
+     * </pre>
+     * @param x the X location of the pixel
+     * @param y the Y location of the pixel
+     * @return the offset for the first band of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        int offset = y*scanlineStride + x*pixelStride + bandOffsets[0];
+        return offset;
+    }
+
+    /** Gets the offset for band b of pixel (x,y).
+     *  A sample of band <code>b</code> can be retrieved from a
+     *  <code>DataBuffer</code> <code>data</code>
+     *  with a <code>ComponentSampleModel</code> <code>csm</code> as
+     * <pre>
+     *       data.getElem(csm.getOffset(x, y, b));
+     * </pre>
+     * @param x the X location of the specified pixel
+     * @param y the Y location of the specified pixel
+     * @param b the specified band
+     * @return the offset for the specified band of the specified pixel.
+     */
+    public int getOffset(int x, int y, int b) {
+        int offset = y*scanlineStride + x*pixelStride + bandOffsets[b];
+        return offset;
+    }
+
+    /** Returns the number of bits per sample for all bands.
+     *  @return an array containing the number of bits per sample
+     *          for all bands, where each element in the array
+     *          represents a band.
+     */
+    public final int[] getSampleSize() {
+        int sampleSize[] = new int [numBands];
+        int sizeInBits = getSampleSize(0);
+
+        for (int i=0; i<numBands; i++)
+            sampleSize[i] = sizeInBits;
+
+        return sampleSize;
+    }
+
+    /** Returns the number of bits per sample for the specified band.
+     *  @param band the specified band
+     *  @return the number of bits per sample for the specified band.
+     */
+    public final int getSampleSize(int band) {
+        return DataBuffer.getDataTypeSize(dataType);
+    }
+
+    /** Returns the bank indices for all bands.
+     *  @return the bank indices for all bands.
+     */
+    public final int [] getBankIndices() {
+        return (int[]) bankIndices.clone();
+    }
+
+    /** Returns the band offset for all bands.
+     *  @return the band offsets for all bands.
+     */
+    public final int [] getBandOffsets() {
+        return (int[])bandOffsets.clone();
+    }
+
+    /** Returns the scanline stride of this ComponentSampleModel.
+     *  @return the scanline stride of this <code>ComponentSampleModel</code>.
+     */
+    public final int getScanlineStride() {
+        return scanlineStride;
+    }
+
+    /** Returns the pixel stride of this ComponentSampleModel.
+     *  @return the pixel stride of this <code>ComponentSampleModel</code>.
+     */
+    public final int getPixelStride() {
+        return pixelStride;
+    }
+
+    /**
+     * Returns the number of data elements needed to transfer a pixel
+     * with the
+     * {@link #getDataElements(int, int, Object, DataBuffer) } and
+     * {@link #setDataElements(int, int, Object, DataBuffer) }
+     * methods.
+     * For a <code>ComponentSampleModel</code>, this is identical to the
+     * number of bands.
+     * @return the number of data elements needed to transfer a pixel with
+     *         the <code>getDataElements</code> and
+     *         <code>setDataElements</code> methods.
+     * @see java.awt.image.SampleModel#getNumDataElements
+     * @see #getNumBands
+     */
+    public final int getNumDataElements() {
+        return getNumBands();
+    }
+
+    /**
+     * Returns data for a single pixel in a primitive array of type
+     * <code>TransferType</code>.  For a <code>ComponentSampleModel</code>,
+     * this is the same as the data type, and samples are returned
+     * one per array element.  Generally, <code>obj</code> should
+     * be passed in as <code>null</code>, so that the <code>Object</code>
+     * is created automatically and is the right primitive data type.
+     * <p>
+     * The following code illustrates transferring data for one pixel from
+     * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
+     * described by <code>ComponentSampleModel</code> <code>csm1</code>,
+     * to <code>DataBuffer</code> <code>db2</code>, whose storage layout
+     * is described by <code>ComponentSampleModel</code> <code>csm2</code>.
+     * The transfer is usually more efficient than using
+     * <code>getPixel</code> and <code>setPixel</code>.
+     * <pre>
+     *       ComponentSampleModel csm1, csm2;
+     *       DataBufferInt db1, db2;
+     *       csm2.setDataElements(x, y,
+     *                            csm1.getDataElements(x, y, null, db1), db2);
+     * </pre>
+     *
+     * Using <code>getDataElements</code> and <code>setDataElements</code>
+     * to transfer between two <code>DataBuffer/SampleModel</code>
+     * pairs is legitimate if the <code>SampleModel</code> objects have
+     * the same number of bands, corresponding bands have the same number of
+     * bits per sample, and the <code>TransferType</code>s are the same.
+     * <p>
+     * If <code>obj</code> is not <code>null</code>, it should be a
+     * primitive array of type <code>TransferType</code>.
+     * Otherwise, a <code>ClassCastException</code> is thrown.  An
+     * <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
+     * coordinates are not in bounds, or if <code>obj</code> is not
+     * <code>null</code> and is not large enough to hold
+     * the pixel data.
+     *
+     * @param x         the X coordinate of the pixel location
+     * @param y         the Y coordinate of the pixel location
+     * @param obj       if non-<code>null</code>, a primitive array
+     *                  in which to return the pixel data
+     * @param data      the <code>DataBuffer</code> containing the image data
+     * @return the data of the specified pixel
+     * @see #setDataElements(int, int, Object, DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if obj is too small to hold the ouput.
+     */
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        int type = getTransferType();
+        int numDataElems = getNumDataElements();
+        int pixelOffset = y*scanlineStride + x*pixelStride;
+
+        switch(type) {
+
+        case DataBuffer.TYPE_BYTE:
+
+            byte[] bdata;
+
+            if (obj == null)
+                bdata = new byte[numDataElems];
+            else
+                bdata = (byte[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                bdata[i] = (byte)data.getElem(bankIndices[i],
+                                              pixelOffset + bandOffsets[i]);
+            }
+
+            obj = (Object)bdata;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_SHORT:
+
+            short[] sdata;
+
+            if (obj == null)
+                sdata = new short[numDataElems];
+            else
+                sdata = (short[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                sdata[i] = (short)data.getElem(bankIndices[i],
+                                               pixelOffset + bandOffsets[i]);
+            }
+
+            obj = (Object)sdata;
+            break;
+
+        case DataBuffer.TYPE_INT:
+
+            int[] idata;
+
+            if (obj == null)
+                idata = new int[numDataElems];
+            else
+                idata = (int[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                idata[i] = data.getElem(bankIndices[i],
+                                        pixelOffset + bandOffsets[i]);
+            }
+
+            obj = (Object)idata;
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+
+            float[] fdata;
+
+            if (obj == null)
+                fdata = new float[numDataElems];
+            else
+                fdata = (float[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                fdata[i] = data.getElemFloat(bankIndices[i],
+                                             pixelOffset + bandOffsets[i]);
+            }
+
+            obj = (Object)fdata;
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+
+            double[] ddata;
+
+            if (obj == null)
+                ddata = new double[numDataElems];
+            else
+                ddata = (double[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                ddata[i] = data.getElemDouble(bankIndices[i],
+                                              pixelOffset + bandOffsets[i]);
+            }
+
+            obj = (Object)ddata;
+            break;
+        }
+
+        return obj;
+    }
+
+    /**
+     * Returns all samples for the specified pixel in an int array,
+     * one sample per array element.
+     * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
+     * the coordinates are not in bounds.
+     * @param x         the X coordinate of the pixel location
+     * @param y         the Y coordinate of the pixel location
+     * @param iArray    If non-null, returns the samples in this array
+     * @param data      The DataBuffer containing the image data
+     * @return the samples of the specified pixel.
+     * @see #setPixel(int, int, int[], DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if iArray is too small to hold the output.
+     */
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int pixels[];
+        if (iArray != null) {
+           pixels = iArray;
+        } else {
+           pixels = new int [numBands];
+        }
+        int pixelOffset = y*scanlineStride + x*pixelStride;
+        for (int i=0; i<numBands; i++) {
+            pixels[i] = data.getElem(bankIndices[i],
+                                     pixelOffset + bandOffsets[i]);
+        }
+        return pixels;
+    }
+
+    /**
+     * Returns all samples for the specified rectangle of pixels in
+     * an int array, one sample per array element.
+     * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
+     * the coordinates are not in bounds.
+     * @param x         The X coordinate of the upper left pixel location
+     * @param y         The Y coordinate of the upper left pixel location
+     * @param w         The width of the pixel rectangle
+     * @param h         The height of the pixel rectangle
+     * @param iArray    If non-null, returns the samples in this array
+     * @param data      The DataBuffer containing the image data
+     * @return the samples of the pixels within the specified region.
+     * @see #setPixels(int, int, int, int, int[], DataBuffer)
+     */
+    public int[] getPixels(int x, int y, int w, int h,
+                           int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int pixels[];
+        if (iArray != null) {
+           pixels = iArray;
+        } else {
+           pixels = new int [w*h*numBands];
+        }
+        int lineOffset = y*scanlineStride + x*pixelStride;
+        int srcOffset = 0;
+
+        for (int i = 0; i < h; i++) {
+           int pixelOffset = lineOffset;
+           for (int j = 0; j < w; j++) {
+              for (int k=0; k < numBands; k++) {
+                 pixels[srcOffset++] =
+                    data.getElem(bankIndices[k], pixelOffset + bandOffsets[k]);
+              }
+              pixelOffset += pixelStride;
+           }
+           lineOffset += scanlineStride;
+        }
+        return pixels;
+    }
+
+    /**
+     * Returns as int the sample in a specified band for the pixel
+     * located at (x,y).
+     * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
+     * the coordinates are not in bounds.
+     * @param x         the X coordinate of the pixel location
+     * @param y         the Y coordinate of the pixel location
+     * @param b         the band to return
+     * @param data      the <code>DataBuffer</code> containing the image data
+     * @return the sample in a specified band for the specified pixel
+     * @see #setSample(int, int, int, int, DataBuffer)
+     */
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int sample = data.getElem(bankIndices[b],
+                                  y*scanlineStride + x*pixelStride +
+                                  bandOffsets[b]);
+        return sample;
+    }
+
+    /**
+     * Returns the sample in a specified band
+     * for the pixel located at (x,y) as a float.
+     * An <code>ArrayIndexOutOfBoundsException</code> might be
+     * thrown if the coordinates are not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param b         The band to return
+     * @param data      The DataBuffer containing the image data
+     * @return a float value representing the sample in the specified
+     * band for the specified pixel.
+     */
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        float sample = data.getElemFloat(bankIndices[b],
+                                         y*scanlineStride + x*pixelStride +
+                                         bandOffsets[b]);
+        return sample;
+    }
+
+    /**
+     * Returns the sample in a specified band
+     * for a pixel located at (x,y) as a double.
+     * An <code>ArrayIndexOutOfBoundsException</code> might be
+     * thrown if the coordinates are not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param b         The band to return
+     * @param data      The DataBuffer containing the image data
+     * @return a double value representing the sample in the specified
+     * band for the specified pixel.
+     */
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        double sample = data.getElemDouble(bankIndices[b],
+                                           y*scanlineStride + x*pixelStride +
+                                           bandOffsets[b]);
+        return sample;
+    }
+
+    /**
+     * Returns the samples in a specified band for the specified rectangle
+     * of pixels in an int array, one sample per data array element.
+     * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
+     * the coordinates are not in bounds.
+     * @param x         The X coordinate of the upper left pixel location
+     * @param y         The Y coordinate of the upper left pixel location
+     * @param w         the width of the pixel rectangle
+     * @param h         the height of the pixel rectangle
+     * @param b         the band to return
+     * @param iArray    if non-<code>null</code>, returns the samples
+     *                  in this array
+     * @param data      the <code>DataBuffer</code> containing the image data
+     * @return the samples in the specified band of the specified pixel
+     * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b,
+                            int iArray[], DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int samples[];
+        if (iArray != null) {
+           samples = iArray;
+        } else {
+           samples = new int [w*h];
+        }
+        int lineOffset = y*scanlineStride + x*pixelStride +  bandOffsets[b];
+        int srcOffset = 0;
+
+        for (int i = 0; i < h; i++) {
+           int sampleOffset = lineOffset;
+           for (int j = 0; j < w; j++) {
+              samples[srcOffset++] = data.getElem(bankIndices[b],
+                                                  sampleOffset);
+              sampleOffset += pixelStride;
+           }
+           lineOffset += scanlineStride;
+        }
+        return samples;
+    }
+
+    /**
+     * Sets the data for a single pixel in the specified
+     * <code>DataBuffer</code> from a primitive array of type
+     * <code>TransferType</code>.  For a <code>ComponentSampleModel</code>,
+     * this is the same as the data type, and samples are transferred
+     * one per array element.
+     * <p>
+     * The following code illustrates transferring data for one pixel from
+     * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
+     * described by <code>ComponentSampleModel</code> <code>csm1</code>,
+     * to <code>DataBuffer</code> <code>db2</code>, whose storage layout
+     * is described by <code>ComponentSampleModel</code> <code>csm2</code>.
+     * The transfer is usually more efficient than using
+     * <code>getPixel</code> and <code>setPixel</code>.
+     * <pre>
+     *       ComponentSampleModel csm1, csm2;
+     *       DataBufferInt db1, db2;
+     *       csm2.setDataElements(x, y, csm1.getDataElements(x, y, null, db1),
+     *                            db2);
+     * </pre>
+     * Using <code>getDataElements</code> and <code>setDataElements</code>
+     * to transfer between two <code>DataBuffer/SampleModel</code> pairs
+     * is legitimate if the <code>SampleModel</code> objects have
+     * the same number of bands, corresponding bands have the same number of
+     * bits per sample, and the <code>TransferType</code>s are the same.
+     * <p>
+     * A <code>ClassCastException</code> is thrown if <code>obj</code> is not
+     * a primitive array of type <code>TransferType</code>.
+     * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
+     * the coordinates are not in bounds, or if <code>obj</code> is not large
+     * enough to hold the pixel data.
+     * @param x         the X coordinate of the pixel location
+     * @param y         the Y coordinate of the pixel location
+     * @param obj       a primitive array containing pixel data
+     * @param data      the DataBuffer containing the image data
+     * @see #getDataElements(int, int, Object, DataBuffer)
+     */
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        int type = getTransferType();
+        int numDataElems = getNumDataElements();
+        int pixelOffset = y*scanlineStride + x*pixelStride;
+
+        switch(type) {
+
+        case DataBuffer.TYPE_BYTE:
+
+            byte[] barray = (byte[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
+                           ((int)barray[i])&0xff);
+            }
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_SHORT:
+
+            short[] sarray = (short[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
+                           ((int)sarray[i])&0xffff);
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+
+            int[] iarray = (int[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                data.setElem(bankIndices[i],
+                             pixelOffset + bandOffsets[i], iarray[i]);
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+
+            float[] farray = (float[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                data.setElemFloat(bankIndices[i],
+                             pixelOffset + bandOffsets[i], farray[i]);
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+
+            double[] darray = (double[])obj;
+
+            for (int i=0; i<numDataElems; i++) {
+                data.setElemDouble(bankIndices[i],
+                             pixelOffset + bandOffsets[i], darray[i]);
+            }
+            break;
+
+        }
+    }
+
+    /**
+     * Sets a pixel in the <code>DataBuffer</code> using an int array of
+     * samples for input.  An <code>ArrayIndexOutOfBoundsException</code>
+     * might be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param iArray    The input samples in an int array
+     * @param data      The DataBuffer containing the image data
+     * @see #getPixel(int, int, int[], DataBuffer)
+     */
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+       int pixelOffset = y*scanlineStride + x*pixelStride;
+       for (int i=0; i<numBands; i++) {
+           data.setElem(bankIndices[i],
+                        pixelOffset + bandOffsets[i],iArray[i]);
+       }
+    }
+
+    /**
+     * Sets all samples for a rectangle of pixels from an int array containing
+     * one sample per array element.
+     * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
+     * coordinates are not in bounds.
+     * @param x         The X coordinate of the upper left pixel location
+     * @param y         The Y coordinate of the upper left pixel location
+     * @param w         The width of the pixel rectangle
+     * @param h         The height of the pixel rectangle
+     * @param iArray    The input samples in an int array
+     * @param data      The DataBuffer containing the image data
+     * @see #getPixels(int, int, int, int, int[], DataBuffer)
+     */
+    public void setPixels(int x, int y, int w, int h,
+                          int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        int lineOffset = y*scanlineStride + x*pixelStride;
+        int srcOffset = 0;
+
+        for (int i = 0; i < h; i++) {
+           int pixelOffset = lineOffset;
+           for (int j = 0; j < w; j++) {
+              for (int k=0; k < numBands; k++) {
+                 data.setElem(bankIndices[k], pixelOffset + bandOffsets[k],
+                              iArray[srcOffset++]);
+              }
+              pixelOffset += pixelStride;
+           }
+           lineOffset += scanlineStride;
+        }
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the <code>DataBuffer</code> using an int for input.
+     * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
+     * coordinates are not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param b         the band to set
+     * @param s         the input sample as an int
+     * @param data      the DataBuffer containing the image data
+     * @see #getSample(int, int, int, DataBuffer)
+     */
+    public void setSample(int x, int y, int b, int s,
+                          DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        data.setElem(bankIndices[b],
+                     y*scanlineStride + x*pixelStride + bandOffsets[b], s);
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the <code>DataBuffer</code> using a float for input.
+     * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
+     * the coordinates are not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param b         The band to set
+     * @param s         The input sample as a float
+     * @param data      The DataBuffer containing the image data
+     * @see #getSample(int, int, int, DataBuffer)
+     */
+    public void setSample(int x, int y, int b,
+                          float s ,
+                          DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        data.setElemFloat(bankIndices[b],
+                          y*scanlineStride + x*pixelStride + bandOffsets[b],
+                          s);
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the <code>DataBuffer</code> using a double for input.
+     * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
+     * the coordinates are not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param b         The band to set
+     * @param s         The input sample as a double
+     * @param data      The DataBuffer containing the image data
+     * @see #getSample(int, int, int, DataBuffer)
+     */
+    public void setSample(int x, int y, int b,
+                          double s,
+                          DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        data.setElemDouble(bankIndices[b],
+                          y*scanlineStride + x*pixelStride + bandOffsets[b],
+                          s);
+    }
+
+    /**
+     * Sets the samples in the specified band for the specified rectangle
+     * of pixels from an int array containing one sample per data array element.
+     * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
+     * coordinates are not in bounds.
+     * @param x         The X coordinate of the upper left pixel location
+     * @param y         The Y coordinate of the upper left pixel location
+     * @param w         The width of the pixel rectangle
+     * @param h         The height of the pixel rectangle
+     * @param b         The band to set
+     * @param iArray    The input samples in an int array
+     * @param data      The DataBuffer containing the image data
+     * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
+     */
+    public void setSamples(int x, int y, int w, int h, int b,
+                           int iArray[], DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int lineOffset = y*scanlineStride + x*pixelStride + bandOffsets[b];
+        int srcOffset = 0;
+
+        for (int i = 0; i < h; i++) {
+           int sampleOffset = lineOffset;
+           for (int j = 0; j < w; j++) {
+              data.setElem(bankIndices[b], sampleOffset, iArray[srcOffset++]);
+              sampleOffset += pixelStride;
+           }
+           lineOffset += scanlineStride;
+        }
+    }
+
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof ComponentSampleModel)) {
+            return false;
+        }
+
+        ComponentSampleModel that = (ComponentSampleModel)o;
+        return this.width == that.width &&
+            this.height == that.height &&
+            this.numBands == that.numBands &&
+            this.dataType == that.dataType &&
+            Arrays.equals(this.bandOffsets, that.bandOffsets) &&
+            Arrays.equals(this.bankIndices, that.bankIndices) &&
+            this.numBands == that.numBands &&
+            this.numBanks == that.numBanks &&
+            this.scanlineStride == that.scanlineStride &&
+            this.pixelStride == that.pixelStride;
+    }
+
+    // If we implement equals() we must also implement hashCode
+    public int hashCode() {
+        int hash = 0;
+        hash = width;
+        hash <<= 8;
+        hash ^= height;
+        hash <<= 8;
+        hash ^= numBands;
+        hash <<= 8;
+        hash ^= dataType;
+        hash <<= 8;
+        for (int i = 0; i < bandOffsets.length; i++) {
+            hash ^= bandOffsets[i];
+            hash <<= 8;
+        }
+        for (int i = 0; i < bankIndices.length; i++) {
+            hash ^= bankIndices[i];
+            hash <<= 8;
+        }
+        hash ^= numBands;
+        hash <<= 8;
+        hash ^= numBanks;
+        hash <<= 8;
+        hash ^= scanlineStride;
+        hash <<= 8;
+        hash ^= pixelStride;
+        return hash;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/DataBuffer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,535 @@
+/*
+ * Portions Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+
+import sun.java2d.StateTrackable.State;
+import static sun.java2d.StateTrackable.State.*;
+import sun.java2d.StateTrackableDelegate;
+
+import sun.awt.image.SunWritableRaster;
+
+/**
+ * This class exists to wrap one or more data arrays.  Each data array in
+ * the DataBuffer is referred to as a bank.  Accessor methods for getting
+ * and setting elements of the DataBuffer's banks exist with and without
+ * a bank specifier.  The methods without a bank specifier use the default 0th
+ * bank.  The DataBuffer can optionally take an offset per bank, so that
+ * data in an existing array can be used even if the interesting data
+ * doesn't start at array location zero.  Getting or setting the 0th
+ * element of a bank, uses the (0+offset)th element of the array.  The
+ * size field specifies how much of the data array is available for
+ * use.  Size + offset for a given bank should never be greater
+ * than the length of the associated data array.  The data type of
+ * a data buffer indicates the type of the data array(s) and may also
+ * indicate additional semantics, e.g. storing unsigned 8-bit data
+ * in elements of a byte array.  The data type may be TYPE_UNDEFINED
+ * or one of the types defined below.  Other types may be added in
+ * the future.  Generally, an object of class DataBuffer will be cast down
+ * to one of its data type specific subclasses to access data type specific
+ * methods for improved performance.  Currently, the Java 2D(tm) API
+ * image classes use TYPE_BYTE, TYPE_USHORT, TYPE_INT, TYPE_SHORT,
+ * TYPE_FLOAT, and TYPE_DOUBLE DataBuffers to store image data.
+ * @see java.awt.image.Raster
+ * @see java.awt.image.SampleModel
+ */
+public abstract class DataBuffer {
+
+    /** Tag for unsigned byte data. */
+    public static final int TYPE_BYTE  = 0;
+
+    /** Tag for unsigned short data. */
+    public static final int TYPE_USHORT = 1;
+
+    /** Tag for signed short data.  Placeholder for future use. */
+    public static final int TYPE_SHORT = 2;
+
+    /** Tag for int data. */
+    public static final int TYPE_INT   = 3;
+
+    /** Tag for float data.  Placeholder for future use. */
+    public static final int TYPE_FLOAT  = 4;
+
+    /** Tag for double data.  Placeholder for future use. */
+    public static final int TYPE_DOUBLE  = 5;
+
+    /** Tag for undefined data. */
+    public static final int TYPE_UNDEFINED = 32;
+
+    /** The data type of this DataBuffer. */
+    protected int dataType;
+
+    /** The number of banks in this DataBuffer. */
+    protected int banks;
+
+    /** Offset into default (first) bank from which to get the first element. */
+    protected int offset;
+
+    /** Usable size of all banks. */
+    protected int size;
+
+    /** Offsets into all banks. */
+    protected int offsets[];
+
+    /* The current StateTrackable state. */
+    StateTrackableDelegate theTrackable;
+
+    /** Size of the data types indexed by DataType tags defined above. */
+    private static final int dataTypeSize[] = {8,16,16,32,32,64};
+
+    /** Returns the size (in bits) of the data type, given a datatype tag.
+      * @param type the value of one of the defined datatype tags
+      * @return the size of the data type
+      * @throws IllegalArgumentException if <code>type</code> is less than
+      *         zero or greater than {@link #TYPE_DOUBLE}
+      */
+    public static int getDataTypeSize(int type) {
+        if (type < TYPE_BYTE || type > TYPE_DOUBLE) {
+            throw new IllegalArgumentException("Unknown data type "+type);
+        }
+        return dataTypeSize[type];
+    }
+
+    /**
+     *  Constructs a DataBuffer containing one bank of the specified
+     *  data type and size.
+     *
+     *  @param dataType the data type of this <code>DataBuffer</code>
+     *  @param size the size of the banks
+     */
+    protected DataBuffer(int dataType, int size) {
+        this(UNTRACKABLE, dataType, size);
+    }
+
+    /**
+     *  Constructs a DataBuffer containing one bank of the specified
+     *  data type and size with the indicated initial {@link State State}.
+     *
+     *  @param initialState the initial {@link State State} state of the data
+     *  @param dataType the data type of this <code>DataBuffer</code>
+     *  @param size the size of the banks
+     *  @since 1.7
+     */
+    DataBuffer(State initialState,
+               int dataType, int size)
+    {
+        this.theTrackable = StateTrackableDelegate.createInstance(initialState);
+        this.dataType = dataType;
+        this.banks = 1;
+        this.size = size;
+        this.offset = 0;
+        this.offsets = new int[1];  // init to 0 by new
+    }
+
+    /**
+     *  Constructs a DataBuffer containing the specified number of
+     *  banks.  Each bank has the specified size and an offset of 0.
+     *
+     *  @param dataType the data type of this <code>DataBuffer</code>
+     *  @param size the size of the banks
+     *  @param numBanks the number of banks in this
+     *         <code>DataBuffer</code>
+     */
+    protected DataBuffer(int dataType, int size, int numBanks) {
+        this(UNTRACKABLE, dataType, size, numBanks);
+    }
+
+    /**
+     *  Constructs a DataBuffer containing the specified number of
+     *  banks with the indicated initial {@link State State}.
+     *  Each bank has the specified size and an offset of 0.
+     *
+     *  @param initialState the initial {@link State State} state of the data
+     *  @param dataType the data type of this <code>DataBuffer</code>
+     *  @param size the size of the banks
+     *  @param numBanks the number of banks in this
+     *         <code>DataBuffer</code>
+     *  @since 1.7
+     */
+    DataBuffer(State initialState,
+               int dataType, int size, int numBanks)
+    {
+        this.theTrackable = StateTrackableDelegate.createInstance(initialState);
+        this.dataType = dataType;
+        this.banks = numBanks;
+        this.size = size;
+        this.offset = 0;
+        this.offsets = new int[banks]; // init to 0 by new
+    }
+
+    /**
+     *  Constructs a DataBuffer that contains the specified number
+     *  of banks.  Each bank has the specified datatype, size and offset.
+     *
+     *  @param dataType the data type of this <code>DataBuffer</code>
+     *  @param size the size of the banks
+     *  @param numBanks the number of banks in this
+     *         <code>DataBuffer</code>
+     *  @param offset the offset for each bank
+     */
+    protected DataBuffer(int dataType, int size, int numBanks, int offset) {
+        this(UNTRACKABLE, dataType, size, numBanks, offset);
+    }
+
+    /**
+     *  Constructs a DataBuffer that contains the specified number
+     *  of banks with the indicated initial {@link State State}.
+     *  Each bank has the specified datatype, size and offset.
+     *
+     *  @param initialState the initial {@link State State} state of the data
+     *  @param dataType the data type of this <code>DataBuffer</code>
+     *  @param size the size of the banks
+     *  @param numBanks the number of banks in this
+     *         <code>DataBuffer</code>
+     *  @param offset the offset for each bank
+     *  @since 1.7
+     */
+    DataBuffer(State initialState,
+               int dataType, int size, int numBanks, int offset)
+    {
+        this.theTrackable = StateTrackableDelegate.createInstance(initialState);
+        this.dataType = dataType;
+        this.banks = numBanks;
+        this.size = size;
+        this.offset = offset;
+        this.offsets = new int[numBanks];
+        for (int i = 0; i < numBanks; i++) {
+            this.offsets[i] = offset;
+        }
+    }
+
+    /**
+     *  Constructs a DataBuffer which contains the specified number
+     *  of banks.  Each bank has the specified datatype and size.  The
+     *  offset for each bank is specified by its respective entry in
+     *  the offsets array.
+     *
+     *  @param dataType the data type of this <code>DataBuffer</code>
+     *  @param size the size of the banks
+     *  @param numBanks the number of banks in this
+     *         <code>DataBuffer</code>
+     *  @param offsets an array containing an offset for each bank.
+     *  @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
+     *          does not equal the length of <code>offsets</code>
+     */
+    protected DataBuffer(int dataType, int size, int numBanks, int offsets[]) {
+        this(UNTRACKABLE, dataType, size, numBanks, offsets);
+    }
+
+    /**
+     *  Constructs a DataBuffer which contains the specified number
+     *  of banks with the indicated initial {@link State State}.
+     *  Each bank has the specified datatype and size.  The
+     *  offset for each bank is specified by its respective entry in
+     *  the offsets array.
+     *
+     *  @param initialState the initial {@link State State} state of the data
+     *  @param dataType the data type of this <code>DataBuffer</code>
+     *  @param size the size of the banks
+     *  @param numBanks the number of banks in this
+     *         <code>DataBuffer</code>
+     *  @param offsets an array containing an offset for each bank.
+     *  @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
+     *          does not equal the length of <code>offsets</code>
+     *  @since 1.7
+     */
+    DataBuffer(State initialState,
+               int dataType, int size, int numBanks, int offsets[])
+    {
+        if (numBanks != offsets.length) {
+            throw new ArrayIndexOutOfBoundsException("Number of banks" +
+                 " does not match number of bank offsets");
+        }
+        this.theTrackable = StateTrackableDelegate.createInstance(initialState);
+        this.dataType = dataType;
+        this.banks = numBanks;
+        this.size = size;
+        this.offset = offsets[0];
+        this.offsets = (int[])offsets.clone();
+    }
+
+    /**  Returns the data type of this DataBuffer.
+     *   @return the data type of this <code>DataBuffer</code>.
+     */
+    public int getDataType() {
+        return dataType;
+    }
+
+    /**  Returns the size (in array elements) of all banks.
+     *   @return the size of all banks.
+     */
+    public int getSize() {
+        return size;
+    }
+
+    /** Returns the offset of the default bank in array elements.
+     *  @return the offset of the default bank.
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /** Returns the offsets (in array elements) of all the banks.
+     *  @return the offsets of all banks.
+     */
+    public int[] getOffsets() {
+        return (int[])offsets.clone();
+    }
+
+    /** Returns the number of banks in this DataBuffer.
+     *  @return the number of banks.
+     */
+    public int getNumBanks() {
+        return banks;
+    }
+
+    /**
+     * Returns the requested data array element from the first (default) bank
+     * as an integer.
+     * @param i the index of the requested data array element
+     * @return the data array element at the specified index.
+     * @see #setElem(int, int)
+     * @see #setElem(int, int, int)
+     */
+    public int getElem(int i) {
+        return getElem(0,i);
+    }
+
+    /**
+     * Returns the requested data array element from the specified bank
+     * as an integer.
+     * @param bank the specified bank
+     * @param i the index of the requested data array element
+     * @return the data array element at the specified index from the
+     *         specified bank at the specified index.
+     * @see #setElem(int, int)
+     * @see #setElem(int, int, int)
+     */
+    public abstract int getElem(int bank, int i);
+
+    /**
+     * Sets the requested data array element in the first (default) bank
+     * from the given integer.
+     * @param i the specified index into the data array
+     * @param val the data to set the element at the specified index in
+     * the data array
+     * @see #getElem(int)
+     * @see #getElem(int, int)
+     */
+    public void  setElem(int i, int val) {
+        setElem(0,i,val);
+    }
+
+    /**
+     * Sets the requested data array element in the specified bank
+     * from the given integer.
+     * @param bank the specified bank
+     * @param i the specified index into the data array
+     * @param val  the data to set the element in the specified bank
+     * at the specified index in the data array
+     * @see #getElem(int)
+     * @see #getElem(int, int)
+     */
+    public abstract void setElem(int bank, int i, int val);
+
+    /**
+     * Returns the requested data array element from the first (default) bank
+     * as a float.  The implementation in this class is to cast getElem(i)
+     * to a float.  Subclasses may override this method if another
+     * implementation is needed.
+     * @param i the index of the requested data array element
+     * @return a float value representing the data array element at the
+     *  specified index.
+     * @see #setElemFloat(int, float)
+     * @see #setElemFloat(int, int, float)
+     */
+    public float getElemFloat(int i) {
+        return (float)getElem(i);
+    }
+
+    /**
+     * Returns the requested data array element from the specified bank
+     * as a float.  The implementation in this class is to cast
+     * {@link #getElem(int, int)}
+     * to a float.  Subclasses can override this method if another
+     * implementation is needed.
+     * @param bank the specified bank
+     * @param i the index of the requested data array element
+     * @return a float value representing the data array element from the
+     * specified bank at the specified index.
+     * @see #setElemFloat(int, float)
+     * @see #setElemFloat(int, int, float)
+     */
+    public float getElemFloat(int bank, int i) {
+        return (float)getElem(bank,i);
+    }
+
+    /**
+     * Sets the requested data array element in the first (default) bank
+     * from the given float.  The implementation in this class is to cast
+     * val to an int and call {@link #setElem(int, int)}.  Subclasses
+     * can override this method if another implementation is needed.
+     * @param i the specified index
+     * @param val the value to set the element at the specified index in
+     * the data array
+     * @see #getElemFloat(int)
+     * @see #getElemFloat(int, int)
+     */
+    public void setElemFloat(int i, float val) {
+        setElem(i,(int)val);
+    }
+
+    /**
+     * Sets the requested data array element in the specified bank
+     * from the given float.  The implementation in this class is to cast
+     * val to an int and call {@link #setElem(int, int)}.  Subclasses can
+     * override this method if another implementation is needed.
+     * @param bank the specified bank
+     * @param i the specified index
+     * @param val the value to set the element in the specified bank at
+     * the specified index in the data array
+     * @see #getElemFloat(int)
+     * @see #getElemFloat(int, int)
+     */
+    public void setElemFloat(int bank, int i, float val) {
+        setElem(bank,i,(int)val);
+    }
+
+    /**
+     * Returns the requested data array element from the first (default) bank
+     * as a double.  The implementation in this class is to cast
+     * {@link #getElem(int)}
+     * to a double.  Subclasses can override this method if another
+     * implementation is needed.
+     * @param i the specified index
+     * @return a double value representing the element at the specified
+     * index in the data array.
+     * @see #setElemDouble(int, double)
+     * @see #setElemDouble(int, int, double)
+     */
+    public double getElemDouble(int i) {
+        return (double)getElem(i);
+    }
+
+    /**
+     * Returns the requested data array element from the specified bank as
+     * a double.  The implementation in this class is to cast getElem(bank, i)
+     * to a double.  Subclasses may override this method if another
+     * implementation is needed.
+     * @param bank the specified bank
+     * @param i the specified index
+     * @return a double value representing the element from the specified
+     * bank at the specified index in the data array.
+     * @see #setElemDouble(int, double)
+     * @see #setElemDouble(int, int, double)
+     */
+    public double getElemDouble(int bank, int i) {
+        return (double)getElem(bank,i);
+    }
+
+    /**
+     * Sets the requested data array element in the first (default) bank
+     * from the given double.  The implementation in this class is to cast
+     * val to an int and call {@link #setElem(int, int)}.  Subclasses can
+     * override this method if another implementation is needed.
+     * @param i the specified index
+     * @param val the value to set the element at the specified index
+     * in the data array
+     * @see #getElemDouble(int)
+     * @see #getElemDouble(int, int)
+     */
+    public void setElemDouble(int i, double val) {
+        setElem(i,(int)val);
+    }
+
+    /**
+     * Sets the requested data array element in the specified bank
+     * from the given double.  The implementation in this class is to cast
+     * val to an int and call {@link #setElem(int, int)}.  Subclasses can
+     * override this method if another implementation is needed.
+     * @param bank the specified bank
+     * @param i the specified index
+     * @param val the value to set the element in the specified bank
+     * at the specified index of the data array
+     * @see #getElemDouble(int)
+     * @see #getElemDouble(int, int)
+     */
+    public void setElemDouble(int bank, int i, double val) {
+        setElem(bank,i,(int)val);
+    }
+
+    static int[] toIntArray(Object obj) {
+        if (obj instanceof int[]) {
+            return (int[])obj;
+        } else if (obj == null) {
+            return null;
+        } else if (obj instanceof short[]) {
+            short sdata[] = (short[])obj;
+            int idata[] = new int[sdata.length];
+            for (int i = 0; i < sdata.length; i++) {
+                idata[i] = (int)sdata[i] & 0xffff;
+            }
+            return idata;
+        } else if (obj instanceof byte[]) {
+            byte bdata[] = (byte[])obj;
+            int idata[] = new int[bdata.length];
+            for (int i = 0; i < bdata.length; i++) {
+                idata[i] = 0xff & (int)bdata[i];
+            }
+            return idata;
+        }
+        return null;
+    }
+
+    static {
+        SunWritableRaster.setDataStealer(new SunWritableRaster.DataStealer() {
+            public byte[] getData(DataBufferByte dbb, int bank) {
+                return dbb.bankdata[bank];
+            }
+
+            public short[] getData(DataBufferUShort dbus, int bank) {
+                return dbus.bankdata[bank];
+            }
+
+            public int[] getData(DataBufferInt dbi, int bank) {
+                return dbi.bankdata[bank];
+            }
+
+            public StateTrackableDelegate getTrackable(DataBuffer db) {
+                return db.theTrackable;
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/DataBufferByte.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,286 @@
+/*
+ * Portions Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+
+import static sun.java2d.StateTrackable.State.*;
+
+/**
+ * This class extends <CODE>DataBuffer</CODE> and stores data internally as bytes.
+ * Values stored in the byte array(s) of this <CODE>DataBuffer</CODE> are treated as
+ * unsigned values.
+ * <p>
+ * <a name="optimizations">
+ * Note that some implementations may function more efficiently
+ * if they can maintain control over how the data for an image is
+ * stored.
+ * For example, optimizations such as caching an image in video
+ * memory require that the implementation track all modifications
+ * to that data.
+ * Other implementations may operate better if they can store the
+ * data in locations other than a Java array.
+ * To maintain optimum compatibility with various optimizations
+ * it is best to avoid constructors and methods which expose the
+ * underlying storage as a Java array, as noted below in the
+ * documentation for those methods.
+ * </a>
+ */
+public final class DataBufferByte extends DataBuffer
+{
+    /** The default data bank. */
+    byte data[];
+
+    /** All data banks */
+    byte bankdata[][];
+
+    /**
+     * Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank and the
+     * specified size.
+     *
+     * @param size The size of the <CODE>DataBuffer</CODE>.
+     */
+    public DataBufferByte(int size) {
+      super(STABLE, TYPE_BYTE, size);
+      data = new byte[size];
+      bankdata = new byte[1][];
+      bankdata[0] = data;
+    }
+
+    /**
+     * Constructs a byte based <CODE>DataBuffer</CODE> with the specified number of
+     * banks all of which are the specified size.
+     *
+     * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
+     * @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
+     */
+    public DataBufferByte(int size, int numBanks) {
+        super(STABLE, TYPE_BYTE, size, numBanks);
+        bankdata = new byte[numBanks][];
+        for (int i= 0; i < numBanks; i++) {
+            bankdata[i] = new byte[size];
+        }
+        data = bankdata[0];
+    }
+
+    /**
+     * Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank using the
+     * specified array.
+     * Only the first <CODE>size</CODE> elements should be used by accessors of
+     * this <CODE>DataBuffer</CODE>.  <CODE>dataArray</CODE> must be large enough to
+     * hold <CODE>size</CODE> elements.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The byte array for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the <CODE>DataBuffer</CODE> bank.
+     */
+    public DataBufferByte(byte dataArray[], int size) {
+        super(UNTRACKABLE, TYPE_BYTE, size);
+        data = dataArray;
+        bankdata = new byte[1][];
+        bankdata[0] = data;
+    }
+
+    /**
+     * Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank using the
+     * specified array, size, and offset.  <CODE>dataArray</CODE> must have at least
+     * <CODE>offset</CODE> + <CODE>size</CODE> elements.  Only elements <CODE>offset</CODE>
+     * through <CODE>offset</CODE> + <CODE>size</CODE> - 1
+     * should be used by accessors of this <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The byte array for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the <CODE>DataBuffer</CODE> bank.
+     * @param offset The offset into the <CODE>dataArray</CODE>. <CODE>dataArray</CODE>
+     * must have at least <CODE>offset</CODE> + <CODE>size</CODE> elements.
+     */
+    public DataBufferByte(byte dataArray[], int size, int offset){
+        super(UNTRACKABLE, TYPE_BYTE, size, 1, offset);
+        data = dataArray;
+        bankdata = new byte[1][];
+        bankdata[0] = data;
+    }
+
+    /**
+     * Constructs a byte-based <CODE>DataBuffer</CODE> with the specified arrays.
+     * The number of banks is equal to <CODE>dataArray.length</CODE>.
+     * Only the first <CODE>size</CODE> elements of each array should be used by
+     * accessors of this <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The byte arrays for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
+     */
+    public DataBufferByte(byte dataArray[][], int size) {
+        super(UNTRACKABLE, TYPE_BYTE, size, dataArray.length);
+        bankdata = (byte[][]) dataArray.clone();
+        data = bankdata[0];
+    }
+
+    /**
+     * Constructs a byte-based <CODE>DataBuffer</CODE> with the specified arrays, size,
+     * and offsets.
+     * The number of banks is equal to <CODE>dataArray.length</CODE>.  Each array must
+     * be at least as large as <CODE>size</CODE> + the corresponding <CODE>offset</CODE>.
+     * There must be an entry in the <CODE>offset</CODE> array for each <CODE>dataArray</CODE>
+     * entry.  For each bank, only elements <CODE>offset</CODE> through
+     * <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be used by accessors of this
+     * <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The byte arrays for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
+     * @param offsets The offsets into each array.
+     */
+    public DataBufferByte(byte dataArray[][], int size, int offsets[]) {
+        super(UNTRACKABLE, TYPE_BYTE, size, dataArray.length, offsets);
+        bankdata = (byte[][]) dataArray.clone();
+        data = bankdata[0];
+    }
+
+    /**
+     * Returns the default (first) byte data array.
+     * <p>
+     * Note that calling this method may cause this {@code DataBuffer}
+     * object to be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @return The first byte data array.
+     */
+    public byte[] getData() {
+        theTrackable.setUntrackable();
+        return data;
+    }
+
+    /**
+     * Returns the data array for the specified bank.
+     * <p>
+     * Note that calling this method may cause this {@code DataBuffer}
+     * object to be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param bank The bank whose data array you want to get.
+     * @return The data array for the specified bank.
+     */
+    public byte[] getData(int bank) {
+        theTrackable.setUntrackable();
+        return bankdata[bank];
+    }
+
+    /**
+     * Returns the data arrays for all banks.
+     * <p>
+     * Note that calling this method may cause this {@code DataBuffer}
+     * object to be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @return All of the data arrays.
+     */
+    public byte[][] getBankData() {
+        theTrackable.setUntrackable();
+        return (byte[][]) bankdata.clone();
+    }
+
+    /**
+     * Returns the requested data array element from the first (default) bank.
+     *
+     * @param i The data array element you want to get.
+     * @return The requested data array element as an integer.
+     * @see #setElem(int, int)
+     * @see #setElem(int, int, int)
+     */
+    public int getElem(int i) {
+        return (int)(data[i+offset]) & 0xff;
+    }
+
+    /**
+     * Returns the requested data array element from the specified bank.
+     *
+     * @param bank The bank from which you want to get a data array element.
+     * @param i The data array element you want to get.
+     * @return The requested data array element as an integer.
+     * @see #setElem(int, int)
+     * @see #setElem(int, int, int)
+     */
+    public int getElem(int bank, int i) {
+        return (int)(bankdata[bank][i+offsets[bank]]) & 0xff;
+    }
+
+    /**
+     * Sets the requested data array element in the first (default) bank
+     * to the specified value.
+     *
+     * @param i The data array element you want to set.
+     * @param val The integer value to which you want to set the data array element.
+     * @see #getElem(int)
+     * @see #getElem(int, int)
+     */
+    public void setElem(int i, int val) {
+        data[i+offset] = (byte)val;
+        theTrackable.markDirty();
+    }
+
+    /**
+     * Sets the requested data array element in the specified bank
+     * from the given integer.
+     * @param bank The bank in which you want to set the data array element.
+     * @param i The data array element you want to set.
+     * @param val The integer value to which you want to set the specified data array element.
+     * @see #getElem(int)
+     * @see #getElem(int, int)
+     */
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i+offsets[bank]] = (byte)val;
+        theTrackable.markDirty();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/DataBufferInt.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,284 @@
+/*
+ * Portions Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+
+import static sun.java2d.StateTrackable.State.*;
+
+/**
+ * This class extends <CODE>DataBuffer</CODE> and stores data internally
+ * as integers.
+ * <p>
+ * <a name="optimizations">
+ * Note that some implementations may function more efficiently
+ * if they can maintain control over how the data for an image is
+ * stored.
+ * For example, optimizations such as caching an image in video
+ * memory require that the implementation track all modifications
+ * to that data.
+ * Other implementations may operate better if they can store the
+ * data in locations other than a Java array.
+ * To maintain optimum compatibility with various optimizations
+ * it is best to avoid constructors and methods which expose the
+ * underlying storage as a Java array as noted below in the
+ * documentation for those methods.
+ * </a>
+ */
+public final class DataBufferInt extends DataBuffer
+{
+    /** The default data bank. */
+    int data[];
+
+    /** All data banks */
+    int bankdata[][];
+
+    /**
+     * Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank
+     * and the specified size.
+     *
+     * @param size The size of the <CODE>DataBuffer</CODE>.
+     */
+    public DataBufferInt(int size) {
+        super(STABLE, TYPE_INT, size);
+        data = new int[size];
+        bankdata = new int[1][];
+        bankdata[0] = data;
+    }
+
+    /**
+     * Constructs an integer-based <CODE>DataBuffer</CODE> with the specified number of
+     * banks, all of which are the specified size.
+     *
+     * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
+     * @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
+     */
+    public DataBufferInt(int size, int numBanks) {
+        super(STABLE, TYPE_INT, size, numBanks);
+        bankdata = new int[numBanks][];
+        for (int i= 0; i < numBanks; i++) {
+            bankdata[i] = new int[size];
+        }
+        data = bankdata[0];
+    }
+
+    /**
+     * Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank using the
+     * specified array.
+     * Only the first <CODE>size</CODE> elements should be used by accessors of
+     * this <CODE>DataBuffer</CODE>.  <CODE>dataArray</CODE> must be large enough to
+     * hold <CODE>size</CODE> elements.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The integer array for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the <CODE>DataBuffer</CODE> bank.
+     */
+    public DataBufferInt(int dataArray[], int size) {
+        super(UNTRACKABLE, TYPE_INT, size);
+        data = dataArray;
+        bankdata = new int[1][];
+        bankdata[0] = data;
+    }
+
+    /**
+     * Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank using the
+     * specified array, size, and offset.  <CODE>dataArray</CODE> must have at least
+     * <CODE>offset</CODE> + <CODE>size</CODE> elements.  Only elements <CODE>offset</CODE>
+     * through <CODE>offset</CODE> + <CODE>size</CODE> - 1
+     * should be used by accessors of this <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The integer array for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the <CODE>DataBuffer</CODE> bank.
+     * @param offset The offset into the <CODE>dataArray</CODE>.
+     */
+    public DataBufferInt(int dataArray[], int size, int offset) {
+        super(UNTRACKABLE, TYPE_INT, size, 1, offset);
+        data = dataArray;
+        bankdata = new int[1][];
+        bankdata[0] = data;
+    }
+
+    /**
+     * Constructs an integer-based <CODE>DataBuffer</CODE> with the specified arrays.
+     * The number of banks will be equal to <CODE>dataArray.length</CODE>.
+     * Only the first <CODE>size</CODE> elements of each array should be used by
+     * accessors of this <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The integer arrays for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
+     */
+    public DataBufferInt(int dataArray[][], int size) {
+        super(UNTRACKABLE, TYPE_INT, size, dataArray.length);
+        bankdata = (int [][]) dataArray.clone();
+        data = bankdata[0];
+    }
+
+    /**
+     * Constructs an integer-based <CODE>DataBuffer</CODE> with the specified arrays, size,
+     * and offsets.
+     * The number of banks is equal to <CODE>dataArray.length</CODE>.  Each array must
+     * be at least as large as <CODE>size</CODE> + the corresponding offset.   There must
+     * be an entry in the offset array for each <CODE>dataArray</CODE> entry.  For each
+     * bank, only elements <CODE>offset</CODE> through
+     * <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
+     * used by accessors of this <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The integer arrays for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
+     * @param offsets The offsets into each array.
+     */
+    public DataBufferInt(int dataArray[][], int size, int offsets[]) {
+        super(UNTRACKABLE, TYPE_INT, size, dataArray.length, offsets);
+        bankdata = (int [][]) dataArray.clone();
+        data = bankdata[0];
+    }
+
+    /**
+     * Returns the default (first) int data array in <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that calling this method may cause this {@code DataBuffer}
+     * object to be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @return The first integer data array.
+     */
+    public int[] getData() {
+        theTrackable.setUntrackable();
+        return data;
+    }
+
+    /**
+     * Returns the data array for the specified bank.
+     * <p>
+     * Note that calling this method may cause this {@code DataBuffer}
+     * object to be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param bank The bank whose data array you want to get.
+     * @return The data array for the specified bank.
+     */
+    public int[] getData(int bank) {
+        theTrackable.setUntrackable();
+        return bankdata[bank];
+    }
+
+    /**
+     * Returns the data arrays for all banks.
+     * <p>
+     * Note that calling this method may cause this {@code DataBuffer}
+     * object to be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @return All of the data arrays.
+     */
+    public int[][] getBankData() {
+        theTrackable.setUntrackable();
+        return (int [][]) bankdata.clone();
+    }
+
+    /**
+     * Returns the requested data array element from the first (default) bank.
+     *
+     * @param i The data array element you want to get.
+     * @return The requested data array element as an integer.
+     * @see #setElem(int, int)
+     * @see #setElem(int, int, int)
+     */
+    public int getElem(int i) {
+        return data[i+offset];
+    }
+
+    /**
+     * Returns the requested data array element from the specified bank.
+     *
+     * @param bank The bank from which you want to get a data array element.
+     * @param i The data array element you want to get.
+     * @return The requested data array element as an integer.
+     * @see #setElem(int, int)
+     * @see #setElem(int, int, int)
+     */
+    public int getElem(int bank, int i) {
+        return bankdata[bank][i+offsets[bank]];
+    }
+
+    /**
+     * Sets the requested data array element in the first (default) bank
+     * to the specified value.
+     *
+     * @param i The data array element you want to set.
+     * @param val The integer value to which you want to set the data array element.
+     * @see #getElem(int)
+     * @see #getElem(int, int)
+     */
+    public void setElem(int i, int val) {
+        data[i+offset] = val;
+        theTrackable.markDirty();
+    }
+
+    /**
+     * Sets the requested data array element in the specified bank
+     * to the integer value <CODE>i</CODE>.
+     * @param bank The bank in which you want to set the data array element.
+     * @param i The data array element you want to set.
+     * @param val The integer value to which you want to set the specified data array element.
+     * @see #getElem(int)
+     * @see #getElem(int, int)
+     */
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i+offsets[bank]] = (int)val;
+        theTrackable.markDirty();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/DataBufferShort.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,283 @@
+/*
+ * Portions Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+
+import static sun.java2d.StateTrackable.State.*;
+
+/**
+ * This class extends <CODE>DataBuffer</CODE> and stores data internally as shorts.
+ * <p>
+ * <a name="optimizations">
+ * Note that some implementations may function more efficiently
+ * if they can maintain control over how the data for an image is
+ * stored.
+ * For example, optimizations such as caching an image in video
+ * memory require that the implementation track all modifications
+ * to that data.
+ * Other implementations may operate better if they can store the
+ * data in locations other than a Java array.
+ * To maintain optimum compatibility with various optimizations
+ * it is best to avoid constructors and methods which expose the
+ * underlying storage as a Java array as noted below in the
+ * documentation for those methods.
+ * </a>
+ */
+public final class DataBufferShort extends DataBuffer
+{
+    /** The default data bank. */
+    short data[];
+
+    /** All data banks */
+    short bankdata[][];
+
+    /**
+     * Constructs a short-based <CODE>DataBuffer</CODE> with a single bank and the
+     * specified size.
+     *
+     * @param size The size of the <CODE>DataBuffer</CODE>.
+     */
+    public DataBufferShort(int size) {
+        super(STABLE, TYPE_SHORT,size);
+        data = new short[size];
+        bankdata = new short[1][];
+        bankdata[0] = data;
+    }
+
+    /**
+     * Constructs a short-based <CODE>DataBuffer</CODE> with the specified number of
+     * banks all of which are the specified size.
+     *
+     * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
+     * @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
+     */
+    public DataBufferShort(int size, int numBanks) {
+        super(STABLE, TYPE_SHORT,size,numBanks);
+        bankdata = new short[numBanks][];
+        for (int i= 0; i < numBanks; i++) {
+            bankdata[i] = new short[size];
+        }
+        data = bankdata[0];
+    }
+
+    /**
+     * Constructs a short-based <CODE>DataBuffer</CODE> with a single bank using the
+     * specified array.
+     * Only the first <CODE>size</CODE> elements should be used by accessors of
+     * this <CODE>DataBuffer</CODE>.  <CODE>dataArray</CODE> must be large enough to
+     * hold <CODE>size</CODE> elements.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The short array for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the <CODE>DataBuffer</CODE> bank.
+     */
+    public DataBufferShort(short dataArray[], int size) {
+        super(UNTRACKABLE, TYPE_SHORT, size);
+        data = dataArray;
+        bankdata = new short[1][];
+        bankdata[0] = data;
+    }
+
+    /**
+     * Constructs a short-based <CODE>DataBuffer</CODE> with a single bank using the
+     * specified array, size, and offset.  <CODE>dataArray</CODE> must have at least
+     * <CODE>offset</CODE> + <CODE>size</CODE> elements.  Only elements <CODE>offset</CODE>
+     * through <CODE>offset</CODE> + <CODE>size</CODE> - 1
+     * should be used by accessors of this <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The short array for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the <CODE>DataBuffer</CODE> bank.
+     * @param offset The offset into the <CODE>dataArray</CODE>.
+     */
+    public DataBufferShort(short dataArray[], int size, int offset) {
+        super(UNTRACKABLE, TYPE_SHORT, size, 1, offset);
+        data = dataArray;
+        bankdata = new short[1][];
+        bankdata[0] = data;
+    }
+
+    /**
+     * Constructs a short-based <CODE>DataBuffer</CODE> with the specified arrays.
+     * The number of banks will be equal to <CODE>dataArray.length</CODE>.
+     * Only the first <CODE>size</CODE> elements of each array should be used by
+     * accessors of this <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The short arrays for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
+     */
+    public DataBufferShort(short dataArray[][], int size) {
+        super(UNTRACKABLE, TYPE_SHORT, size, dataArray.length);
+        bankdata = (short[][]) dataArray.clone();
+        data = bankdata[0];
+    }
+
+    /**
+     * Constructs a short-based <CODE>DataBuffer</CODE> with the specified arrays, size,
+     * and offsets.
+     * The number of banks is equal to <CODE>dataArray.length</CODE>.  Each array must
+     * be at least as large as <CODE>size</CODE> + the corresponding offset.   There must
+     * be an entry in the offset array for each <CODE>dataArray</CODE> entry.  For each
+     * bank, only elements <CODE>offset</CODE> through
+     * <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
+     * used by accessors of this <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The short arrays for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
+     * @param offsets The offsets into each array.
+     */
+    public DataBufferShort(short dataArray[][], int size, int offsets[]) {
+        super(UNTRACKABLE, TYPE_SHORT, size, dataArray.length, offsets);
+        bankdata = (short[][]) dataArray.clone();
+        data = bankdata[0];
+    }
+
+    /**
+     * Returns the default (first) byte data array.
+     * <p>
+     * Note that calling this method may cause this {@code DataBuffer}
+     * object to be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @return The first short data array.
+     */
+    public short[] getData() {
+        theTrackable.setUntrackable();
+        return data;
+    }
+
+    /**
+     * Returns the data array for the specified bank.
+     * <p>
+     * Note that calling this method may cause this {@code DataBuffer}
+     * object to be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param bank The bank whose data array you want to get.
+     * @return The data array for the specified bank.
+     */
+    public short[] getData(int bank) {
+        theTrackable.setUntrackable();
+        return bankdata[bank];
+    }
+
+    /**
+     * Returns the data arrays for all banks.
+     * <p>
+     * Note that calling this method may cause this {@code DataBuffer}
+     * object to be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @return All of the data arrays.
+     */
+    public short[][] getBankData() {
+        theTrackable.setUntrackable();
+        return (short[][]) bankdata.clone();
+    }
+
+    /**
+     * Returns the requested data array element from the first (default) bank.
+     *
+     * @param i The data array element you want to get.
+     * @return The requested data array element as an integer.
+     * @see #setElem(int, int)
+     * @see #setElem(int, int, int)
+     */
+    public int getElem(int i) {
+        return (int)(data[i+offset]);
+    }
+
+    /**
+     * Returns the requested data array element from the specified bank.
+     *
+     * @param bank The bank from which you want to get a data array element.
+     * @param i The data array element you want to get.
+     * @return The requested data array element as an integer.
+     * @see #setElem(int, int)
+     * @see #setElem(int, int, int)
+     */
+    public int getElem(int bank, int i) {
+        return (int)(bankdata[bank][i+offsets[bank]]);
+    }
+
+    /**
+     * Sets the requested data array element in the first (default) bank
+     * to the specified value.
+     *
+     * @param i The data array element you want to set.
+     * @param val The integer value to which you want to set the data array element.
+     * @see #getElem(int)
+     * @see #getElem(int, int)
+     */
+    public void setElem(int i, int val) {
+        data[i+offset] = (short)val;
+        theTrackable.markDirty();
+    }
+
+    /**
+     * Sets the requested data array element in the specified bank
+     * from the given integer.
+     * @param bank The bank in which you want to set the data array element.
+     * @param i The data array element you want to set.
+     * @param val The integer value to which you want to set the specified data array element.
+     * @see #getElem(int)
+     * @see #getElem(int, int)
+     */
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i+offsets[bank]] = (short)val;
+        theTrackable.markDirty();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/DataBufferUShort.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,318 @@
+/*
+ * Portions Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+
+import static sun.java2d.StateTrackable.State.*;
+
+/**
+ * This class extends <CODE>DataBuffer</CODE> and stores data internally as
+ * shorts.  Values stored in the short array(s) of this <CODE>DataBuffer</CODE>
+ * are treated as unsigned values.
+ * <p>
+ * <a name="optimizations">
+ * Note that some implementations may function more efficiently
+ * if they can maintain control over how the data for an image is
+ * stored.
+ * For example, optimizations such as caching an image in video
+ * memory require that the implementation track all modifications
+ * to that data.
+ * Other implementations may operate better if they can store the
+ * data in locations other than a Java array.
+ * To maintain optimum compatibility with various optimizations
+ * it is best to avoid constructors and methods which expose the
+ * underlying storage as a Java array as noted below in the
+ * documentation for those methods.
+ * </a>
+ */
+public final class DataBufferUShort extends DataBuffer
+{
+    /** The default data bank. */
+    short data[];
+
+    /** All data banks */
+    short bankdata[][];
+
+    /**
+     * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank and the
+     * specified size.
+     *
+     * @param size The size of the <CODE>DataBuffer</CODE>.
+     */
+    public DataBufferUShort(int size) {
+        super(STABLE, TYPE_USHORT, size);
+        data = new short[size];
+        bankdata = new short[1][];
+        bankdata[0] = data;
+    }
+
+    /**
+     * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified number of
+     * banks, all of which are the specified size.
+     *
+     * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
+     * @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
+    */
+    public DataBufferUShort(int size, int numBanks) {
+        super(STABLE, TYPE_USHORT, size, numBanks);
+        bankdata = new short[numBanks][];
+        for (int i= 0; i < numBanks; i++) {
+            bankdata[i] = new short[size];
+        }
+        data = bankdata[0];
+    }
+
+    /**
+     * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
+     * using the specified array.
+     * Only the first <CODE>size</CODE> elements should be used by accessors of
+     * this <CODE>DataBuffer</CODE>.  <CODE>dataArray</CODE> must be large enough to
+     * hold <CODE>size</CODE> elements.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the <CODE>DataBuffer</CODE> bank.
+     */
+    public DataBufferUShort(short dataArray[], int size) {
+        super(UNTRACKABLE, TYPE_USHORT, size);
+        if (dataArray == null) {
+            throw new NullPointerException("dataArray is null");
+        }
+        data = dataArray;
+        bankdata = new short[1][];
+        bankdata[0] = data;
+    }
+
+    /**
+     * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
+     * using the specified array, size, and offset.  <CODE>dataArray</CODE> must have at
+     * least <CODE>offset</CODE> + <CODE>size</CODE> elements.  Only elements
+     * <CODE>offset</CODE> through <CODE>offset</CODE> + <CODE>size</CODE> - 1 should
+     * be used by accessors of this <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the <CODE>DataBuffer</CODE> bank.
+     * @param offset The offset into the <CODE>dataArray</CODE>.
+     */
+    public DataBufferUShort(short dataArray[], int size, int offset) {
+        super(UNTRACKABLE, TYPE_USHORT, size, 1, offset);
+        if (dataArray == null) {
+            throw new NullPointerException("dataArray is null");
+        }
+        if ((size+offset) > dataArray.length) {
+            throw new IllegalArgumentException("Length of dataArray is less "+
+                                               " than size+offset.");
+        }
+        data = dataArray;
+        bankdata = new short[1][];
+        bankdata[0] = data;
+    }
+
+    /**
+     * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified arrays.
+     * The number of banks will be equal to <CODE>dataArray.length</CODE>.
+     * Only the first <CODE>size</CODE> elements of each array should be used by
+     * accessors of this <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
+     */
+    public DataBufferUShort(short dataArray[][], int size) {
+        super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length);
+        if (dataArray == null) {
+            throw new NullPointerException("dataArray is null");
+        }
+        for (int i=0; i < dataArray.length; i++) {
+            if (dataArray[i] == null) {
+                throw new NullPointerException("dataArray["+i+"] is null");
+            }
+        }
+
+        bankdata = (short[][]) dataArray.clone();
+        data = bankdata[0];
+    }
+
+    /**
+     * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with specified arrays,
+     * size, and offsets.
+     * The number of banks is equal to <CODE>dataArray.length</CODE>.  Each array must
+     * be at least as large as <CODE>size</CODE> + the corresponding offset.   There must
+     * be an entry in the offset array for each <CODE>dataArray</CODE> entry.  For each
+     * bank, only elements <CODE>offset</CODE> through
+     * <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
+     * used by accessors of this <CODE>DataBuffer</CODE>.
+     * <p>
+     * Note that {@code DataBuffer} objects created by this constructor
+     * may be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
+     * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
+     * @param offsets The offsets into each array.
+     */
+    public DataBufferUShort(short dataArray[][], int size, int offsets[]) {
+        super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length, offsets);
+        if (dataArray == null) {
+            throw new NullPointerException("dataArray is null");
+        }
+        for (int i=0; i < dataArray.length; i++) {
+            if (dataArray[i] == null) {
+                throw new NullPointerException("dataArray["+i+"] is null");
+            }
+            if ((size+offsets[i]) > dataArray[i].length) {
+                throw new IllegalArgumentException("Length of dataArray["+i+
+                                                   "] is less than size+"+
+                                                   "offsets["+i+"].");
+            }
+
+        }
+        bankdata = (short[][]) dataArray.clone();
+        data = bankdata[0];
+    }
+
+    /**
+     * Returns the default (first) unsigned-short data array.
+     * <p>
+     * Note that calling this method may cause this {@code DataBuffer}
+     * object to be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @return The first unsigned-short data array.
+     */
+    public short[] getData() {
+        theTrackable.setUntrackable();
+        return data;
+    }
+
+    /**
+     * Returns the data array for the specified bank.
+     * <p>
+     * Note that calling this method may cause this {@code DataBuffer}
+     * object to be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @param bank The bank whose data array you want to get.
+     * @return The data array for the specified bank.
+     */
+    public short[] getData(int bank) {
+        theTrackable.setUntrackable();
+        return bankdata[bank];
+    }
+
+    /**
+     * Returns the data arrays for all banks.
+     * <p>
+     * Note that calling this method may cause this {@code DataBuffer}
+     * object to be incompatible with <a href="#optimizations">performance
+     * optimizations</a> used by some implementations (such as caching
+     * an associated image in video memory).
+     *
+     * @return All of the data arrays.
+     */
+    public short[][] getBankData() {
+        theTrackable.setUntrackable();
+        return (short[][]) bankdata.clone();
+    }
+
+    /**
+     * Returns the requested data array element from the first (default) bank.
+     *
+     * @param i The data array element you want to get.
+     * @return The requested data array element as an integer.
+     * @see #setElem(int, int)
+     * @see #setElem(int, int, int)
+     */
+    public int getElem(int i) {
+        return (int)(data[i+offset]&0xffff);
+    }
+
+    /**
+     * Returns the requested data array element from the specified bank.
+     *
+     * @param bank The bank from which you want to get a data array element.
+     * @param i The data array element you want to get.
+     * @return The requested data array element as an integer.
+     * @see #setElem(int, int)
+     * @see #setElem(int, int, int)
+     */
+    public int getElem(int bank, int i) {
+        return (int)(bankdata[bank][i+offsets[bank]]&0xffff);
+    }
+
+    /**
+     * Sets the requested data array element in the first (default) bank
+     * to the specified value.
+     *
+     * @param i The data array element you want to set.
+     * @param val The integer value to which you want to set the data array element.
+     * @see #getElem(int)
+     * @see #getElem(int, int)
+     */
+    public void setElem(int i, int val) {
+        data[i+offset] = (short)(val&0xffff);
+        theTrackable.markDirty();
+    }
+
+    /**
+     * Sets the requested data array element in the specified bank
+     * from the given integer.
+     * @param bank The bank in which you want to set the data array element.
+     * @param i The data array element you want to set.
+     * @param val The integer value to which you want to set the specified data array element.
+     * @see #getElem(int)
+     * @see #getElem(int, int)
+     */
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i+offsets[bank]] = (short)(val&0xffff);
+        theTrackable.markDirty();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/MultiPixelPackedSampleModel.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,699 @@
+/*
+ * Portions Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+
+/**
+ * The <code>MultiPixelPackedSampleModel</code> class represents
+ * one-banded images and can pack multiple one-sample
+ * pixels into one data element.  Pixels are not allowed to span data elements.
+ * The data type can be DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
+ * or DataBuffer.TYPE_INT.  Each pixel must be a power of 2 number of bits
+ * and a power of 2 number of pixels must fit exactly in one data element.
+ * Pixel bit stride is equal to the number of bits per pixel.  Scanline
+ * stride is in data elements and the last several data elements might be
+ * padded with unused pixels.  Data bit offset is the offset in bits from
+ * the beginning of the {@link DataBuffer} to the first pixel and must be
+ * a multiple of pixel bit stride.
+ * <p>
+ * The following code illustrates extracting the bits for pixel
+ * <code>x,&nbsp;y</code> from <code>DataBuffer</code> <code>data</code>
+ * and storing the pixel data in data elements of type
+ * <code>dataType</code>:
+ * <pre>
+ *      int dataElementSize = DataBuffer.getDataTypeSize(dataType);
+ *      int bitnum = dataBitOffset + x*pixelBitStride;
+ *      int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
+ *      int shift = dataElementSize - (bitnum & (dataElementSize-1))
+ *                  - pixelBitStride;
+ *      int pixel = (element >> shift) & ((1 << pixelBitStride) - 1);
+ * </pre>
+ */
+
+public class MultiPixelPackedSampleModel extends SampleModel
+{
+    /** The number of bits from one pixel to the next. */
+    int pixelBitStride;
+
+    /** Bitmask that extracts the rightmost pixel of a data element. */
+    int bitMask;
+
+    /**
+      * The number of pixels that fit in a data element.  Also used
+      * as the number of bits per pixel.
+      */
+    int pixelsPerDataElement;
+
+    /** The size of a data element in bits. */
+    int dataElementSize;
+
+    /** The bit offset into the data array where the first pixel begins.
+     */
+    int dataBitOffset;
+
+    /** ScanlineStride of the data buffer described in data array elements. */
+    int scanlineStride;
+
+    /**
+     * Constructs a <code>MultiPixelPackedSampleModel</code> with the
+     * specified data type, width, height and number of bits per pixel.
+     * @param dataType  the data type for storing samples
+     * @param w         the width, in pixels, of the region of
+     *                  image data described
+     * @param h         the height, in pixels, of the region of
+     *                  image data described
+     * @param numberOfBits the number of bits per pixel
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         either <code>DataBuffer.TYPE_BYTE</code>,
+     *         <code>DataBuffer.TYPE_USHORT</code>, or
+     *         <code>DataBuffer.TYPE_INT</code>
+     */
+    public MultiPixelPackedSampleModel(int dataType,
+                                       int w,
+                                       int h,
+                                       int numberOfBits) {
+        this(dataType,w,h,
+             numberOfBits,
+            (w*numberOfBits+DataBuffer.getDataTypeSize(dataType)-1)/
+                DataBuffer.getDataTypeSize(dataType),
+             0);
+        if (dataType != DataBuffer.TYPE_BYTE &&
+            dataType != DataBuffer.TYPE_USHORT &&
+            dataType != DataBuffer.TYPE_INT) {
+            throw new IllegalArgumentException("Unsupported data type "+
+                                               dataType);
+        }
+    }
+
+    /**
+     * Constructs a <code>MultiPixelPackedSampleModel</code> with
+     * specified data type, width, height, number of bits per pixel,
+     * scanline stride and data bit offset.
+     * @param dataType  the data type for storing samples
+     * @param w         the width, in pixels, of the region of
+     *                  image data described
+     * @param h         the height, in pixels, of the region of
+     *                  image data described
+     * @param numberOfBits the number of bits per pixel
+     * @param scanlineStride the line stride of the image data
+     * @param dataBitOffset the data bit offset for the region of image
+     *                  data described
+     * @exception RasterFormatException if the number of bits per pixel
+     *                  is not a power of 2 or if a power of 2 number of
+     *                  pixels do not fit in one data element.
+     * @throws IllegalArgumentException if <code>w</code> or
+     *         <code>h</code> is not greater than 0
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         either <code>DataBuffer.TYPE_BYTE</code>,
+     *         <code>DataBuffer.TYPE_USHORT</code>, or
+     *         <code>DataBuffer.TYPE_INT</code>
+     */
+    public MultiPixelPackedSampleModel(int dataType, int w, int h,
+                                       int numberOfBits,
+                                       int scanlineStride,
+                                       int dataBitOffset) {
+        super(dataType, w, h, 1);
+        if (dataType != DataBuffer.TYPE_BYTE &&
+            dataType != DataBuffer.TYPE_USHORT &&
+            dataType != DataBuffer.TYPE_INT) {
+            throw new IllegalArgumentException("Unsupported data type "+
+                                               dataType);
+        }
+        this.dataType = dataType;
+        this.pixelBitStride = numberOfBits;
+        this.scanlineStride = scanlineStride;
+        this.dataBitOffset = dataBitOffset;
+        this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
+        this.pixelsPerDataElement = dataElementSize/numberOfBits;
+        if (pixelsPerDataElement*numberOfBits != dataElementSize) {
+           throw new RasterFormatException("MultiPixelPackedSampleModel " +
+                                             "does not allow pixels to " +
+                                             "span data element boundaries");
+        }
+        this.bitMask = (1 << numberOfBits) - 1;
+    }
+
+
+    /**
+     * Creates a new <code>MultiPixelPackedSampleModel</code> with the
+     * specified width and height.  The new
+     * <code>MultiPixelPackedSampleModel</code> has the
+     * same storage data type and number of bits per pixel as this
+     * <code>MultiPixelPackedSampleModel</code>.
+     * @param w the specified width
+     * @param h the specified height
+     * @return a {@link SampleModel} with the specified width and height
+     * and with the same storage data type and number of bits per pixel
+     * as this <code>MultiPixelPackedSampleModel</code>.
+     * @throws IllegalArgumentException if <code>w</code> or
+     *         <code>h</code> is not greater than 0
+     */
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+      SampleModel sampleModel =
+            new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
+      return sampleModel;
+    }
+
+    /**
+     * Creates a <code>DataBuffer</code> that corresponds to this
+     * <code>MultiPixelPackedSampleModel</code>.  The
+     * <code>DataBuffer</code> object's data type and size
+     * is consistent with this <code>MultiPixelPackedSampleModel</code>.
+     * The <code>DataBuffer</code> has a single bank.
+     * @return a <code>DataBuffer</code> with the same data type and
+     * size as this <code>MultiPixelPackedSampleModel</code>.
+     */
+    public DataBuffer createDataBuffer() {
+        DataBuffer dataBuffer = null;
+
+        int size = (int)scanlineStride*height;
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            dataBuffer = new DataBufferByte(size+(dataBitOffset+7)/8);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            dataBuffer = new DataBufferUShort(size+(dataBitOffset+15)/16);
+            break;
+        case DataBuffer.TYPE_INT:
+            dataBuffer = new DataBufferInt(size+(dataBitOffset+31)/32);
+            break;
+        }
+        return dataBuffer;
+    }
+
+    /**
+     * Returns the number of data elements needed to transfer one pixel
+     * via the {@link #getDataElements} and {@link #setDataElements}
+     * methods.  For a <code>MultiPixelPackedSampleModel</code>, this is
+     * one.
+     * @return the number of data elements.
+     */
+    public int getNumDataElements() {
+        return 1;
+    }
+
+    /**
+     * Returns the number of bits per sample for all bands.
+     * @return the number of bits per sample.
+     */
+    public int[] getSampleSize() {
+        int sampleSize[] = {pixelBitStride};
+        return sampleSize;
+    }
+
+    /**
+     * Returns the number of bits per sample for the specified band.
+     * @param band the specified band
+     * @return the number of bits per sample for the specified band.
+     */
+    public int getSampleSize(int band) {
+        return pixelBitStride;
+    }
+
+    /**
+     * Returns the offset of pixel (x,&nbsp;y) in data array elements.
+     * @param x the X coordinate of the specified pixel
+     * @param y the Y coordinate of the specified pixel
+     * @return the offset of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        int offset = y * scanlineStride;
+        offset +=  (x*pixelBitStride+dataBitOffset)/dataElementSize;
+        return offset;
+    }
+
+    /**
+     *  Returns the offset, in bits, into the data element in which it is
+     *  stored for the <code>x</code>th pixel of a scanline.
+     *  This offset is the same for all scanlines.
+     *  @param x the specified pixel
+     *  @return the bit offset of the specified pixel.
+     */
+    public int getBitOffset(int x){
+       return  (x*pixelBitStride+dataBitOffset)%dataElementSize;
+    }
+
+    /**
+     * Returns the scanline stride.
+     * @return the scanline stride of this
+     * <code>MultiPixelPackedSampleModel</code>.
+     */
+    public int getScanlineStride() {
+        return scanlineStride;
+    }
+
+    /**
+     * Returns the pixel bit stride in bits.  This value is the same as
+     * the number of bits per pixel.
+     * @return the <code>pixelBitStride</code> of this
+     * <code>MultiPixelPackedSampleModel</code>.
+     */
+    public int getPixelBitStride() {
+        return pixelBitStride;
+    }
+
+    /**
+     * Returns the data bit offset in bits.
+     * @return the <code>dataBitOffset</code> of this
+     * <code>MultiPixelPackedSampleModel</code>.
+     */
+    public int getDataBitOffset() {
+        return dataBitOffset;
+    }
+
+    /**
+     *  Returns the TransferType used to transfer pixels by way of the
+     *  <code>getDataElements</code> and <code>setDataElements</code>
+     *  methods. The TransferType might or might not be the same as the
+     *  storage DataType.  The TransferType is one of
+     *  DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
+     *  or DataBuffer.TYPE_INT.
+     *  @return the transfertype.
+     */
+    public int getTransferType() {
+        if (pixelBitStride > 16)
+            return DataBuffer.TYPE_INT;
+        else if (pixelBitStride > 8)
+            return DataBuffer.TYPE_USHORT;
+        else
+            return DataBuffer.TYPE_BYTE;
+    }
+
+    /**
+     * Creates a new <code>MultiPixelPackedSampleModel</code> with a
+     * subset of the bands of this
+     * <code>MultiPixelPackedSampleModel</code>.  Since a
+     * <code>MultiPixelPackedSampleModel</code> only has one band, the
+     * bands argument must have a length of one and indicate the zeroth
+     * band.
+     * @param bands the specified bands
+     * @return a new <code>SampleModel</code> with a subset of bands of
+     * this <code>MultiPixelPackedSampleModel</code>.
+     * @exception RasterFormatException if the number of bands requested
+     * is not one.
+     * @throws IllegalArgumentException if <code>w</code> or
+     *         <code>h</code> is not greater than 0
+     */
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands != null) {
+           if (bands.length != 1)
+            throw new RasterFormatException("MultiPixelPackedSampleModel has "
+                                            + "only one band.");
+        }
+        SampleModel sm = createCompatibleSampleModel(width, height);
+        return sm;
+    }
+
+    /**
+     * Returns as <code>int</code> the sample in a specified band for the
+     * pixel located at (x,&nbsp;y).  An
+     * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
+     * coordinates are not in bounds.
+     * @param x         the X coordinate of the specified pixel
+     * @param y         the Y coordinate of the specified pixel
+     * @param b         the band to return, which is assumed to be 0
+     * @param data      the <code>DataBuffer</code> containing the image
+     *                  data
+     * @return the specified band containing the sample of the specified
+     * pixel.
+     * @exception ArrayIndexOutOfBoundException if the specified
+     *          coordinates are not in bounds.
+     * @see #setSample(int, int, int, int, DataBuffer)
+     */
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        // 'b' must be 0
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
+            (b != 0)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int bitnum = dataBitOffset + x*pixelBitStride;
+        int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
+        int shift = dataElementSize - (bitnum & (dataElementSize-1))
+                    - pixelBitStride;
+        return (element >> shift) & bitMask;
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at
+     * (x,&nbsp;y) in the <code>DataBuffer</code> using an
+     * <code>int</code> for input.
+     * An <code>ArrayIndexOutOfBoundsException</code> is thrown if the
+     * coordinates are not in bounds.
+     * @param x the X coordinate of the specified pixel
+     * @param y the Y coordinate of the specified pixel
+     * @param b the band to return, which is assumed to be 0
+     * @param s the input sample as an <code>int</code>
+     * @param data the <code>DataBuffer</code> where image data is stored
+     * @exception ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds.
+     * @see #getSample(int, int, int, DataBuffer)
+     */
+    public void setSample(int x, int y, int b, int s,
+                          DataBuffer data) {
+        // 'b' must be 0
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
+            (b != 0)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int bitnum = dataBitOffset + x * pixelBitStride;
+        int index = y * scanlineStride + (bitnum / dataElementSize);
+        int shift = dataElementSize - (bitnum & (dataElementSize-1))
+                    - pixelBitStride;
+        int element = data.getElem(index);
+        element &= ~(bitMask << shift);
+        element |= (s & bitMask) << shift;
+        data.setElem(index,element);
+    }
+
+    /**
+     * Returns data for a single pixel in a primitive array of type
+     * TransferType.  For a <code>MultiPixelPackedSampleModel</code>,
+     * the array has one element, and the type is the smallest of
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
+     * that can hold a single pixel.  Generally, <code>obj</code>
+     * should be passed in as <code>null</code>, so that the
+     * <code>Object</code> is created automatically and is the
+     * correct primitive data type.
+     * <p>
+     * The following code illustrates transferring data for one pixel from
+     * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
+     * described by <code>MultiPixelPackedSampleModel</code>
+     * <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
+     * whose storage layout is described by
+     * <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
+     * The transfer is generally more efficient than using
+     * <code>getPixel</code> or <code>setPixel</code>.
+     * <pre>
+     *       MultiPixelPackedSampleModel mppsm1, mppsm2;
+     *       DataBufferInt db1, db2;
+     *       mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
+     *                              db1), db2);
+     * </pre>
+     * Using <code>getDataElements</code> or <code>setDataElements</code>
+     * to transfer between two <code>DataBuffer/SampleModel</code> pairs
+     * is legitimate if the <code>SampleModels</code> have the same number
+     * of bands, corresponding bands have the same number of
+     * bits per sample, and the TransferTypes are the same.
+     * <p>
+     * If <code>obj</code> is not <code>null</code>, it should be a
+     * primitive array of type TransferType.  Otherwise, a
+     * <code>ClassCastException</code> is thrown.  An
+     * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
+     * coordinates are not in bounds, or if <code>obj</code> is not
+     * <code>null</code> and is not large enough to hold the pixel data.
+     * @param x the X coordinate of the specified pixel
+     * @param y the Y coordinate of the specified pixel
+     * @param obj a primitive array in which to return the pixel data or
+     *          <code>null</code>.
+     * @param data the <code>DataBuffer</code> containing the image data.
+     * @return an <code>Object</code> containing data for the specified
+     *  pixel.
+     * @exception ClassCastException if <code>obj</code> is not a
+     *  primitive array of type TransferType or is not <code>null</code>
+     * @exception ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if <code>obj</code> is not <code>null</code> or
+     * not large enough to hold the pixel data
+     * @see #setDataElements(int, int, Object, DataBuffer)
+     */
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        int type = getTransferType();
+        int bitnum = dataBitOffset + x*pixelBitStride;
+        int shift = dataElementSize - (bitnum & (dataElementSize-1))
+                    - pixelBitStride;
+        int element = 0;
+
+        switch(type) {
+
+        case DataBuffer.TYPE_BYTE:
+
+            byte[] bdata;
+
+            if (obj == null)
+                bdata = new byte[1];
+            else
+                bdata = (byte[])obj;
+
+            element = data.getElem(y*scanlineStride +
+                                    bitnum/dataElementSize);
+            bdata[0] = (byte)((element >> shift) & bitMask);
+
+            obj = (Object)bdata;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+
+            short[] sdata;
+
+            if (obj == null)
+                sdata = new short[1];
+            else
+                sdata = (short[])obj;
+
+            element = data.getElem(y*scanlineStride +
+                                   bitnum/dataElementSize);
+            sdata[0] = (short)((element >> shift) & bitMask);
+
+            obj = (Object)sdata;
+            break;
+
+        case DataBuffer.TYPE_INT:
+
+            int[] idata;
+
+            if (obj == null)
+                idata = new int[1];
+            else
+                idata = (int[])obj;
+
+            element = data.getElem(y*scanlineStride +
+                                   bitnum/dataElementSize);
+            idata[0] = (element >> shift) & bitMask;
+
+            obj = (Object)idata;
+            break;
+        }
+
+        return obj;
+    }
+
+    /**
+     * Returns the specified single band pixel in the first element
+     * of an <code>int</code> array.
+     * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
+     * coordinates are not in bounds.
+     * @param x the X coordinate of the specified pixel
+     * @param y the Y coordinate of the specified pixel
+     * @param iArray the array containing the pixel to be returned or
+     *  <code>null</code>
+     * @param data the <code>DataBuffer</code> where image data is stored
+     * @return an array containing the specified pixel.
+     * @exception ArrayIndexOutOfBoundsException if the coordinates
+     *  are not in bounds
+     * @see #setPixel(int, int, int[], DataBuffer)
+     */
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int pixels[];
+        if (iArray != null) {
+           pixels = iArray;
+        } else {
+           pixels = new int [numBands];
+        }
+        int bitnum = dataBitOffset + x*pixelBitStride;
+        int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
+        int shift = dataElementSize - (bitnum & (dataElementSize-1))
+                    - pixelBitStride;
+        pixels[0] = (element >> shift) & bitMask;
+        return pixels;
+    }
+
+    /**
+     * Sets the data for a single pixel in the specified
+     * <code>DataBuffer</code> from a primitive array of type
+     * TransferType.  For a <code>MultiPixelPackedSampleModel</code>,
+     * only the first element of the array holds valid data,
+     * and the type must be the smallest of
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
+     * that can hold a single pixel.
+     * <p>
+     * The following code illustrates transferring data for one pixel from
+     * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
+     * described by <code>MultiPixelPackedSampleModel</code>
+     * <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
+     * whose storage layout is described by
+     * <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
+     * The transfer is generally more efficient than using
+     * <code>getPixel</code> or <code>setPixel</code>.
+     * <pre>
+     *       MultiPixelPackedSampleModel mppsm1, mppsm2;
+     *       DataBufferInt db1, db2;
+     *       mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
+     *                              db1), db2);
+     * </pre>
+     * Using <code>getDataElements</code> or <code>setDataElements</code> to
+     * transfer between two <code>DataBuffer/SampleModel</code> pairs is
+     * legitimate if the <code>SampleModel</code> objects have
+     * the same number of bands, corresponding bands have the same number of
+     * bits per sample, and the TransferTypes are the same.
+     * <p>
+     * <code>obj</code> must be a primitive array of type TransferType.
+     * Otherwise, a <code>ClassCastException</code> is thrown.  An
+     * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
+     * coordinates are not in bounds, or if <code>obj</code> is not large
+     * enough to hold the pixel data.
+     * @param x the X coordinate of the pixel location
+     * @param y the Y coordinate of the pixel location
+     * @param obj a primitive array containing pixel data
+     * @param data the <code>DataBuffer</code> containing the image data
+     * @see #getDataElements(int, int, Object, DataBuffer)
+     */
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        int type = getTransferType();
+        int bitnum = dataBitOffset + x * pixelBitStride;
+        int index = y * scanlineStride + (bitnum / dataElementSize);
+        int shift = dataElementSize - (bitnum & (dataElementSize-1))
+                    - pixelBitStride;
+        int element = data.getElem(index);
+        element &= ~(bitMask << shift);
+
+        switch(type) {
+
+        case DataBuffer.TYPE_BYTE:
+
+            byte[] barray = (byte[])obj;
+            element |= ( ((int)(barray[0])&0xff) & bitMask) << shift;
+            data.setElem(index, element);
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+
+            short[] sarray = (short[])obj;
+            element |= ( ((int)(sarray[0])&0xffff) & bitMask) << shift;
+            data.setElem(index, element);
+            break;
+
+        case DataBuffer.TYPE_INT:
+
+            int[] iarray = (int[])obj;
+            element |= (iarray[0] & bitMask) << shift;
+            data.setElem(index, element);
+            break;
+        }
+    }
+
+    /**
+     * Sets a pixel in the <code>DataBuffer</code> using an
+     * <code>int</code> array for input.
+     * <code>ArrayIndexOutOfBoundsException</code> is thrown if
+     * the coordinates are not in bounds.
+     * @param x the X coordinate of the pixel location
+     * @param y the Y coordinate of the pixel location
+     * @param iArray the input pixel in an <code>int</code> array
+     * @param data the <code>DataBuffer</code> containing the image data
+     * @see #getPixel(int, int, int[], DataBuffer)
+     */
+    public void setPixel(int x, int y, int[] iArray, DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int bitnum = dataBitOffset + x * pixelBitStride;
+        int index = y * scanlineStride + (bitnum / dataElementSize);
+        int shift = dataElementSize - (bitnum & (dataElementSize-1))
+                    - pixelBitStride;
+        int element = data.getElem(index);
+        element &= ~(bitMask << shift);
+        element |= (iArray[0] & bitMask) << shift;
+        data.setElem(index,element);
+    }
+
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof MultiPixelPackedSampleModel)) {
+            return false;
+        }
+
+        MultiPixelPackedSampleModel that = (MultiPixelPackedSampleModel)o;
+        return this.width == that.width &&
+            this.height == that.height &&
+            this.numBands == that.numBands &&
+            this.dataType == that.dataType &&
+            this.pixelBitStride == that.pixelBitStride &&
+            this.bitMask == that.bitMask &&
+            this.pixelsPerDataElement == that.pixelsPerDataElement &&
+            this.dataElementSize == that.dataElementSize &&
+            this.dataBitOffset == that.dataBitOffset &&
+            this.scanlineStride == that.scanlineStride;
+    }
+
+    // If we implement equals() we must also implement hashCode
+    public int hashCode() {
+        int hash = 0;
+        hash = width;
+        hash <<= 8;
+        hash ^= height;
+        hash <<= 8;
+        hash ^= numBands;
+        hash <<= 8;
+        hash ^= dataType;
+        hash <<= 8;
+        hash ^= pixelBitStride;
+        hash <<= 8;
+        hash ^= bitMask;
+        hash <<= 8;
+        hash ^= pixelsPerDataElement;
+        hash <<= 8;
+        hash ^= dataElementSize;
+        hash <<= 8;
+        hash ^= dataBitOffset;
+        hash <<= 8;
+        hash ^= scanlineStride;
+        return hash;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/Raster.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,1777 @@
+/*
+ * Portions Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+
+package java.awt.image;
+import java.awt.Rectangle;
+import java.awt.Point;
+
+import sun.awt.image.ByteInterleavedRaster;
+import sun.awt.image.ShortInterleavedRaster;
+import sun.awt.image.IntegerInterleavedRaster;
+import sun.awt.image.ByteBandedRaster;
+import sun.awt.image.ShortBandedRaster;
+import sun.awt.image.BytePackedRaster;
+import sun.awt.image.SunWritableRaster;
+
+/**
+ * A class representing a rectangular array of pixels.  A Raster
+ * encapsulates a DataBuffer that stores the sample values and a
+ * SampleModel that describes how to locate a given sample value in a
+ * DataBuffer.
+ * <p>
+ * A Raster defines values for pixels occupying a particular
+ * rectangular area of the plane, not necessarily including (0, 0).
+ * The rectangle, known as the Raster's bounding rectangle and
+ * available by means of the getBounds method, is defined by minX,
+ * minY, width, and height values.  The minX and minY values define
+ * the coordinate of the upper left corner of the Raster.  References
+ * to pixels outside of the bounding rectangle may result in an
+ * exception being thrown, or may result in references to unintended
+ * elements of the Raster's associated DataBuffer.  It is the user's
+ * responsibility to avoid accessing such pixels.
+ * <p>
+ * A SampleModel describes how samples of a Raster
+ * are stored in the primitive array elements of a DataBuffer.
+ * Samples may be stored one per data element, as in a
+ * PixelInterleavedSampleModel or BandedSampleModel, or packed several to
+ * an element, as in a SinglePixelPackedSampleModel or
+ * MultiPixelPackedSampleModel.  The SampleModel is also
+ * controls whether samples are sign extended, allowing unsigned
+ * data to be stored in signed Java data types such as byte, short, and
+ * int.
+ * <p>
+ * Although a Raster may live anywhere in the plane, a SampleModel
+ * makes use of a simple coordinate system that starts at (0, 0).  A
+ * Raster therefore contains a translation factor that allows pixel
+ * locations to be mapped between the Raster's coordinate system and
+ * that of the SampleModel.  The translation from the SampleModel
+ * coordinate system to that of the Raster may be obtained by the
+ * getSampleModelTranslateX and getSampleModelTranslateY methods.
+ * <p>
+ * A Raster may share a DataBuffer with another Raster either by
+ * explicit construction or by the use of the createChild and
+ * createTranslatedChild methods.  Rasters created by these methods
+ * can return a reference to the Raster they were created from by
+ * means of the getParent method.  For a Raster that was not
+ * constructed by means of a call to createTranslatedChild or
+ * createChild, getParent will return null.
+ * <p>
+ * The createTranslatedChild method returns a new Raster that
+ * shares all of the data of the current Raster, but occupies a
+ * bounding rectangle of the same width and height but with a
+ * different starting point.  For example, if the parent Raster
+ * occupied the region (10, 10) to (100, 100), and the translated
+ * Raster was defined to start at (50, 50), then pixel (20, 20) of the
+ * parent and pixel (60, 60) of the child occupy the same location in
+ * the DataBuffer shared by the two Rasters.  In the first case, (-10,
+ * -10) should be added to a pixel coordinate to obtain the
+ * corresponding SampleModel coordinate, and in the second case (-50,
+ * -50) should be added.
+ * <p>
+ * The translation between a parent and child Raster may be
+ * determined by subtracting the child's sampleModelTranslateX and
+ * sampleModelTranslateY values from those of the parent.
+ * <p>
+ * The createChild method may be used to create a new Raster
+ * occupying only a subset of its parent's bounding rectangle
+ * (with the same or a translated coordinate system) or
+ * with a subset of the bands of its parent.
+ * <p>
+ * All constructors are protected.  The correct way to create a
+ * Raster is to use one of the static create methods defined in this
+ * class.  These methods create instances of Raster that use the
+ * standard Interleaved, Banded, and Packed SampleModels and that may
+ * be processed more efficiently than a Raster created by combining
+ * an externally generated SampleModel and DataBuffer.
+ * @see java.awt.image.DataBuffer
+ * @see java.awt.image.SampleModel
+ * @see java.awt.image.PixelInterleavedSampleModel
+ * @see java.awt.image.BandedSampleModel
+ * @see java.awt.image.SinglePixelPackedSampleModel
+ * @see java.awt.image.MultiPixelPackedSampleModel
+ */
+public class Raster {
+
+    /**
+     * The SampleModel that describes how pixels from this Raster
+     * are stored in the DataBuffer.
+     */
+    protected SampleModel sampleModel;
+
+    /** The DataBuffer that stores the image data. */
+    protected DataBuffer dataBuffer;
+
+    /** The X coordinate of the upper-left pixel of this Raster. */
+    protected int minX;
+
+    /** The Y coordinate of the upper-left pixel of this Raster. */
+    protected int minY;
+
+    /** The width of this Raster. */
+    protected int width;
+
+    /** The height of this Raster. */
+    protected int height;
+
+    /**
+     * The X translation from the coordinate space of the
+     * Raster's SampleModel to that of the Raster.
+     */
+    protected int sampleModelTranslateX;
+
+    /**
+     * The Y translation from the coordinate space of the
+     * Raster's SampleModel to that of the Raster.
+     */
+    protected int sampleModelTranslateY;
+
+    /** The number of bands in the Raster. */
+    protected int numBands;
+
+    /** The number of DataBuffer data elements per pixel. */
+    protected int numDataElements;
+
+    /** The parent of this Raster, or null. */
+    protected Raster parent;
+
+    static private native void initIDs();
+    static {
+        ColorModel.loadLibraries();
+        initIDs();
+    }
+
+    /**
+     * Creates a Raster based on a PixelInterleavedSampleModel with the
+     * specified data type, width, height, and number of bands.
+     *
+     * <p> The upper left corner of the Raster is given by the
+     * location argument.  If location is null, (0, 0) will be used.
+     * The dataType parameter should be one of the enumerated values
+     * defined in the DataBuffer class.
+     *
+     * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
+     * Rasters are not supported.  To create a 1-band Raster of type
+     * <code>DataBuffer.TYPE_INT</code>, use
+     * Raster.createPackedRaster().
+     * <p> The only dataTypes supported currently are TYPE_BYTE
+     * and TYPE_USHORT.
+     * @param dataType  the data type for storing samples
+     * @param w         the width in pixels of the image data
+     * @param h         the height in pixels of the image data
+     * @param bands     the number of bands
+     * @param location  the upper-left corner of the <code>Raster</code>
+     * @return a WritableRaster object with the specified data type,
+     *         width, height and number of bands.
+     * @throws RasterFormatException if <code>w</code> or <code>h</code>
+     *         is less than or equal to zero, or computing either
+     *         <code>location.x + w</code> or
+     *         <code>location.y + h</code> results in integer
+     *         overflow
+     */
+    public static WritableRaster createInterleavedRaster(int dataType,
+                                                         int w, int h,
+                                                         int bands,
+                                                         Point location) {
+        int[] bandOffsets = new int[bands];
+        for (int i = 0; i < bands; i++) {
+            bandOffsets[i] = i;
+        }
+        return createInterleavedRaster(dataType, w, h, w*bands, bands,
+                                       bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster based on a PixelInterleavedSampleModel with the
+     * specified data type, width, height, scanline stride, pixel
+     * stride, and band offsets.  The number of bands is inferred from
+     * bandOffsets.length.
+     *
+     * <p> The upper left corner of the Raster is given by the
+     * location argument.  If location is null, (0, 0) will be used.
+     * The dataType parameter should be one of the enumerated values
+     * defined in the DataBuffer class.
+     *
+     * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
+     * Rasters are not supported.  To create a 1-band Raster of type
+     * <code>DataBuffer.TYPE_INT</code>, use
+     * Raster.createPackedRaster().
+     * <p> The only dataTypes supported currently are TYPE_BYTE
+     * and TYPE_USHORT.
+     * @param dataType  the data type for storing samples
+     * @param w         the width in pixels of the image data
+     * @param h         the height in pixels of the image data
+     * @param scanlineStride the line stride of the image data
+     * @param pixelStride the pixel stride of the image data
+     * @param bandOffsets the offsets of all bands
+     * @param location  the upper-left corner of the <code>Raster</code>
+     * @return a WritableRaster object with the specified data type,
+     *         width, height, scanline stride, pixel stride and band
+     *         offsets.
+     * @throws RasterFormatException if <code>w</code> or <code>h</code>
+     *         is less than or equal to zero, or computing either
+     *         <code>location.x + w</code> or
+     *         <code>location.y + h</code> results in integer
+     *         overflow
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types, which are
+     *         <code>DataBuffer.TYPE_BYTE</code>, or
+     *         <code>DataBuffer.TYPE_USHORT</code>.
+     */
+    public static WritableRaster createInterleavedRaster(int dataType,
+                                                         int w, int h,
+                                                         int scanlineStride,
+                                                         int pixelStride,
+                                                         int bandOffsets[],
+                                                         Point location) {
+        DataBuffer d;
+        int bands = bandOffsets.length;
+
+        int maxBandOff = bandOffsets[0];
+        for (int i=1; i < bands; i++) {
+            if (bandOffsets[i] > maxBandOff) {
+                maxBandOff = bandOffsets[i];
+            }
+        }
+        int size = maxBandOff + scanlineStride*(h-1) + pixelStride*(w-1) + 1;
+        switch(dataType) {
+        case DataBuffer.TYPE_BYTE:
+            d = new DataBufferByte(size);
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            d = new DataBufferUShort(size);
+            break;
+
+        default:
+            throw new IllegalArgumentException("Unsupported data type " +
+                                                dataType);
+        }
+
+        return createInterleavedRaster(d, w, h, scanlineStride,
+                                       pixelStride, bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster based on a BandedSampleModel with the
+     * specified data type, width, height, and number of bands.
+     *
+     * <p> The upper left corner of the Raster is given by the
+     * location argument.  If location is null, (0, 0) will be used.
+     * The dataType parameter should be one of the enumerated values
+     * defined in the DataBuffer class.
+     *
+     * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
+     * and TYPE_INT.
+     * @param dataType  the data type for storing samples
+     * @param w         the width in pixels of the image data
+     * @param h         the height in pixels of the image data
+     * @param bands     the number of bands
+     * @param location  the upper-left corner of the <code>Raster</code>
+     * @return a WritableRaster object with the specified data type,
+     *         width, height and number of bands.
+     * @throws RasterFormatException if <code>w</code> or <code>h</code>
+     *         is less than or equal to zero, or computing either
+     *         <code>location.x + w</code> or
+     *         <code>location.y + h</code> results in integer
+     *         overflow
+     * @throws ArrayIndexOutOfBoundsException if <code>bands</code>
+     *         is less than 1
+     */
+    public static WritableRaster createBandedRaster(int dataType,
+                                                    int w, int h,
+                                                    int bands,
+                                                    Point location) {
+        if (bands < 1) {
+            throw new ArrayIndexOutOfBoundsException("Number of bands ("+
+                                                     bands+") must"+
+                                                     " be greater than 0");
+        }
+        int[] bankIndices = new int[bands];
+        int[] bandOffsets = new int[bands];
+        for (int i = 0; i < bands; i++) {
+            bankIndices[i] = i;
+            bandOffsets[i] = 0;
+        }
+
+        return createBandedRaster(dataType, w, h, w,
+                                  bankIndices, bandOffsets,
+                                  location);
+    }
+
+    /**
+     * Creates a Raster based on a BandedSampleModel with the
+     * specified data type, width, height, scanline stride, bank
+     * indices and band offsets.  The number of bands is inferred from
+     * bankIndices.length and bandOffsets.length, which must be the
+     * same.
+     *
+     * <p> The upper left corner of the Raster is given by the
+     * location argument.  The dataType parameter should be one of the
+     * enumerated values defined in the DataBuffer class.
+     *
+     * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
+     * and TYPE_INT.
+     * @param dataType  the data type for storing samples
+     * @param w         the width in pixels of the image data
+     * @param h         the height in pixels of the image data
+     * @param scanlineStride the line stride of the image data
+     * @param bankIndices the bank indices for each band
+     * @param bandOffsets the offsets of all bands
+     * @param location  the upper-left corner of the <code>Raster</code>
+     * @return a WritableRaster object with the specified data type,
+     *         width, height, scanline stride, bank indices and band
+     *         offsets.
+     * @throws RasterFormatException if <code>w</code> or <code>h</code>
+     *         is less than or equal to zero, or computing either
+     *         <code>location.x + w</code> or
+     *         <code>location.y + h</code> results in integer
+     *         overflow
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types, which are
+     *         <code>DataBuffer.TYPE_BYTE</code>,
+     *         <code>DataBuffer.TYPE_USHORT</code>
+     *         or <code>DataBuffer.TYPE_INT</code>
+     * @throws ArrayIndexOutOfBoundsException if <code>bankIndices</code>
+     *         or <code>bandOffsets</code> is <code>null</code>
+     */
+    public static WritableRaster createBandedRaster(int dataType,
+                                                    int w, int h,
+                                                    int scanlineStride,
+                                                    int bankIndices[],
+                                                    int bandOffsets[],
+                                                    Point location) {
+        DataBuffer d;
+        int bands = bandOffsets.length;
+
+        if (bankIndices == null) {
+            throw new
+                ArrayIndexOutOfBoundsException("Bank indices array is null");
+        }
+        if (bandOffsets == null) {
+            throw new
+                ArrayIndexOutOfBoundsException("Band offsets array is null");
+        }
+
+        // Figure out the #banks and the largest band offset
+        int maxBank = bankIndices[0];
+        int maxBandOff = bandOffsets[0];
+        for (int i = 1; i < bands; i++) {
+            if (bankIndices[i] > maxBank) {
+                maxBank = bankIndices[i];
+            }
+            if (bandOffsets[i] > maxBandOff) {
+                maxBandOff = bandOffsets[i];
+            }
+        }
+        int banks = maxBank + 1;
+        int size = maxBandOff + scanlineStride*(h-1) + (w-1) + 1;
+
+        switch(dataType) {
+        case DataBuffer.TYPE_BYTE:
+            d = new DataBufferByte(size, banks);
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            d = new DataBufferUShort(size, banks);
+            break;
+
+        case DataBuffer.TYPE_INT:
+            d = new DataBufferInt(size, banks);
+            break;
+
+        default:
+            throw new IllegalArgumentException("Unsupported data type " +
+                                                dataType);
+        }
+
+        return createBandedRaster(d, w, h, scanlineStride,
+                                  bankIndices, bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster based on a SinglePixelPackedSampleModel with
+     * the specified data type, width, height, and band masks.
+     * The number of bands is inferred from bandMasks.length.
+     *
+     * <p> The upper left corner of the Raster is given by the
+     * location argument.  If location is null, (0, 0) will be used.
+     * The dataType parameter should be one of the enumerated values
+     * defined in the DataBuffer class.
+     *
+     * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
+     * and TYPE_INT.
+     * @param dataType  the data type for storing samples
+     * @param w         the width in pixels of the image data
+     * @param h         the height in pixels of the image data
+     * @param bandMasks an array containing an entry for each band
+     * @param location  the upper-left corner of the <code>Raster</code>
+     * @return a WritableRaster object with the specified data type,
+     *         width, height, and band masks.
+     * @throws RasterFormatException if <code>w</code> or <code>h</code>
+     *         is less than or equal to zero, or computing either
+     *         <code>location.x + w</code> or
+     *         <code>location.y + h</code> results in integer
+     *         overflow
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types, which are
+     *         <code>DataBuffer.TYPE_BYTE</code>,
+     *         <code>DataBuffer.TYPE_USHORT</code>
+     *         or <code>DataBuffer.TYPE_INT</code>
+     */
+    public static WritableRaster createPackedRaster(int dataType,
+                                                    int w, int h,
+                                                    int bandMasks[],
+                                                    Point location) {
+        DataBuffer d;
+
+        switch(dataType) {
+        case DataBuffer.TYPE_BYTE:
+            d = new DataBufferByte(w*h);
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            d = new DataBufferUShort(w*h);
+            break;
+
+        case DataBuffer.TYPE_INT:
+            d = new DataBufferInt(w*h);
+            break;
+
+        default:
+            throw new IllegalArgumentException("Unsupported data type " +
+                                                dataType);
+        }
+
+        return createPackedRaster(d, w, h, w, bandMasks, location);
+    }
+
+    /**
+     * Creates a Raster based on a packed SampleModel with the
+     * specified data type, width, height, number of bands, and bits
+     * per band.  If the number of bands is one, the SampleModel will
+     * be a MultiPixelPackedSampleModel.
+     *
+     * <p> If the number of bands is more than one, the SampleModel
+     * will be a SinglePixelPackedSampleModel, with each band having
+     * bitsPerBand bits.  In either case, the requirements on dataType
+     * and bitsPerBand imposed by the corresponding SampleModel must
+     * be met.
+     *
+     * <p> The upper left corner of the Raster is given by the
+     * location argument.  If location is null, (0, 0) will be used.
+     * The dataType parameter should be one of the enumerated values
+     * defined in the DataBuffer class.
+     *
+     * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
+     * and TYPE_INT.
+     * @param dataType  the data type for storing samples
+     * @param w         the width in pixels of the image data
+     * @param h         the height in pixels of the image data
+     * @param bands     the number of bands
+     * @param bitsPerBand the number of bits per band
+     * @param location  the upper-left corner of the <code>Raster</code>
+     * @return a WritableRaster object with the specified data type,
+     *         width, height, number of bands, and bits per band.
+     * @throws RasterFormatException if <code>w</code> or <code>h</code>
+     *         is less than or equal to zero, or computing either
+     *         <code>location.x + w</code> or
+     *         <code>location.y + h</code> results in integer
+     *         overflow
+     * @throws IllegalArgumentException if the product of
+     *         <code>bitsPerBand</code> and <code>bands</code> is
+     *         greater than the number of bits held by
+     *         <code>dataType</code>
+     * @throws IllegalArgumentException if <code>bitsPerBand</code> or
+     *         <code>bands</code> is not greater than zero
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types, which are
+     *         <code>DataBuffer.TYPE_BYTE</code>,
+     *         <code>DataBuffer.TYPE_USHORT</code>
+     *         or <code>DataBuffer.TYPE_INT</code>
+     */
+    public static WritableRaster createPackedRaster(int dataType,
+                                                    int w, int h,
+                                                    int bands,
+                                                    int bitsPerBand,
+                                                    Point location) {
+        DataBuffer d;
+
+        if (bands <= 0) {
+            throw new IllegalArgumentException("Number of bands ("+bands+
+                                               ") must be greater than 0");
+        }
+
+        if (bitsPerBand <= 0) {
+            throw new IllegalArgumentException("Bits per band ("+bitsPerBand+
+                                               ") must be greater than 0");
+        }
+
+        if (bands != 1) {
+            int[] masks = new int[bands];
+            int mask = (1 << bitsPerBand) - 1;
+            int shift = (bands-1)*bitsPerBand;
+
+            /* Make sure the total mask size will fit in the data type */
+            if (shift+bitsPerBand > DataBuffer.getDataTypeSize(dataType)) {
+                throw new IllegalArgumentException("bitsPerBand("+
+                                                   bitsPerBand+") * bands is "+
+                                                   " greater than data type "+
+                                                   "size.");
+            }
+            switch(dataType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                break;
+            default:
+                throw new IllegalArgumentException("Unsupported data type " +
+                                                    dataType);
+            }
+
+            for (int i = 0; i < bands; i++) {
+                masks[i] = mask << shift;
+                shift = shift - bitsPerBand;
+            }
+
+            return createPackedRaster(dataType, w, h, masks, location);
+        }
+        else {
+            double fw = w;
+            switch(dataType) {
+            case DataBuffer.TYPE_BYTE:
+                d = new DataBufferByte((int)(Math.ceil(fw/(8/bitsPerBand)))*h);
+                break;
+
+            case DataBuffer.TYPE_USHORT:
+                d = new DataBufferUShort((int)(Math.ceil(fw/(16/bitsPerBand)))*h);
+                break;
+
+            case DataBuffer.TYPE_INT:
+                d = new DataBufferInt((int)(Math.ceil(fw/(32/bitsPerBand)))*h);
+                break;
+
+            default:
+                throw new IllegalArgumentException("Unsupported data type " +
+                                                   dataType);
+            }
+
+            return createPackedRaster(d, w, h, bitsPerBand, location);
+        }
+    }
+
+    /**
+     * Creates a Raster based on a PixelInterleavedSampleModel with the
+     * specified DataBuffer, width, height, scanline stride, pixel
+     * stride, and band offsets.  The number of bands is inferred from
+     * bandOffsets.length.  The upper left corner of the Raster
+     * is given by the location argument.  If location is null, (0, 0)
+     * will be used.
+     * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
+     * Rasters are not supported.  To create a 1-band Raster of type
+     * <code>DataBuffer.TYPE_INT</code>, use
+     * Raster.createPackedRaster().
+     * @param dataBuffer the <code>DataBuffer</code> that contains the
+     *        image data
+     * @param w         the width in pixels of the image data
+     * @param h         the height in pixels of the image data
+     * @param scanlineStride the line stride of the image data
+     * @param pixelStride the pixel stride of the image data
+     * @param bandOffsets the offsets of all bands
+     * @param location  the upper-left corner of the <code>Raster</code>
+     * @return a WritableRaster object with the specified
+     *         <code>DataBuffer</code>, width, height, scanline stride,
+     *         pixel stride and band offsets.
+     * @throws RasterFormatException if <code>w</code> or <code>h</code>
+     *         is less than or equal to zero, or computing either
+     *         <code>location.x + w</code> or
+     *         <code>location.y + h</code> results in integer
+     *         overflow
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types, which are
+     *         <code>DataBuffer.TYPE_BYTE</code>,
+     *         <code>DataBuffer.TYPE_USHORT</code>
+     * @throws RasterFormatException if <code>dataBuffer</code> has more
+     *         than one bank.
+     * @throws NullPointerException if <code>dataBuffer</code> is null
+     */
+    public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer,
+                                                         int w, int h,
+                                                         int scanlineStride,
+                                                         int pixelStride,
+                                                         int bandOffsets[],
+                                                         Point location) {
+        if (dataBuffer == null) {
+            throw new NullPointerException("DataBuffer cannot be null");
+        }
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+        int dataType = dataBuffer.getDataType();
+
+        PixelInterleavedSampleModel csm =
+            new PixelInterleavedSampleModel(dataType, w, h,
+                                            pixelStride,
+                                            scanlineStride,
+                                            bandOffsets);
+        switch(dataType) {
+        case DataBuffer.TYPE_BYTE:
+            return new ByteInterleavedRaster(csm, dataBuffer, location);
+
+        case DataBuffer.TYPE_USHORT:
+            return new ShortInterleavedRaster(csm, dataBuffer, location);
+
+        default:
+            throw new IllegalArgumentException("Unsupported data type " +
+                                                dataType);
+        }
+    }
+
+    /**
+     * Creates a Raster based on a BandedSampleModel with the
+     * specified DataBuffer, width, height, scanline stride, bank
+     * indices, and band offsets.  The number of bands is inferred
+     * from bankIndices.length and bandOffsets.length, which must be
+     * the same.  The upper left corner of the Raster is given by the
+     * location argument.  If location is null, (0, 0) will be used.
+     * @param dataBuffer the <code>DataBuffer</code> that contains the
+     *        image data
+     * @param w         the width in pixels of the image data
+     * @param h         the height in pixels of the image data
+     * @param scanlineStride the line stride of the image data
+     * @param bankIndices the bank indices for each band
+     * @param bandOffsets the offsets of all bands
+     * @param location  the upper-left corner of the <code>Raster</code>
+     * @return a WritableRaster object with the specified
+     *         <code>DataBuffer</code>, width, height, scanline stride,
+     *         bank indices and band offsets.
+     * @throws RasterFormatException if <code>w</code> or <code>h</code>
+     *         is less than or equal to zero, or computing either
+     *         <code>location.x + w</code> or
+     *         <code>location.y + h</code> results in integer
+     *         overflow
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types, which are
+     *         <code>DataBuffer.TYPE_BYTE</code>,
+     *         <code>DataBuffer.TYPE_USHORT</code>
+     *         or <code>DataBuffer.TYPE_INT</code>
+     * @throws NullPointerException if <code>dataBuffer</code> is null
+     */
+    public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
+                                                    int w, int h,
+                                                    int scanlineStride,
+                                                    int bankIndices[],
+                                                    int bandOffsets[],
+                                                    Point location) {
+        if (dataBuffer == null) {
+            throw new NullPointerException("DataBuffer cannot be null");
+        }
+        if (location == null) {
+           location = new Point(0,0);
+        }
+        int dataType = dataBuffer.getDataType();
+
+        int bands = bankIndices.length;
+        if (bandOffsets.length != bands) {
+            throw new IllegalArgumentException(
+                                   "bankIndices.length != bandOffsets.length");
+        }
+
+        BandedSampleModel bsm =
+            new BandedSampleModel(dataType, w, h,
+                                  scanlineStride,
+                                  bankIndices, bandOffsets);
+
+        switch(dataType) {
+        case DataBuffer.TYPE_BYTE:
+            return new ByteBandedRaster(bsm, dataBuffer, location);
+
+        case DataBuffer.TYPE_USHORT:
+            return new ShortBandedRaster(bsm, dataBuffer, location);
+
+        case DataBuffer.TYPE_INT:
+            return new SunWritableRaster(bsm, dataBuffer, location);
+
+        default:
+            throw new IllegalArgumentException("Unsupported data type " +
+                                                dataType);
+        }
+    }
+
+    /**
+     * Creates a Raster based on a SinglePixelPackedSampleModel with
+     * the specified DataBuffer, width, height, scanline stride, and
+     * band masks.  The number of bands is inferred from bandMasks.length.
+     * The upper left corner of the Raster is given by
+     * the location argument.  If location is null, (0, 0) will be used.
+     * @param dataBuffer the <code>DataBuffer</code> that contains the
+     *        image data
+     * @param w         the width in pixels of the image data
+     * @param h         the height in pixels of the image data
+     * @param scanlineStride the line stride of the image data
+     * @param bandMasks an array containing an entry for each band
+     * @param location  the upper-left corner of the <code>Raster</code>
+     * @return a WritableRaster object with the specified
+     *         <code>DataBuffer</code>, width, height, scanline stride,
+     *         and band masks.
+     * @throws RasterFormatException if <code>w</code> or <code>h</code>
+     *         is less than or equal to zero, or computing either
+     *         <code>location.x + w</code> or
+     *         <code>location.y + h</code> results in integer
+     *         overflow
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types, which are
+     *         <code>DataBuffer.TYPE_BYTE</code>,
+     *         <code>DataBuffer.TYPE_USHORT</code>
+     *         or <code>DataBuffer.TYPE_INT</code>
+     * @throws RasterFormatException if <code>dataBuffer</code> has more
+     *         than one bank.
+     * @throws NullPointerException if <code>dataBuffer</code> is null
+     */
+    public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
+                                                    int w, int h,
+                                                    int scanlineStride,
+                                                    int bandMasks[],
+                                                    Point location) {
+        if (dataBuffer == null) {
+            throw new NullPointerException("DataBuffer cannot be null");
+        }
+        if (location == null) {
+           location = new Point(0,0);
+        }
+        int dataType = dataBuffer.getDataType();
+
+        SinglePixelPackedSampleModel sppsm =
+            new SinglePixelPackedSampleModel(dataType, w, h, scanlineStride,
+                                             bandMasks);
+
+        switch(dataType) {
+        case DataBuffer.TYPE_BYTE:
+            return new ByteInterleavedRaster(sppsm, dataBuffer, location);
+
+        case DataBuffer.TYPE_USHORT:
+            return new ShortInterleavedRaster(sppsm, dataBuffer, location);
+
+        case DataBuffer.TYPE_INT:
+            return new IntegerInterleavedRaster(sppsm, dataBuffer, location);
+
+        default:
+            throw new IllegalArgumentException("Unsupported data type " +
+                                                dataType);
+        }
+    }
+
+    /**
+     * Creates a Raster based on a MultiPixelPackedSampleModel with the
+     * specified DataBuffer, width, height, and bits per pixel.  The upper
+     * left corner of the Raster is given by the location argument.  If
+     * location is null, (0, 0) will be used.
+     * @param dataBuffer the <code>DataBuffer</code> that contains the
+     *        image data
+     * @param w         the width in pixels of the image data
+     * @param h         the height in pixels of the image data
+     * @param bitsPerPixel the number of bits for each pixel
+     * @param location  the upper-left corner of the <code>Raster</code>
+     * @return a WritableRaster object with the specified
+     *         <code>DataBuffer</code>, width, height, and
+     *         bits per pixel.
+     * @throws RasterFormatException if <code>w</code> or <code>h</code>
+     *         is less than or equal to zero, or computing either
+     *         <code>location.x + w</code> or
+     *         <code>location.y + h</code> results in integer
+     *         overflow
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types, which are
+     *         <code>DataBuffer.TYPE_BYTE</code>,
+     *         <code>DataBuffer.TYPE_USHORT</code>
+     *         or <code>DataBuffer.TYPE_INT</code>
+     * @throws RasterFormatException if <code>dataBuffer</code> has more
+     *         than one bank.
+     * @throws NullPointerException if <code>dataBuffer</code> is null
+     */
+    public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
+                                                    int w, int h,
+                                                    int bitsPerPixel,
+                                                    Point location) {
+        if (dataBuffer == null) {
+            throw new NullPointerException("DataBuffer cannot be null");
+        }
+        if (location == null) {
+           location = new Point(0,0);
+        }
+        int dataType = dataBuffer.getDataType();
+
+        if (dataType != DataBuffer.TYPE_BYTE &&
+            dataType != DataBuffer.TYPE_USHORT &&
+            dataType != DataBuffer.TYPE_INT) {
+            throw new IllegalArgumentException("Unsupported data type " +
+                                               dataType);
+        }
+
+        if (dataBuffer.getNumBanks() != 1) {
+            throw new
+                RasterFormatException("DataBuffer for packed Rasters"+
+                                      " must only have 1 bank.");
+        }
+
+        MultiPixelPackedSampleModel mppsm =
+                new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel);
+
+        if (dataType == DataBuffer.TYPE_BYTE &&
+            (bitsPerPixel == 1 || bitsPerPixel == 2 || bitsPerPixel == 4)) {
+            return new BytePackedRaster(mppsm, dataBuffer, location);
+        } else {
+            return new SunWritableRaster(mppsm, dataBuffer, location);
+        }
+    }
+
+
+    /**
+     *  Creates a Raster with the specified SampleModel and DataBuffer.
+     *  The upper left corner of the Raster is given by the location argument.
+     *  If location is null, (0, 0) will be used.
+     *  @param sm the specified <code>SampleModel</code>
+     *  @param db the specified <code>DataBuffer</code>
+     *  @param location the upper-left corner of the <code>Raster</code>
+     *  @return a <code>Raster</code> with the specified
+     *          <code>SampleModel</code>, <code>DataBuffer</code>, and
+     *          location.
+     * @throws RasterFormatException if computing either
+     *         <code>location.x + sm.getWidth()</code> or
+     *         <code>location.y + sm.getHeight()</code> results in integer
+     *         overflow
+     * @throws RasterFormatException if <code>db</code> has more
+     *         than one bank and <code>sm</code> is a
+     *         PixelInterleavedSampleModel, SinglePixelPackedSampleModel,
+     *         or MultiPixelPackedSampleModel.
+     *  @throws NullPointerException if either SampleModel or DataBuffer is
+     *          null
+     */
+    public static Raster createRaster(SampleModel sm,
+                                      DataBuffer db,
+                                      Point location) {
+        if ((sm == null) || (db == null)) {
+            throw new NullPointerException("SampleModel and DataBuffer cannot be null");
+        }
+
+        if (location == null) {
+           location = new Point(0,0);
+        }
+        int dataType = sm.getDataType();
+
+        if (sm instanceof PixelInterleavedSampleModel) {
+            switch(dataType) {
+                case DataBuffer.TYPE_BYTE:
+                    return new ByteInterleavedRaster(sm, db, location);
+
+                case DataBuffer.TYPE_USHORT:
+                    return new ShortInterleavedRaster(sm, db, location);
+            }
+        } else if (sm instanceof SinglePixelPackedSampleModel) {
+            switch(dataType) {
+                case DataBuffer.TYPE_BYTE:
+                    return new ByteInterleavedRaster(sm, db, location);
+
+                case DataBuffer.TYPE_USHORT:
+                    return new ShortInterleavedRaster(sm, db, location);
+
+                case DataBuffer.TYPE_INT:
+                    return new IntegerInterleavedRaster(sm, db, location);
+            }
+        } else if (sm instanceof MultiPixelPackedSampleModel &&
+                   dataType == DataBuffer.TYPE_BYTE &&
+                   sm.getSampleSize(0) < 8) {
+            return new BytePackedRaster(sm, db, location);
+        }
+
+        // we couldn't do anything special - do the generic thing
+
+        return new Raster(sm,db,location);
+    }
+
+    /**
+     *  Creates a WritableRaster with the specified SampleModel.
+     *  The upper left corner of the Raster is given by the location argument.
+     *  If location is null, (0, 0) will be used.
+     *  @param sm the specified <code>SampleModel</code>
+     *  @param location the upper-left corner of the
+     *         <code>WritableRaster</code>
+     *  @return a <code>WritableRaster</code> with the specified
+     *          <code>SampleModel</code> and location.
+     *  @throws RasterFormatException if computing either
+     *          <code>location.x + sm.getWidth()</code> or
+     *          <code>location.y + sm.getHeight()</code> results in integer
+     *          overflow
+     */
+    public static WritableRaster createWritableRaster(SampleModel sm,
+                                                      Point location) {
+        if (location == null) {
+           location = new Point(0,0);
+        }
+
+        return createWritableRaster(sm, sm.createDataBuffer(), location);
+    }
+
+    /**
+     *  Creates a WritableRaster with the specified SampleModel and DataBuffer.
+     *  The upper left corner of the Raster is given by the location argument.
+     *  If location is null, (0, 0) will be used.
+     *  @param sm the specified <code>SampleModel</code>
+     *  @param db the specified <code>DataBuffer</code>
+     *  @param location the upper-left corner of the
+     *         <code>WritableRaster</code>
+     *  @return a <code>WritableRaster</code> with the specified
+     *          <code>SampleModel</code>, <code>DataBuffer</code>, and
+     *          location.
+     * @throws RasterFormatException if computing either
+     *         <code>location.x + sm.getWidth()</code> or
+     *         <code>location.y + sm.getHeight()</code> results in integer
+     *         overflow
+     * @throws RasterFormatException if <code>db</code> has more
+     *         than one bank and <code>sm</code> is a
+     *         PixelInterleavedSampleModel, SinglePixelPackedSampleModel,
+     *         or MultiPixelPackedSampleModel.
+     * @throws NullPointerException if either SampleModel or DataBuffer is null
+     */
+    public static WritableRaster createWritableRaster(SampleModel sm,
+                                                      DataBuffer db,
+                                                      Point location) {
+        if ((sm == null) || (db == null)) {
+            throw new NullPointerException("SampleModel and DataBuffer cannot be null");
+        }
+        if (location == null) {
+           location = new Point(0,0);
+        }
+
+        int dataType = sm.getDataType();
+
+        if (sm instanceof PixelInterleavedSampleModel) {
+            switch(dataType) {
+                case DataBuffer.TYPE_BYTE:
+                    return new ByteInterleavedRaster(sm, db, location);
+
+                case DataBuffer.TYPE_USHORT:
+                    return new ShortInterleavedRaster(sm, db, location);
+            }
+        } else if (sm instanceof SinglePixelPackedSampleModel) {
+            switch(dataType) {
+                case DataBuffer.TYPE_BYTE:
+                    return new ByteInterleavedRaster(sm, db, location);
+
+                case DataBuffer.TYPE_USHORT:
+                    return new ShortInterleavedRaster(sm, db, location);
+
+                case DataBuffer.TYPE_INT:
+                    return new IntegerInterleavedRaster(sm, db, location);
+            }
+        } else if (sm instanceof MultiPixelPackedSampleModel &&
+                   dataType == DataBuffer.TYPE_BYTE &&
+                   sm.getSampleSize(0) < 8) {
+            return new BytePackedRaster(sm, db, location);
+        }
+
+        // we couldn't do anything special - do the generic thing
+
+        return new SunWritableRaster(sm,db,location);
+    }
+
+    /**
+     *  Constructs a Raster with the given SampleModel.  The Raster's
+     *  upper left corner is origin and it is the same size as the
+     *  SampleModel.  A DataBuffer large enough to describe the
+     *  Raster is automatically created.
+     *  @param sampleModel     The SampleModel that specifies the layout
+     *  @param origin          The Point that specified the origin
+     *  @throws RasterFormatException if computing either
+     *          <code>origin.x + sampleModel.getWidth()</code> or
+     *          <code>origin.y + sampleModel.getHeight()</code> results in
+     *          integer overflow
+     *  @throws NullPointerException either <code>sampleModel</code> or
+     *          <code>origin</code> is null
+     */
+    protected Raster(SampleModel sampleModel,
+                     Point origin) {
+        this(sampleModel,
+             sampleModel.createDataBuffer(),
+             new Rectangle(origin.x,
+                           origin.y,
+                           sampleModel.getWidth(),
+                           sampleModel.getHeight()),
+             origin,
+             null);
+    }
+
+    /**
+     *  Constructs a Raster with the given SampleModel and DataBuffer.
+     *  The Raster's upper left corner is origin and it is the same size
+     *  as the SampleModel.  The DataBuffer is not initialized and must
+     *  be compatible with SampleModel.
+     *  @param sampleModel     The SampleModel that specifies the layout
+     *  @param dataBuffer      The DataBuffer that contains the image data
+     *  @param origin          The Point that specifies the origin
+     *  @throws RasterFormatException if computing either
+     *          <code>origin.x + sampleModel.getWidth()</code> or
+     *          <code>origin.y + sampleModel.getHeight()</code> results in
+     *          integer overflow
+     *  @throws NullPointerException either <code>sampleModel</code> or
+     *          <code>origin</code> is null
+     */
+    protected Raster(SampleModel sampleModel,
+                     DataBuffer dataBuffer,
+                     Point origin) {
+        this(sampleModel,
+             dataBuffer,
+             new Rectangle(origin.x,
+                           origin.y,
+                           sampleModel.getWidth(),
+                           sampleModel.getHeight()),
+             origin,
+             null);
+    }
+
+    /**
+     * Constructs a Raster with the given SampleModel, DataBuffer, and
+     * parent.  aRegion specifies the bounding rectangle of the new
+     * Raster.  When translated into the base Raster's coordinate
+     * system, aRegion must be contained by the base Raster.
+     * (The base Raster is the Raster's ancestor which has no parent.)
+     * sampleModelTranslate specifies the sampleModelTranslateX and
+     * sampleModelTranslateY values of the new Raster.
+     *
+     * Note that this constructor should generally be called by other
+     * constructors or create methods, it should not be used directly.
+     * @param sampleModel     The SampleModel that specifies the layout
+     * @param dataBuffer      The DataBuffer that contains the image data
+     * @param aRegion         The Rectangle that specifies the image area
+     * @param sampleModelTranslate  The Point that specifies the translation
+     *                        from SampleModel to Raster coordinates
+     * @param parent          The parent (if any) of this raster
+     * @throws NullPointerException if any of <code>sampleModel</code>,
+     *         <code>dataBuffer</code>, <code>aRegion</code> or
+     *         <code>sampleModelTranslate</code> is null
+     * @throws RasterFormatException if <code>aRegion</code> has width
+     *         or height less than or equal to zero, or computing either
+     *         <code>aRegion.x + aRegion.width</code> or
+     *         <code>aRegion.y + aRegion.height</code> results in integer
+     *         overflow
+     */
+    protected Raster(SampleModel sampleModel,
+                     DataBuffer dataBuffer,
+                     Rectangle aRegion,
+                     Point sampleModelTranslate,
+                     Raster parent) {
+
+        if ((sampleModel == null) || (dataBuffer == null) ||
+            (aRegion == null) || (sampleModelTranslate == null)) {
+            throw new NullPointerException("SampleModel, dataBuffer, aRegion and " +
+                                           "sampleModelTranslate cannot be null");
+        }
+       this.sampleModel = sampleModel;
+       this.dataBuffer = dataBuffer;
+       minX = aRegion.x;
+       minY = aRegion.y;
+       width = aRegion.width;
+       height = aRegion.height;
+       if (width <= 0 || height <= 0) {
+           throw new RasterFormatException("negative or zero " +
+               ((width <= 0) ? "width" : "height"));
+       }
+       if ((minX + width) < minX) {
+           throw new RasterFormatException(
+               "overflow condition for X coordinates of Raster");
+       }
+       if ((minY + height) < minY) {
+           throw new RasterFormatException(
+               "overflow condition for Y coordinates of Raster");
+       }
+
+       sampleModelTranslateX = sampleModelTranslate.x;
+       sampleModelTranslateY = sampleModelTranslate.y;
+
+       numBands = sampleModel.getNumBands();
+       numDataElements = sampleModel.getNumDataElements();
+       this.parent = parent;
+    }
+
+
+    /**
+     * Returns the parent Raster (if any) of this Raster or null.
+     * @return the parent Raster or <code>null</code>.
+     */
+    public Raster getParent() {
+        return parent;
+    }
+
+    /**
+     * Returns the X translation from the coordinate system of the
+     * SampleModel to that of the Raster.  To convert a pixel's X
+     * coordinate from the Raster coordinate system to the SampleModel
+     * coordinate system, this value must be subtracted.
+     * @return the X translation from the coordinate space of the
+     *         Raster's SampleModel to that of the Raster.
+     */
+    final public int getSampleModelTranslateX() {
+        return sampleModelTranslateX;
+    }
+
+    /**
+     * Returns the Y translation from the coordinate system of the
+     * SampleModel to that of the Raster.  To convert a pixel's Y
+     * coordinate from the Raster coordinate system to the SampleModel
+     * coordinate system, this value must be subtracted.
+     * @return the Y translation from the coordinate space of the
+     *         Raster's SampleModel to that of the Raster.
+     */
+    final public int getSampleModelTranslateY() {
+        return sampleModelTranslateY;
+    }
+
+    /**
+     * Create a compatible WritableRaster the same size as this Raster with
+     * the same SampleModel and a new initialized DataBuffer.
+     * @return a compatible <code>WritableRaster</code> with the same sample
+     *         model and a new data buffer.
+     */
+    public WritableRaster createCompatibleWritableRaster() {
+        return new SunWritableRaster(sampleModel, new Point(0,0));
+    }
+
+    /**
+     * Create a compatible WritableRaster with the specified size, a new
+     * SampleModel, and a new initialized DataBuffer.
+     * @param w the specified width of the new <code>WritableRaster</code>
+     * @param h the specified height of the new <code>WritableRaster</code>
+     * @return a compatible <code>WritableRaster</code> with the specified
+     *         size and a new sample model and data buffer.
+     * @exception RasterFormatException if the width or height is less than
+     *                               or equal to zero.
+     */
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        if (w <= 0 || h <=0) {
+            throw new RasterFormatException("negative " +
+                                          ((w <= 0) ? "width" : "height"));
+        }
+
+        SampleModel sm = sampleModel.createCompatibleSampleModel(w,h);
+
+        return new SunWritableRaster(sm, new Point(0,0));
+    }
+
+    /**
+     * Create a compatible WritableRaster with location (minX, minY)
+     * and size (width, height) specified by rect, a
+     * new SampleModel, and a new initialized DataBuffer.
+     * @param rect a <code>Rectangle</code> that specifies the size and
+     *        location of the <code>WritableRaster</code>
+     * @return a compatible <code>WritableRaster</code> with the specified
+     *         size and location and a new sample model and data buffer.
+     * @throws RasterFormatException if <code>rect</code> has width
+     *         or height less than or equal to zero, or computing either
+     *         <code>rect.x + rect.width</code> or
+     *         <code>rect.y + rect.height</code> results in integer
+     *         overflow
+     * @throws NullPointerException if <code>rect</code> is null
+     */
+    public WritableRaster createCompatibleWritableRaster(Rectangle rect) {
+        if (rect == null) {
+            throw new NullPointerException("Rect cannot be null");
+        }
+        return createCompatibleWritableRaster(rect.x, rect.y,
+                                              rect.width, rect.height);
+    }
+
+    /**
+     * Create a compatible WritableRaster with the specified
+     * location (minX, minY) and size (width, height), a
+     * new SampleModel, and a new initialized DataBuffer.
+     * @param x the X coordinate of the upper-left corner of
+     *        the <code>WritableRaster</code>
+     * @param y the Y coordinate of the upper-left corner of
+     *        the <code>WritableRaster</code>
+     * @param w the specified width of the <code>WritableRaster</code>
+     * @param h the specified height of the <code>WritableRaster</code>
+     * @return a compatible <code>WritableRaster</code> with the specified
+     *         size and location and a new sample model and data buffer.
+     * @throws RasterFormatException if <code>w</code> or <code>h</code>
+     *         is less than or equal to zero, or computing either
+     *         <code>x + w</code> or
+     *         <code>y + h</code> results in integer
+     *         overflow
+     */
+    public WritableRaster createCompatibleWritableRaster(int x, int y,
+                                                         int w, int h) {
+        WritableRaster ret = createCompatibleWritableRaster(w, h);
+        return ret.createWritableChild(0,0,w,h,x,y,null);
+    }
+
+    /**
+     * Create a Raster with the same size, SampleModel and DataBuffer
+     * as this one, but with a different location.  The new Raster
+     * will possess a reference to the current Raster, accessible
+     * through its getParent() method.
+     *
+     * @param childMinX the X coordinate of the upper-left
+     *        corner of the new <code>Raster</code>
+     * @param childMinY the Y coordinate of the upper-left
+     *        corner of the new <code>Raster</code>
+     * @return a new <code>Raster</code> with the same size, SampleModel,
+     *         and DataBuffer as this <code>Raster</code>, but with the
+     *         specified location.
+     * @throws RasterFormatException if  computing either
+     *         <code>childMinX + this.getWidth()</code> or
+     *         <code>childMinY + this.getHeight()</code> results in integer
+     *         overflow
+     */
+    public Raster createTranslatedChild(int childMinX, int childMinY) {
+        return createChild(minX,minY,width,height,
+                           childMinX,childMinY,null);
+    }
+
+    /**
+     * Returns a new Raster which shares all or part of this Raster's
+     * DataBuffer.  The new Raster will possess a reference to the
+     * current Raster, accessible through its getParent() method.
+     *
+     * <p> The parentX, parentY, width and height parameters
+     * form a Rectangle in this Raster's coordinate space,
+     * indicating the area of pixels to be shared.  An error will
+     * be thrown if this Rectangle is not contained with the bounds
+     * of the current Raster.
+     *
+     * <p> The new Raster may additionally be translated to a
+     * different coordinate system for the plane than that used by the current
+     * Raster.  The childMinX and childMinY parameters give the new
+     * (x, y) coordinate of the upper-left pixel of the returned
+     * Raster; the coordinate (childMinX, childMinY) in the new Raster
+     * will map to the same pixel as the coordinate (parentX, parentY)
+     * in the current Raster.
+     *
+     * <p> The new Raster may be defined to contain only a subset of
+     * the bands of the current Raster, possibly reordered, by means
+     * of the bandList parameter.  If bandList is null, it is taken to
+     * include all of the bands of the current Raster in their current
+     * order.
+     *
+     * <p> To create a new Raster that contains a subregion of the current
+     * Raster, but shares its coordinate system and bands,
+     * this method should be called with childMinX equal to parentX,
+     * childMinY equal to parentY, and bandList equal to null.
+     *
+     * @param parentX The X coordinate of the upper-left corner
+     *        in this Raster's coordinates
+     * @param parentY The Y coordinate of the upper-left corner
+     *        in this Raster's coordinates
+     * @param width      Width of the region starting at (parentX, parentY)
+     * @param height     Height of the region starting at (parentX, parentY).
+     * @param childMinX The X coordinate of the upper-left corner
+     *                   of the returned Raster
+     * @param childMinY The Y coordinate of the upper-left corner
+     *                   of the returned Raster
+     * @param bandList   Array of band indices, or null to use all bands
+     * @return a new <code>Raster</code>.
+     * @exception RasterFormatException if the specified subregion is outside
+     *                               of the raster bounds.
+     * @throws RasterFormatException if <code>width</code> or
+     *         <code>height</code>
+     *         is less than or equal to zero, or computing any of
+     *         <code>parentX + width</code>, <code>parentY + height</code>,
+     *         <code>childMinX + width</code>, or
+     *         <code>childMinY + height</code> results in integer
+     *         overflow
+     */
+    public Raster createChild(int parentX, int parentY,
+                              int width, int height,
+                              int childMinX, int childMinY,
+                              int bandList[]) {
+        if (parentX < this.minX) {
+            throw new RasterFormatException("parentX lies outside raster");
+        }
+        if (parentY < this.minY) {
+            throw new RasterFormatException("parentY lies outside raster");
+        }
+        if ((parentX + width < parentX) ||
+            (parentX + width > this.width + this.minX)) {
+            throw new RasterFormatException("(parentX + width) is outside raster");
+        }
+        if ((parentY + height < parentY) ||
+            (parentY + height > this.height + this.minY)) {
+            throw new RasterFormatException("(parentY + height) is outside raster");
+        }
+
+        SampleModel subSampleModel;
+        // Note: the SampleModel for the child Raster should have the same
+        // width and height as that for the parent, since it represents
+        // the physical layout of the pixel data.  The child Raster's width
+        // and height represent a "virtual" view of the pixel data, so
+        // they may be different than those of the SampleModel.
+        if (bandList == null) {
+            subSampleModel = sampleModel;
+        } else {
+            subSampleModel = sampleModel.createSubsetSampleModel(bandList);
+        }
+
+        int deltaX = childMinX - parentX;
+        int deltaY = childMinY - parentY;
+
+        return new Raster(subSampleModel, getDataBuffer(),
+                          new Rectangle(childMinX, childMinY, width, height),
+                          new Point(sampleModelTranslateX + deltaX,
+                                    sampleModelTranslateY + deltaY), this);
+    }
+
+    /**
+     * Returns the bounding Rectangle of this Raster. This function returns
+     * the same information as getMinX/MinY/Width/Height.
+     * @return the bounding box of this <code>Raster</code>.
+     */
+    public Rectangle getBounds() {
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /** Returns the minimum valid X coordinate of the Raster.
+     *  @return the minimum x coordinate of this <code>Raster</code>.
+     */
+    final public int getMinX() {
+        return minX;
+    }
+
+    /** Returns the minimum valid Y coordinate of the Raster.
+     *  @return the minimum y coordinate of this <code>Raster</code>.
+     */
+    final public int getMinY() {
+        return minY;
+    }
+
+    /** Returns the width in pixels of the Raster.
+     *  @return the width of this <code>Raster</code>.
+     */
+    final public int getWidth() {
+        return width;
+    }
+
+    /** Returns the height in pixels of the Raster.
+     *  @return the height of this <code>Raster</code>.
+     */
+    final public int getHeight() {
+        return height;
+    }
+
+    /** Returns the number of bands (samples per pixel) in this Raster.
+     *  @return the number of bands of this <code>Raster</code>.
+     */
+    final public int getNumBands() {
+        return numBands;
+    }
+
+    /**
+     *  Returns the number of data elements needed to transfer one pixel
+     *  via the getDataElements and setDataElements methods.  When pixels
+     *  are transferred via these methods, they may be transferred in a
+     *  packed or unpacked format, depending on the implementation of the
+     *  underlying SampleModel.  Using these methods, pixels are transferred
+     *  as an array of getNumDataElements() elements of a primitive type given
+     *  by getTransferType().  The TransferType may or may not be the same
+     *  as the storage data type of the DataBuffer.
+     *  @return the number of data elements.
+     */
+    final public int getNumDataElements() {
+        return sampleModel.getNumDataElements();
+    }
+
+    /**
+     *  Returns the TransferType used to transfer pixels via the
+     *  getDataElements and setDataElements methods.  When pixels
+     *  are transferred via these methods, they may be transferred in a
+     *  packed or unpacked format, depending on the implementation of the
+     *  underlying SampleModel.  Using these methods, pixels are transferred
+     *  as an array of getNumDataElements() elements of a primitive type given
+     *  by getTransferType().  The TransferType may or may not be the same
+     *  as the storage data type of the DataBuffer.  The TransferType will
+     *  be one of the types defined in DataBuffer.
+     *  @return this transfer type.
+     */
+    final public int getTransferType() {
+        return sampleModel.getTransferType();
+    }
+
+    /** Returns the DataBuffer associated with this Raster.
+     *  @return the <code>DataBuffer</code> of this <code>Raster</code>.
+     */
+    public DataBuffer getDataBuffer() {
+        return dataBuffer;
+    }
+
+    /** Returns the SampleModel that describes the layout of the image data.
+     *  @return the <code>SampleModel</code> of this <code>Raster</code>.
+     */
+    public SampleModel getSampleModel() {
+        return sampleModel;
+    }
+
+    /**
+     * Returns data for a single pixel in a primitive array of type
+     * TransferType.  For image data supported by the Java 2D(tm) API,
+     * this will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
+     * or DataBuffer.TYPE_DOUBLE.  Data may be returned in a packed format,
+     * thus increasing efficiency for data transfers.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * A ClassCastException will be thrown if the input object is non null
+     * and references anything other than an array of TransferType.
+     * @see java.awt.image.SampleModel#getDataElements(int, int, Object, DataBuffer)
+     * @param x        The X coordinate of the pixel location
+     * @param y        The Y coordinate of the pixel location
+     * @param outData  An object reference to an array of type defined by
+     *                 getTransferType() and length getNumDataElements().
+     *                 If null, an array of appropriate type and size will be
+     *                 allocated
+     * @return         An object reference to an array of type defined by
+     *                 getTransferType() with the requested pixel data.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if outData is too small to hold the output.
+     */
+    public Object getDataElements(int x, int y, Object outData) {
+        return sampleModel.getDataElements(x - sampleModelTranslateX,
+                                           y - sampleModelTranslateY,
+                                           outData, dataBuffer);
+    }
+
+    /**
+     * Returns the pixel data for the specified rectangle of pixels in a
+     * primitive array of type TransferType.
+     * For image data supported by the Java 2D API, this
+     * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
+     * or DataBuffer.TYPE_DOUBLE.  Data may be returned in a packed format,
+     * thus increasing efficiency for data transfers.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * A ClassCastException will be thrown if the input object is non null
+     * and references anything other than an array of TransferType.
+     * @see java.awt.image.SampleModel#getDataElements(int, int, int, int, Object, DataBuffer)
+     * @param x    The X coordinate of the upper-left pixel location
+     * @param y    The Y coordinate of the upper-left pixel location
+     * @param w    Width of the pixel rectangle
+     * @param h   Height of the pixel rectangle
+     * @param outData  An object reference to an array of type defined by
+     *                 getTransferType() and length w*h*getNumDataElements().
+     *                 If null, an array of appropriate type and size will be
+     *                 allocated.
+     * @return         An object reference to an array of type defined by
+     *                 getTransferType() with the requested pixel data.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if outData is too small to hold the output.
+     */
+    public Object getDataElements(int x, int y, int w, int h, Object outData) {
+        return sampleModel.getDataElements(x - sampleModelTranslateX,
+                                           y - sampleModelTranslateY,
+                                           w, h, outData, dataBuffer);
+    }
+
+    /**
+     * Returns the samples in an array of int for the specified pixel.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * @param x The X coordinate of the pixel location
+     * @param y The Y coordinate of the pixel location
+     * @param iArray An optionally preallocated int array
+     * @return the samples for the specified pixel.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if iArray is too small to hold the output.
+     */
+    public int[] getPixel(int x, int y, int iArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX,
+                                    y - sampleModelTranslateY,
+                                    iArray, dataBuffer);
+    }
+
+    /**
+     * Returns the samples in an array of float for the
+     * specified pixel.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * @param x The X coordinate of the pixel location
+     * @param y The Y coordinate of the pixel location
+     * @param fArray An optionally preallocated float array
+     * @return the samples for the specified pixel.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if fArray is too small to hold the output.
+     */
+    public float[] getPixel(int x, int y, float fArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX,
+                                    y - sampleModelTranslateY,
+                                    fArray, dataBuffer);
+    }
+
+    /**
+     * Returns the samples in an array of double for the specified pixel.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * @param x The X coordinate of the pixel location
+     * @param y The Y coordinate of the pixel location
+     * @param dArray An optionally preallocated double array
+     * @return the samples for the specified pixel.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if dArray is too small to hold the output.
+     */
+    public double[] getPixel(int x, int y, double dArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX,
+                                    y - sampleModelTranslateY,
+                                    dArray, dataBuffer);
+    }
+
+    /**
+     * Returns an int array containing all samples for a rectangle of pixels,
+     * one sample per array element.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * @param x      The X coordinate of the upper-left pixel location
+     * @param y      The Y coordinate of the upper-left pixel location
+     * @param w      Width of the pixel rectangle
+     * @param h      Height of the pixel rectangle
+     * @param iArray An optionally pre-allocated int array
+     * @return the samples for the specified rectangle of pixels.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if iArray is too small to hold the output.
+     */
+    public int[] getPixels(int x, int y, int w, int h, int iArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX,
+                                     y - sampleModelTranslateY, w, h,
+                                     iArray, dataBuffer);
+    }
+
+    /**
+     * Returns a float array containing all samples for a rectangle of pixels,
+     * one sample per array element.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * @param x        The X coordinate of the pixel location
+     * @param y        The Y coordinate of the pixel location
+     * @param w        Width of the pixel rectangle
+     * @param h        Height of the pixel rectangle
+     * @param fArray   An optionally pre-allocated float array
+     * @return the samples for the specified rectangle of pixels.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if fArray is too small to hold the output.
+     */
+    public float[] getPixels(int x, int y, int w, int h,
+                             float fArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX,
+                                     y - sampleModelTranslateY, w, h,
+                                     fArray, dataBuffer);
+    }
+
+    /**
+     * Returns a double array containing all samples for a rectangle of pixels,
+     * one sample per array element.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * @param x        The X coordinate of the upper-left pixel location
+     * @param y        The Y coordinate of the upper-left pixel location
+     * @param w        Width of the pixel rectangle
+     * @param h        Height of the pixel rectangle
+     * @param dArray   An optionally pre-allocated double array
+     * @return the samples for the specified rectangle of pixels.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if dArray is too small to hold the output.
+     */
+    public double[] getPixels(int x, int y, int w, int h,
+                              double dArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX,
+                                     y - sampleModelTranslateY,
+                                     w, h, dArray, dataBuffer);
+    }
+
+
+    /**
+     * Returns the sample in a specified band for the pixel located
+     * at (x,y) as an int.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * @param x        The X coordinate of the pixel location
+     * @param y        The Y coordinate of the pixel location
+     * @param b        The band to return
+     * @return the sample in the specified band for the pixel at the
+     *         specified coordinate.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds.
+     */
+    public int getSample(int x, int y, int b) {
+        return sampleModel.getSample(x - sampleModelTranslateX,
+                                     y - sampleModelTranslateY, b,
+                                     dataBuffer);
+    }
+
+    /**
+     * Returns the sample in a specified band
+     * for the pixel located at (x,y) as a float.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * @param x        The X coordinate of the pixel location
+     * @param y        The Y coordinate of the pixel location
+     * @param b        The band to return
+     * @return the sample in the specified band for the pixel at the
+     *         specified coordinate.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds.
+     */
+    public float getSampleFloat(int x, int y, int b) {
+        return sampleModel.getSampleFloat(x - sampleModelTranslateX,
+                                          y - sampleModelTranslateY, b,
+                                          dataBuffer);
+    }
+
+    /**
+     * Returns the sample in a specified band
+     * for a pixel located at (x,y) as a double.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * @param x        The X coordinate of the pixel location
+     * @param y        The Y coordinate of the pixel location
+     * @param b        The band to return
+     * @return the sample in the specified band for the pixel at the
+     *         specified coordinate.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds.
+     */
+    public double getSampleDouble(int x, int y, int b) {
+        return sampleModel.getSampleDouble(x - sampleModelTranslateX,
+                                           y - sampleModelTranslateY,
+                                           b, dataBuffer);
+    }
+
+    /**
+     * Returns the samples for a specified band for the specified rectangle
+     * of pixels in an int array, one sample per array element.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * @param x        The X coordinate of the upper-left pixel location
+     * @param y        The Y coordinate of the upper-left pixel location
+     * @param w        Width of the pixel rectangle
+     * @param h        Height of the pixel rectangle
+     * @param b        The band to return
+     * @param iArray   An optionally pre-allocated int array
+     * @return the samples for the specified band for the specified
+     *         rectangle of pixels.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds, or if iArray is too small to
+     * hold the output.
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b,
+                            int iArray[]) {
+        return sampleModel.getSamples(x - sampleModelTranslateX,
+                                      y - sampleModelTranslateY,
+                                      w, h, b, iArray,
+                                      dataBuffer);
+    }
+
+    /**
+     * Returns the samples for a specified band for the specified rectangle
+     * of pixels in a float array, one sample per array element.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * @param x        The X coordinate of the upper-left pixel location
+     * @param y        The Y coordinate of the upper-left pixel location
+     * @param w        Width of the pixel rectangle
+     * @param h        Height of the pixel rectangle
+     * @param b        The band to return
+     * @param fArray   An optionally pre-allocated float array
+     * @return the samples for the specified band for the specified
+     *         rectangle of pixels.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds, or if fArray is too small to
+     * hold the output.
+     */
+    public float[] getSamples(int x, int y, int w, int h, int b,
+                              float fArray[]) {
+        return sampleModel.getSamples(x - sampleModelTranslateX,
+                                      y - sampleModelTranslateY,
+                                      w, h, b, fArray, dataBuffer);
+    }
+
+    /**
+     * Returns the samples for a specified band for a specified rectangle
+     * of pixels in a double array, one sample per array element.
+     * An ArrayIndexOutOfBoundsException may be thrown
+     * if the coordinates are not in bounds.  However, explicit bounds
+     * checking is not guaranteed.
+     * @param x        The X coordinate of the upper-left pixel location
+     * @param y        The Y coordinate of the upper-left pixel location
+     * @param w        Width of the pixel rectangle
+     * @param h        Height of the pixel rectangle
+     * @param b        The band to return
+     * @param dArray   An optionally pre-allocated double array
+     * @return the samples for the specified band for the specified
+     *         rectangle of pixels.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds, or if dArray is too small to
+     * hold the output.
+     */
+    public double[] getSamples(int x, int y, int w, int h, int b,
+                               double dArray[]) {
+         return sampleModel.getSamples(x - sampleModelTranslateX,
+                                       y - sampleModelTranslateY,
+                                       w, h, b, dArray, dataBuffer);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/RenderedImage.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,217 @@
+/*
+ * Portions Copyright 1997-2000 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+import java.awt.Rectangle;
+import java.util.Dictionary;
+import java.util.Vector;
+
+/**
+ * RenderedImage is a common interface for objects which contain
+ * or can produce image data in the form of Rasters.  The image
+ * data may be stored/produced as a single tile or a regular array
+ * of tiles.
+ */
+
+public interface RenderedImage {
+
+    /**
+     * Returns a vector of RenderedImages that are the immediate sources of
+     * image data for this RenderedImage.  This method returns null if
+     * the RenderedImage object has no information about its immediate
+     * sources.  It returns an empty Vector if the RenderedImage object has
+     * no immediate sources.
+     * @return a Vector of <code>RenderedImage</code> objects.
+     */
+    Vector<RenderedImage> getSources();
+
+    /**
+     * Gets a property from the property set of this image.  The set of
+     * properties and whether it is immutable is determined by the
+     * implementing class.  This method returns
+     * java.awt.Image.UndefinedProperty if the specified property is
+     * not defined for this RenderedImage.
+     * @param name the name of the property
+     * @return the property indicated by the specified name.
+     * @see java.awt.Image#UndefinedProperty
+     */
+    Object getProperty(String name);
+
+    /**
+      * Returns an array of names recognized by
+      * {@link #getProperty(String) getProperty(String)}
+      * or <code>null</code>, if no property names are recognized.
+      * @return a <code>String</code> array containing all of the
+      * property names that <code>getProperty(String)</code> recognizes;
+      * or <code>null</code> if no property names are recognized.
+      */
+    String[] getPropertyNames();
+
+    /**
+     * Returns the ColorModel associated with this image.  All Rasters
+     * returned from this image will have this as their ColorModel.  This
+     * can return null.
+     * @return the <code>ColorModel</code> of this image.
+     */
+    ColorModel getColorModel();
+
+    /**
+     * Returns the SampleModel associated with this image.  All Rasters
+     * returned from this image will have this as their SampleModel.
+     * @return the <code>SampleModel</code> of this image.
+     */
+    SampleModel getSampleModel();
+
+    /**
+     * Returns the width of the RenderedImage.
+     * @return the width of this <code>RenderedImage</code>.
+     */
+    int getWidth();
+
+    /**
+     * Returns the height of the RenderedImage.
+     * @return the height of this <code>RenderedImage</code>.
+     */
+    int getHeight();
+
+    /**
+     * Returns the minimum X coordinate (inclusive) of the RenderedImage.
+     * @return the X coordinate of this <code>RenderedImage</code>.
+     */
+    int getMinX();
+
+    /**
+     * Returns the minimum Y coordinate (inclusive) of the RenderedImage.
+     * @return the Y coordinate of this <code>RenderedImage</code>.
+     */
+    int getMinY();
+
+    /**
+     * Returns the number of tiles in the X direction.
+     * @return the number of tiles in the X direction.
+     */
+    int getNumXTiles();
+
+    /**
+     * Returns the number of tiles in the Y direction.
+     * @return the number of tiles in the Y direction.
+     */
+    int getNumYTiles();
+
+    /**
+     *  Returns the minimum tile index in the X direction.
+     *  @return the minimum tile index in the X direction.
+     */
+    int getMinTileX();
+
+    /**
+     *  Returns the minimum tile index in the Y direction.
+     *  @return the minimum tile index in the X direction.
+     */
+    int getMinTileY();
+
+    /**
+     *  Returns the tile width in pixels.  All tiles must have the same
+     *  width.
+     *  @return the tile width in pixels.
+     */
+    int getTileWidth();
+
+    /**
+     *  Returns the tile height in pixels.  All tiles must have the same
+     *  height.
+     *  @return the tile height in pixels.
+     */
+    int getTileHeight();
+
+    /**
+     * Returns the X offset of the tile grid relative to the origin,
+     * i.e., the X coordinate of the upper-left pixel of tile (0, 0).
+     * (Note that tile (0, 0) may not actually exist.)
+     * @return the X offset of the tile grid relative to the origin.
+     */
+    int getTileGridXOffset();
+
+    /**
+     * Returns the Y offset of the tile grid relative to the origin,
+     * i.e., the Y coordinate of the upper-left pixel of tile (0, 0).
+     * (Note that tile (0, 0) may not actually exist.)
+     * @return the Y offset of the tile grid relative to the origin.
+     */
+    int getTileGridYOffset();
+
+    /**
+     * Returns tile (tileX, tileY).  Note that tileX and tileY are indices
+     * into the tile array, not pixel locations.  The Raster that is returned
+     * is live and will be updated if the image is changed.
+     * @param tileX the X index of the requested tile in the tile array
+     * @param tileY the Y index of the requested tile in the tile array
+     * @return the tile given the specified indices.
+     */
+   Raster getTile(int tileX, int tileY);
+
+    /**
+     * Returns the image as one large tile (for tile based
+     * images this will require fetching the whole image
+     * and copying the image data over).  The Raster returned is
+     * a copy of the image data and will not be updated if the image
+     * is changed.
+     * @return the image as one large tile.
+     */
+    Raster getData();
+
+    /**
+     * Computes and returns an arbitrary region of the RenderedImage.
+     * The Raster returned is a copy of the image data and will not
+     * be updated if the image is changed.
+     * @param rect the region of the RenderedImage to be returned.
+     * @return the region of the <code>RenderedImage</code>
+     * indicated by the specified <code>Rectangle</code>.
+     */
+    Raster getData(Rectangle rect);
+
+    /**
+     * Computes an arbitrary rectangular region of the RenderedImage
+     * and copies it into a caller-supplied WritableRaster.  The region
+     * to be computed is determined from the bounds of the supplied
+     * WritableRaster.  The supplied WritableRaster must have a
+     * SampleModel that is compatible with this image.  If raster is null,
+     * an appropriate WritableRaster is created.
+     * @param raster a WritableRaster to hold the returned portion of the
+     *               image, or null.
+     * @return a reference to the supplied or created WritableRaster.
+     */
+    WritableRaster copyData(WritableRaster raster);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/SampleModel.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,1393 @@
+/*
+ * Portions Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+
+/**
+ *  This abstract class defines an interface for extracting samples of pixels
+ *  in an image.  All image data is expressed as a collection of pixels.
+ *  Each pixel consists of a number of samples. A sample is a datum
+ *  for one band of an image and a band consists of all samples of a
+ *  particular type in an image.  For example, a pixel might contain
+ *  three samples representing its red, green and blue components.
+ *  There are three bands in the image containing this pixel.  One band
+ *  consists of all the red samples from all pixels in the
+ *  image.  The second band consists of all the green samples and
+ *  the remaining band consists of all of the blue samples.  The pixel
+ *  can be stored in various formats.  For example, all samples from
+ *  a particular band can be stored contiguously or all samples from a
+ *  single pixel can be stored contiguously.
+ *  <p>
+ *  Subclasses of SampleModel specify the types of samples they can
+ *  represent (e.g. unsigned 8-bit byte, signed 16-bit short, etc.)
+ *  and may specify how the samples are organized in memory.
+ *  In the Java 2D(tm) API, built-in image processing operators may
+ *  not operate on all possible sample types, but generally will work
+ *  for unsigned integral samples of 16 bits or less.  Some operators
+ *  support a wider variety of sample types.
+ *  <p>
+ *  A collection of pixels is represented as a Raster, which consists of
+ *  a DataBuffer and a SampleModel.  The SampleModel allows access to
+ *  samples in the DataBuffer and may provide low-level information that
+ *  a programmer can use to directly manipulate samples and pixels in the
+ *  DataBuffer.
+ *  <p>
+ *  This class is generally a fall back method for dealing with
+ *  images.  More efficient code will cast the SampleModel to the
+ *  appropriate subclass and extract the information needed to directly
+ *  manipulate pixels in the DataBuffer.
+ *
+ *  @see java.awt.image.DataBuffer
+ *  @see java.awt.image.Raster
+ *  @see java.awt.image.ComponentSampleModel
+ *  @see java.awt.image.PixelInterleavedSampleModel
+ *  @see java.awt.image.BandedSampleModel
+ *  @see java.awt.image.MultiPixelPackedSampleModel
+ *  @see java.awt.image.SinglePixelPackedSampleModel
+ */
+
+public abstract class SampleModel
+{
+
+    /** Width in pixels of the region of image data that this SampleModel
+     *  describes.
+     */
+    protected int width;
+
+    /** Height in pixels of the region of image data that this SampleModel
+     *  describes.
+     */
+    protected int height;
+
+    /** Number of bands of the image data that this SampleModel describes. */
+    protected int numBands;
+
+    /** Data type of the DataBuffer storing the pixel data.
+     *  @see java.awt.image.DataBuffer
+     */
+    protected int dataType;
+
+    static private native void initIDs();
+    static {
+        ColorModel.loadLibraries();
+        initIDs();
+    }
+
+    /**
+     * Constructs a SampleModel with the specified parameters.
+     * @param dataType  The data type of the DataBuffer storing the pixel data.
+     * @param w         The width (in pixels) of the region of image data.
+     * @param h         The height (in pixels) of the region of image data.
+     * @param numBands  The number of bands of the image data.
+     * @throws IllegalArgumentException if <code>w</code> or <code>h</code>
+     *         is not greater than 0
+     * @throws IllegalArgumentException if the product of <code>w</code>
+     *         and <code>h</code> is greater than
+     *         <code>Integer.MAX_VALUE</code>
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         one of the supported data types
+     */
+    public SampleModel(int dataType, int w, int h, int numBands)
+    {
+        float size = (float)w*h;
+        if (w <= 0 || h <= 0) {
+            throw new IllegalArgumentException("Width ("+w+") and height ("+
+                                               h+") must be > 0");
+        }
+        if (size >= Integer.MAX_VALUE) {
+            throw new IllegalArgumentException("Dimensions (width="+w+
+                                               " height="+h+") are too large");
+        }
+
+        if (dataType < DataBuffer.TYPE_BYTE ||
+            (dataType > DataBuffer.TYPE_DOUBLE &&
+             dataType != DataBuffer.TYPE_UNDEFINED))
+        {
+            throw new IllegalArgumentException("Unsupported dataType: "+
+                                               dataType);
+        }
+
+        if (numBands <= 0) {
+            throw new IllegalArgumentException("Number of bands must be > 0");
+        }
+
+        this.dataType = dataType;
+        this.width = w;
+        this.height = h;
+        this.numBands = numBands;
+    }
+
+    /** Returns the width in pixels.
+     *  @return the width in pixels of the region of image data
+     *          that this <code>SampleModel</code> describes.
+     */
+    final public int getWidth() {
+         return width;
+    }
+
+    /** Returns the height in pixels.
+     *  @return the height in pixels of the region of image data
+     *          that this <code>SampleModel</code> describes.
+     */
+    final public int getHeight() {
+         return height;
+    }
+
+    /** Returns the total number of bands of image data.
+     *  @return the number of bands of image data that this
+     *          <code>SampleModel</code> describes.
+     */
+    final public int getNumBands() {
+         return numBands;
+    }
+
+    /** Returns the number of data elements needed to transfer a pixel
+     *  via the getDataElements and setDataElements methods.  When pixels
+     *  are transferred via these methods, they may be transferred in a
+     *  packed or unpacked format, depending on the implementation of the
+     *  SampleModel.  Using these methods, pixels are transferred as an
+     *  array of getNumDataElements() elements of a primitive type given
+     *  by getTransferType().  The TransferType may or may not be the same
+     *  as the storage DataType.
+     *  @return the number of data elements.
+     *  @see #getDataElements(int, int, Object, DataBuffer)
+     *  @see #getDataElements(int, int, int, int, Object, DataBuffer)
+     *  @see #setDataElements(int, int, Object, DataBuffer)
+     *  @see #setDataElements(int, int, int, int, Object, DataBuffer)
+     *  @see #getTransferType
+     */
+    public abstract int getNumDataElements();
+
+    /** Returns the data type of the DataBuffer storing the pixel data.
+     *  @return the data type.
+     */
+    final public int getDataType() {
+        return dataType;
+    }
+
+    /** Returns the TransferType used to transfer pixels via the
+     *  getDataElements and setDataElements methods.  When pixels
+     *  are transferred via these methods, they may be transferred in a
+     *  packed or unpacked format, depending on the implementation of the
+     *  SampleModel.  Using these methods, pixels are transferred as an
+     *  array of getNumDataElements() elements of a primitive type given
+     *  by getTransferType().  The TransferType may or may not be the same
+     *  as the storage DataType.  The TransferType will be one of the types
+     *  defined in DataBuffer.
+     *  @return the transfer type.
+     *  @see #getDataElements(int, int, Object, DataBuffer)
+     *  @see #getDataElements(int, int, int, int, Object, DataBuffer)
+     *  @see #setDataElements(int, int, Object, DataBuffer)
+     *  @see #setDataElements(int, int, int, int, Object, DataBuffer)
+     *  @see #getNumDataElements
+     *  @see java.awt.image.DataBuffer
+     */
+    public int getTransferType() {
+        return dataType;
+    }
+
+    /**
+     * Returns the samples for a specified pixel in an int array,
+     * one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location
+     * @param y         The Y coordinate of the pixel location
+     * @param iArray    If non-null, returns the samples in this array
+     * @param data      The DataBuffer containing the image data
+     * @return the samples for the specified pixel.
+     * @see #setPixel(int, int, int[], DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if iArray is too small to hold the output.
+     */
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+
+        int pixels[];
+
+        if (iArray != null)
+            pixels = iArray;
+        else
+            pixels = new int[numBands];
+
+        for (int i=0; i<numBands; i++) {
+            pixels[i] = getSample(x, y, i, data);
+        }
+
+        return pixels;
+    }
+
+    /**
+     * Returns data for a single pixel in a primitive array of type
+     * TransferType.  For image data supported by the Java 2D API, this
+     * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
+     * or DataBuffer.TYPE_DOUBLE.  Data may be returned in a packed format,
+     * thus increasing efficiency for data transfers. Generally, obj
+     * should be passed in as null, so that the Object will be created
+     * automatically and will be of the right primitive data type.
+     * <p>
+     * The following code illustrates transferring data for one pixel from
+     * DataBuffer <code>db1</code>, whose storage layout is described by
+     * SampleModel <code>sm1</code>, to DataBuffer <code>db2</code>, whose
+     * storage layout is described by SampleModel <code>sm2</code>.
+     * The transfer will generally be more efficient than using
+     * getPixel/setPixel.
+     * <pre>
+     *       SampleModel sm1, sm2;
+     *       DataBuffer db1, db2;
+     *       sm2.setDataElements(x, y, sm1.getDataElements(x, y, null, db1), db2);
+     * </pre>
+     * Using getDataElements/setDataElements to transfer between two
+     * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
+     * the same number of bands, corresponding bands have the same number of
+     * bits per sample, and the TransferTypes are the same.
+     * <p>
+     * If obj is non-null, it should be a primitive array of type TransferType.
+     * Otherwise, a ClassCastException is thrown.  An
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds, or if obj is non-null and is not large enough to hold
+     * the pixel data.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param obj       If non-null, a primitive array in which to return
+     *                  the pixel data.
+     * @param data      The DataBuffer containing the image data.
+     * @return the data elements for the specified pixel.
+     * @see #getNumDataElements
+     * @see #getTransferType
+     * @see java.awt.image.DataBuffer
+     * @see #setDataElements(int, int, Object, DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if obj is too small to hold the output.
+     */
+    public abstract Object getDataElements(int x, int y,
+                                           Object obj, DataBuffer data);
+
+    /**
+     * Returns the pixel data for the specified rectangle of pixels in a
+     * primitive array of type TransferType.
+     * For image data supported by the Java 2D API, this
+     * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
+     * or DataBuffer.TYPE_DOUBLE.  Data may be returned in a packed format,
+     * thus increasing efficiency for data transfers. Generally, obj
+     * should be passed in as null, so that the Object will be created
+     * automatically and will be of the right primitive data type.
+     * <p>
+     * The following code illustrates transferring data for a rectangular
+     * region of pixels from
+     * DataBuffer <code>db1</code>, whose storage layout is described by
+     * SampleModel <code>sm1</code>, to DataBuffer <code>db2</code>, whose
+     * storage layout is described by SampleModel <code>sm2</code>.
+     * The transfer will generally be more efficient than using
+     * getPixels/setPixels.
+     * <pre>
+     *       SampleModel sm1, sm2;
+     *       DataBuffer db1, db2;
+     *       sm2.setDataElements(x, y, w, h, sm1.getDataElements(x, y, w,
+     *                           h, null, db1), db2);
+     * </pre>
+     * Using getDataElements/setDataElements to transfer between two
+     * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
+     * the same number of bands, corresponding bands have the same number of
+     * bits per sample, and the TransferTypes are the same.
+     * <p>
+     * If obj is non-null, it should be a primitive array of type TransferType.
+     * Otherwise, a ClassCastException is thrown.  An
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds, or if obj is non-null and is not large enough to hold
+     * the pixel data.
+     * @param x         The minimum X coordinate of the pixel rectangle.
+     * @param y         The minimum Y coordinate of the pixel rectangle.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param obj       If non-null, a primitive array in which to return
+     *                  the pixel data.
+     * @param data      The DataBuffer containing the image data.
+     * @return the data elements for the specified region of pixels.
+     * @see #getNumDataElements
+     * @see #getTransferType
+     * @see #setDataElements(int, int, int, int, Object, DataBuffer)
+     * @see java.awt.image.DataBuffer
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if obj is too small to hold the output.
+     */
+    public Object getDataElements(int x, int y, int w, int h,
+                                  Object obj, DataBuffer data) {
+
+        int type = getTransferType();
+        int numDataElems = getNumDataElements();
+        int cnt = 0;
+        Object o = null;
+
+        switch(type) {
+
+        case DataBuffer.TYPE_BYTE:
+
+            byte[] btemp;
+            byte[] bdata;
+
+            if (obj == null)
+                bdata = new byte[numDataElems*w*h];
+            else
+                bdata = (byte[])obj;
+
+            for (int i=y; i<y+h; i++) {
+                for (int j=x; j<x+w; j++) {
+                    o = getDataElements(j, i, o, data);
+                    btemp = (byte[])o;
+                    for (int k=0; k<numDataElems; k++) {
+                        bdata[cnt++] = btemp[k];
+                    }
+                }
+            }
+            obj = (Object)bdata;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_SHORT:
+
+            short[] sdata;
+            short[] stemp;
+
+            if (obj == null)
+                sdata = new short[numDataElems*w*h];
+            else
+                sdata = (short[])obj;
+
+            for (int i=y; i<y+h; i++) {
+                for (int j=x; j<x+w; j++) {
+                    o = getDataElements(j, i, o, data);
+                    stemp = (short[])o;
+                    for (int k=0; k<numDataElems; k++) {
+                        sdata[cnt++] = stemp[k];
+                    }
+                }
+            }
+
+            obj = (Object)sdata;
+            break;
+
+        case DataBuffer.TYPE_INT:
+
+            int[] idata;
+            int[] itemp;
+
+            if (obj == null)
+                idata = new int[numDataElems*w*h];
+            else
+                idata = (int[])obj;
+
+            for (int i=y; i<y+h; i++) {
+                for (int j=x; j<x+w; j++) {
+                    o = getDataElements(j, i, o, data);
+                    itemp = (int[])o;
+                    for (int k=0; k<numDataElems; k++) {
+                        idata[cnt++] = itemp[k];
+                    }
+                }
+            }
+
+            obj = (Object)idata;
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+
+            float[] fdata;
+            float[] ftemp;
+
+            if (obj == null)
+                fdata = new float[numDataElems*w*h];
+            else
+                fdata = (float[])obj;
+
+            for (int i=y; i<y+h; i++) {
+                for (int j=x; j<x+w; j++) {
+                    o = getDataElements(j, i, o, data);
+                    ftemp = (float[])o;
+                    for (int k=0; k<numDataElems; k++) {
+                        fdata[cnt++] = ftemp[k];
+                    }
+                }
+            }
+
+            obj = (Object)fdata;
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+
+            double[] ddata;
+            double[] dtemp;
+
+            if (obj == null)
+                ddata = new double[numDataElems*w*h];
+            else
+                ddata = (double[])obj;
+
+            for (int i=y; i<y+h; i++) {
+                for (int j=x; j<x+w; j++) {
+                    o = getDataElements(j, i, o, data);
+                    dtemp = (double[])o;
+                    for (int k=0; k<numDataElems; k++) {
+                        ddata[cnt++] = dtemp[k];
+                    }
+                }
+            }
+
+            obj = (Object)ddata;
+            break;
+        }
+
+        return obj;
+    }
+
+    /**
+     * Sets the data for a single pixel in the specified DataBuffer from a
+     * primitive array of type TransferType.  For image data supported by
+     * the Java 2D API, this will be one of DataBuffer.TYPE_BYTE,
+     * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.  Data in the array
+     * may be in a packed format, thus increasing efficiency for data
+     * transfers.
+     * <p>
+     * The following code illustrates transferring data for one pixel from
+     * DataBuffer <code>db1</code>, whose storage layout is described by
+     * SampleModel <code>sm1</code>, to DataBuffer <code>db2</code>, whose
+     * storage layout is described by SampleModel <code>sm2</code>.
+     * The transfer will generally be more efficient than using
+     * getPixel/setPixel.
+     * <pre>
+     *       SampleModel sm1, sm2;
+     *       DataBuffer db1, db2;
+     *       sm2.setDataElements(x, y, sm1.getDataElements(x, y, null, db1),
+     *                           db2);
+     * </pre>
+     * Using getDataElements/setDataElements to transfer between two
+     * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
+     * the same number of bands, corresponding bands have the same number of
+     * bits per sample, and the TransferTypes are the same.
+     * <p>
+     * obj must be a primitive array of type TransferType.  Otherwise,
+     * a ClassCastException is thrown.  An
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds, or if obj is not large enough to hold the pixel data.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param obj       A primitive array containing pixel data.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getNumDataElements
+     * @see #getTransferType
+     * @see #getDataElements(int, int, Object, DataBuffer)
+     * @see java.awt.image.DataBuffer
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if obj is too small to hold the input.
+     */
+    public abstract void setDataElements(int x, int y,
+                                         Object obj, DataBuffer data);
+
+    /**
+     * Sets the data for a rectangle of pixels in the specified DataBuffer
+     * from a primitive array of type TransferType.  For image data supported
+     * by the Java 2D API, this will be one of DataBuffer.TYPE_BYTE,
+     * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.  Data in the array
+     * may be in a packed format, thus increasing efficiency for data
+     * transfers.
+     * <p>
+     * The following code illustrates transferring data for a rectangular
+     * region of pixels from
+     * DataBuffer <code>db1</code>, whose storage layout is described by
+     * SampleModel <code>sm1</code>, to DataBuffer <code>db2</code>, whose
+     * storage layout is described by SampleModel <code>sm2</code>.
+     * The transfer will generally be more efficient than using
+     * getPixels/setPixels.
+     * <pre>
+     *       SampleModel sm1, sm2;
+     *       DataBuffer db1, db2;
+     *       sm2.setDataElements(x, y, w, h, sm1.getDataElements(x, y, w, h,
+     *                           null, db1), db2);
+     * </pre>
+     * Using getDataElements/setDataElements to transfer between two
+     * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
+     * the same number of bands, corresponding bands have the same number of
+     * bits per sample, and the TransferTypes are the same.
+     * <p>
+     * obj must be a primitive array of type TransferType.  Otherwise,
+     * a ClassCastException is thrown.  An
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds, or if obj is not large enough to hold the pixel data.
+     * @param x         The minimum X coordinate of the pixel rectangle.
+     * @param y         The minimum Y coordinate of the pixel rectangle.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param obj       A primitive array containing pixel data.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getNumDataElements
+     * @see #getTransferType
+     * @see #getDataElements(int, int, int, int, Object, DataBuffer)
+     * @see java.awt.image.DataBuffer
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if obj is too small to hold the input.
+     */
+    public void setDataElements(int x, int y, int w, int h,
+                                Object obj, DataBuffer data) {
+
+        int cnt = 0;
+        Object o = null;
+        int type = getTransferType();
+        int numDataElems = getNumDataElements();
+
+        switch(type) {
+
+        case DataBuffer.TYPE_BYTE:
+
+            byte[] barray = (byte[])obj;
+            byte[] btemp = new byte[numDataElems];
+
+            for (int i=y; i<y+h; i++) {
+                for (int j=x; j<x+w; j++) {
+                    for (int k=0; k<numDataElems; k++) {
+                        btemp[k] = barray[cnt++];
+                    }
+
+                    setDataElements(j, i, btemp, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_SHORT:
+
+            short[] sarray = (short[])obj;
+            short[] stemp = new short[numDataElems];
+
+            for (int i=y; i<y+h; i++) {
+                for (int j=x; j<x+w; j++) {
+                    for (int k=0; k<numDataElems; k++) {
+                        stemp[k] = sarray[cnt++];
+                    }
+
+                    setDataElements(j, i, stemp, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+
+            int[] iArray = (int[])obj;
+            int[] itemp = new int[numDataElems];
+
+            for (int i=y; i<y+h; i++) {
+                for (int j=x; j<x+w; j++) {
+                    for (int k=0; k<numDataElems; k++) {
+                        itemp[k] = iArray[cnt++];
+                    }
+
+                    setDataElements(j, i, itemp, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+
+            float[] fArray = (float[])obj;
+            float[] ftemp = new float[numDataElems];
+
+            for (int i=y; i<y+h; i++) {
+                for (int j=x; j<x+w; j++) {
+                    for (int k=0; k<numDataElems; k++) {
+                        ftemp[k] = fArray[cnt++];
+                    }
+
+                    setDataElements(j, i, ftemp, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+
+            double[] dArray = (double[])obj;
+            double[] dtemp = new double[numDataElems];
+
+            for (int i=y; i<y+h; i++) {
+                for (int j=x; j<x+w; j++) {
+                    for (int k=0; k<numDataElems; k++) {
+                        dtemp[k] = dArray[cnt++];
+                    }
+
+                    setDataElements(j, i, dtemp, data);
+                }
+            }
+            break;
+        }
+
+    }
+
+    /**
+     * Returns the samples for the specified pixel in an array of float.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param fArray    If non-null, returns the samples in this array.
+     * @param data      The DataBuffer containing the image data.
+     * @return the samples for the specified pixel.
+     * @see #setPixel(int, int, float[], DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if fArray is too small to hold the output.
+     */
+    public float[] getPixel(int x, int y, float fArray[],
+                            DataBuffer data) {
+
+        float pixels[];
+
+        if (fArray != null)
+            pixels = fArray;
+        else
+            pixels = new float[numBands];
+
+        for (int i=0; i<numBands; i++)
+            pixels[i] = getSampleFloat(x, y, i, data);
+
+        return pixels;
+    }
+
+    /**
+     * Returns the samples for the specified pixel in an array of double.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param dArray    If non-null, returns the samples in this array.
+     * @param data      The DataBuffer containing the image data.
+     * @return the samples for the specified pixel.
+     * @see #setPixel(int, int, double[], DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if dArray is too small to hold the output.
+     */
+    public double[] getPixel(int x, int y, double dArray[],
+                             DataBuffer data) {
+
+        double pixels[];
+
+        if(dArray != null)
+            pixels = dArray;
+        else
+            pixels = new double[numBands];
+
+        for (int i=0; i<numBands; i++)
+            pixels[i] = getSampleDouble(x, y, i, data);
+
+        return pixels;
+    }
+
+    /**
+     * Returns all samples for a rectangle of pixels in an
+     * int array, one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param iArray    If non-null, returns the samples in this array.
+     * @param data      The DataBuffer containing the image data.
+     * @return the samples for the specified region of pixels.
+     * @see #setPixels(int, int, int, int, int[], DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if iArray is too small to hold the output.
+     */
+    public int[] getPixels(int x, int y, int w, int h,
+                           int iArray[], DataBuffer data) {
+
+        int pixels[];
+        int Offset=0;
+
+        if (iArray != null)
+            pixels = iArray;
+        else
+            pixels = new int[numBands * w * h];
+
+        for (int i=y; i<(h+y); i++) {
+            for (int j=x; j<(w+x); j++) {
+                for(int k=0; k<numBands; k++) {
+                    pixels[Offset++] = getSample(j, i, k, data);
+                }
+            }
+        }
+
+        return pixels;
+    }
+
+    /**
+     * Returns all samples for a rectangle of pixels in a float
+     * array, one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param fArray    If non-null, returns the samples in this array.
+     * @param data      The DataBuffer containing the image data.
+     * @return the samples for the specified region of pixels.
+     * @see #setPixels(int, int, int, int, float[], DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if fArray is too small to hold the output.
+     */
+    public float[] getPixels(int x, int y, int w, int h,
+                             float fArray[], DataBuffer data) {
+
+        float pixels[];
+        int Offset = 0;
+
+        if (fArray != null)
+            pixels = fArray;
+        else
+            pixels = new float[numBands * w * h];
+
+        for (int i=y; i<(h+y); i++) {
+            for(int j=x; j<(w+x); j++) {
+                for(int k=0; k<numBands; k++) {
+                    pixels[Offset++] = getSampleFloat(j, i, k, data);
+                }
+            }
+        }
+
+        return pixels;
+    }
+
+    /**
+     * Returns all samples for a rectangle of pixels in a double
+     * array, one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param dArray    If non-null, returns the samples in this array.
+     * @param data      The DataBuffer containing the image data.
+     * @return the samples for the specified region of pixels.
+     * @see #setPixels(int, int, int, int, double[], DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if dArray is too small to hold the output.
+     */
+    public double[] getPixels(int x, int y, int w, int h,
+                              double dArray[], DataBuffer data) {
+        double pixels[];
+        int    Offset = 0;
+
+        if (dArray != null)
+            pixels = dArray;
+        else
+            pixels = new double[numBands * w * h];
+
+        // Fix 4217412
+        for (int i=y; i<(h+y); i++) {
+            for (int j=x; j<(w+x); j++) {
+                for (int k=0; k<numBands; k++) {
+                    pixels[Offset++] = getSampleDouble(j, i, k, data);
+                }
+            }
+        }
+
+        return pixels;
+    }
+
+
+    /**
+     * Returns the sample in a specified band for the pixel located
+     * at (x,y) as an int.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param b         The band to return.
+     * @param data      The DataBuffer containing the image data.
+     * @return the sample in a specified band for the specified pixel.
+     * @see #setSample(int, int, int, int, DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds.
+     */
+    public abstract int getSample(int x, int y, int b, DataBuffer data);
+
+
+    /**
+     * Returns the sample in a specified band
+     * for the pixel located at (x,y) as a float.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param b         The band to return.
+     * @param data      The DataBuffer containing the image data.
+     * @return the sample in a specified band for the specified pixel.
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds.
+     */
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+
+        float sample;
+        sample = (float) getSample(x, y, b, data);
+        return sample;
+    }
+
+    /**
+     * Returns the sample in a specified band
+     * for a pixel located at (x,y) as a double.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param b         The band to return.
+     * @param data      The DataBuffer containing the image data.
+     * @return the sample in a specified band for the specified pixel.
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds.
+     */
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+
+        double sample;
+
+        sample = (double) getSample(x, y, b, data);
+        return sample;
+    }
+
+    /**
+     * Returns the samples for a specified band for the specified rectangle
+     * of pixels in an int array, one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param b         The band to return.
+     * @param iArray    If non-null, returns the samples in this array.
+     * @param data      The DataBuffer containing the image data.
+     * @return the samples for the specified band for the specified region
+     *         of pixels.
+     * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds, or if iArray is too small to
+     * hold the output.
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b,
+                            int iArray[], DataBuffer data) {
+        int pixels[];
+        int Offset=0;
+
+        if (iArray != null)
+            pixels = iArray;
+        else
+            pixels = new int[w * h];
+
+        for(int i=y; i<(h+y); i++) {
+            for (int j=x; j<(w+x); j++) {
+                pixels[Offset++] = getSample(j, i, b, data);
+            }
+        }
+
+        return pixels;
+    }
+
+    /**
+     * Returns the samples for a specified band for the specified rectangle
+     * of pixels in a float array, one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param b         The band to return.
+     * @param fArray    If non-null, returns the samples in this array.
+     * @param data      The DataBuffer containing the image data.
+     * @return the samples for the specified band for the specified region
+     *         of pixels.
+     * @see #setSamples(int, int, int, int, int, float[], DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds, or if fArray is too small to
+     * hold the output.
+     */
+    public float[] getSamples(int x, int y, int w, int h,
+                              int b, float fArray[],
+                              DataBuffer data) {
+        float pixels[];
+        int   Offset=0;
+
+        if (fArray != null)
+            pixels = fArray;
+        else
+            pixels = new float[w * h];
+
+        for (int i=y; i<(h+y); i++) {
+            for (int j=x; j<(w+x); j++) {
+                pixels[Offset++] = getSampleFloat(j, i, b, data);
+            }
+        }
+
+        return pixels;
+    }
+
+    /**
+     * Returns the samples for a specified band for a specified rectangle
+     * of pixels in a double array, one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param b         The band to return.
+     * @param dArray    If non-null, returns the samples in this array.
+     * @param data      The DataBuffer containing the image data.
+     * @return the samples for the specified band for the specified region
+     *         of pixels.
+     * @see #setSamples(int, int, int, int, int, double[], DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds, or if dArray is too small to
+     * hold the output.
+     */
+    public double[] getSamples(int x, int y, int w, int h,
+                               int b, double dArray[],
+                               DataBuffer data) {
+        double pixels[];
+        int    Offset=0;
+
+        if (dArray != null)
+            pixels = dArray;
+        else
+            pixels = new double[w * h];
+
+        for (int i=y; i<(y+h); i++) {
+            for (int j=x; j<(x+w); j++) {
+                pixels[Offset++] = getSampleDouble(j, i, b, data);
+            }
+        }
+
+        return pixels;
+    }
+
+    /**
+     * Sets a pixel in  the DataBuffer using an int array of samples for input.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param iArray    The input samples in an int array.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getPixel(int, int, int[], DataBuffer)
+     *
+     * @throws NullPointerException if iArray or data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if iArray is too small to hold the input.
+     */
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+
+        for (int i=0; i<numBands; i++)
+            setSample(x, y, i, iArray[i], data);
+    }
+
+    /**
+     * Sets a pixel in the DataBuffer using a float array of samples for input.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param fArray    The input samples in a float array.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getPixel(int, int, float[], DataBuffer)
+     *
+     * @throws NullPointerException if fArray or data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if fArray is too small to hold the input.
+     */
+    public void setPixel(int x, int y, float fArray[], DataBuffer data) {
+
+        for (int i=0; i<numBands; i++)
+            setSample(x, y, i, fArray[i], data);
+    }
+
+    /**
+     * Sets a pixel in the DataBuffer using a double array of samples
+     * for input.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param dArray    The input samples in a double array.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getPixel(int, int, double[], DataBuffer)
+     *
+     * @throws NullPointerException if dArray or data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if fArray is too small to hold the input.
+     */
+    public void setPixel(int x, int y, double dArray[], DataBuffer data) {
+
+        for (int i=0; i<numBands; i++)
+            setSample(x, y, i, dArray[i], data);
+    }
+
+    /**
+     * Sets all samples for a rectangle of pixels from an int array containing
+     * one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param iArray    The input samples in an int array.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getPixels(int, int, int, int, int[], DataBuffer)
+     *
+     * @throws NullPointerException if iArray or data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if iArray is too small to hold the input.
+     */
+    public void setPixels(int x, int y, int w, int h,
+                          int iArray[], DataBuffer data) {
+        int Offset=0;
+
+        for (int i=y; i<(y+h); i++) {
+            for (int j=x; j<(x+w); j++) {
+                for (int k=0; k<numBands; k++) {
+                    setSample(j, i, k, iArray[Offset++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets all samples for a rectangle of pixels from a float array containing
+     * one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param fArray    The input samples in a float array.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getPixels(int, int, int, int, float[], DataBuffer)
+     *
+     * @throws NullPointerException if fArray or data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if fArray is too small to hold the input.
+     */
+    public void setPixels(int x, int y, int w, int h,
+                          float fArray[], DataBuffer data) {
+        int Offset=0;
+
+        for (int i=y; i<(y+h); i++) {
+            for (int j=x; j<(x+w); j++) {
+                for(int k=0; k<numBands; k++) {
+                    setSample(j, i, k, fArray[Offset++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets all samples for a rectangle of pixels from a double array
+     * containing one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param dArray    The input samples in a double array.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getPixels(int, int, int, int, double[], DataBuffer)
+     *
+     * @throws NullPointerException if dArray or data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are
+     * not in bounds, or if dArray is too small to hold the input.
+     */
+    public void setPixels(int x, int y, int w, int h,
+                          double dArray[], DataBuffer data) {
+        int Offset=0;
+
+        for (int i=y; i<(y+h); i++) {
+            for (int j=x; j<(x+w); j++) {
+                for (int k=0; k<numBands; k++) {
+                    setSample(j, i, k, dArray[Offset++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the DataBuffer using an int for input.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param b         The band to set.
+     * @param s         The input sample as an int.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getSample(int, int, int,  DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds.
+     */
+    public abstract void setSample(int x, int y, int b,
+                                   int s,
+                                   DataBuffer data);
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the DataBuffer using a float for input.
+     * The default implementation of this method casts the input
+     * float sample to an int and then calls the
+     * <code>setSample(int, int, int, DataBuffer)</code> method using
+     * that int value.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param b         The band to set.
+     * @param s         The input sample as a float.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getSample(int, int, int, DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds.
+     */
+    public void setSample(int x, int y, int b,
+                          float s ,
+                          DataBuffer data) {
+        int sample = (int)s;
+
+        setSample(x, y, b, sample, data);
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the DataBuffer using a double for input.
+     * The default implementation of this method casts the input
+     * double sample to an int and then calls the
+     * <code>setSample(int, int, int, DataBuffer)</code> method using
+     * that int value.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param b         The band to set.
+     * @param s         The input sample as a double.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getSample(int, int, int, DataBuffer)
+     *
+     * @throws NullPointerException if data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds.
+     */
+    public void setSample(int x, int y, int b,
+                          double s,
+                          DataBuffer data) {
+        int sample = (int)s;
+
+        setSample(x, y, b, sample, data);
+    }
+
+    /**
+     * Sets the samples in the specified band for the specified rectangle
+     * of pixels from an int array containing one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param b         The band to set.
+     * @param iArray    The input samples in an int array.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
+     *
+     * @throws NullPointerException if iArray or data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds, or if iArray is too small to
+     * hold the input.
+     */
+    public void setSamples(int x, int y, int w, int h, int b,
+                           int iArray[], DataBuffer data) {
+
+        int Offset=0;
+
+        for (int i=y; i<(y+h); i++) {
+            for (int j=x; j<(x+w); j++) {
+                setSample(j, i, b, iArray[Offset++], data);
+            }
+        }
+    }
+
+    /**
+     * Sets the samples in the specified band for the specified rectangle
+     * of pixels from a float array containing one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param b         The band to set.
+     * @param fArray    The input samples in a float array.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getSamples(int, int, int, int, int, float[], DataBuffer)
+     *
+     * @throws NullPointerException if fArray or data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds, or if fArray is too small to
+     * hold the input.
+     */
+    public void setSamples(int x, int y, int w, int h, int b,
+                           float fArray[], DataBuffer data) {
+        int Offset=0;
+
+        for (int i=y; i<(y+h); i++) {
+            for (int j=x; j<(x+w); j++) {
+                setSample(j, i, b, fArray[Offset++], data);
+            }
+        }
+    }
+
+    /**
+     * Sets the samples in the specified band for the specified rectangle
+     * of pixels from a double array containing one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param b         The band to set.
+     * @param dArray    The input samples in a double array.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getSamples(int, int, int, int, int, double[], DataBuffer)
+     *
+     * @throws NullPointerException if dArray or data is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds, or if dArray is too small to
+     * hold the input.
+     */
+    public void setSamples(int x, int y, int w, int h, int b,
+                           double dArray[], DataBuffer data) {
+        int Offset=0;
+
+        for (int i=y; i<(y+h); i++) {
+            for (int j=x; j<(x+w); j++) {
+                setSample(j, i, b, dArray[Offset++], data);
+            }
+        }
+    }
+
+    /**
+     *  Creates a SampleModel which describes data in this SampleModel's
+     *  format, but with a different width and height.
+     *  @param w the width of the image data
+     *  @param h the height of the image data
+     *  @return a <code>SampleModel</code> describing the same image
+     *          data as this <code>SampleModel</code>, but with a
+     *          different size.
+     */
+    public abstract SampleModel createCompatibleSampleModel(int w, int h);
+
+    /**
+     * Creates a new SampleModel
+     * with a subset of the bands of this
+     * SampleModel.
+     * @param bands the subset of bands of this <code>SampleModel</code>
+     * @return a <code>SampleModel</code> with a subset of bands of this
+     *         <code>SampleModel</code>.
+     */
+    public abstract SampleModel createSubsetSampleModel(int bands[]);
+
+    /**
+     * Creates a DataBuffer that corresponds to this SampleModel.
+     * The DataBuffer's width and height will match this SampleModel's.
+     * @return a <code>DataBuffer</code> corresponding to this
+     *         <code>SampleModel</code>.
+     */
+    public abstract DataBuffer createDataBuffer();
+
+    /** Returns the size in bits of samples for all bands.
+     *  @return the size of samples for all bands.
+     */
+    public abstract int[] getSampleSize();
+
+    /** Returns the size in bits of samples for the specified band.
+     *  @param band the specified band
+     *  @return the size of the samples of the specified band.
+     */
+    public abstract int getSampleSize(int band);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/SinglePixelPackedSampleModel.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,805 @@
+/*
+ * Portions Copyright 1997-2001 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+
+import java.util.Arrays;
+
+/**
+ *  This class represents pixel data packed such that the N samples which make
+ *  up a single pixel are stored in a single data array element, and each data
+ *  data array element holds samples for only one pixel.
+ *  This class supports
+ *  {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
+ *  {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
+ *  {@link DataBuffer#TYPE_INT TYPE_INT} data types.
+ *  All data array elements reside
+ *  in the first bank of a DataBuffer.  Accessor methods are provided so
+ *  that the image data can be manipulated directly. Scanline stride is the
+ *  number of data array elements between a given sample and the corresponding
+ *  sample in the same column of the next scanline. Bit masks are the masks
+ *  required to extract the samples representing the bands of the pixel.
+ *  Bit offsets are the offsets in bits into the data array
+ *  element of the samples representing the bands of the pixel.
+ * <p>
+ * The following code illustrates extracting the bits of the sample
+ * representing band <code>b</code> for pixel <code>x,y</code>
+ * from DataBuffer <code>data</code>:
+ * <pre>
+ *      int sample = data.getElem(y * scanlineStride + x);
+ *      sample = (sample & bitMasks[b]) >>> bitOffsets[b];
+ * </pre>
+ */
+
+public class SinglePixelPackedSampleModel extends SampleModel
+{
+    /** Bit masks for all bands of the image data. */
+    private int bitMasks[];
+
+    /** Bit Offsets for all bands of the image data. */
+    private int bitOffsets[];
+
+    /** Bit sizes for all the bands of the image data. */
+    private int bitSizes[];
+
+    /** Maximum bit size. */
+    private int maxBitSize;
+
+    /** Line stride of the region of image data described by this
+     *  SinglePixelPackedSampleModel.
+     */
+    private int scanlineStride;
+
+    private static native void initIDs();
+    static {
+        ColorModel.loadLibraries();
+        initIDs();
+    }
+
+    /**
+     * Constructs a SinglePixelPackedSampleModel with bitMasks.length bands.
+     * Each sample is stored in a data array element in the position of
+     * its corresponding bit mask.  Each bit mask must be contiguous and
+     * masks must not overlap.
+     * @param dataType  The data type for storing samples.
+     * @param w         The width (in pixels) of the region of the
+     *                  image data described.
+     * @param h         The height (in pixels) of the region of the
+     *                  image data described.
+     * @param bitMasks  The bit masks for all bands.
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         either <code>DataBuffer.TYPE_BYTE</code>,
+     *         <code>DataBuffer.TYPE_USHORT</code>, or
+     *         <code>DataBuffer.TYPE_INT</code>
+     */
+    public SinglePixelPackedSampleModel(int dataType, int w, int h,
+                                   int bitMasks[]) {
+        this(dataType, w, h, w, bitMasks);
+        if (dataType != DataBuffer.TYPE_BYTE &&
+            dataType != DataBuffer.TYPE_USHORT &&
+            dataType != DataBuffer.TYPE_INT) {
+            throw new IllegalArgumentException("Unsupported data type "+
+                                               dataType);
+        }
+    }
+
+    /**
+     * Constructs a SinglePixelPackedSampleModel with bitMasks.length bands
+     * and a scanline stride equal to scanlineStride data array elements.
+     * Each sample is stored in a data array element in the position of
+     * its corresponding bit mask.  Each bit mask must be contiguous and
+     * masks must not overlap.
+     * @param dataType  The data type for storing samples.
+     * @param w         The width (in pixels) of the region of
+     *                  image data described.
+     * @param h         The height (in pixels) of the region of
+     *                  image data described.
+     * @param scanlineStride The line stride of the image data.
+     * @param bitMasks The bit masks for all bands.
+     * @throws IllegalArgumentException if <code>w</code> or
+     *         <code>h</code> is not greater than 0
+     * @throws IllegalArgumentException if any mask in
+     *         <code>bitMask</code> is not contiguous
+     * @throws IllegalArgumentException if <code>dataType</code> is not
+     *         either <code>DataBuffer.TYPE_BYTE</code>,
+     *         <code>DataBuffer.TYPE_USHORT</code>, or
+     *         <code>DataBuffer.TYPE_INT</code>
+     */
+    public SinglePixelPackedSampleModel(int dataType, int w, int h,
+                                   int scanlineStride, int bitMasks[]) {
+        super(dataType, w, h, bitMasks.length);
+        if (dataType != DataBuffer.TYPE_BYTE &&
+            dataType != DataBuffer.TYPE_USHORT &&
+            dataType != DataBuffer.TYPE_INT) {
+            throw new IllegalArgumentException("Unsupported data type "+
+                                               dataType);
+        }
+        this.dataType = dataType;
+        this.bitMasks = (int[]) bitMasks.clone();
+        this.scanlineStride = scanlineStride;
+
+        this.bitOffsets = new int[numBands];
+        this.bitSizes = new int[numBands];
+
+        this.maxBitSize = 0;
+        for (int i=0; i<numBands; i++) {
+            int bitOffset = 0, bitSize = 0, mask;
+            mask = bitMasks[i];
+
+            if (mask != 0) {
+                while ((mask & 1) == 0) {
+                    mask = mask >>> 1;
+                    bitOffset++;
+                }
+                while ((mask & 1) == 1) {
+                    mask = mask >>> 1;
+                    bitSize++;
+                }
+                if (mask != 0) {
+                    throw new IllegalArgumentException("Mask "+bitMasks[i]+
+                                                       " must be contiguous");
+                }
+            }
+            bitOffsets[i] = bitOffset;
+            bitSizes[i] = bitSize;
+            if (bitSize > maxBitSize) {
+                maxBitSize = bitSize;
+            }
+        }
+    }
+
+    /**
+     * Returns the number of data elements needed to transfer one pixel
+     * via the getDataElements and setDataElements methods.
+     * For a SinglePixelPackedSampleModel, this is one.
+     */
+    public int getNumDataElements() {
+        return 1;
+    }
+
+    /**
+     * Returns the size of the buffer (in data array elements)
+     * needed for a data buffer that matches this
+     * SinglePixelPackedSampleModel.
+     */
+    private long getBufferSize() {
+      long size = scanlineStride * (height-1) + width;
+      return size;
+    }
+
+    /**
+     * Creates a new SinglePixelPackedSampleModel with the specified
+     * width and height.  The new SinglePixelPackedSampleModel will have the
+     * same storage data type and bit masks as this
+     * SinglePixelPackedSampleModel.
+     * @param w the width of the resulting <code>SampleModel</code>
+     * @param h the height of the resulting <code>SampleModel</code>
+     * @return a <code>SinglePixelPackedSampleModel</code> with the
+     *         specified width and height.
+     * @throws IllegalArgumentException if <code>w</code> or
+     *         <code>h</code> is not greater than 0
+     */
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+      SampleModel sampleModel = new SinglePixelPackedSampleModel(dataType, w, h,
+                                                              bitMasks);
+      return sampleModel;
+    }
+
+    /**
+     * Creates a DataBuffer that corresponds to this
+     * SinglePixelPackedSampleModel.  The DataBuffer's data type and size
+     * will be consistent with this SinglePixelPackedSampleModel.  The
+     * DataBuffer will have a single bank.
+     */
+    public DataBuffer createDataBuffer() {
+        DataBuffer dataBuffer = null;
+
+        int size = (int)getBufferSize();
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            dataBuffer = new DataBufferByte(size);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            dataBuffer = new DataBufferUShort(size);
+            break;
+        case DataBuffer.TYPE_INT:
+            dataBuffer = new DataBufferInt(size);
+            break;
+        }
+        return dataBuffer;
+    }
+
+    /** Returns the number of bits per sample for all bands. */
+    public int[] getSampleSize() {
+        int mask;
+        int sampleSize[] = new int [numBands];
+        for (int i=0; i<numBands; i++) {
+            sampleSize[i] = 0;
+            mask = bitMasks[i] >>> bitOffsets[i];
+            while ((mask & 1) != 0) {
+                sampleSize[i] ++;
+                mask = mask >>> 1;
+            }
+        }
+
+        return sampleSize;
+    }
+
+    /** Returns the number of bits per sample for the specified band. */
+    public int getSampleSize(int band) {
+        int sampleSize = 0;
+        int mask = bitMasks[band] >>> bitOffsets[band];
+        while ((mask & 1) != 0) {
+            sampleSize ++;
+            mask = mask >>> 1;
+        }
+
+        return sampleSize;
+    }
+
+    /** Returns the offset (in data array elements) of pixel (x,y).
+     *  The data element containing pixel <code>x,y</code>
+     *  can be retrieved from a DataBuffer <code>data</code> with a
+     *  SinglePixelPackedSampleModel <code>sppsm</code> as:
+     * <pre>
+     *        data.getElem(sppsm.getOffset(x, y));
+     * </pre>
+     * @param x the X coordinate of the specified pixel
+     * @param y the Y coordinate of the specified pixel
+     * @return the offset of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        int offset = y * scanlineStride + x;
+        return offset;
+    }
+
+    /** Returns the bit offsets into the data array element representing
+     *  a pixel for all bands.
+     *  @return the bit offsets representing a pixel for all bands.
+     */
+    public int [] getBitOffsets() {
+      return (int[])bitOffsets.clone();
+    }
+
+    /** Returns the bit masks for all bands.
+     *  @return the bit masks for all bands.
+     */
+    public int [] getBitMasks() {
+      return (int[])bitMasks.clone();
+    }
+
+    /** Returns the scanline stride of this SinglePixelPackedSampleModel.
+     *  @return the scanline stride of this
+     *          <code>SinglePixelPackedSampleModel</code>.
+     */
+    public int getScanlineStride() {
+      return scanlineStride;
+    }
+
+    /**
+     * This creates a new SinglePixelPackedSampleModel with a subset of the
+     * bands of this SinglePixelPackedSampleModel.  The new
+     * SinglePixelPackedSampleModel can be used with any DataBuffer that the
+     * existing SinglePixelPackedSampleModel can be used with.  The new
+     * SinglePixelPackedSampleModel/DataBuffer combination will represent
+     * an image with a subset of the bands of the original
+     * SinglePixelPackedSampleModel/DataBuffer combination.
+     * @exception RasterFormatException if the length of the bands argument is
+     *                                  greater than the number of bands in
+     *                                  the sample model.
+     */
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands.length > numBands)
+            throw new RasterFormatException("There are only " +
+                                            numBands +
+                                            " bands");
+        int newBitMasks[] = new int[bands.length];
+        for (int i=0; i<bands.length; i++)
+            newBitMasks[i] = bitMasks[bands[i]];
+
+        return new SinglePixelPackedSampleModel(this.dataType, width, height,
+                                           this.scanlineStride, newBitMasks);
+    }
+
+    /**
+     * Returns data for a single pixel in a primitive array of type
+     * TransferType.  For a SinglePixelPackedSampleModel, the array will
+     * have one element, and the type will be the same as the storage
+     * data type.  Generally, obj
+     * should be passed in as null, so that the Object will be created
+     * automatically and will be of the right primitive data type.
+     * <p>
+     * The following code illustrates transferring data for one pixel from
+     * DataBuffer <code>db1</code>, whose storage layout is described by
+     * SinglePixelPackedSampleModel <code>sppsm1</code>, to
+     * DataBuffer <code>db2</code>, whose storage layout is described by
+     * SinglePixelPackedSampleModel <code>sppsm2</code>.
+     * The transfer will generally be more efficient than using
+     * getPixel/setPixel.
+     * <pre>
+     *       SinglePixelPackedSampleModel sppsm1, sppsm2;
+     *       DataBufferInt db1, db2;
+     *       sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
+     *                              db1), db2);
+     * </pre>
+     * Using getDataElements/setDataElements to transfer between two
+     * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
+     * the same number of bands, corresponding bands have the same number of
+     * bits per sample, and the TransferTypes are the same.
+     * <p>
+     * If obj is non-null, it should be a primitive array of type TransferType.
+     * Otherwise, a ClassCastException is thrown.  An
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds, or if obj is non-null and is not large enough to hold
+     * the pixel data.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param obj       If non-null, a primitive array in which to return
+     *                  the pixel data.
+     * @param data      The DataBuffer containing the image data.
+     * @return the data for the specified pixel.
+     * @see #setDataElements(int, int, Object, DataBuffer)
+     */
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        int type = getTransferType();
+
+        switch(type) {
+
+        case DataBuffer.TYPE_BYTE:
+
+            byte[] bdata;
+
+            if (obj == null)
+                bdata = new byte[1];
+            else
+                bdata = (byte[])obj;
+
+            bdata[0] = (byte)data.getElem(y * scanlineStride + x);
+
+            obj = (Object)bdata;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+
+            short[] sdata;
+
+            if (obj == null)
+                sdata = new short[1];
+            else
+                sdata = (short[])obj;
+
+            sdata[0] = (short)data.getElem(y * scanlineStride + x);
+
+            obj = (Object)sdata;
+            break;
+
+        case DataBuffer.TYPE_INT:
+
+            int[] idata;
+
+            if (obj == null)
+                idata = new int[1];
+            else
+                idata = (int[])obj;
+
+            idata[0] = data.getElem(y * scanlineStride + x);
+
+            obj = (Object)idata;
+            break;
+        }
+
+        return obj;
+    }
+
+    /**
+     * Returns all samples in for the specified pixel in an int array.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param iArray    If non-null, returns the samples in this array
+     * @param data      The DataBuffer containing the image data.
+     * @return all samples for the specified pixel.
+     * @see #setPixel(int, int, int[], DataBuffer)
+     */
+    public int [] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int pixels[];
+        if (iArray == null) {
+            pixels = new int [numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        int value = data.getElem(y * scanlineStride + x);
+        for (int i=0; i<numBands; i++) {
+            pixels[i] = (value & bitMasks[i]) >>> bitOffsets[i];
+        }
+        return pixels;
+    }
+
+    /**
+     * Returns all samples for the specified rectangle of pixels in
+     * an int array, one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param iArray    If non-null, returns the samples in this array.
+     * @param data      The DataBuffer containing the image data.
+     * @return all samples for the specified region of pixels.
+     * @see #setPixels(int, int, int, int, int[], DataBuffer)
+     */
+    public int[] getPixels(int x, int y, int w, int h,
+                           int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int pixels[];
+        if (iArray != null) {
+           pixels = iArray;
+        } else {
+           pixels = new int [w*h*numBands];
+        }
+        int lineOffset = y*scanlineStride + x;
+        int dstOffset = 0;
+
+        for (int i = 0; i < h; i++) {
+           for (int j = 0; j < w; j++) {
+              int value = data.getElem(lineOffset+j);
+              for (int k=0; k < numBands; k++) {
+                  pixels[dstOffset++] =
+                     ((value & bitMasks[k]) >>> bitOffsets[k]);
+              }
+           }
+           lineOffset += scanlineStride;
+        }
+        return pixels;
+    }
+
+    /**
+     * Returns as int the sample in a specified band for the pixel
+     * located at (x,y).
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param b         The band to return.
+     * @param data      The DataBuffer containing the image data.
+     * @return the sample in a specified band for the specified
+     *         pixel.
+     * @see #setSample(int, int, int, int, DataBuffer)
+     */
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int sample = data.getElem(y * scanlineStride + x);
+        return ((sample & bitMasks[b]) >>> bitOffsets[b]);
+    }
+
+    /**
+     * Returns the samples for a specified band for the specified rectangle
+     * of pixels in an int array, one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param b         The band to return.
+     * @param iArray    If non-null, returns the samples in this array.
+     * @param data      The DataBuffer containing the image data.
+     * @return the samples for the specified band for the specified
+     *         region of pixels.
+     * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b,
+                           int iArray[], DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int samples[];
+        if (iArray != null) {
+           samples = iArray;
+        } else {
+           samples = new int [w*h];
+        }
+        int lineOffset = y*scanlineStride + x;
+        int dstOffset = 0;
+
+        for (int i = 0; i < h; i++) {
+           for (int j = 0; j < w; j++) {
+              int value = data.getElem(lineOffset+j);
+              samples[dstOffset++] =
+                 ((value & bitMasks[b]) >>> bitOffsets[b]);
+           }
+           lineOffset += scanlineStride;
+        }
+        return samples;
+    }
+
+    /**
+     * Sets the data for a single pixel in the specified DataBuffer from a
+     * primitive array of type TransferType.  For a
+     * SinglePixelPackedSampleModel, only the first element of the array
+     * will hold valid data, and the type of the array must be the same as
+     * the storage data type of the SinglePixelPackedSampleModel.
+     * <p>
+     * The following code illustrates transferring data for one pixel from
+     * DataBuffer <code>db1</code>, whose storage layout is described by
+     * SinglePixelPackedSampleModel <code>sppsm1</code>,
+     * to DataBuffer <code>db2</code>, whose storage layout is described by
+     * SinglePixelPackedSampleModel <code>sppsm2</code>.
+     * The transfer will generally be more efficient than using
+     * getPixel/setPixel.
+     * <pre>
+     *       SinglePixelPackedSampleModel sppsm1, sppsm2;
+     *       DataBufferInt db1, db2;
+     *       sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
+     *                              db1), db2);
+     * </pre>
+     * Using getDataElements/setDataElements to transfer between two
+     * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
+     * the same number of bands, corresponding bands have the same number of
+     * bits per sample, and the TransferTypes are the same.
+     * <p>
+     * obj must be a primitive array of type TransferType.  Otherwise,
+     * a ClassCastException is thrown.  An
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds, or if obj is not large enough to hold the pixel data.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param obj       A primitive array containing pixel data.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getDataElements(int, int, Object, DataBuffer)
+     */
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        int type = getTransferType();
+
+        switch(type) {
+
+        case DataBuffer.TYPE_BYTE:
+
+            byte[] barray = (byte[])obj;
+            data.setElem(y*scanlineStride+x, ((int)barray[0])&0xff);
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+
+            short[] sarray = (short[])obj;
+            data.setElem(y*scanlineStride+x, ((int)sarray[0])&0xffff);
+            break;
+
+        case DataBuffer.TYPE_INT:
+
+            int[] iarray = (int[])obj;
+            data.setElem(y*scanlineStride+x, iarray[0]);
+            break;
+        }
+    }
+
+    /**
+     * Sets a pixel in the DataBuffer using an int array of samples for input.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param iArray    The input samples in an int array.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getPixel(int, int, int[], DataBuffer)
+     */
+    public void setPixel(int x, int y,
+                         int iArray[],
+                         DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int lineOffset = y * scanlineStride + x;
+        int value = data.getElem(lineOffset);
+        for (int i=0; i < numBands; i++) {
+            value &= ~bitMasks[i];
+            value |= ((iArray[i] << bitOffsets[i]) & bitMasks[i]);
+        }
+        data.setElem(lineOffset, value);
+    }
+
+    /**
+     * Sets all samples for a rectangle of pixels from an int array containing
+     * one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param iArray    The input samples in an int array.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getPixels(int, int, int, int, int[], DataBuffer)
+     */
+    public void setPixels(int x, int y, int w, int h,
+                          int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        int lineOffset = y*scanlineStride + x;
+        int srcOffset = 0;
+
+        for (int i = 0; i < h; i++) {
+           for (int j = 0; j < w; j++) {
+               int value = data.getElem(lineOffset+j);
+               for (int k=0; k < numBands; k++) {
+                   value &= ~bitMasks[k];
+                   int srcValue = iArray[srcOffset++];
+                   value |= ((srcValue << bitOffsets[k])
+                             & bitMasks[k]);
+               }
+               data.setElem(lineOffset+j, value);
+           }
+           lineOffset += scanlineStride;
+        }
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the DataBuffer using an int for input.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the pixel location.
+     * @param y         The Y coordinate of the pixel location.
+     * @param b         The band to set.
+     * @param s         The input sample as an int.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getSample(int, int, int, DataBuffer)
+     */
+    public void setSample(int x, int y, int b, int s,
+                          DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int value = data.getElem(y*scanlineStride + x);
+        value &= ~bitMasks[b];
+        value |= (s << bitOffsets[b]) & bitMasks[b];
+        data.setElem(y*scanlineStride + x,value);
+    }
+
+    /**
+     * Sets the samples in the specified band for the specified rectangle
+     * of pixels from an int array containing one sample per array element.
+     * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * @param x         The X coordinate of the upper left pixel location.
+     * @param y         The Y coordinate of the upper left pixel location.
+     * @param w         The width of the pixel rectangle.
+     * @param h         The height of the pixel rectangle.
+     * @param b         The band to set.
+     * @param iArray    The input samples in an int array.
+     * @param data      The DataBuffer containing the image data.
+     * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
+     */
+    public void setSamples(int x, int y, int w, int h, int b,
+                          int iArray[], DataBuffer data) {
+        // Bounds check for 'b' will be performed automatically
+        if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+        int lineOffset = y*scanlineStride + x;
+        int srcOffset = 0;
+
+        for (int i = 0; i < h; i++) {
+           for (int j = 0; j < w; j++) {
+              int value = data.getElem(lineOffset+j);
+              value &= ~bitMasks[b];
+              int sample = iArray[srcOffset++];
+              value |= ((int)sample << bitOffsets[b]) & bitMasks[b];
+              data.setElem(lineOffset+j,value);
+           }
+           lineOffset += scanlineStride;
+        }
+    }
+
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+
+        SinglePixelPackedSampleModel that = (SinglePixelPackedSampleModel)o;
+        return this.width == that.width &&
+            this.height == that.height &&
+            this.numBands == that.numBands &&
+            this.dataType == that.dataType &&
+            Arrays.equals(this.bitMasks, that.bitMasks) &&
+            Arrays.equals(this.bitOffsets, that.bitOffsets) &&
+            Arrays.equals(this.bitSizes, that.bitSizes) &&
+            this.maxBitSize == that.maxBitSize &&
+            this.scanlineStride == that.scanlineStride;
+    }
+
+    // If we implement equals() we must also implement hashCode
+    public int hashCode() {
+        int hash = 0;
+        hash = width;
+        hash <<= 8;
+        hash ^= height;
+        hash <<= 8;
+        hash ^= numBands;
+        hash <<= 8;
+        hash ^= dataType;
+        hash <<= 8;
+        for (int i = 0; i < bitMasks.length; i++) {
+            hash ^= bitMasks[i];
+            hash <<= 8;
+        }
+        for (int i = 0; i < bitOffsets.length; i++) {
+            hash ^= bitOffsets[i];
+            hash <<= 8;
+        }
+        for (int i = 0; i < bitSizes.length; i++) {
+            hash ^= bitSizes[i];
+            hash <<= 8;
+        }
+        hash ^= maxBitSize;
+        hash <<= 8;
+        hash ^= scanlineStride;
+        return hash;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/WritableRaster.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,741 @@
+/*
+ * Portions Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+import java.awt.Rectangle;
+import java.awt.Point;
+
+/**
+ * This class extends Raster to provide pixel writing capabilities.
+ * Refer to the class comment for Raster for descriptions of how
+ * a Raster stores pixels.
+ *
+ * <p> The constructors of this class are protected.  To instantiate
+ * a WritableRaster, use one of the createWritableRaster factory methods
+ * in the Raster class.
+ */
+public class WritableRaster extends Raster {
+
+    /**
+     *  Constructs a WritableRaster with the given SampleModel.  The
+     *  WritableRaster's upper left corner is origin and it is the
+     *  same size as the  SampleModel.  A DataBuffer large enough to
+     *  describe the WritableRaster is automatically created.
+     *  @param sampleModel     The SampleModel that specifies the layout.
+     *  @param origin          The Point that specifies the origin.
+     *  @throws RasterFormatException if computing either
+     *          <code>origin.x + sampleModel.getWidth()</code> or
+     *          <code>origin.y + sampleModel.getHeight()</code> results
+     *          in integer overflow
+     */
+    protected WritableRaster(SampleModel sampleModel,
+                             Point origin) {
+        this(sampleModel,
+             sampleModel.createDataBuffer(),
+             new Rectangle(origin.x,
+                           origin.y,
+                           sampleModel.getWidth(),
+                           sampleModel.getHeight()),
+             origin,
+             null);
+    }
+
+    /**
+     *  Constructs a WritableRaster with the given SampleModel and DataBuffer.
+     *  The WritableRaster's upper left corner is origin and it is the same
+     *  size as the SampleModel.  The DataBuffer is not initialized and must
+     *  be compatible with SampleModel.
+     *  @param sampleModel     The SampleModel that specifies the layout.
+     *  @param dataBuffer      The DataBuffer that contains the image data.
+     *  @param origin          The Point that specifies the origin.
+     *  @throws RasterFormatException if computing either
+     *          <code>origin.x + sampleModel.getWidth()</code> or
+     *          <code>origin.y + sampleModel.getHeight()</code> results
+     *          in integer overflow
+     */
+    protected WritableRaster(SampleModel sampleModel,
+                             DataBuffer dataBuffer,
+                             Point origin) {
+        this(sampleModel,
+             dataBuffer,
+             new Rectangle(origin.x,
+                           origin.y,
+                           sampleModel.getWidth(),
+                           sampleModel.getHeight()),
+             origin,
+             null);
+    }
+
+    /**
+     * Constructs a WritableRaster with the given SampleModel, DataBuffer,
+     * and parent.  aRegion specifies the bounding rectangle of the new
+     * Raster.  When translated into the base Raster's coordinate
+     * system, aRegion must be contained by the base Raster.
+     * (The base Raster is the Raster's ancestor which has no parent.)
+     * sampleModelTranslate specifies the sampleModelTranslateX and
+     * sampleModelTranslateY values of the new Raster.
+     *
+     * Note that this constructor should generally be called by other
+     * constructors or create methods, it should not be used directly.
+     * @param sampleModel     The SampleModel that specifies the layout.
+     * @param dataBuffer      The DataBuffer that contains the image data.
+     * @param aRegion         The Rectangle that specifies the image area.
+     * @param sampleModelTranslate  The Point that specifies the translation
+     *                        from SampleModel to Raster coordinates.
+     * @param parent          The parent (if any) of this raster.
+     * @throws RasterFormatException if <code>aRegion</code> has width
+     *         or height less than or equal to zero, or computing either
+     *         <code>aRegion.x + aRegion.width</code> or
+     *         <code>aRegion.y + aRegion.height</code> results in integer
+     *         overflow
+     */
+    protected WritableRaster(SampleModel sampleModel,
+                             DataBuffer dataBuffer,
+                             Rectangle aRegion,
+                             Point sampleModelTranslate,
+                             WritableRaster parent){
+        super(sampleModel,dataBuffer,aRegion,sampleModelTranslate,parent);
+    }
+
+    /** Returns the parent WritableRaster (if any) of this WritableRaster,
+     *  or else null.
+     *  @return the parent of this <code>WritableRaster</code>, or
+     *          <code>null</code>.
+     */
+    public WritableRaster getWritableParent() {
+        return (WritableRaster)parent;
+    }
+
+    /**
+     * Create a WritableRaster with the same size, SampleModel and DataBuffer
+     * as this one, but with a different location.  The new WritableRaster
+     * will possess a reference to the current WritableRaster, accessible
+     * through its getParent() and getWritableParent() methods.
+     *
+     * @param childMinX X coord of the upper left corner of the new Raster.
+     * @param childMinY Y coord of the upper left corner of the new Raster.
+     * @return a <code>WritableRaster</code> the same as this one except
+     *         for the specified location.
+     * @throws RasterFormatException if  computing either
+     *         <code>childMinX + this.getWidth()</code> or
+     *         <code>childMinY + this.getHeight()</code> results in integer
+     *         overflow
+     */
+    public WritableRaster createWritableTranslatedChild(int childMinX,
+                                                        int childMinY) {
+        return createWritableChild(minX,minY,width,height,
+                                   childMinX,childMinY,null);
+    }
+
+    /**
+     * Returns a new WritableRaster which shares all or part of this
+     * WritableRaster's DataBuffer.  The new WritableRaster will
+     * possess a reference to the current WritableRaster, accessible
+     * through its getParent() and getWritableParent() methods.
+     *
+     * <p> The parentX, parentY, width and height parameters form a
+     * Rectangle in this WritableRaster's coordinate space, indicating
+     * the area of pixels to be shared.  An error will be thrown if
+     * this Rectangle is not contained with the bounds of the current
+     * WritableRaster.
+     *
+     * <p> The new WritableRaster may additionally be translated to a
+     * different coordinate system for the plane than that used by the current
+     * WritableRaster.  The childMinX and childMinY parameters give
+     * the new (x, y) coordinate of the upper-left pixel of the
+     * returned WritableRaster; the coordinate (childMinX, childMinY)
+     * in the new WritableRaster will map to the same pixel as the
+     * coordinate (parentX, parentY) in the current WritableRaster.
+     *
+     * <p> The new WritableRaster may be defined to contain only a
+     * subset of the bands of the current WritableRaster, possibly
+     * reordered, by means of the bandList parameter.  If bandList is
+     * null, it is taken to include all of the bands of the current
+     * WritableRaster in their current order.
+     *
+     * <p> To create a new WritableRaster that contains a subregion of
+     * the current WritableRaster, but shares its coordinate system
+     * and bands, this method should be called with childMinX equal to
+     * parentX, childMinY equal to parentY, and bandList equal to
+     * null.
+     *
+     * @param parentX    X coordinate of the upper left corner in this
+     *                   WritableRaster's coordinates.
+     * @param parentY    Y coordinate of the upper left corner in this
+     *                   WritableRaster's coordinates.
+     * @param w          Width of the region starting at (parentX, parentY).
+     * @param h          Height of the region starting at (parentX, parentY).
+     * @param childMinX  X coordinate of the upper left corner of
+     *                   the returned WritableRaster.
+     * @param childMinY  Y coordinate of the upper left corner of
+     *                   the returned WritableRaster.
+     * @param bandList   Array of band indices, or null to use all bands.
+     * @return a <code>WritableRaster</code> sharing all or part of the
+     *         <code>DataBuffer</code> of this <code>WritableRaster</code>.
+     * @exception RasterFormatException if the subregion is outside of the
+     *                               raster bounds.
+     * @throws RasterFormatException if <code>w</code> or
+     *         <code>h</code>
+     *         is less than or equal to zero, or computing any of
+     *         <code>parentX + w</code>, <code>parentY + h</code>,
+     *         <code>childMinX + w</code>, or
+     *         <code>childMinY + h</code> results in integer
+     *         overflow
+     */
+    public WritableRaster createWritableChild(int parentX, int parentY,
+                                              int w, int h,
+                                              int childMinX, int childMinY,
+                                              int bandList[]) {
+        if (parentX < this.minX) {
+            throw new RasterFormatException("parentX lies outside raster");
+        }
+        if (parentY < this.minY) {
+            throw new RasterFormatException("parentY lies outside raster");
+        }
+        if ((parentX+w < parentX) || (parentX+w > this.width + this.minX)) {
+            throw new RasterFormatException("(parentX + width) is outside raster");
+        }
+        if ((parentY+h < parentY) || (parentY+h > this.height + this.minY)) {
+            throw new RasterFormatException("(parentY + height) is outside raster");
+        }
+
+        SampleModel sm;
+        // Note: the SampleModel for the child Raster should have the same
+        // width and height as that for the parent, since it represents
+        // the physical layout of the pixel data.  The child Raster's width
+        // and height represent a "virtual" view of the pixel data, so
+        // they may be different than those of the SampleModel.
+        if (bandList != null) {
+            sm = sampleModel.createSubsetSampleModel(bandList);
+        }
+        else {
+            sm = sampleModel;
+        }
+
+        int deltaX = childMinX - parentX;
+        int deltaY = childMinY - parentY;
+
+        return new WritableRaster(sm,
+                                  getDataBuffer(),
+                                  new Rectangle(childMinX,childMinY,
+                                                w, h),
+                                  new Point(sampleModelTranslateX+deltaX,
+                                            sampleModelTranslateY+deltaY),
+                                  this);
+    }
+
+    /**
+     * Sets the data for a single pixel from a
+     * primitive array of type TransferType.  For image data supported by
+     * the Java 2D(tm) API, this will be one of DataBuffer.TYPE_BYTE,
+     * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.  Data in the array
+     * may be in a packed format, thus increasing efficiency for data
+     * transfers.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds, or if inData is not large enough to hold the pixel data.
+     * However, explicit bounds checking is not guaranteed.
+     * A ClassCastException will be thrown if the input object is not null
+     * and references anything other than an array of TransferType.
+     * @see java.awt.image.SampleModel#setDataElements(int, int, Object, DataBuffer)
+     * @param x        The X coordinate of the pixel location.
+     * @param y        The Y coordinate of the pixel location.
+     * @param inData   An object reference to an array of type defined by
+     *                 getTransferType() and length getNumDataElements()
+     *                 containing the pixel data to place at x,y.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if inData is too small to hold the input.
+     */
+    public void setDataElements(int x, int y, Object inData) {
+        sampleModel.setDataElements(x-sampleModelTranslateX,
+                                    y-sampleModelTranslateY,
+                                    inData, dataBuffer);
+    }
+
+    /**
+     * Sets the data for a rectangle of pixels from an input Raster.
+     * The input Raster must be compatible with this WritableRaster
+     * in that they must have the same number of bands, corresponding bands
+     * must have the same number of bits per sample, the TransferTypes
+     * and NumDataElements must be the same, and the packing used by
+     * the getDataElements/setDataElements must be identical.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x        The X coordinate of the pixel location.
+     * @param y        The Y coordinate of the pixel location.
+     * @param inRaster Raster containing data to place at x,y.
+     *
+     * @throws NullPointerException if inRaster is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds.
+     */
+    public void setDataElements(int x, int y, Raster inRaster) {
+        int dstOffX = x+inRaster.getMinX();
+        int dstOffY = y+inRaster.getMinY();
+        int width  = inRaster.getWidth();
+        int height = inRaster.getHeight();
+        if ((dstOffX < this.minX) || (dstOffY < this.minY) ||
+            (dstOffX + width > this.minX + this.width) ||
+            (dstOffY + height > this.minY + this.height)) {
+            throw new ArrayIndexOutOfBoundsException
+                ("Coordinate out of bounds!");
+        }
+
+        int srcOffX = inRaster.getMinX();
+        int srcOffY = inRaster.getMinY();
+        Object tdata = null;
+
+        for (int startY=0; startY < height; startY++) {
+            tdata = inRaster.getDataElements(srcOffX, srcOffY+startY,
+                                             width, 1, tdata);
+            setDataElements(dstOffX, dstOffY+startY,
+                            width, 1, tdata);
+        }
+    }
+
+    /**
+     * Sets the data for a rectangle of pixels from a
+     * primitive array of type TransferType.  For image data supported by
+     * the Java 2D API, this will be one of DataBuffer.TYPE_BYTE,
+     * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.  Data in the array
+     * may be in a packed format, thus increasing efficiency for data
+     * transfers.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds, or if inData is not large enough to hold the pixel data.
+     * However, explicit bounds checking is not guaranteed.
+     * A ClassCastException will be thrown if the input object is not null
+     * and references anything other than an array of TransferType.
+     * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, Object, DataBuffer)
+     * @param x        The X coordinate of the upper left pixel location.
+     * @param y        The Y coordinate of the upper left pixel location.
+     * @param w        Width of the pixel rectangle.
+     * @param h        Height of the pixel rectangle.
+     * @param inData   An object reference to an array of type defined by
+     *                 getTransferType() and length w*h*getNumDataElements()
+     *                 containing the pixel data to place between x,y and
+     *                 x+w-1, y+h-1.
+     *
+     * @throws NullPointerException if inData is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if inData is too small to hold the input.
+     */
+    public void setDataElements(int x, int y, int w, int h, Object inData) {
+        sampleModel.setDataElements(x-sampleModelTranslateX,
+                                    y-sampleModelTranslateY,
+                                    w,h,inData,dataBuffer);
+    }
+
+    /**
+     * Copies pixels from Raster srcRaster to this WritableRaster.  Each pixel
+     * in srcRaster is copied to the same x,y address in this raster, unless
+     * the address falls outside the bounds of this raster.  srcRaster
+     * must have the same number of bands as this WritableRaster.  The
+     * copy is a simple copy of source samples to the corresponding destination
+     * samples.
+     * <p>
+     * If all samples of both source and destination Rasters are of
+     * integral type and less than or equal to 32 bits in size, then calling
+     * this method is equivalent to executing the following code for all
+     * <code>x,y</code> addresses valid in both Rasters.
+     * <pre>
+     *       Raster srcRaster;
+     *       WritableRaster dstRaster;
+     *       for (int b = 0; b < srcRaster.getNumBands(); b++) {
+     *           dstRaster.setSample(x, y, b, srcRaster.getSample(x, y, b));
+     *       }
+     * </pre>
+     * Thus, when copying an integral type source to an integral type
+     * destination, if the source sample size is greater than the destination
+     * sample size for a particular band, the high order bits of the source
+     * sample are truncated.  If the source sample size is less than the
+     * destination size for a particular band, the high order bits of the
+     * destination are zero-extended or sign-extended depending on whether
+     * srcRaster's SampleModel treats the sample as a signed or unsigned
+     * quantity.
+     * <p>
+     * When copying a float or double source to an integral type destination,
+     * each source sample is cast to the destination type.  When copying an
+     * integral type source to a float or double destination, the source
+     * is first converted to a 32-bit int (if necessary), using the above
+     * rules for integral types, and then the int is cast to float or
+     * double.
+     * <p>
+     * @param srcRaster  The  Raster from which to copy pixels.
+     *
+     * @throws NullPointerException if srcRaster is null.
+     */
+    public void setRect(Raster srcRaster) {
+        setRect(0,0,srcRaster);
+    }
+
+    /**
+     * Copies pixels from Raster srcRaster to this WritableRaster.
+     * For each (x, y) address in srcRaster, the corresponding pixel
+     * is copied to address (x+dx, y+dy) in this WritableRaster,
+     * unless (x+dx, y+dy) falls outside the bounds of this raster.
+     * srcRaster must have the same number of bands as this WritableRaster.
+     * The copy is a simple copy of source samples to the corresponding
+     * destination samples.  For details, see
+     * {@link WritableRaster#setRect(Raster)}.
+     *
+     * @param dx        The X translation factor from src space to dst space
+     *                  of the copy.
+     * @param dy        The Y translation factor from src space to dst space
+     *                  of the copy.
+     * @param srcRaster The Raster from which to copy pixels.
+     *
+     * @throws NullPointerException if srcRaster is null.
+     */
+    public void setRect(int dx, int dy, Raster srcRaster) {
+        int width  = srcRaster.getWidth();
+        int height = srcRaster.getHeight();
+        int srcOffX = srcRaster.getMinX();
+        int srcOffY = srcRaster.getMinY();
+        int dstOffX = dx+srcOffX;
+        int dstOffY = dy+srcOffY;
+
+        // Clip to this raster
+        if (dstOffX < this.minX) {
+            int skipX = this.minX - dstOffX;
+            width -= skipX;
+            srcOffX += skipX;
+            dstOffX = this.minX;
+        }
+        if (dstOffY < this.minY) {
+            int skipY = this.minY - dstOffY;
+            height -= skipY;
+            srcOffY += skipY;
+            dstOffY = this.minY;
+        }
+        if (dstOffX+width > this.minX+this.width) {
+            width = this.minX + this.width - dstOffX;
+        }
+        if (dstOffY+height > this.minY+this.height) {
+            height = this.minY + this.height - dstOffY;
+        }
+
+        if (width <= 0 || height <= 0) {
+            return;
+        }
+
+        switch (srcRaster.getSampleModel().getDataType()) {
+        case DataBuffer.TYPE_BYTE:
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_INT:
+            int[] iData = null;
+            for (int startY=0; startY < height; startY++) {
+                // Grab one scanline at a time
+                iData =
+                    srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
+                                        iData);
+                setPixels(dstOffX, dstOffY+startY, width, 1, iData);
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float[] fData = null;
+            for (int startY=0; startY < height; startY++) {
+                fData =
+                    srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
+                                        fData);
+                setPixels(dstOffX, dstOffY+startY, width, 1, fData);
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double[] dData = null;
+            for (int startY=0; startY < height; startY++) {
+                // Grab one scanline at a time
+                dData =
+                    srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
+                                        dData);
+                setPixels(dstOffX, dstOffY+startY, width, 1, dData);
+            }
+            break;
+        }
+    }
+
+    /**
+     * Sets a pixel in the DataBuffer using an int array of samples for input.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x      The X coordinate of the pixel location.
+     * @param y      The Y coordinate of the pixel location.
+     * @param iArray The input samples in a int array.
+     *
+     * @throws NullPointerException if iArray is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if iArray is too small to hold the input.
+     */
+    public void setPixel(int x, int y, int iArray[]) {
+        sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
+                             iArray,dataBuffer);
+    }
+
+    /**
+     * Sets a pixel in the DataBuffer using a float array of samples for input.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x      The X coordinate of the pixel location.
+     * @param y      The Y coordinate of the pixel location.
+     * @param fArray The input samples in a float array.
+     *
+     * @throws NullPointerException if fArray is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if fArray is too small to hold the input.
+     */
+    public void setPixel(int x, int y, float fArray[]) {
+        sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
+                             fArray,dataBuffer);
+    }
+
+    /**
+     * Sets a pixel in the DataBuffer using a double array of samples for input.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x      The X coordinate of the pixel location.
+     * @param y      The Y coordinate of the pixel location.
+     * @param dArray The input samples in a double array.
+     *
+     * @throws NullPointerException if dArray is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if dArray is too small to hold the input.
+     */
+    public void setPixel(int x, int y, double dArray[]) {
+        sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
+                             dArray,dataBuffer);
+    }
+
+    /**
+     * Sets all samples for a rectangle of pixels from an int array containing
+     * one sample per array element.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x        The X coordinate of the upper left pixel location.
+     * @param y        The Y coordinate of the upper left pixel location.
+     * @param w        Width of the pixel rectangle.
+     * @param h        Height of the pixel rectangle.
+     * @param iArray   The input int pixel array.
+     *
+     * @throws NullPointerException if iArray is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if iArray is too small to hold the input.
+     */
+    public void setPixels(int x, int y, int w, int h, int iArray[]) {
+        sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
+                              w,h,iArray,dataBuffer);
+    }
+
+    /**
+     * Sets all samples for a rectangle of pixels from a float array containing
+     * one sample per array element.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x        The X coordinate of the upper left pixel location.
+     * @param y        The Y coordinate of the upper left pixel location.
+     * @param w        Width of the pixel rectangle.
+     * @param h        Height of the pixel rectangle.
+     * @param fArray   The input float pixel array.
+     *
+     * @throws NullPointerException if fArray is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if fArray is too small to hold the input.
+     */
+    public void setPixels(int x, int y, int w, int h, float fArray[]) {
+        sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
+                              w,h,fArray,dataBuffer);
+    }
+
+    /**
+     * Sets all samples for a rectangle of pixels from a double array containing
+     * one sample per array element.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x        The X coordinate of the upper left pixel location.
+     * @param y        The Y coordinate of the upper left pixel location.
+     * @param w        Width of the pixel rectangle.
+     * @param h        Height of the pixel rectangle.
+     * @param dArray   The input double pixel array.
+     *
+     * @throws NullPointerException if dArray is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
+     * in bounds, or if dArray is too small to hold the input.
+     */
+    public void setPixels(int x, int y, int w, int h, double dArray[]) {
+        sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
+                              w,h,dArray,dataBuffer);
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the DataBuffer using an int for input.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x        The X coordinate of the pixel location.
+     * @param y        The Y coordinate of the pixel location.
+     * @param b        The band to set.
+     * @param s        The input sample.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds.
+     */
+    public void setSample(int x, int y, int b, int s) {
+        sampleModel.setSample(x-sampleModelTranslateX,
+                              y-sampleModelTranslateY, b, s,
+                              dataBuffer);
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the DataBuffer using a float for input.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x        The X coordinate of the pixel location.
+     * @param y        The Y coordinate of the pixel location.
+     * @param b        The band to set.
+     * @param s        The input sample as a float.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds.
+     */
+    public void setSample(int x, int y, int b, float s){
+        sampleModel.setSample(x-sampleModelTranslateX,y-sampleModelTranslateY,
+                              b,s,dataBuffer);
+    }
+
+    /**
+     * Sets a sample in the specified band for the pixel located at (x,y)
+     * in the DataBuffer using a double for input.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x        The X coordinate of the pixel location.
+     * @param y        The Y coordinate of the pixel location.
+     * @param b        The band to set.
+     * @param s        The input sample as a double.
+     *
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds.
+     */
+    public void setSample(int x, int y, int b, double s){
+        sampleModel.setSample(x-sampleModelTranslateX,y-sampleModelTranslateY,
+                                    b,s,dataBuffer);
+    }
+
+    /**
+     * Sets the samples in the specified band for the specified rectangle
+     * of pixels from an int array containing one sample per array element.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x        The X coordinate of the upper left pixel location.
+     * @param y        The Y coordinate of the upper left pixel location.
+     * @param w        Width of the pixel rectangle.
+     * @param h        Height of the pixel rectangle.
+     * @param b        The band to set.
+     * @param iArray   The input int sample array.
+     *
+     * @throws NullPointerException if iArray is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds, or if iArray is too small to
+     * hold the input.
+     */
+    public void setSamples(int x, int y, int w, int h, int b,
+                           int iArray[]) {
+        sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
+                               w,h,b,iArray,dataBuffer);
+    }
+
+    /**
+     * Sets the samples in the specified band for the specified rectangle
+     * of pixels from a float array containing one sample per array element.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x        The X coordinate of the upper left pixel location.
+     * @param y        The Y coordinate of the upper left pixel location.
+     * @param w        Width of the pixel rectangle.
+     * @param h        Height of the pixel rectangle.
+     * @param b        The band to set.
+     * @param fArray   The input float sample array.
+     *
+     * @throws NullPointerException if fArray is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds, or if fArray is too small to
+     * hold the input.
+     */
+    public void setSamples(int x, int y, int w, int h, int b,
+                           float fArray[]) {
+        sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
+                               w,h,b,fArray,dataBuffer);
+    }
+
+    /**
+     * Sets the samples in the specified band for the specified rectangle
+     * of pixels from a double array containing one sample per array element.
+     * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
+     * not in bounds.
+     * However, explicit bounds checking is not guaranteed.
+     * @param x        The X coordinate of the upper left pixel location.
+     * @param y        The Y coordinate of the upper left pixel location.
+     * @param w        Width of the pixel rectangle.
+     * @param h        Height of the pixel rectangle.
+     * @param b        The band to set.
+     * @param dArray   The input double sample array.
+     *
+     * @throws NullPointerException if dArray is null.
+     * @throws ArrayIndexOutOfBoundsException if the coordinates or
+     * the band index are not in bounds, or if dArray is too small to
+     * hold the input.
+     */
+    public void setSamples(int x, int y, int w, int h, int b,
+                           double dArray[]) {
+        sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
+                              w,h,b,dArray,dataBuffer);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/WritableRenderedImage.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,151 @@
+/*
+ * Portions Copyright 1997-2000 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ****************************************************************
+ ******************************************************************
+ ******************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997
+ *** As  an unpublished  work pursuant to Title 17 of the United
+ *** States Code.  All rights reserved.
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+package java.awt.image;
+import java.awt.Point;
+
+/**
+ * WriteableRenderedImage is a common interface for objects which
+ * contain or can produce image data in the form of Rasters and
+ * which can be modified and/or written over.  The image
+ * data may be stored/produced as a single tile or a regular array
+ * of tiles.
+ * <p>
+ * WritableRenderedImage provides notification to other interested
+ * objects when a tile is checked out for writing (via the
+ * getWritableTile method) and when the last writer of a particular
+ * tile relinquishes its access (via a call to releaseWritableTile).
+ * Additionally, it allows any caller to determine whether any tiles
+ * are currently checked out (via hasTileWriters), and to obtain a
+ * list of such tiles (via getWritableTileIndices, in the form of a Vector
+ * of Point objects).
+ * <p>
+ * Objects wishing to be notified of changes in tile writability must
+ * implement the TileObserver interface, and are added by a
+ * call to addTileObserver.  Multiple calls to
+ * addTileObserver for the same object will result in multiple
+ * notifications.  An existing observer may reduce its notifications
+ * by calling removeTileObserver; if the observer had no
+ * notifications the operation is a no-op.
+ * <p>
+ * It is necessary for a WritableRenderedImage to ensure that
+ * notifications occur only when the first writer acquires a tile and
+ * the last writer releases it.
+ *
+ */
+
+public interface WritableRenderedImage extends RenderedImage
+{
+
+  /**
+   * Adds an observer.  If the observer is already present,
+   * it will receive multiple notifications.
+   * @param to the specified <code>TileObserver</code>
+   */
+  public void addTileObserver(TileObserver to);
+
+  /**
+   * Removes an observer.  If the observer was not registered,
+   * nothing happens.  If the observer was registered for multiple
+   * notifications, it will now be registered for one fewer.
+   * @param to the specified <code>TileObserver</code>
+   */
+  public void removeTileObserver(TileObserver to);
+
+  /**
+   * Checks out a tile for writing.
+   *
+   * The WritableRenderedImage is responsible for notifying all
+   * of its TileObservers when a tile goes from having
+   * no writers to having one writer.
+   *
+   * @param tileX the X index of the tile.
+   * @param tileY the Y index of the tile.
+   * @return a writable tile.
+   */
+  public WritableRaster getWritableTile(int tileX, int tileY);
+
+  /**
+   * Relinquishes the right to write to a tile.  If the caller
+   * continues to write to the tile, the results are undefined.
+   * Calls to this method should only appear in matching pairs
+   * with calls to getWritableTile; any other use will lead
+   * to undefined results.
+   *
+   * The WritableRenderedImage is responsible for notifying all of
+   * its TileObservers when a tile goes from having one writer
+   * to having no writers.
+   *
+   * @param tileX the X index of the tile.
+   * @param tileY the Y index of the tile.
+   */
+  public void releaseWritableTile(int tileX, int tileY);
+
+  /**
+   * Returns whether a tile is currently checked out for writing.
+   *
+   * @param tileX the X index of the tile.
+   * @param tileY the Y index of the tile.
+   * @return <code>true</code> if specified tile is checked out
+   *         for writing; <code>false</code> otherwise.
+   */
+  public boolean isTileWritable(int tileX, int tileY);
+
+  /**
+   * Returns an array of Point objects indicating which tiles
+   * are checked out for writing.  Returns null if none are
+   * checked out.
+   * @return an array containing the locations of tiles that are
+   *         checked out for writing.
+   */
+  public Point[] getWritableTileIndices();
+
+  /**
+   * Returns whether any tile is checked out for writing.
+   * Semantically equivalent to (getWritableTileIndices() != null).
+   * @return <code>true</code> if any tiles are checked out for
+   *         writing; <code>false</code> otherwise.
+   */
+  public boolean hasTileWriters();
+
+  /**
+   * Sets a rect of the image to the contents of the Raster r, which is
+   * assumed to be in the same coordinate space as the WritableRenderedImage.
+   * The operation is clipped to the bounds of the WritableRenderedImage.
+   * @param r the specified <code>Raster</code>
+   */
+  public void setData(Raster r);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/renderable/ContextualRenderedImageFactory.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,143 @@
+/*
+ * Portions Copyright 1998-2000 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+package java.awt.image.renderable;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
+
+/**
+ * ContextualRenderedImageFactory provides an interface for the
+ * functionality that may differ between instances of
+ * RenderableImageOp.  Thus different operations on RenderableImages
+ * may be performed by a single class such as RenderedImageOp through
+ * the use of multiple instances of ContextualRenderedImageFactory.
+ * The name ContextualRenderedImageFactory is commonly shortened to
+ * "CRIF."
+ *
+ * <p> All operations that are to be used in a rendering-independent
+ * chain must implement ContextualRenderedImageFactory.
+ *
+ * <p> Classes that implement this interface must provide a
+ * constructor with no arguments.
+ */
+public interface ContextualRenderedImageFactory extends RenderedImageFactory {
+
+    /**
+     * Maps the operation's output RenderContext into a RenderContext
+     * for each of the operation's sources.  This is useful for
+     * operations that can be expressed in whole or in part simply as
+     * alterations in the RenderContext, such as an affine mapping, or
+     * operations that wish to obtain lower quality renderings of
+     * their sources in order to save processing effort or
+     * transmission bandwith.  Some operations, such as blur, can also
+     * use this mechanism to avoid obtaining sources of higher quality
+     * than necessary.
+     *
+     * @param i the index of the source image.
+     * @param renderContext the RenderContext being applied to the operation.
+     * @param paramBlock a ParameterBlock containing the operation's
+     *        sources and parameters.
+     * @param image the RenderableImage being rendered.
+     * @return a <code>RenderContext</code> for
+     *         the source at the specified index of the parameters
+     *         Vector contained in the specified ParameterBlock.
+     */
+    RenderContext mapRenderContext(int i,
+                                   RenderContext renderContext,
+                                   ParameterBlock paramBlock,
+                                   RenderableImage image);
+
+    /**
+     * Creates a rendering, given a RenderContext and a ParameterBlock
+     * containing the operation's sources and parameters.  The output
+     * is a RenderedImage that takes the RenderContext into account to
+     * determine its dimensions and placement on the image plane.
+     * This method houses the "intelligence" that allows a
+     * rendering-independent operation to adapt to a specific
+     * RenderContext.
+     *
+     * @param renderContext The RenderContext specifying the rendering
+     * @param paramBlock a ParameterBlock containing the operation's
+     *        sources and parameters
+     * @return a <code>RenderedImage</code> from the sources and parameters
+     *         in the specified ParameterBlock and according to the
+     *         rendering instructions in the specified RenderContext.
+     */
+    RenderedImage create(RenderContext renderContext,
+                         ParameterBlock paramBlock);
+
+    /**
+     * Returns the bounding box for the output of the operation,
+     * performed on a given set of sources, in rendering-independent
+     * space.  The bounds are returned as a Rectangle2D, that is, an
+     * axis-aligned rectangle with floating-point corner coordinates.
+     *
+     * @param paramBlock a ParameterBlock containing the operation's
+     *        sources and parameters.
+     * @return a Rectangle2D specifying the rendering-independent
+     *         bounding box of the output.
+     */
+    Rectangle2D getBounds2D(ParameterBlock paramBlock);
+
+    /**
+     * Gets the appropriate instance of the property specified by the name
+     * parameter.  This method must determine which instance of a property to
+     * return when there are multiple sources that each specify the property.
+     *
+     * @param paramBlock a ParameterBlock containing the operation's
+     *        sources and parameters.
+     * @param name a String naming the desired property.
+     * @return an object reference to the value of the property requested.
+     */
+    Object getProperty(ParameterBlock paramBlock, String name);
+
+    /**
+     * Returns a list of names recognized by getProperty.
+     * @return the list of property names.
+     */
+    String[] getPropertyNames();
+
+    /**
+     * Returns true if successive renderings (that is, calls to
+     * create(RenderContext, ParameterBlock)) with the same arguments
+     * may produce different results.  This method may be used to
+     * determine whether an existing rendering may be cached and
+     * reused.  It is always safe to return true.
+     * @return <code>true</code> if successive renderings with the
+     *         same arguments might produce different results;
+     *         <code>false</code> otherwise.
+     */
+    boolean isDynamic();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/renderable/RenderContext.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,272 @@
+/*
+ * Portions Copyright 1998-2000 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+package java.awt.image.renderable;
+import java.util.*;
+import java.awt.geom.*;
+import java.awt.*;
+import java.awt.image.*;
+
+/**
+ * A RenderContext encapsulates the information needed to produce a
+ * specific rendering from a RenderableImage.  It contains the area to
+ * be rendered specified in rendering-independent terms, the
+ * resolution at which the rendering is to be performed, and hints
+ * used to control the rendering process.
+ *
+ * <p> Users create RenderContexts and pass them to the
+ * RenderableImage via the createRendering method.  Most of the methods of
+ * RenderContexts are not meant to be used directly by applications,
+ * but by the RenderableImage and operator classes to which it is
+ * passed.
+ *
+ * <p> The AffineTransform parameter passed into and out of this class
+ * are cloned.  The RenderingHints and Shape parameters are not
+ * necessarily cloneable and are therefore only reference copied.
+ * Altering RenderingHints or Shape instances that are in use by
+ * instances of RenderContext may have undesired side effects.
+ */
+public class RenderContext implements Cloneable {
+
+    /** Table of hints. May be null. */
+    RenderingHints hints;
+
+    /** Transform to convert user coordinates to device coordinates.  */
+    AffineTransform usr2dev;
+
+    /** The area of interest.  May be null. */
+    Shape aoi;
+
+    // Various constructors that allow different levels of
+    // specificity. If the Shape is missing the whole renderable area
+    // is assumed. If hints is missing no hints are assumed.
+
+    /**
+     * Constructs a RenderContext with a given transform.
+     * The area of interest is supplied as a Shape,
+     * and the rendering hints are supplied as a RenderingHints object.
+     *
+     * @param usr2dev an AffineTransform.
+     * @param aoi a Shape representing the area of interest.
+     * @param hints a RenderingHints object containing rendering hints.
+     */
+    public RenderContext(AffineTransform usr2dev,
+                         Shape aoi,
+                         RenderingHints hints) {
+        this.hints = hints;
+        this.aoi = aoi;
+        this.usr2dev = (AffineTransform)usr2dev.clone();
+    }
+
+    /**
+     * Constructs a RenderContext with a given transform.
+     * The area of interest is taken to be the entire renderable area.
+     * No rendering hints are used.
+     *
+     * @param usr2dev an AffineTransform.
+     */
+    public RenderContext(AffineTransform usr2dev) {
+        this(usr2dev, null, null);
+    }
+
+    /**
+     * Constructs a RenderContext with a given transform and rendering hints.
+     * The area of interest is taken to be the entire renderable area.
+     *
+     * @param usr2dev an AffineTransform.
+     * @param hints a RenderingHints object containing rendering hints.
+     */
+    public RenderContext(AffineTransform usr2dev, RenderingHints hints) {
+        this(usr2dev, null, hints);
+    }
+
+    /**
+     * Constructs a RenderContext with a given transform and area of interest.
+     * The area of interest is supplied as a Shape.
+     * No rendering hints are used.
+     *
+     * @param usr2dev an AffineTransform.
+     * @param aoi a Shape representing the area of interest.
+     */
+    public RenderContext(AffineTransform usr2dev, Shape aoi) {
+        this(usr2dev, aoi, null);
+    }
+
+    /**
+     * Gets the rendering hints of this <code>RenderContext</code>.
+     * @return a <code>RenderingHints</code> object that represents
+     * the rendering hints of this <code>RenderContext</code>.
+     * @see #setRenderingHints(RenderingHints)
+     */
+    public RenderingHints getRenderingHints() {
+        return hints;
+    }
+
+    /**
+     * Sets the rendering hints of this <code>RenderContext</code>.
+     * @param hints a <code>RenderingHints</code> object that represents
+     * the rendering hints to assign to this <code>RenderContext</code>.
+     * @see #getRenderingHints
+     */
+    public void setRenderingHints(RenderingHints hints) {
+        this.hints = hints;
+    }
+
+    /**
+     * Sets the current user-to-device AffineTransform contained
+     * in the RenderContext to a given transform.
+     *
+     * @param newTransform the new AffineTransform.
+     * @see #getTransform
+     */
+    public void setTransform(AffineTransform newTransform) {
+        usr2dev = (AffineTransform)newTransform.clone();
+    }
+
+    /**
+     * Modifies the current user-to-device transform by prepending another
+     * transform.  In matrix notation the operation is:
+     * <pre>
+     * [this] = [modTransform] x [this]
+     * </pre>
+     *
+     * @param modTransform the AffineTransform to prepend to the
+     *        current usr2dev transform.
+     * @since 1.3
+     */
+    public void preConcatenateTransform(AffineTransform modTransform) {
+        this.preConcetenateTransform(modTransform);
+    }
+
+    /**
+     * Modifies the current user-to-device transform by prepending another
+     * transform.  In matrix notation the operation is:
+     * <pre>
+     * [this] = [modTransform] x [this]
+     * </pre>
+     * This method does the same thing as the preConcatenateTransform
+     * method.  It is here for backward compatibility with previous releases
+     * which misspelled the method name.
+     *
+     * @param modTransform the AffineTransform to prepend to the
+     *        current usr2dev transform.
+     * @deprecated     replaced by
+     *                 <code>preConcatenateTransform(AffineTransform)</code>.
+     */
+    @Deprecated
+    public void preConcetenateTransform(AffineTransform modTransform) {
+        usr2dev.preConcatenate(modTransform);
+    }
+
+    /**
+     * Modifies the current user-to-device transform by appending another
+     * transform.  In matrix notation the operation is:
+     * <pre>
+     * [this] = [this] x [modTransform]
+     * </pre>
+     *
+     * @param modTransform the AffineTransform to append to the
+     *        current usr2dev transform.
+     * @since 1.3
+     */
+    public void concatenateTransform(AffineTransform modTransform) {
+        this.concetenateTransform(modTransform);
+    }
+
+    /**
+     * Modifies the current user-to-device transform by appending another
+     * transform.  In matrix notation the operation is:
+     * <pre>
+     * [this] = [this] x [modTransform]
+     * </pre>
+     * This method does the same thing as the concatenateTransform
+     * method.  It is here for backward compatibility with previous releases
+     * which misspelled the method name.
+     *
+     * @param modTransform the AffineTransform to append to the
+     *        current usr2dev transform.
+     * @deprecated     replaced by
+     *                 <code>concatenateTransform(AffineTransform)</code>.
+     */
+    @Deprecated
+    public void concetenateTransform(AffineTransform modTransform) {
+        usr2dev.concatenate(modTransform);
+    }
+
+    /**
+     * Gets the current user-to-device AffineTransform.
+     *
+     * @return a reference to the current AffineTransform.
+     * @see #setTransform(AffineTransform)
+     */
+    public AffineTransform getTransform() {
+        return (AffineTransform)usr2dev.clone();
+    }
+
+    /**
+     * Sets the current area of interest.  The old area is discarded.
+     *
+     * @param newAoi The new area of interest.
+     * @see #getAreaOfInterest
+     */
+    public void setAreaOfInterest(Shape newAoi) {
+        aoi = newAoi;
+    }
+
+    /**
+     * Gets the ares of interest currently contained in the
+     * RenderContext.
+     *
+     * @return a reference to the area of interest of the RenderContext,
+     *         or null if none is specified.
+     * @see #setAreaOfInterest(Shape)
+     */
+    public Shape getAreaOfInterest() {
+        return aoi;
+    }
+
+    /**
+     * Makes a copy of a RenderContext. The area of interest is copied
+     * by reference.  The usr2dev AffineTransform and hints are cloned,
+     * while the area of interest is copied by reference.
+     *
+     * @return the new cloned RenderContext.
+     */
+    public Object clone() {
+        RenderContext newRenderContext = new RenderContext(usr2dev,
+                                                           aoi, hints);
+        return newRenderContext;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/renderable/RenderableImage.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,198 @@
+/*
+ * Portions Copyright 1998-2000 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+package java.awt.image.renderable;
+import java.util.Vector;
+import java.awt.RenderingHints;
+import java.awt.image.*;
+
+/**
+ * A RenderableImage is a common interface for rendering-independent
+ * images (a notion which subsumes resolution independence).  That is,
+ * images which are described and have operations applied to them
+ * independent of any specific rendering of the image.  For example, a
+ * RenderableImage can be rotated and cropped in
+ * resolution-independent terms.  Then, it can be rendered for various
+ * specific contexts, such as a draft preview, a high-quality screen
+ * display, or a printer, each in an optimal fashion.
+ *
+ * <p> A RenderedImage is returned from a RenderableImage via the
+ * createRendering() method, which takes a RenderContext.  The
+ * RenderContext specifies how the RenderedImage should be
+ * constructed.  Note that it is not possible to extract pixels
+ * directly from a RenderableImage.
+ *
+ * <p> The createDefaultRendering() and createScaledRendering() methods are
+ * convenience methods that construct an appropriate RenderContext
+ * internally.  All of the rendering methods may return a reference to a
+ * previously produced rendering.
+ */
+public interface RenderableImage {
+
+    /**
+     * String constant that can be used to identify a property on
+     * a RenderedImage obtained via the createRendering or
+     * createScaledRendering methods.  If such a property exists,
+     * the value of the propoery will be a RenderingHints object
+     * specifying which hints were observed in creating the rendering.
+     */
+     static final String HINTS_OBSERVED = "HINTS_OBSERVED";
+
+    /**
+     * Returns a vector of RenderableImages that are the sources of
+     * image data for this RenderableImage. Note that this method may
+     * return an empty vector, to indicate that the image has no sources,
+     * or null, to indicate that no information is available.
+     *
+     * @return a (possibly empty) Vector of RenderableImages, or null.
+     */
+    Vector<RenderableImage> getSources();
+
+    /**
+     * Gets a property from the property set of this image.
+     * If the property name is not recognized, java.awt.Image.UndefinedProperty
+     * will be returned.
+     *
+     * @param name the name of the property to get, as a String.
+     * @return a reference to the property Object, or the value
+     *         java.awt.Image.UndefinedProperty.
+     */
+    Object getProperty(String name);
+
+    /**
+     * Returns a list of names recognized by getProperty.
+     * @return a list of property names.
+     */
+    String[] getPropertyNames();
+
+    /**
+     * Returns true if successive renderings (that is, calls to
+     * createRendering() or createScaledRendering()) with the same arguments
+     * may produce different results.  This method may be used to
+     * determine whether an existing rendering may be cached and
+     * reused.  It is always safe to return true.
+     * @return <code>true</code> if successive renderings with the
+     *         same arguments might produce different results;
+     *         <code>false</code> otherwise.
+     */
+    boolean isDynamic();
+
+    /**
+     * Gets the width in user coordinate space.  By convention, the
+     * usual width of a RenderableImage is equal to the image's aspect
+     * ratio (width divided by height).
+     *
+     * @return the width of the image in user coordinates.
+     */
+    float getWidth();
+
+    /**
+     * Gets the height in user coordinate space.  By convention, the
+     * usual height of a RenderedImage is equal to 1.0F.
+     *
+     * @return the height of the image in user coordinates.
+     */
+    float getHeight();
+
+    /**
+     * Gets the minimum X coordinate of the rendering-independent image data.
+     * @return the minimum X coordinate of the rendering-independent image
+     * data.
+     */
+    float getMinX();
+
+    /**
+     * Gets the minimum Y coordinate of the rendering-independent image data.
+     * @return the minimum Y coordinate of the rendering-independent image
+     * data.
+     */
+    float getMinY();
+
+    /**
+     * Creates a RenderedImage instance of this image with width w, and
+     * height h in pixels.  The RenderContext is built automatically
+     * with an appropriate usr2dev transform and an area of interest
+     * of the full image.  All the rendering hints come from hints
+     * passed in.
+     *
+     * <p> If w == 0, it will be taken to equal
+     * Math.round(h*(getWidth()/getHeight())).
+     * Similarly, if h == 0, it will be taken to equal
+     * Math.round(w*(getHeight()/getWidth())).  One of
+     * w or h must be non-zero or else an IllegalArgumentException
+     * will be thrown.
+     *
+     * <p> The created RenderedImage may have a property identified
+     * by the String HINTS_OBSERVED to indicate which RenderingHints
+     * were used to create the image.  In addition any RenderedImages
+     * that are obtained via the getSources() method on the created
+     * RenderedImage may have such a property.
+     *
+     * @param w the width of rendered image in pixels, or 0.
+     * @param h the height of rendered image in pixels, or 0.
+     * @param hints a RenderingHints object containg hints.
+     * @return a RenderedImage containing the rendered data.
+     */
+    RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
+
+    /**
+     * Returnd a RenderedImage instance of this image with a default
+     * width and height in pixels.  The RenderContext is built
+     * automatically with an appropriate usr2dev transform and an area
+     * of interest of the full image.  The rendering hints are
+     * empty.  createDefaultRendering may make use of a stored
+     * rendering for speed.
+     *
+     * @return a RenderedImage containing the rendered data.
+     */
+    RenderedImage createDefaultRendering();
+
+    /**
+     * Creates a RenderedImage that represented a rendering of this image
+     * using a given RenderContext.  This is the most general way to obtain a
+     * rendering of a RenderableImage.
+     *
+     * <p> The created RenderedImage may have a property identified
+     * by the String HINTS_OBSERVED to indicate which RenderingHints
+     * (from the RenderContext) were used to create the image.
+     * In addition any RenderedImages
+     * that are obtained via the getSources() method on the created
+     * RenderedImage may have such a property.
+     *
+     * @param renderContext the RenderContext to use to produce the rendering.
+     * @return a RenderedImage containing the rendered data.
+     */
+    RenderedImage createRendering(RenderContext renderContext);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/renderable/RenderableImageOp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,350 @@
+/*
+ * Portions Copyright 1998-2000 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+package java.awt.image.renderable;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
+import java.awt.RenderingHints;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * This class handles the renderable aspects of an operation with help
+ * from its associated instance of a ContextualRenderedImageFactory.
+ */
+public class RenderableImageOp implements RenderableImage {
+
+    /** A ParameterBlock containing source and parameters. */
+    ParameterBlock paramBlock;
+
+    /** The associated ContextualRenderedImageFactory. */
+    ContextualRenderedImageFactory myCRIF;
+
+    /** The bounding box of the results of this RenderableImageOp. */
+    Rectangle2D boundingBox;
+
+
+    /**
+     * Constructs a RenderedImageOp given a
+     * ContextualRenderedImageFactory object, and
+     * a ParameterBlock containing RenderableImage sources and other
+     * parameters.  Any RenderedImage sources referenced by the
+     * ParameterBlock will be ignored.
+     *
+     * @param CRIF a ContextualRenderedImageFactory object
+     * @param paramBlock a ParameterBlock containing this operation's source
+     *        images and other parameters necessary for the operation
+     *        to run.
+     */
+    public RenderableImageOp(ContextualRenderedImageFactory CRIF,
+                             ParameterBlock paramBlock) {
+        this.myCRIF = CRIF;
+        this.paramBlock = (ParameterBlock) paramBlock.clone();
+    }
+
+    /**
+     * Returns a vector of RenderableImages that are the sources of
+     * image data for this RenderableImage. Note that this method may
+     * return an empty vector, to indicate that the image has no sources,
+     * or null, to indicate that no information is available.
+     *
+     * @return a (possibly empty) Vector of RenderableImages, or null.
+     */
+    public Vector<RenderableImage> getSources() {
+        return getRenderableSources();
+    }
+
+    private Vector getRenderableSources() {
+        Vector sources = null;
+
+        if (paramBlock.getNumSources() > 0) {
+            sources = new Vector();
+            int i = 0;
+            while (i < paramBlock.getNumSources()) {
+                Object o = paramBlock.getSource(i);
+                if (o instanceof RenderableImage) {
+                    sources.add((RenderableImage)o);
+                    i++;
+                } else {
+                    break;
+                }
+            }
+        }
+        return sources;
+    }
+
+    /**
+     * Gets a property from the property set of this image.
+     * If the property name is not recognized, java.awt.Image.UndefinedProperty
+     * will be returned.
+     *
+     * @param name the name of the property to get, as a String.
+     * @return a reference to the property Object, or the value
+     *         java.awt.Image.UndefinedProperty.
+     */
+    public Object getProperty(String name) {
+        return myCRIF.getProperty(paramBlock, name);
+    }
+
+    /**
+     * Return a list of names recognized by getProperty.
+     * @return a list of property names.
+     */
+    public String[] getPropertyNames() {
+        return myCRIF.getPropertyNames();
+    }
+
+    /**
+     * Returns true if successive renderings (that is, calls to
+     * createRendering() or createScaledRendering()) with the same arguments
+     * may produce different results.  This method may be used to
+     * determine whether an existing rendering may be cached and
+     * reused.  The CRIF's isDynamic method will be called.
+     * @return <code>true</code> if successive renderings with the
+     *         same arguments might produce different results;
+     *         <code>false</code> otherwise.
+     */
+    public boolean isDynamic() {
+        return myCRIF.isDynamic();
+    }
+
+    /**
+     * Gets the width in user coordinate space.  By convention, the
+     * usual width of a RenderableImage is equal to the image's aspect
+     * ratio (width divided by height).
+     *
+     * @return the width of the image in user coordinates.
+     */
+    public float getWidth() {
+        if (boundingBox == null) {
+            boundingBox = myCRIF.getBounds2D(paramBlock);
+        }
+        return (float)boundingBox.getWidth();
+    }
+
+    /**
+     * Gets the height in user coordinate space.  By convention, the
+     * usual height of a RenderedImage is equal to 1.0F.
+     *
+     * @return the height of the image in user coordinates.
+     */
+    public float getHeight() {
+        if (boundingBox == null) {
+            boundingBox = myCRIF.getBounds2D(paramBlock);
+        }
+        return (float)boundingBox.getHeight();
+    }
+
+    /**
+     * Gets the minimum X coordinate of the rendering-independent image data.
+     */
+    public float getMinX() {
+        if (boundingBox == null) {
+            boundingBox = myCRIF.getBounds2D(paramBlock);
+        }
+        return (float)boundingBox.getMinX();
+    }
+
+    /**
+     * Gets the minimum Y coordinate of the rendering-independent image data.
+     */
+    public float getMinY() {
+        if (boundingBox == null) {
+            boundingBox = myCRIF.getBounds2D(paramBlock);
+        }
+        return (float)boundingBox.getMinY();
+    }
+
+    /**
+     * Change the current ParameterBlock of the operation, allowing
+     * editing of image rendering chains.  The effects of such a
+     * change will be visible when a new rendering is created from
+     * this RenderableImageOp or any dependent RenderableImageOp.
+     *
+     * @param paramBlock the new ParameterBlock.
+     * @return the old ParameterBlock.
+     * @see #getParameterBlock
+     */
+    public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
+        ParameterBlock oldParamBlock = this.paramBlock;
+        this.paramBlock = (ParameterBlock)paramBlock.clone();
+        return oldParamBlock;
+    }
+
+    /**
+     * Returns a reference to the current parameter block.
+     * @return the <code>ParameterBlock</code> of this
+     *         <code>RenderableImageOp</code>.
+     * @see #setParameterBlock(ParameterBlock)
+     */
+    public ParameterBlock getParameterBlock() {
+        return paramBlock;
+    }
+
+    /**
+     * Creates a RenderedImage instance of this image with width w, and
+     * height h in pixels.  The RenderContext is built automatically
+     * with an appropriate usr2dev transform and an area of interest
+     * of the full image.  All the rendering hints come from hints
+     * passed in.
+     *
+     * <p> If w == 0, it will be taken to equal
+     * Math.round(h*(getWidth()/getHeight())).
+     * Similarly, if h == 0, it will be taken to equal
+     * Math.round(w*(getHeight()/getWidth())).  One of
+     * w or h must be non-zero or else an IllegalArgumentException
+     * will be thrown.
+     *
+     * <p> The created RenderedImage may have a property identified
+     * by the String HINTS_OBSERVED to indicate which RenderingHints
+     * were used to create the image.  In addition any RenderedImages
+     * that are obtained via the getSources() method on the created
+     * RenderedImage may have such a property.
+     *
+     * @param w the width of rendered image in pixels, or 0.
+     * @param h the height of rendered image in pixels, or 0.
+     * @param hints a RenderingHints object containg hints.
+     * @return a RenderedImage containing the rendered data.
+     */
+    public RenderedImage createScaledRendering(int w, int h,
+                                               RenderingHints hints) {
+        // DSR -- code to try to get a unit scale
+        double sx = (double)w/getWidth();
+        double sy = (double)h/getHeight();
+        if (Math.abs(sx/sy - 1.0) < 0.01) {
+            sx = sy;
+        }
+        AffineTransform usr2dev = AffineTransform.getScaleInstance(sx, sy);
+        RenderContext newRC = new RenderContext(usr2dev, hints);
+        return createRendering(newRC);
+    }
+
+    /**
+     * Gets a RenderedImage instance of this image with a default
+     * width and height in pixels.  The RenderContext is built
+     * automatically with an appropriate usr2dev transform and an area
+     * of interest of the full image.  All the rendering hints come
+     * from hints passed in.  Implementors of this interface must be
+     * sure that there is a defined default width and height.
+     *
+     * @return a RenderedImage containing the rendered data.
+     */
+    public RenderedImage createDefaultRendering() {
+        AffineTransform usr2dev = new AffineTransform(); // Identity
+        RenderContext newRC = new RenderContext(usr2dev);
+        return createRendering(newRC);
+    }
+
+    /**
+     * Creates a RenderedImage which represents this
+     * RenderableImageOp (including its Renderable sources) rendered
+     * according to the given RenderContext.
+     *
+     * <p> This method supports chaining of either Renderable or
+     * RenderedImage operations.  If sources in
+     * the ParameterBlock used to construct the RenderableImageOp are
+     * RenderableImages, then a three step process is followed:
+     *
+     * <ol>
+     * <li> mapRenderContext() is called on the associated CRIF for
+     * each RenderableImage source;
+     * <li> createRendering() is called on each of the RenderableImage sources
+     * using the backwards-mapped RenderContexts obtained in step 1,
+     * resulting in a rendering of each source;
+     * <li> ContextualRenderedImageFactory.create() is called
+     * with a new ParameterBlock containing the parameters of
+     * the RenderableImageOp and the RenderedImages that were created by the
+     * createRendering() calls.
+     * </ol>
+     *
+     * <p> If the elements of the source Vector of
+     * the ParameterBlock used to construct the RenderableImageOp are
+     * instances of RenderedImage, then the CRIF.create() method is
+     * called immediately using the original ParameterBlock.
+     * This provides a basis case for the recursion.
+     *
+     * <p> The created RenderedImage may have a property identified
+     * by the String HINTS_OBSERVED to indicate which RenderingHints
+     * (from the RenderContext) were used to create the image.
+     * In addition any RenderedImages
+     * that are obtained via the getSources() method on the created
+     * RenderedImage may have such a property.
+     *
+     * @param renderContext The RenderContext to use to perform the rendering.
+     * @return a RenderedImage containing the desired output image.
+     */
+    public RenderedImage createRendering(RenderContext renderContext) {
+        RenderedImage image = null;
+        RenderContext rcOut = null;
+
+        // Clone the original ParameterBlock; if the ParameterBlock
+        // contains RenderableImage sources, they will be replaced by
+        // RenderedImages.
+        ParameterBlock renderedParamBlock = (ParameterBlock)paramBlock.clone();
+        Vector sources = getRenderableSources();
+
+        try {
+            // This assumes that if there is no renderable source, that there
+            // is a rendered source in paramBlock
+
+            if (sources != null) {
+                Vector renderedSources = new Vector();
+                for (int i = 0; i < sources.size(); i++) {
+                    rcOut = myCRIF.mapRenderContext(i, renderContext,
+                                                    paramBlock, this);
+                    RenderedImage rdrdImage =
+                       ((RenderableImage)sources.elementAt(i)).createRendering(rcOut);
+                    if (rdrdImage == null) {
+                        return null;
+                    }
+
+                    // Add this rendered image to the ParameterBlock's
+                    // list of RenderedImages.
+                    renderedSources.addElement(rdrdImage);
+                }
+
+                if (renderedSources.size() > 0) {
+                    renderedParamBlock.setSources(renderedSources);
+                }
+            }
+
+            return myCRIF.create(renderContext, renderedParamBlock);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // This should never happen
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/renderable/RenderableImageProducer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,219 @@
+/*
+ * Portions Copyright 1998 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+package java.awt.image.renderable;
+import java.awt.color.ColorSpace;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DirectColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * An adapter class that implements ImageProducer to allow the
+ * asynchronous production of a RenderableImage.  The size of the
+ * ImageConsumer is determined by the scale factor of the usr2dev
+ * transform in the RenderContext.  If the RenderContext is null, the
+ * default rendering of the RenderableImage is used.  This class
+ * implements an asynchronous production that produces the image in
+ * one thread at one resolution.  This class may be subclassed to
+ * implement versions that will render the image using several
+ * threads.  These threads could render either the same image at
+ * progressively better quality, or different sections of the image at
+ * a single resolution.
+ */
+public class RenderableImageProducer implements ImageProducer, Runnable {
+
+    /** The RenderableImage source for the producer. */
+    RenderableImage rdblImage;
+
+    /** The RenderContext to use for producing the image. */
+    RenderContext rc;
+
+    /** A Vector of image consumers. */
+    Vector ics = new Vector();
+
+    /**
+     * Constructs a new RenderableImageProducer from a RenderableImage
+     * and a RenderContext.
+     *
+     * @param rdblImage the RenderableImage to be rendered.
+     * @param rc the RenderContext to use for producing the pixels.
+     */
+    public RenderableImageProducer(RenderableImage rdblImage,
+                                   RenderContext rc) {
+        this.rdblImage = rdblImage;
+        this.rc = rc;
+    }
+
+    /**
+     * Sets a new RenderContext to use for the next startProduction() call.
+     *
+     * @param rc the new RenderContext.
+     */
+    public synchronized void setRenderContext(RenderContext rc) {
+        this.rc = rc;
+    }
+
+   /**
+     * Adds an ImageConsumer to the list of consumers interested in
+     * data for this image.
+     *
+     * @param ic an ImageConsumer to be added to the interest list.
+     */
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if (!ics.contains(ic)) {
+            ics.addElement(ic);
+        }
+    }
+
+    /**
+     * Determine if an ImageConsumer is on the list of consumers
+     * currently interested in data for this image.
+     *
+     * @param ic the ImageConsumer to be checked.
+     * @return true if the ImageConsumer is on the list; false otherwise.
+     */
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        return ics.contains(ic);
+    }
+
+    /**
+     * Remove an ImageConsumer from the list of consumers interested in
+     * data for this image.
+     *
+     * @param ic the ImageConsumer to be removed.
+     */
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        ics.removeElement(ic);
+    }
+
+    /**
+     * Adds an ImageConsumer to the list of consumers interested in
+     * data for this image, and immediately starts delivery of the
+     * image data through the ImageConsumer interface.
+     *
+     * @param ic the ImageConsumer to be added to the list of consumers.
+     */
+    public synchronized void startProduction(ImageConsumer ic) {
+        addConsumer(ic);
+        // Need to build a runnable object for the Thread.
+        Thread thread = new Thread(this, "RenderableImageProducer Thread");
+        thread.start();
+    }
+
+    /**
+     * Requests that a given ImageConsumer have the image data delivered
+     * one more time in top-down, left-right order.
+     *
+     * @param ic the ImageConsumer requesting the resend.
+     */
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {
+        // So far, all pixels are already sent in TDLR order
+    }
+
+    /**
+     * The runnable method for this class. This will produce an image using
+     * the current RenderableImage and RenderContext and send it to all the
+     * ImageConsumer currently registered with this class.
+     */
+    public void run() {
+        // First get the rendered image
+        RenderedImage rdrdImage;
+        if (rc != null) {
+            rdrdImage = rdblImage.createRendering(rc);
+        } else {
+            rdrdImage = rdblImage.createDefaultRendering();
+        }
+
+        // And its ColorModel
+        ColorModel colorModel = rdrdImage.getColorModel();
+        Raster raster = rdrdImage.getData();
+        SampleModel sampleModel = raster.getSampleModel();
+        DataBuffer dataBuffer = raster.getDataBuffer();
+
+        if (colorModel == null) {
+            colorModel = ColorModel.getRGBdefault();
+        }
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+        int width = raster.getWidth();
+        int height = raster.getHeight();
+
+        Enumeration icList;
+        ImageConsumer ic;
+        // Set up the ImageConsumers
+        icList = ics.elements();
+        while (icList.hasMoreElements()) {
+            ic = (ImageConsumer)icList.nextElement();
+            ic.setDimensions(width,height);
+            ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
+                        ImageConsumer.COMPLETESCANLINES |
+                        ImageConsumer.SINGLEPASS |
+                        ImageConsumer.SINGLEFRAME);
+        }
+
+        // Get RGB pixels from the raster scanline by scanline and
+        // send to consumers.
+        int pix[] = new int[width];
+        int i,j;
+        int numBands = sampleModel.getNumBands();
+        int tmpPixel[] = new int[numBands];
+        for (j = 0; j < height; j++) {
+            for(i = 0; i < width; i++) {
+                sampleModel.getPixel(i, j, tmpPixel, dataBuffer);
+                pix[i] = colorModel.getDataElement(tmpPixel, 0);
+            }
+            // Now send the scanline to the Consumers
+            icList = ics.elements();
+            while (icList.hasMoreElements()) {
+                ic = (ImageConsumer)icList.nextElement();
+                ic.setPixels(0, j, width, 1, colorModel, pix, 0, width);
+            }
+        }
+
+        // Now tell the consumers we're done.
+        icList = ics.elements();
+        while (icList.hasMoreElements()) {
+            ic = (ImageConsumer)icList.nextElement();
+            ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/awt/image/renderable/RenderedImageFactory.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,78 @@
+/*
+ * Portions Copyright 1998 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* ********************************************************************
+ **********************************************************************
+ **********************************************************************
+ *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
+ *** As  an unpublished  work pursuant to Title 17 of the United    ***
+ *** States Code.  All rights reserved.                             ***
+ **********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+package java.awt.image.renderable;
+import java.awt.image.RenderedImage;
+import java.awt.RenderingHints;
+
+/**
+ * The RenderedImageFactory interface (often abbreviated RIF) is
+ * intended to be implemented by classes that wish to act as factories
+ * to produce different renderings, for example by executing a series
+ * of BufferedImageOps on a set of sources, depending on a specific
+ * set of parameters, properties, and rendering hints.
+ */
+public interface RenderedImageFactory {
+
+  /**
+   * Creates a RenderedImage representing the results of an imaging
+   * operation (or chain of operations) for a given ParameterBlock and
+   * RenderingHints.  The RIF may also query any source images
+   * referenced by the ParameterBlock for their dimensions,
+   * SampleModels, properties, etc., as necessary.
+   *
+   * <p> The create() method can return null if the
+   * RenderedImageFactory is not capable of producing output for the
+   * given set of source images and parameters.  For example, if a
+   * RenderedImageFactory is only capable of performing a 3x3
+   * convolution on single-banded image data, and the source image has
+   * multiple bands or the convolution Kernel is 5x5, null should be
+   * returned.
+   *
+   * <p> Hints should be taken into account, but can be ignored.
+   * The created RenderedImage may have a property identified
+   * by the String HINTS_OBSERVED to indicate which RenderingHints
+   * were used to create the image.  In addition any RenderedImages
+   * that are obtained via the getSources() method on the created
+   * RenderedImage may have such a property.
+   *
+   * @param paramBlock a ParameterBlock containing sources and parameters
+   *        for the RenderedImage to be created.
+   * @param hints a RenderingHints object containing hints.
+   * @return A RenderedImage containing the desired output.
+   */
+  RenderedImage create(ParameterBlock paramBlock,
+                       RenderingHints hints);
+}
--- a/src/share/classes/java/io/FileInputStream.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/io/FileInputStream.java	Mon Apr 14 11:34:15 2008 -0700
@@ -48,15 +48,15 @@
 class FileInputStream extends InputStream
 {
     /* File Descriptor - handle to the open file */
-    private FileDescriptor fd;
+    private final FileDescriptor fd;
 
     private FileChannel channel = null;
 
-    private Object closeLock = new Object();
+    private final Object closeLock = new Object();
     private volatile boolean closed = false;
 
-    private static ThreadLocal<Boolean> runningFinalize =
-                                new ThreadLocal<Boolean>();
+    private static final ThreadLocal<Boolean> runningFinalize =
+        new ThreadLocal<Boolean>();
 
     private static boolean isRunningFinalize() {
         Boolean val;
@@ -151,7 +151,7 @@
      * is thrown.
      * <p>
      * This constructor does not throw an exception if <code>fdObj</code>
-     * is {link java.io.FileDescriptor#valid() invalid}.
+     * is {@link java.io.FileDescriptor#valid() invalid}.
      * However, if the methods are invoked on the resulting stream to attempt
      * I/O on the stream, an <code>IOException</code> is thrown.
      *
@@ -389,7 +389,7 @@
      * @see        java.io.FileInputStream#close()
      */
     protected void finalize() throws IOException {
-        if ((fd != null) &&  (fd != fd.in)) {
+        if ((fd != null) &&  (fd != FileDescriptor.in)) {
 
             /*
              * Finalizer should not release the FileDescriptor if another
--- a/src/share/classes/java/io/FileOutputStream.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/io/FileOutputStream.java	Mon Apr 14 11:34:15 2008 -0700
@@ -52,20 +52,16 @@
 class FileOutputStream extends OutputStream
 {
     /**
-     * The system dependent file descriptor. The value is
-     * 1 more than actual file descriptor. This means that
-     * the default value 0 indicates that the file is not open.
+     * The system dependent file descriptor.
      */
-    private FileDescriptor fd;
+    private final FileDescriptor fd;
 
     private FileChannel channel= null;
 
-    private boolean append = false;
-
-    private Object closeLock = new Object();
+    private final Object closeLock = new Object();
     private volatile boolean closed = false;
-    private static ThreadLocal<Boolean> runningFinalize =
-                                        new ThreadLocal<Boolean>();
+    private static final ThreadLocal<Boolean> runningFinalize =
+        new ThreadLocal<Boolean>();
 
     private static boolean isRunningFinalize() {
         Boolean val;
@@ -75,7 +71,7 @@
     }
 
     /**
-     * Creates an output file stream to write to the file with the
+     * Creates a file output stream to write to the file with the
      * specified name. A new <code>FileDescriptor</code> object is
      * created to represent this file connection.
      * <p>
@@ -100,8 +96,8 @@
     }
 
     /**
-     * Creates an output file stream to write to the file with the specified
-     * <code>name</code>.  If the second argument is <code>true</code>, then
+     * Creates a file output stream to write to the file with the specified
+     * name.  If the second argument is <code>true</code>, then
      * bytes will be written to the end of the file rather than the beginning.
      * A new <code>FileDescriptor</code> object is created to represent this
      * file connection.
@@ -202,16 +198,11 @@
         }
         fd = new FileDescriptor();
         fd.incrementAndGetUseCount();
-        this.append = append;
-        if (append) {
-            openAppend(name);
-        } else {
-            open(name);
-        }
+        open(name, append);
     }
 
     /**
-     * Creates an output file stream to write to the specified file
+     * Creates a file output stream to write to the specified file
      * descriptor, which represents an existing connection to an actual
      * file in the file system.
      * <p>
@@ -223,7 +214,7 @@
      * is thrown.
      * <p>
      * This constructor does not throw an exception if <code>fdObj</code>
-     * is {link java.io.FileDescriptor#valid() invalid}.
+     * is {@link java.io.FileDescriptor#valid() invalid}.
      * However, if the methods are invoked on the resulting stream to attempt
      * I/O on the stream, an <code>IOException</code> is thrown.
      *
@@ -252,16 +243,12 @@
     }
 
     /**
-     * Opens a file, with the specified name, for writing.
+     * Opens a file, with the specified name, for overwriting or appending.
      * @param name name of file to be opened
+     * @param append whether the file is to be opened in append mode
      */
-    private native void open(String name) throws FileNotFoundException;
-
-    /**
-     * Opens a file, with the specified name, for appending.
-     * @param name name of file to be opened
-     */
-    private native void openAppend(String name) throws FileNotFoundException;
+    private native void open(String name, boolean append)
+        throws FileNotFoundException;
 
     /**
      * Writes the specified byte to this file output stream. Implements
@@ -385,7 +372,7 @@
     public FileChannel getChannel() {
         synchronized (this) {
             if (channel == null) {
-                channel = FileChannelImpl.open(fd, false, true, this, append);
+                channel = FileChannelImpl.open(fd, false, true, this);
 
                 /*
                  * Increment fd's use count. Invoking the channel's close()
@@ -408,7 +395,7 @@
      */
     protected void finalize() throws IOException {
         if (fd != null) {
-            if (fd == fd.out || fd == fd.err) {
+            if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
                 flush();
             } else {
 
--- a/src/share/classes/java/io/ObjectInputStream.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/io/ObjectInputStream.java	Mon Apr 14 11:34:15 2008 -0700
@@ -212,7 +212,8 @@
     private static final Object unsharedMarker = new Object();
 
     /** table mapping primitive type names to corresponding class objects */
-    private static final HashMap primClasses = new HashMap(8, 1.0F);
+    private static final HashMap<String, Class<?>> primClasses
+        = new HashMap<String, Class<?>>(8, 1.0F);
     static {
         primClasses.put("boolean", boolean.class);
         primClasses.put("byte", byte.class);
@@ -620,7 +621,7 @@
         try {
             return Class.forName(name, false, latestUserDefinedLoader());
         } catch (ClassNotFoundException ex) {
-            Class cl = (Class) primClasses.get(name);
+            Class<?> cl = primClasses.get(name);
             if (cl != null) {
                 return cl;
             } else {
@@ -1254,11 +1255,11 @@
      * override security-sensitive non-final methods.  Returns true if subclass
      * is "safe", false otherwise.
      */
-    private static boolean auditSubclass(final Class subcl) {
+    private static boolean auditSubclass(final Class<?> subcl) {
         Boolean result = AccessController.doPrivileged(
             new PrivilegedAction<Boolean>() {
                 public Boolean run() {
-                    for (Class cl = subcl;
+                    for (Class<?> cl = subcl;
                          cl != ObjectInputStream.class;
                          cl = cl.getSuperclass())
                     {
@@ -2217,9 +2218,9 @@
             try {
                 while (list != null) {
                     AccessController.doPrivileged(
-                        new PrivilegedExceptionAction()
+                        new PrivilegedExceptionAction<Void>()
                     {
-                        public Object run() throws InvalidObjectException {
+                        public Void run() throws InvalidObjectException {
                             list.obj.validateObject();
                             return null;
                         }
--- a/src/share/classes/java/io/ObjectStreamClass.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/io/ObjectStreamClass.java	Mon Apr 14 11:34:15 2008 -0700
@@ -77,7 +77,7 @@
         NO_FIELDS;
 
     /** reflection factory for obtaining serialization constructors */
-    private static final ReflectionFactory reflFactory = (ReflectionFactory)
+    private static final ReflectionFactory reflFactory =
         AccessController.doPrivileged(
             new ReflectionFactory.GetReflectionFactoryAction());
 
@@ -216,10 +216,10 @@
     public long getSerialVersionUID() {
         // REMIND: synchronize instead of relying on volatile?
         if (suid == null) {
-            suid = (Long) AccessController.doPrivileged(
-                new PrivilegedAction() {
-                    public Object run() {
-                        return Long.valueOf(computeDefaultSUID(cl));
+            suid = AccessController.doPrivileged(
+                new PrivilegedAction<Long>() {
+                    public Long run() {
+                        return computeDefaultSUID(cl);
                     }
                 }
             );
@@ -392,8 +392,8 @@
             }
             if (interrupted) {
                 AccessController.doPrivileged(
-                    new PrivilegedAction() {
-                        public Object run() {
+                    new PrivilegedAction<Void>() {
+                        public Void run() {
                             Thread.currentThread().interrupt();
                             return null;
                         }
@@ -427,8 +427,8 @@
         localDesc = this;
 
         if (serializable) {
-            AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
                     if (isEnum) {
                         suid = Long.valueOf(0);
                         fields = NO_FIELDS;
@@ -802,7 +802,7 @@
      * non-primitive types, and any other non-null type matches assignable
      * types only.  Returns matching field, or null if no match found.
      */
-    ObjectStreamField getField(String name, Class type) {
+    ObjectStreamField getField(String name, Class<?> type) {
         for (int i = 0; i < fields.length; i++) {
             ObjectStreamField f = fields[i];
             if (f.getName().equals(name)) {
@@ -811,7 +811,7 @@
                 {
                     return f;
                 }
-                Class ftype = f.getType();
+                Class<?> ftype = f.getType();
                 if (ftype != null && type.isAssignableFrom(ftype)) {
                     return f;
                 }
@@ -1130,7 +1130,7 @@
     private ClassDataSlot[] getClassDataLayout0()
         throws InvalidClassException
     {
-        ArrayList slots = new ArrayList();
+        ArrayList<ClassDataSlot> slots = new ArrayList<ClassDataSlot>();
         Class start = cl, end = cl;
 
         // locate closest non-serializable superclass
@@ -1171,8 +1171,7 @@
 
         // order slots from superclass -> subclass
         Collections.reverse(slots);
-        return (ClassDataSlot[])
-            slots.toArray(new ClassDataSlot[slots.size()]);
+        return slots.toArray(new ClassDataSlot[slots.size()]);
     }
 
     /**
@@ -1309,9 +1308,9 @@
      * Access checks are disabled on the returned constructor (if any), since
      * the defining class may still be non-public.
      */
-    private static Constructor getExternalizableConstructor(Class cl) {
+    private static Constructor getExternalizableConstructor(Class<?> cl) {
         try {
-            Constructor cons = cl.getDeclaredConstructor((Class[]) null);
+            Constructor cons = cl.getDeclaredConstructor((Class<?>[]) null);
             cons.setAccessible(true);
             return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ?
                 cons : null;
@@ -1325,15 +1324,15 @@
      * superclass, or null if none found.  Access checks are disabled on the
      * returned constructor (if any).
      */
-    private static Constructor getSerializableConstructor(Class cl) {
-        Class initCl = cl;
+    private static Constructor getSerializableConstructor(Class<?> cl) {
+        Class<?> initCl = cl;
         while (Serializable.class.isAssignableFrom(initCl)) {
             if ((initCl = initCl.getSuperclass()) == null) {
                 return null;
             }
         }
         try {
-            Constructor cons = initCl.getDeclaredConstructor((Class[]) null);
+            Constructor cons = initCl.getDeclaredConstructor((Class<?>[]) null);
             int mods = cons.getModifiers();
             if ((mods & Modifier.PRIVATE) != 0 ||
                 ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
@@ -1355,12 +1354,12 @@
      * null if no match found.  Access checks are disabled on the returned
      * method (if any).
      */
-    private static Method getInheritableMethod(Class cl, String name,
+    private static Method getInheritableMethod(Class<?> cl, String name,
                                                Class[] argTypes,
                                                Class returnType)
     {
         Method meth = null;
-        Class defCl = cl;
+        Class<?> defCl = cl;
         while (defCl != null) {
             try {
                 meth = defCl.getDeclaredMethod(name, argTypes);
@@ -1391,9 +1390,9 @@
      * class, or null if none found.  Access checks are disabled on the
      * returned method (if any).
      */
-    private static Method getPrivateMethod(Class cl, String name,
-                                           Class[] argTypes,
-                                           Class returnType)
+    private static Method getPrivateMethod(Class<?> cl, String name,
+                                           Class<?>[] argTypes,
+                                           Class<?> returnType)
     {
         try {
             Method meth = cl.getDeclaredMethod(name, argTypes);
@@ -1567,7 +1566,7 @@
 
         ObjectStreamField[] boundFields =
             new ObjectStreamField[serialPersistentFields.length];
-        Set fieldNames = new HashSet(serialPersistentFields.length);
+        Set<String> fieldNames = new HashSet<String>(serialPersistentFields.length);
 
         for (int i = 0; i < serialPersistentFields.length; i++) {
             ObjectStreamField spf = serialPersistentFields[i];
@@ -1605,7 +1604,7 @@
      */
     private static ObjectStreamField[] getDefaultSerialFields(Class cl) {
         Field[] clFields = cl.getDeclaredFields();
-        ArrayList list = new ArrayList();
+        ArrayList<ObjectStreamField> list = new ArrayList<ObjectStreamField>();
         int mask = Modifier.STATIC | Modifier.TRANSIENT;
 
         for (int i = 0; i < clFields.length; i++) {
@@ -1615,7 +1614,7 @@
         }
         int size = list.size();
         return (size == 0) ? NO_FIELDS :
-            (ObjectStreamField[]) list.toArray(new ObjectStreamField[size]);
+            list.toArray(new ObjectStreamField[size]);
     }
 
     /**
@@ -1688,11 +1687,9 @@
             for (int i = 0; i < fields.length; i++) {
                 fieldSigs[i] = new MemberSignature(fields[i]);
             }
-            Arrays.sort(fieldSigs, new Comparator() {
-                public int compare(Object o1, Object o2) {
-                    String name1 = ((MemberSignature) o1).name;
-                    String name2 = ((MemberSignature) o2).name;
-                    return name1.compareTo(name2);
+            Arrays.sort(fieldSigs, new Comparator<MemberSignature>() {
+                public int compare(MemberSignature ms1, MemberSignature ms2) {
+                    return ms1.name.compareTo(ms2.name);
                 }
             });
             for (int i = 0; i < fieldSigs.length; i++) {
@@ -1721,11 +1718,9 @@
             for (int i = 0; i < cons.length; i++) {
                 consSigs[i] = new MemberSignature(cons[i]);
             }
-            Arrays.sort(consSigs, new Comparator() {
-                public int compare(Object o1, Object o2) {
-                    String sig1 = ((MemberSignature) o1).signature;
-                    String sig2 = ((MemberSignature) o2).signature;
-                    return sig1.compareTo(sig2);
+            Arrays.sort(consSigs, new Comparator<MemberSignature>() {
+                public int compare(MemberSignature ms1, MemberSignature ms2) {
+                    return ms1.signature.compareTo(ms2.signature);
                 }
             });
             for (int i = 0; i < consSigs.length; i++) {
@@ -1746,10 +1741,8 @@
             for (int i = 0; i < methods.length; i++) {
                 methSigs[i] = new MemberSignature(methods[i]);
             }
-            Arrays.sort(methSigs, new Comparator() {
-                public int compare(Object o1, Object o2) {
-                    MemberSignature ms1 = (MemberSignature) o1;
-                    MemberSignature ms2 = (MemberSignature) o2;
+            Arrays.sort(methSigs, new Comparator<MemberSignature>() {
+                public int compare(MemberSignature ms1, MemberSignature ms2) {
                     int comp = ms1.name.compareTo(ms2.name);
                     if (comp == 0) {
                         comp = ms1.signature.compareTo(ms2.signature);
@@ -1859,7 +1852,7 @@
             keys = new long[nfields];
             offsets = new int[nfields];
             typeCodes = new char[nfields];
-            ArrayList typeList = new ArrayList();
+            ArrayList<Class<?>> typeList = new ArrayList<Class<?>>();
 
             for (int i = 0; i < nfields; i++) {
                 ObjectStreamField f = fields[i];
@@ -1873,7 +1866,7 @@
                 }
             }
 
-            types = (Class[]) typeList.toArray(new Class[typeList.size()]);
+            types = typeList.toArray(new Class<?>[typeList.size()]);
             numPrimFields = nfields - types.length;
         }
 
--- a/src/share/classes/java/lang/Class.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/lang/Class.java	Mon Apr 14 11:34:15 2008 -0700
@@ -345,9 +345,9 @@
                 // since we have to do the security check here anyway
                 // (the stack depth is wrong for the Constructor's
                 // security check to work)
-                java.security.AccessController.doPrivileged
-                    (new java.security.PrivilegedAction() {
-                            public Object run() {
+                java.security.AccessController.doPrivileged(
+                    new java.security.PrivilegedAction<Void>() {
+                        public Void run() {
                                 c.setAccessible(true);
                                 return null;
                             }
@@ -1302,10 +1302,10 @@
         // out anything other than public members and (2) public member access
         // has already been ok'd by the SecurityManager.
 
-        Class[] result = (Class[]) java.security.AccessController.doPrivileged
-            (new java.security.PrivilegedAction() {
-                public Object run() {
-                    java.util.List<Class> list = new java.util.ArrayList();
+        return java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Class[]>() {
+                public Class[] run() {
+                    List<Class> list = new ArrayList<Class>();
                     Class currentClass = Class.this;
                     while (currentClass != null) {
                         Class[] members = currentClass.getDeclaredClasses();
@@ -1316,12 +1316,9 @@
                         }
                         currentClass = currentClass.getSuperclass();
                     }
-                    Class[] empty = {};
-                    return list.toArray(empty);
+                    return list.toArray(new Class[0]);
                 }
             });
-
-        return result;
     }
 
 
@@ -2215,15 +2212,15 @@
 
     // Caches for certain reflective results
     private static boolean useCaches = true;
-    private volatile transient SoftReference declaredFields;
-    private volatile transient SoftReference publicFields;
-    private volatile transient SoftReference declaredMethods;
-    private volatile transient SoftReference publicMethods;
-    private volatile transient SoftReference declaredConstructors;
-    private volatile transient SoftReference publicConstructors;
+    private volatile transient SoftReference<Field[]> declaredFields;
+    private volatile transient SoftReference<Field[]> publicFields;
+    private volatile transient SoftReference<Method[]> declaredMethods;
+    private volatile transient SoftReference<Method[]> publicMethods;
+    private volatile transient SoftReference<Constructor<T>[]> declaredConstructors;
+    private volatile transient SoftReference<Constructor<T>[]> publicConstructors;
     // Intermediate results for getFields and getMethods
-    private volatile transient SoftReference declaredPublicFields;
-    private volatile transient SoftReference declaredPublicMethods;
+    private volatile transient SoftReference<Field[]> declaredPublicFields;
+    private volatile transient SoftReference<Method[]> declaredPublicMethods;
 
     // Incremented by the VM on each call to JVM TI RedefineClasses()
     // that redefines this class or a superclass.
@@ -2295,11 +2292,11 @@
             clearCachesOnClassRedefinition();
             if (publicOnly) {
                 if (declaredPublicFields != null) {
-                    res = (Field[]) declaredPublicFields.get();
+                    res = declaredPublicFields.get();
                 }
             } else {
                 if (declaredFields != null) {
-                    res = (Field[]) declaredFields.get();
+                    res = declaredFields.get();
                 }
             }
             if (res != null) return res;
@@ -2308,9 +2305,9 @@
         res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
         if (useCaches) {
             if (publicOnly) {
-                declaredPublicFields = new SoftReference(res);
+                declaredPublicFields = new SoftReference<Field[]>(res);
             } else {
-                declaredFields = new SoftReference(res);
+                declaredFields = new SoftReference<Field[]>(res);
             }
         }
         return res;
@@ -2319,22 +2316,22 @@
     // Returns an array of "root" fields. These Field objects must NOT
     // be propagated to the outside world, but must instead be copied
     // via ReflectionFactory.copyField.
-    private Field[] privateGetPublicFields(Set traversedInterfaces) {
+    private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
         checkInitted();
         Field[] res = null;
         if (useCaches) {
             clearCachesOnClassRedefinition();
             if (publicFields != null) {
-                res = (Field[]) publicFields.get();
+                res = publicFields.get();
             }
             if (res != null) return res;
         }
 
         // No cached value available; compute value recursively.
         // Traverse in correct order for getField().
-        List fields = new ArrayList();
+        List<Field> fields = new ArrayList<Field>();
         if (traversedInterfaces == null) {
-            traversedInterfaces = new HashSet();
+            traversedInterfaces = new HashSet<Class<?>>();
         }
 
         // Local fields
@@ -2342,9 +2339,7 @@
         addAll(fields, tmp);
 
         // Direct superinterfaces, recursively
-        Class[] interfaces = getInterfaces();
-        for (int i = 0; i < interfaces.length; i++) {
-            Class c = interfaces[i];
+        for (Class<?> c : getInterfaces()) {
             if (!traversedInterfaces.contains(c)) {
                 traversedInterfaces.add(c);
                 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
@@ -2353,7 +2348,7 @@
 
         // Direct superclass, recursively
         if (!isInterface()) {
-            Class c = getSuperclass();
+            Class<?> c = getSuperclass();
             if (c != null) {
                 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
             }
@@ -2362,12 +2357,12 @@
         res = new Field[fields.size()];
         fields.toArray(res);
         if (useCaches) {
-            publicFields = new SoftReference(res);
+            publicFields = new SoftReference<Field[]>(res);
         }
         return res;
     }
 
-    private static void addAll(Collection c, Field[] o) {
+    private static void addAll(Collection<Field> c, Field[] o) {
         for (int i = 0; i < o.length; i++) {
             c.add(o[i]);
         }
@@ -2383,18 +2378,18 @@
     // Returns an array of "root" constructors. These Constructor
     // objects must NOT be propagated to the outside world, but must
     // instead be copied via ReflectionFactory.copyConstructor.
-    private Constructor[] privateGetDeclaredConstructors(boolean publicOnly) {
+    private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
         checkInitted();
-        Constructor[] res = null;
+        Constructor<T>[] res = null;
         if (useCaches) {
             clearCachesOnClassRedefinition();
             if (publicOnly) {
                 if (publicConstructors != null) {
-                    res = (Constructor[]) publicConstructors.get();
+                    res = publicConstructors.get();
                 }
             } else {
                 if (declaredConstructors != null) {
-                    res = (Constructor[]) declaredConstructors.get();
+                    res = declaredConstructors.get();
                 }
             }
             if (res != null) return res;
@@ -2407,9 +2402,9 @@
         }
         if (useCaches) {
             if (publicOnly) {
-                publicConstructors = new SoftReference(res);
+                publicConstructors = new SoftReference<Constructor<T>[]>(res);
             } else {
-                declaredConstructors = new SoftReference(res);
+                declaredConstructors = new SoftReference<Constructor<T>[]>(res);
             }
         }
         return res;
@@ -2431,11 +2426,11 @@
             clearCachesOnClassRedefinition();
             if (publicOnly) {
                 if (declaredPublicMethods != null) {
-                    res = (Method[]) declaredPublicMethods.get();
+                    res = declaredPublicMethods.get();
                 }
             } else {
                 if (declaredMethods != null) {
-                    res = (Method[]) declaredMethods.get();
+                    res = declaredMethods.get();
                 }
             }
             if (res != null) return res;
@@ -2444,9 +2439,9 @@
         res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
         if (useCaches) {
             if (publicOnly) {
-                declaredPublicMethods = new SoftReference(res);
+                declaredPublicMethods = new SoftReference<Method[]>(res);
             } else {
-                declaredMethods = new SoftReference(res);
+                declaredMethods = new SoftReference<Method[]>(res);
             }
         }
         return res;
@@ -2552,7 +2547,7 @@
         if (useCaches) {
             clearCachesOnClassRedefinition();
             if (publicMethods != null) {
-                res = (Method[]) publicMethods.get();
+                res = publicMethods.get();
             }
             if (res != null) return res;
         }
@@ -2602,7 +2597,7 @@
         methods.compactAndTrim();
         res = methods.getArray();
         if (useCaches) {
-            publicMethods = new SoftReference(res);
+            publicMethods = new SoftReference<Method[]>(res);
         }
         return res;
     }
@@ -2713,11 +2708,11 @@
     private Constructor<T> getConstructor0(Class[] parameterTypes,
                                         int which) throws NoSuchMethodException
     {
-        Constructor[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
-        for (int i = 0; i < constructors.length; i++) {
+        Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
+        for (Constructor<T> constructor : constructors) {
             if (arrayContentsEq(parameterTypes,
-                                constructors[i].getParameterTypes())) {
-                return getReflectionFactory().copyConstructor(constructors[i]);
+                                constructor.getParameterTypes())) {
+                return getReflectionFactory().copyConstructor(constructor);
             }
         }
         throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
@@ -2767,18 +2762,18 @@
         return out;
     }
 
-    private static Constructor[] copyConstructors(Constructor[] arg) {
-        Constructor[] out = new Constructor[arg.length];
+    private static <U> Constructor<U>[] copyConstructors(Constructor<U>[] arg) {
+        Constructor<U>[] out = arg.clone();
         ReflectionFactory fact = getReflectionFactory();
-        for (int i = 0; i < arg.length; i++) {
-            out[i] = fact.copyConstructor(arg[i]);
+        for (int i = 0; i < out.length; i++) {
+            out[i] = fact.copyConstructor(out[i]);
         }
         return out;
     }
 
     private native Field[]       getDeclaredFields0(boolean publicOnly);
     private native Method[]      getDeclaredMethods0(boolean publicOnly);
-    private native Constructor[] getDeclaredConstructors0(boolean publicOnly);
+    private native Constructor<T>[] getDeclaredConstructors0(boolean publicOnly);
     private native Class[]   getDeclaredClasses0();
 
     private static String        argumentTypesToString(Class[] argTypes) {
@@ -2883,7 +2878,7 @@
     // Fetches the factory for reflective objects
     private static ReflectionFactory getReflectionFactory() {
         if (reflectionFactory == null) {
-            reflectionFactory =  (ReflectionFactory)
+            reflectionFactory =
                 java.security.AccessController.doPrivileged
                     (new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
         }
@@ -2895,8 +2890,8 @@
     private static boolean initted = false;
     private static void checkInitted() {
         if (initted) return;
-        AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
                     // Tests to ensure the system properties table is fully
                     // initialized. This is needed because reflection code is
                     // called very early in the initialization process (before
@@ -2941,17 +2936,17 @@
     /**
      * Returns the elements of this enum class or null if this
      * Class object does not represent an enum type;
-     * identical to getEnumConstantsShared except that
-     * the result is uncloned, cached, and shared by all callers.
+     * identical to getEnumConstants except that the result is
+     * uncloned, cached, and shared by all callers.
      */
     T[] getEnumConstantsShared() {
         if (enumConstants == null) {
             if (!isEnum()) return null;
             try {
                 final Method values = getMethod("values");
-                java.security.AccessController.doPrivileged
-                    (new java.security.PrivilegedAction() {
-                            public Object run() {
+                java.security.AccessController.doPrivileged(
+                    new java.security.PrivilegedAction<Void>() {
+                        public Void run() {
                                 values.setAccessible(true);
                                 return null;
                             }
--- a/src/share/classes/java/lang/ClassLoader.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/lang/ClassLoader.java	Mon Apr 14 11:34:15 2008 -0700
@@ -39,6 +39,7 @@
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.HashMap;
@@ -172,17 +173,18 @@
     private ClassLoader parent;
 
     // Hashtable that maps packages to certs
-    private Hashtable package2certs = new Hashtable(11);
+    private Hashtable<String, Certificate[]> package2certs
+        = new Hashtable<String, Certificate[]>(11);
 
     // Shared among all packages with unsigned classes
-    java.security.cert.Certificate[] nocerts;
+    Certificate[] nocerts;
 
     // The classes loaded by this class loader.  The only purpose of this table
     // is to keep the classes from being GC'ed until the loader is GC'ed.
-    private Vector classes = new Vector();
+    private Vector<Class<?>> classes = new Vector<Class<?>>();
 
     // The initiating protection domains for all classes loaded by this loader
-    private Set domains = new HashSet();
+    private Set<ProtectionDomain> domains = new HashSet<ProtectionDomain>();
 
     // Invoked by the VM to record every loaded class with this loader.
     void addClass(Class c) {
@@ -191,7 +193,7 @@
 
     // The packages defined in this class loader.  Each package name is mapped
     // to its corresponding Package object.
-    private HashMap packages = new HashMap();
+    private HashMap<String, Package> packages = new HashMap<String, Package>();
 
     /**
      * Creates a new class loader using the specified parent class loader for
@@ -342,8 +344,8 @@
             final String name = cls.getName();
             final int i = name.lastIndexOf('.');
             if (i != -1) {
-                AccessController.doPrivileged(new PrivilegedAction() {
-                    public Object run() {
+                AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    public Void run() {
                         sm.checkPackageAccess(name.substring(0, i));
                         return null;
                     }
@@ -524,17 +526,20 @@
         // Class format error - try to transform the bytecode and
         // define the class again
         //
-        Object[] transformers = ClassFileTransformer.getTransformers();
+        ClassFileTransformer[] transformers = ClassFileTransformer.getTransformers();
         Class c = null;
 
-        for (int i = 0; transformers != null && i < transformers.length; i++) {
-            try {
-              // Transform byte code using transformer
-              byte[] tb = ((ClassFileTransformer) transformers[i]).transform(b, off, len);
-              c = defineClass1(name, tb, 0, tb.length, protectionDomain, source);
-              break;
-            } catch (ClassFormatError cfe2)     {
-              // If ClassFormatError occurs, try next transformer
+        if (transformers != null) {
+            for (ClassFileTransformer transformer : transformers) {
+                try {
+                    // Transform byte code using transformer
+                    byte[] tb = transformer.transform(b, off, len);
+                    c = defineClass1(name, tb, 0, tb.length,
+                                     protectionDomain, source);
+                    break;
+                } catch (ClassFormatError cfe2)     {
+                    // If ClassFormatError occurs, try next transformer
+                }
             }
         }
 
@@ -550,7 +555,7 @@
     private void postDefineClass(Class c, ProtectionDomain protectionDomain)
     {
         if (protectionDomain.getCodeSource() != null) {
-            java.security.cert.Certificate certs[] =
+            Certificate certs[] =
                 protectionDomain.getCodeSource().getCertificates();
             if (certs != null)
                 setSigners(c, certs);
@@ -767,8 +772,7 @@
     private synchronized void checkCerts(String name, CodeSource cs) {
         int i = name.lastIndexOf('.');
         String pname = (i == -1) ? "" : name.substring(0, i);
-        java.security.cert.Certificate[] pcerts =
-            (java.security.cert.Certificate[]) package2certs.get(pname);
+        Certificate[] pcerts = package2certs.get(pname);
         if (pcerts == null) {
             // first class in this package gets to define which
             // certificates must be the same for all other classes
@@ -778,12 +782,12 @@
             }
             if (pcerts == null) {
                 if (nocerts == null)
-                    nocerts = new java.security.cert.Certificate[0];
+                    nocerts = new Certificate[0];
                 pcerts = nocerts;
             }
             package2certs.put(pname, pcerts);
         } else {
-            java.security.cert.Certificate[] certs = null;
+            Certificate[] certs = null;
             if (cs != null) {
                 certs = cs.getCertificates();
             }
@@ -799,8 +803,8 @@
      * check to make sure the certs for the new class (certs) are the same as
      * the certs for the first class inserted in the package (pcerts)
      */
-    private boolean compareCerts(java.security.cert.Certificate[] pcerts,
-                                 java.security.cert.Certificate[] certs)
+    private boolean compareCerts(Certificate[] pcerts,
+                                 Certificate[] certs)
     {
         // certs can be null, indicating no certs.
         if ((certs == null) || (certs.length == 0)) {
@@ -1031,7 +1035,7 @@
         }
         tmp[1] = findResources(name);
 
-        return new CompoundEnumeration(tmp);
+        return new CompoundEnumeration<URL>(tmp);
     }
 
     /**
@@ -1068,7 +1072,7 @@
      * @since  1.2
      */
     protected Enumeration<URL> findResources(String name) throws IOException {
-        return new CompoundEnumeration(new Enumeration[0]);
+        return java.util.Collections.emptyEnumeration();
     }
 
     /**
@@ -1134,13 +1138,13 @@
     /**
      * Find resources from the VM's built-in classloader.
      */
-    private static Enumeration getBootstrapResources(String name)
+    private static Enumeration<URL> getBootstrapResources(String name)
         throws IOException
     {
-        final Enumeration e = getBootstrapClassPath().getResources(name);
-        return new Enumeration () {
-            public Object nextElement() {
-                return ((Resource)e.nextElement()).getURL();
+        final Enumeration<Resource> e = getBootstrapClassPath().getResources(name);
+        return new Enumeration<URL> () {
+            public URL nextElement() {
+                return e.nextElement().getURL();
             }
             public boolean hasMoreElements() {
                 return e.hasMoreElements();
@@ -1323,9 +1327,8 @@
                 Throwable oops = null;
                 scl = l.getClassLoader();
                 try {
-                    PrivilegedExceptionAction a;
-                    a = new SystemClassLoaderAction(scl);
-                    scl = (ClassLoader) AccessController.doPrivileged(a);
+                    scl = AccessController.doPrivileged(
+                        new SystemClassLoaderAction(scl));
                 } catch (PrivilegedActionException pae) {
                     oops = pae.getCause();
                     if (oops instanceof InvocationTargetException) {
@@ -1456,7 +1459,7 @@
      */
     protected Package getPackage(String name) {
         synchronized (packages) {
-            Package pkg = (Package)packages.get(name);
+            Package pkg = packages.get(name);
             if (pkg == null) {
                 if (parent != null) {
                     pkg = parent.getPackage(name);
@@ -1481,9 +1484,9 @@
      * @since  1.2
      */
     protected Package[] getPackages() {
-        Map map;
+        Map<String, Package> map;
         synchronized (packages) {
-            map = (Map)packages.clone();
+            map = new HashMap<String, Package>(packages);
         }
         Package[] pkgs;
         if (parent != null) {
@@ -1499,7 +1502,7 @@
                 }
             }
         }
-        return (Package[])map.values().toArray(new Package[map.size()]);
+        return map.values().toArray(new Package[map.size()]);
     }
 
 
@@ -1585,8 +1588,7 @@
         // Invoked in the VM to determine the context class in
         // JNI_Load/JNI_Unload
         static Class getFromClass() {
-            return ((NativeLibrary)
-                    (ClassLoader.nativeLibraryContext.peek())).fromClass;
+            return ClassLoader.nativeLibraryContext.peek().fromClass;
         }
     }
 
@@ -1597,22 +1599,27 @@
     // Returns (and initializes) the default domain.
     private synchronized ProtectionDomain getDefaultDomain() {
         if (defaultDomain == null) {
-            CodeSource cs =
-                new CodeSource(null, (java.security.cert.Certificate[]) null);
+            CodeSource cs = new CodeSource(null, (Certificate[]) null);
             defaultDomain = new ProtectionDomain(cs, null, this, null);
         }
         return defaultDomain;
     }
 
     // All native library names we've loaded.
-    private static Vector loadedLibraryNames = new Vector();
+    private static Vector<String> loadedLibraryNames
+        = new Vector<String>();
+
     // Native libraries belonging to system classes.
-    private static Vector systemNativeLibraries = new Vector();
+    private static Vector<NativeLibrary> systemNativeLibraries
+        = new Vector<NativeLibrary>();
+
     // Native libraries associated with the class loader.
-    private Vector nativeLibraries = new Vector();
+    private Vector<NativeLibrary> nativeLibraries
+        = new Vector<NativeLibrary>();
 
     // native libraries being loaded/unloaded.
-    private static Stack nativeLibraryContext = new Stack();
+    private static Stack<NativeLibrary> nativeLibraryContext
+        = new Stack<NativeLibrary>();
 
     // The paths searched for libraries
     static private String usr_paths[];
@@ -1699,13 +1706,13 @@
     }
 
     private static boolean loadLibrary0(Class fromClass, final File file) {
-        Boolean exists = (Boolean)
-            AccessController.doPrivileged(new PrivilegedAction() {
+        boolean exists = AccessController.doPrivileged(
+            new PrivilegedAction<Object>() {
                 public Object run() {
-                    return new Boolean(file.exists());
-                }
-            });
-        if (!exists.booleanValue()) {
+                    return file.exists() ? Boolean.TRUE : null;
+                }})
+            != null;
+        if (!exists) {
             return false;
         }
         String name;
@@ -1716,12 +1723,12 @@
         }
         ClassLoader loader =
             (fromClass == null) ? null : fromClass.getClassLoader();
-        Vector libs =
+        Vector<NativeLibrary> libs =
             loader != null ? loader.nativeLibraries : systemNativeLibraries;
         synchronized (libs) {
             int size = libs.size();
             for (int i = 0; i < size; i++) {
-                NativeLibrary lib = (NativeLibrary)libs.elementAt(i);
+                NativeLibrary lib = libs.elementAt(i);
                 if (name.equals(lib.name)) {
                     return true;
                 }
@@ -1748,8 +1755,7 @@
                  */
                 int n = nativeLibraryContext.size();
                 for (int i = 0; i < n; i++) {
-                    NativeLibrary lib = (NativeLibrary)
-                        nativeLibraryContext.elementAt(i);
+                    NativeLibrary lib = nativeLibraryContext.elementAt(i);
                     if (name.equals(lib.name)) {
                         if (loader == lib.fromClass.getClassLoader()) {
                             return true;
@@ -1780,12 +1786,12 @@
 
     // Invoked in the VM class linking code.
     static long findNative(ClassLoader loader, String name) {
-        Vector libs =
+        Vector<NativeLibrary> libs =
             loader != null ? loader.nativeLibraries : systemNativeLibraries;
         synchronized (libs) {
             int size = libs.size();
             for (int i = 0; i < size; i++) {
-                NativeLibrary lib = (NativeLibrary)libs.elementAt(i);
+                NativeLibrary lib = libs.elementAt(i);
                 long entry = lib.find(name);
                 if (entry != 0)
                     return entry;
@@ -1805,13 +1811,13 @@
     // is null then we are delegating assertion status queries to the VM, i.e.,
     // none of this ClassLoader's assertion status modification methods have
     // been invoked.
-    private Map packageAssertionStatus = null;
+    private Map<String, Boolean> packageAssertionStatus = null;
 
     // Maps String fullyQualifiedClassName to Boolean assertionStatus If this
     // field is null then we are delegating assertion status queries to the VM,
     // i.e., none of this ClassLoader's assertion status modification methods
     // have been invoked.
-    Map classAssertionStatus = null;
+    Map<String, Boolean> classAssertionStatus = null;
 
     /**
      * Sets the default assertion status for this class loader.  This setting
@@ -1878,7 +1884,7 @@
         if (packageAssertionStatus == null)
             initializeJavaAssertionMaps();
 
-        packageAssertionStatus.put(packageName, Boolean.valueOf(enabled));
+        packageAssertionStatus.put(packageName, enabled);
     }
 
     /**
@@ -1909,7 +1915,7 @@
         if (classAssertionStatus == null)
             initializeJavaAssertionMaps();
 
-        classAssertionStatus.put(className, Boolean.valueOf(enabled));
+        classAssertionStatus.put(className, enabled);
     }
 
     /**
@@ -1927,8 +1933,8 @@
          * Whether or not "Java assertion maps" are initialized, set
          * them to empty maps, effectively ignoring any present settings.
          */
-        classAssertionStatus = new HashMap();
-        packageAssertionStatus = new HashMap();
+        classAssertionStatus = new HashMap<String, Boolean>();
+        packageAssertionStatus = new HashMap<String, Boolean>();
 
         defaultAssertionStatus = false;
     }
@@ -1962,20 +1968,20 @@
         // assert packageAssertionStatus != null;
 
         // Check for a class entry
-        result = (Boolean)classAssertionStatus.get(className);
+        result = classAssertionStatus.get(className);
         if (result != null)
             return result.booleanValue();
 
         // Check for most specific package entry
         int dotIndex = className.lastIndexOf(".");
         if (dotIndex < 0) { // default package
-            result = (Boolean)packageAssertionStatus.get(null);
+            result = packageAssertionStatus.get(null);
             if (result != null)
                 return result.booleanValue();
         }
         while(dotIndex > 0) {
             className = className.substring(0, dotIndex);
-            result = (Boolean)packageAssertionStatus.get(className);
+            result = packageAssertionStatus.get(className);
             if (result != null)
                 return result.booleanValue();
             dotIndex = className.lastIndexOf(".", dotIndex-1);
@@ -1989,17 +1995,17 @@
     private void initializeJavaAssertionMaps() {
         // assert Thread.holdsLock(this);
 
-        classAssertionStatus = new HashMap();
-        packageAssertionStatus = new HashMap();
+        classAssertionStatus = new HashMap<String, Boolean>();
+        packageAssertionStatus = new HashMap<String, Boolean>();
         AssertionStatusDirectives directives = retrieveDirectives();
 
         for(int i = 0; i < directives.classes.length; i++)
             classAssertionStatus.put(directives.classes[i],
-                              Boolean.valueOf(directives.classEnabled[i]));
+                                     directives.classEnabled[i]);
 
         for(int i = 0; i < directives.packages.length; i++)
             packageAssertionStatus.put(directives.packages[i],
-                              Boolean.valueOf(directives.packageEnabled[i]));
+                                       directives.packageEnabled[i]);
 
         defaultAssertionStatus = directives.deflt;
     }
@@ -2009,28 +2015,24 @@
 }
 
 
-class SystemClassLoaderAction implements PrivilegedExceptionAction {
+class SystemClassLoaderAction
+    implements PrivilegedExceptionAction<ClassLoader> {
     private ClassLoader parent;
 
     SystemClassLoaderAction(ClassLoader parent) {
         this.parent = parent;
     }
 
-    public Object run() throws Exception {
-        ClassLoader sys;
-        Constructor ctor;
-        Class c;
-        Class cp[] = { ClassLoader.class };
-        Object params[] = { parent };
-
+    public ClassLoader run() throws Exception {
         String cls = System.getProperty("java.system.class.loader");
         if (cls == null) {
             return parent;
         }
 
-        c = Class.forName(cls, true, parent);
-        ctor = c.getDeclaredConstructor(cp);
-        sys = (ClassLoader) ctor.newInstance(params);
+        Constructor ctor = Class.forName(cls, true, parent)
+            .getDeclaredConstructor(new Class[] { ClassLoader.class });
+        ClassLoader sys = (ClassLoader) ctor.newInstance(
+            new Object[] { parent });
         Thread.currentThread().setContextClassLoader(sys);
         return sys;
     }
--- a/src/share/classes/java/lang/Compiler.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/lang/Compiler.java	Mon Apr 14 11:34:15 2008 -0700
@@ -53,9 +53,9 @@
 
     static {
         registerNatives();
-        java.security.AccessController.doPrivileged
-            (new java.security.PrivilegedAction() {
-                public Object run() {
+        java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
                     boolean loaded = false;
                     String jit = System.getProperty("java.compiler");
                     if ((jit != null) && (!jit.equals("NONE")) &&
--- a/src/share/classes/java/lang/Long.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/lang/Long.java	Mon Apr 14 11:34:15 2008 -0700
@@ -650,7 +650,7 @@
 
         try {
             result = Long.valueOf(nm.substring(index), radix);
-            result = negative ? new Long((long)-result.longValue()) : result;
+            result = negative ? new Long(-result.longValue()) : result;
         } catch (NumberFormatException e) {
             // If number is Long.MIN_VALUE, we'll end up here. The next line
             // handles this case, and causes any genuine format error to be
--- a/src/share/classes/java/lang/Package.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/lang/Package.java	Mon Apr 14 11:34:15 2008 -0700
@@ -507,7 +507,7 @@
      */
     static Package getSystemPackage(String name) {
         synchronized (pkgs) {
-            Package pkg = (Package)pkgs.get(name);
+            Package pkg = pkgs.get(name);
             if (pkg == null) {
                 name = name.replace('.', '/').concat("/");
                 String fn = getSystemPackage0(name);
@@ -529,18 +529,18 @@
             for (int i = 0; i < names.length; i++) {
                 defineSystemPackage(names[i], getSystemPackage0(names[i]));
             }
-            return (Package[])pkgs.values().toArray(new Package[pkgs.size()]);
+            return pkgs.values().toArray(new Package[pkgs.size()]);
         }
     }
 
     private static Package defineSystemPackage(final String iname,
                                                final String fn)
     {
-        return (Package) AccessController.doPrivileged(new PrivilegedAction() {
-            public Object run() {
+        return AccessController.doPrivileged(new PrivilegedAction<Package>() {
+            public Package run() {
                 String name = iname;
                 // Get the cached code source url for the file name
-                URL url = (URL)urls.get(fn);
+                URL url = urls.get(fn);
                 if (url == null) {
                     // URL not found, so create one
                     File file = new File(fn);
@@ -559,7 +559,7 @@
                 // Convert to "."-separated package name
                 name = name.substring(0, name.length() - 1).replace('/', '.');
                 Package pkg;
-                Manifest man = (Manifest)mans.get(fn);
+                Manifest man = mans.get(fn);
                 if (man != null) {
                     pkg = new Package(name, man, url, null);
                 } else {
@@ -588,13 +588,16 @@
     }
 
     // The map of loaded system packages
-    private static Map pkgs = new HashMap(31);
+    private static Map<String, Package> pkgs
+        = new HashMap<String, Package>(31);
 
     // Maps each directory or zip file name to its corresponding url
-    private static Map urls = new HashMap(10);
+    private static Map<String, URL> urls
+        = new HashMap<String, URL>(10);
 
     // Maps each code source url for a jar file to its manifest
-    private static Map mans = new HashMap(10);
+    private static Map<String, Manifest> mans
+        = new HashMap<String, Manifest>(10);
 
     private static native String getSystemPackage0(String name);
     private static native String[] getSystemPackages0();
--- a/src/share/classes/java/lang/Process.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/lang/Process.java	Mon Apr 14 11:34:15 2008 -0700
@@ -41,18 +41,24 @@
  * <p>The methods that create processes may not work well for special
  * processes on certain native platforms, such as native windowing
  * processes, daemon processes, Win16/DOS processes on Microsoft
- * Windows, or shell scripts.  The created subprocess does not have
- * its own terminal or console.  All its standard I/O (i.e. stdin,
- * stdout, stderr) operations will be redirected to the parent process
- * through three streams
- * ({@link #getOutputStream()},
- * {@link #getInputStream()},
- * {@link #getErrorStream()}).
+ * Windows, or shell scripts.
+ *
+ * <p>By default, the created subprocess does not have its own terminal
+ * or console.  All its standard I/O (i.e. stdin, stdout, stderr)
+ * operations will be redirected to the parent process, where they can
+ * be accessed via the streams obtained using the methods
+ * {@link #getOutputStream()},
+ * {@link #getInputStream()}, and
+ * {@link #getErrorStream()}.
  * The parent process uses these streams to feed input to and get output
  * from the subprocess.  Because some native platforms only provide
  * limited buffer size for standard input and output streams, failure
  * to promptly write the input stream or read the output stream of
- * the subprocess may cause the subprocess to block, and even deadlock.
+ * the subprocess may cause the subprocess to block, or even deadlock.
+ *
+ * <p>Where desired, <a href="ProcessBuilder.html#redirect-input">
+ * subprocess I/O can also be redirected</a>
+ * using methods of the {@link ProcessBuilder} class.
  *
  * <p>The subprocess is not killed when there are no more references to
  * the {@code Process} object, but rather the subprocess
@@ -62,16 +68,22 @@
  * Process} object execute asynchronously or concurrently with respect
  * to the Java process that owns the {@code Process} object.
  *
- * @author  unascribed
- * @see     ProcessBuilder
+ * <p>As of 1.5, {@link ProcessBuilder#start()} is the preferred way
+ * to create a {@code Process}.
+ *
  * @since   JDK1.0
  */
 public abstract class Process {
     /**
      * Returns the output stream connected to the normal input of the
      * subprocess.  Output to the stream is piped into the standard
-     * input stream of the process represented by this {@code Process}
-     * object.
+     * input of the process represented by this {@code Process} object.
+     *
+     * <p>If the standard input of the subprocess has been redirected using
+     * {@link ProcessBuilder#redirectInput(Redirect)
+     * ProcessBuilder.redirectInput}
+     * then this method will return a
+     * <a href="ProcessBuilder.html#redirect-input">null output stream</a>.
      *
      * <p>Implementation note: It is a good idea for the returned
      * output stream to be buffered.
@@ -84,30 +96,47 @@
     /**
      * Returns the input stream connected to the normal output of the
      * subprocess.  The stream obtains data piped from the standard
-     * output stream of the process represented by this {@code
-     * Process} object.
+     * output of the process represented by this {@code Process} object.
+     *
+     * <p>If the standard output of the subprocess has been redirected using
+     * {@link ProcessBuilder#redirectOutput(Redirect)
+     * ProcessBuilder.redirectOutput}
+     * then this method will return a
+     * <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
+     *
+     * <p>Otherwise, if the standard error of the subprocess has been
+     * redirected using
+     * {@link ProcessBuilder#redirectErrorStream(boolean)
+     * ProcessBuilder.redirectErrorStream}
+     * then the input stream returned by this method will receive the
+     * merged standard output and the standard error of the subprocess.
      *
      * <p>Implementation note: It is a good idea for the returned
      * input stream to be buffered.
      *
      * @return the input stream connected to the normal output of the
      *         subprocess
-     * @see ProcessBuilder#redirectErrorStream()
      */
     abstract public InputStream getInputStream();
 
     /**
-     * Returns the input stream connected to the error output stream of
-     * the subprocess.  The stream obtains data piped from the error
-     * output stream of the process represented by this {@code Process}
-     * object.
+     * Returns the input stream connected to the error output of the
+     * subprocess.  The stream obtains data piped from the error output
+     * of the process represented by this {@code Process} object.
+     *
+     * <p>If the standard error of the subprocess has been redirected using
+     * {@link ProcessBuilder#redirectError(Redirect)
+     * ProcessBuilder.redirectError} or
+     * {@link ProcessBuilder#redirectErrorStream(boolean)
+     * ProcessBuilder.redirectErrorStream}
+     * then this method will return a
+     * <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
      *
      * <p>Implementation note: It is a good idea for the returned
      * input stream to be buffered.
      *
-     * @return the input stream connected to the error output stream of
+     * @return the input stream connected to the error output of
      *         the subprocess
-     * @see ProcessBuilder#redirectErrorStream()
      */
     abstract public InputStream getErrorStream();
 
--- a/src/share/classes/java/lang/ProcessBuilder.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/lang/ProcessBuilder.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,10 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.FileOutputStream;
+import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -34,7 +38,7 @@
 /**
  * This class is used to create operating system processes.
  *
- * <p>Each <code>ProcessBuilder</code> instance manages a collection
+ * <p>Each {@code ProcessBuilder} instance manages a collection
  * of process attributes.  The {@link #start()} method creates a new
  * {@link Process} instance with those attributes.  The {@link
  * #start()} method can be invoked repeatedly from the same instance
@@ -59,19 +63,64 @@
  *
  * <li>a <i>working directory</i>.  The default value is the current
  * working directory of the current process, usually the directory
- * named by the system property <code>user.dir</code>.
+ * named by the system property {@code user.dir}.
+ *
+ * <li><a name="redirect-input">a source of <i>standard input</i>.
+ * By default, the subprocess reads input from a pipe.  Java code
+ * can access this pipe via the output stream returned by
+ * {@link Process#getOutputStream()}.  However, standard input may
+ * be redirected to another source using
+ * {@link #redirectInput(Redirect) redirectInput}.
+ * In this case, {@link Process#getOutputStream()} will return a
+ * <i>null output stream</i>, for which:
+ *
+ * <ul>
+ * <li>the {@link OutputStream#write(int) write} methods always
+ * throw {@code IOException}
+ * <li>the {@link OutputStream#close() close} method does nothing
+ * </ul>
+ *
+ * <li><a name="redirect-output">a destination for <i>standard output</i>
+ * and <i>standard error</i>.  By default, the subprocess writes standard
+ * output and standard error to pipes.  Java code can access these pipes
+ * via the input streams returned by {@link Process#getInputStream()} and
+ * {@link Process#getErrorStream()}.  However, standard output and
+ * standard error may be redirected to other destinations using
+ * {@link #redirectOutput(Redirect) redirectOutput} and
+ * {@link #redirectError(Redirect) redirectError}.
+ * In this case, {@link Process#getInputStream()} and/or
+ * {@link Process#getErrorStream()} will return a <i>null input
+ * stream</i>, for which:
+ *
+ * <ul>
+ * <li>the {@link InputStream#read() read} methods always return
+ * {@code -1}
+ * <li>the {@link InputStream#available() available} method always returns
+ * {@code 0}
+ * <li>the {@link InputStream#close() close} method does nothing
+ * </ul>
  *
  * <li>a <i>redirectErrorStream</i> property.  Initially, this property
- * is <code>false</code>, meaning that the standard output and error
+ * is {@code false}, meaning that the standard output and error
  * output of a subprocess are sent to two separate streams, which can
  * be accessed using the {@link Process#getInputStream()} and {@link
- * Process#getErrorStream()} methods.  If the value is set to
- * <code>true</code>, the standard error is merged with the standard
- * output.  This makes it easier to correlate error messages with the
- * corresponding output.  In this case, the merged data can be read
- * from the stream returned by {@link Process#getInputStream()}, while
- * reading from the stream returned by {@link
- * Process#getErrorStream()} will get an immediate end of file.
+ * Process#getErrorStream()} methods.
+ *
+ * <p>If the value is set to {@code true}, then:
+ *
+ * <ul>
+ * <li>standard error is merged with the standard output and always sent
+ * to the same destination (this makes it easier to correlate error
+ * messages with the corresponding output)
+ * <li>the common destination of standard error and standard output can be
+ * redirected using
+ * {@link #redirectOutput(Redirect) redirectOutput}
+ * <li>any redirection set by the
+ * {@link #redirectError(Redirect) redirectError}
+ * method is ignored when creating a subprocess
+ * <li>the stream returned from {@link Process#getErrorStream()} will
+ * always be a <a href="#redirect-output">null input stream</a>
+ * </ul>
  *
  * </ul>
  *
@@ -87,34 +136,43 @@
  * is invoked.
  *
  * <p><strong>Note that this class is not synchronized.</strong>
- * If multiple threads access a <code>ProcessBuilder</code> instance
+ * If multiple threads access a {@code ProcessBuilder} instance
  * concurrently, and at least one of the threads modifies one of the
  * attributes structurally, it <i>must</i> be synchronized externally.
  *
  * <p>Starting a new process which uses the default working directory
  * and environment is easy:
  *
- * <blockquote><pre>
+ * <pre> {@code
  * Process p = new ProcessBuilder("myCommand", "myArg").start();
- * </pre></blockquote>
+ * }</pre>
  *
  * <p>Here is an example that starts a process with a modified working
- * directory and environment:
+ * directory and environment, and redirects standard output and error
+ * to be appended to a log file:
  *
- * <blockquote><pre>
- * ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
- * Map&lt;String, String&gt; env = pb.environment();
+ * <pre> {@code
+ * ProcessBuilder pb =
+ *   new ProcessBuilder("myCommand", "myArg1", "myArg2");
+ * Map<String, String> env = pb.environment();
  * env.put("VAR1", "myValue");
  * env.remove("OTHERVAR");
  * env.put("VAR2", env.get("VAR1") + "suffix");
  * pb.directory(new File("myDir"));
+ * File log = new File("log");
+ * pb.redirectErrorStream(true);
+ * pb.redirectOutput(Redirect.appendTo(log));
  * Process p = pb.start();
- * </pre></blockquote>
+ * assert pb.redirectInput() == Redirect.PIPE;
+ * assert pb.redirectOutput().file() == log;
+ * assert p.getInputStream().read() == -1;
+ * }</pre>
  *
  * <p>To start a process with an explicit set of environment
  * variables, first call {@link java.util.Map#clear() Map.clear()}
  * before adding environment variables.
  *
+ * @author Martin Buchholz
  * @since 1.5
  */
 
@@ -124,20 +182,19 @@
     private File directory;
     private Map<String,String> environment;
     private boolean redirectErrorStream;
+    private Redirect[] redirects;
 
     /**
      * Constructs a process builder with the specified operating
      * system program and arguments.  This constructor does <i>not</i>
-     * make a copy of the <code>command</code> list.  Subsequent
+     * make a copy of the {@code command} list.  Subsequent
      * updates to the list will be reflected in the state of the
      * process builder.  It is not checked whether
-     * <code>command</code> corresponds to a valid operating system
-     * command.</p>
+     * {@code command} corresponds to a valid operating system
+     * command.
      *
-     * @param   command  The list containing the program and its arguments
-     *
-     * @throws  NullPointerException
-     *          If the argument is <code>null</code>
+     * @param  command the list containing the program and its arguments
+     * @throws NullPointerException if the argument is null
      */
     public ProcessBuilder(List<String> command) {
         if (command == null)
@@ -149,12 +206,12 @@
      * Constructs a process builder with the specified operating
      * system program and arguments.  This is a convenience
      * constructor that sets the process builder's command to a string
-     * list containing the same strings as the <code>command</code>
+     * list containing the same strings as the {@code command}
      * array, in the same order.  It is not checked whether
-     * <code>command</code> corresponds to a valid operating system
-     * command.</p>
+     * {@code command} corresponds to a valid operating system
+     * command.
      *
-     * @param   command  A string array containing the program and its arguments
+     * @param command a string array containing the program and its arguments
      */
     public ProcessBuilder(String... command) {
         this.command = new ArrayList<String>(command.length);
@@ -165,16 +222,15 @@
     /**
      * Sets this process builder's operating system program and
      * arguments.  This method does <i>not</i> make a copy of the
-     * <code>command</code> list.  Subsequent updates to the list will
+     * {@code command} list.  Subsequent updates to the list will
      * be reflected in the state of the process builder.  It is not
-     * checked whether <code>command</code> corresponds to a valid
-     * operating system command.</p>
+     * checked whether {@code command} corresponds to a valid
+     * operating system command.
      *
-     * @param   command  The list containing the program and its arguments
-     * @return  This process builder
+     * @param  command the list containing the program and its arguments
+     * @return this process builder
      *
-     * @throws  NullPointerException
-     *          If the argument is <code>null</code>
+     * @throws NullPointerException if the argument is null
      */
     public ProcessBuilder command(List<String> command) {
         if (command == null)
@@ -187,12 +243,12 @@
      * Sets this process builder's operating system program and
      * arguments.  This is a convenience method that sets the command
      * to a string list containing the same strings as the
-     * <code>command</code> array, in the same order.  It is not
-     * checked whether <code>command</code> corresponds to a valid
-     * operating system command.</p>
+     * {@code command} array, in the same order.  It is not
+     * checked whether {@code command} corresponds to a valid
+     * operating system command.
      *
-     * @param   command  A string array containing the program and its arguments
-     * @return  This process builder
+     * @param  command a string array containing the program and its arguments
+     * @return this process builder
      */
     public ProcessBuilder command(String... command) {
         this.command = new ArrayList<String>(command.length);
@@ -205,9 +261,9 @@
      * Returns this process builder's operating system program and
      * arguments.  The returned list is <i>not</i> a copy.  Subsequent
      * updates to the list will be reflected in the state of this
-     * process builder.</p>
+     * process builder.
      *
-     * @return  This process builder's program and its arguments
+     * @return this process builder's program and its arguments
      */
     public List<String> command() {
         return command;
@@ -225,10 +281,10 @@
      * <p>The returned object may be modified using ordinary {@link
      * java.util.Map Map} operations.  These modifications will be
      * visible to subprocesses started via the {@link #start()}
-     * method.  Two <code>ProcessBuilder</code> instances always
+     * method.  Two {@code ProcessBuilder} instances always
      * contain independent process environments, so changes to the
      * returned map will never be reflected in any other
-     * <code>ProcessBuilder</code> instance or the values returned by
+     * {@code ProcessBuilder} instance or the values returned by
      * {@link System#getenv System.getenv}.
      *
      * <p>If the system does not support environment variables, an
@@ -262,25 +318,24 @@
      * <p>The returned map is typically case-sensitive on all platforms.
      *
      * <p>If a security manager exists, its
-     * {@link SecurityManager#checkPermission checkPermission}
-     * method is called with a
-     * <code>{@link RuntimePermission}("getenv.*")</code>
-     * permission.  This may result in a {@link SecurityException} being
-     * thrown.
+     * {@link SecurityManager#checkPermission checkPermission} method
+     * is called with a
+     * {@link RuntimePermission}{@code ("getenv.*")} permission.
+     * This may result in a {@link SecurityException} being thrown.
      *
      * <p>When passing information to a Java subprocess,
      * <a href=System.html#EnvironmentVSSystemProperties>system properties</a>
-     * are generally preferred over environment variables.</p>
+     * are generally preferred over environment variables.
      *
-     * @return  This process builder's environment
+     * @return this process builder's environment
      *
-     * @throws  SecurityException
-     *          If a security manager exists and its
-     *          {@link SecurityManager#checkPermission checkPermission}
-     *          method doesn't allow access to the process environment
+     * @throws SecurityException
+     *         if a security manager exists and its
+     *         {@link SecurityManager#checkPermission checkPermission}
+     *         method doesn't allow access to the process environment
      *
-     * @see     Runtime#exec(String[],String[],java.io.File)
-     * @see     System#getenv()
+     * @see    Runtime#exec(String[],String[],java.io.File)
+     * @see    System#getenv()
      */
     public Map<String,String> environment() {
         SecurityManager security = System.getSecurityManager();
@@ -328,12 +383,12 @@
      *
      * Subprocesses subsequently started by this object's {@link
      * #start()} method will use this as their working directory.
-     * The returned value may be <code>null</code> -- this means to use
+     * The returned value may be {@code null} -- this means to use
      * the working directory of the current Java process, usually the
-     * directory named by the system property <code>user.dir</code>,
-     * as the working directory of the child process.</p>
+     * directory named by the system property {@code user.dir},
+     * as the working directory of the child process.
      *
-     * @return  This process builder's working directory
+     * @return this process builder's working directory
      */
     public File directory() {
         return directory;
@@ -344,50 +399,522 @@
      *
      * Subprocesses subsequently started by this object's {@link
      * #start()} method will use this as their working directory.
-     * The argument may be <code>null</code> -- this means to use the
+     * The argument may be {@code null} -- this means to use the
      * working directory of the current Java process, usually the
-     * directory named by the system property <code>user.dir</code>,
-     * as the working directory of the child process.</p>
+     * directory named by the system property {@code user.dir},
+     * as the working directory of the child process.
      *
-     * @param   directory  The new working directory
-     * @return  This process builder
+     * @param  directory the new working directory
+     * @return this process builder
      */
     public ProcessBuilder directory(File directory) {
         this.directory = directory;
         return this;
     }
 
+    // ---------------- I/O Redirection ----------------
+
+    /**
+     * Implements a <a href="#redirect-output">null input stream</a>.
+     */
+    static class NullInputStream extends InputStream {
+        public int read()      { return -1; }
+        public int available() { return 0; }
+    }
+
+    /**
+     * Implements a <a href="#redirect-input">null output stream</a>.
+     */
+    static class NullOutputStream extends OutputStream {
+        public void write(int b) throws IOException {
+            throw new IOException("Stream closed");
+        }
+    }
+
+    /**
+     * Represents a source of subprocess input or a destination of
+     * subprocess output.
+     *
+     * Each {@code Redirect} instance is one of the following:
+     *
+     * <ul>
+     * <li>the special value {@link #PIPE Redirect.PIPE}
+     * <li>the special value {@link #INHERIT Redirect.INHERIT}
+     * <li>a redirection to read from a file, created by an invocation of
+     *     {@link Redirect#from Redirect.from(File)}
+     * <li>a redirection to write to a file,  created by an invocation of
+     *     {@link Redirect#to Redirect.to(File)}
+     * <li>a redirection to append to a file, created by an invocation of
+     *     {@link Redirect#appendTo Redirect.appendTo(File)}
+     * </ul>
+     *
+     * <p>Each of the above categories has an associated unique
+     * {@link Type Type}.
+     *
+     * @since 1.7
+     */
+    public static abstract class Redirect {
+        /**
+         * The type of a {@link Redirect}.
+         */
+        public enum Type {
+            /**
+             * The type of {@link Redirect#PIPE Redirect.PIPE}.
+             */
+            PIPE,
+
+            /**
+             * The type of {@link Redirect#INHERIT Redirect.INHERIT}.
+             */
+            INHERIT,
+
+            /**
+             * The type of redirects returned from
+             * {@link Redirect#from Redirect.from(File)}.
+             */
+            READ,
+
+            /**
+             * The type of redirects returned from
+             * {@link Redirect#to Redirect.to(File)}.
+             */
+            WRITE,
+
+            /**
+             * The type of redirects returned from
+             * {@link Redirect#appendTo Redirect.appendTo(File)}.
+             */
+            APPEND
+        };
+
+        /**
+         * Returns the type of this {@code Redirect}.
+         * @return the type of this {@code Redirect}
+         */
+        public abstract Type type();
+
+        /**
+         * Indicates that subprocess I/O will be connected to the
+         * current Java process over a pipe.
+         *
+         * This is the default handling of subprocess standard I/O.
+         *
+         * <p>It will always be true that
+         *  <pre> {@code
+         * Redirect.PIPE.file() == null &&
+         * Redirect.PIPE.type() == Redirect.Type.PIPE
+         * }</pre>
+         */
+        public static final Redirect PIPE = new Redirect() {
+                public Type type() { return Type.PIPE; }
+                public String toString() { return type().toString(); }};
+
+        /**
+         * Indicates that subprocess I/O source or destination will be the
+         * same as those of the current process.  This is the normal
+         * behavior of most operating system command interpreters (shells).
+         *
+         * <p>It will always be true that
+         *  <pre> {@code
+         * Redirect.INHERIT.file() == null &&
+         * Redirect.INHERIT.type() == Redirect.Type.INHERIT
+         * }</pre>
+         */
+        public static final Redirect INHERIT = new Redirect() {
+                public Type type() { return Type.INHERIT; }
+                public String toString() { return type().toString(); }};
+
+        /**
+         * Returns the {@link File} source or destination associated
+         * with this redirect, or {@code null} if there is no such file.
+         *
+         * @return the file associated with this redirect,
+         *         or {@code null} if there is no such file
+         */
+        public File file() { return null; }
+
+        FileOutputStream toFileOutputStream() throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * Returns a redirect to read from the specified file.
+         *
+         * <p>It will always be true that
+         *  <pre> {@code
+         * Redirect.from(file).file() == file &&
+         * Redirect.from(file).type() == Redirect.Type.READ
+         * }</pre>
+         *
+         * @throws NullPointerException if the specified file is null
+         * @return a redirect to read from the specified file
+         */
+        public static Redirect from(final File file) {
+            if (file == null)
+                throw new NullPointerException();
+            return new Redirect() {
+                    public Type type() { return Type.READ; }
+                    public File file() { return file; }
+                    public String toString() {
+                        return "redirect to read from file \"" + file + "\"";
+                    }
+                };
+        }
+
+        /**
+         * Returns a redirect to write to the specified file.
+         * If the specified file exists when the subprocess is started,
+         * its previous contents will be discarded.
+         *
+         * <p>It will always be true that
+         *  <pre> {@code
+         * Redirect.to(file).file() == file &&
+         * Redirect.to(file).type() == Redirect.Type.WRITE
+         * }</pre>
+         *
+         * @throws NullPointerException if the specified file is null
+         * @return a redirect to write to the specified file
+         */
+        public static Redirect to(final File file) {
+            if (file == null)
+                throw new NullPointerException();
+            return new Redirect() {
+                    public Type type() { return Type.WRITE; }
+                    public File file() { return file; }
+                    public String toString() {
+                        return "redirect to write to file \"" + file + "\"";
+                    }
+                    FileOutputStream toFileOutputStream() throws IOException {
+                        return new FileOutputStream(file, false);
+                    }
+                };
+        }
+
+        /**
+         * Returns a redirect to append to the specified file.
+         * Each write operation first advances the position to the
+         * end of the file and then writes the requested data.
+         * Whether the advancement of the position and the writing
+         * of the data are done in a single atomic operation is
+         * system-dependent and therefore unspecified.
+         *
+         * <p>It will always be true that
+         *  <pre> {@code
+         * Redirect.appendTo(file).file() == file &&
+         * Redirect.appendTo(file).type() == Redirect.Type.APPEND
+         * }</pre>
+         *
+         * @throws NullPointerException if the specified file is null
+         * @return a redirect to append to the specified file
+         */
+        public static Redirect appendTo(final File file) {
+            if (file == null)
+                throw new NullPointerException();
+            return new Redirect() {
+                    public Type type() { return Type.APPEND; }
+                    public File file() { return file; }
+                    public String toString() {
+                        return "redirect to append to file \"" + file + "\"";
+                    }
+                    FileOutputStream toFileOutputStream() throws IOException {
+                        return new FileOutputStream(file, true);
+                    }
+                };
+        }
+
+        /**
+         * Compares the specified object with this {@code Redirect} for
+         * equality.  Returns {@code true} if and only if the two
+         * objects are identical or both objects are {@code Redirect}
+         * instances of the same type associated with non-null equal
+         * {@code File} instances.
+         */
+        public boolean equals(Object obj) {
+            if (obj == this)
+                return true;
+            if (! (obj instanceof Redirect))
+                return false;
+            Redirect r = (Redirect) obj;
+            if (r.type() != this.type())
+                return false;
+            assert this.file() != null;
+            return this.file().equals(r.file());
+        }
+
+        /**
+         * Returns a hash code value for this {@code Redirect}.
+         * @return a hash code value for this {@code Redirect}
+         */
+        public int hashCode() {
+            File file = file();
+            if (file == null)
+                return super.hashCode();
+            else
+                return file.hashCode();
+        }
+
+        /**
+         * No public constructors.  Clients must use predefined
+         * static {@code Redirect} instances or factory methods.
+         */
+        private Redirect() {}
+    }
+
+    private Redirect[] redirects() {
+        if (redirects == null)
+            redirects = new Redirect[] {
+                Redirect.PIPE, Redirect.PIPE, Redirect.PIPE
+            };
+        return redirects;
+    }
+
+    /**
+     * Sets this process builder's standard input source.
+     *
+     * Subprocesses subsequently started by this object's {@link #start()}
+     * method obtain their standard input from this source.
+     *
+     * <p>If the source is {@link Redirect#PIPE Redirect.PIPE}
+     * (the initial value), then the standard input of a
+     * subprocess can be written to using the output stream
+     * returned by {@link Process#getOutputStream()}.
+     * If the source is set to any other value, then
+     * {@link Process#getOutputStream()} will return a
+     * <a href="#redirect-input">null output stream</a>.
+     *
+     * @param  source the new standard input source
+     * @return this process builder
+     * @throws IllegalArgumentException
+     *         if the redirect does not correspond to a valid source
+     *         of data, that is, has type
+     *         {@link Redirect.Type#WRITE WRITE} or
+     *         {@link Redirect.Type#APPEND APPEND}
+     * @since  1.7
+     */
+    public ProcessBuilder redirectInput(Redirect source) {
+        if (source.type() == Redirect.Type.WRITE ||
+            source.type() == Redirect.Type.APPEND)
+            throw new IllegalArgumentException(
+                "Redirect invalid for reading: " + source);
+        redirects()[0] = source;
+        return this;
+    }
+
+    /**
+     * Sets this process builder's standard output destination.
+     *
+     * Subprocesses subsequently started by this object's {@link #start()}
+     * method send their standard output to this destination.
+     *
+     * <p>If the destination is {@link Redirect#PIPE Redirect.PIPE}
+     * (the initial value), then the standard output of a subprocess
+     * can be read using the input stream returned by {@link
+     * Process#getInputStream()}.
+     * If the destination is set to any other value, then
+     * {@link Process#getInputStream()} will return a
+     * <a href="#redirect-output">null input stream</a>.
+     *
+     * @param  destination the new standard output destination
+     * @return this process builder
+     * @throws IllegalArgumentException
+     *         if the redirect does not correspond to a valid
+     *         destination of data, that is, has type
+     *         {@link Redirect.Type#READ READ}
+     * @since  1.7
+     */
+    public ProcessBuilder redirectOutput(Redirect destination) {
+        if (destination.type() == Redirect.Type.READ)
+            throw new IllegalArgumentException(
+                "Redirect invalid for writing: " + destination);
+        redirects()[1] = destination;
+        return this;
+    }
+
+    /**
+     * Sets this process builder's standard error destination.
+     *
+     * Subprocesses subsequently started by this object's {@link #start()}
+     * method send their standard error to this destination.
+     *
+     * <p>If the destination is {@link Redirect#PIPE Redirect.PIPE}
+     * (the initial value), then the error output of a subprocess
+     * can be read using the input stream returned by {@link
+     * Process#getErrorStream()}.
+     * If the destination is set to any other value, then
+     * {@link Process#getErrorStream()} will return a
+     * <a href="#redirect-output">null input stream</a>.
+     *
+     * <p>If the {@link #redirectErrorStream redirectErrorStream}
+     * attribute has been set {@code true}, then the redirection set
+     * by this method has no effect.
+     *
+     * @param  destination the new standard error destination
+     * @return this process builder
+     * @throws IllegalArgumentException
+     *         if the redirect does not correspond to a valid
+     *         destination of data, that is, has type
+     *         {@link Redirect.Type#READ READ}
+     * @since  1.7
+     */
+    public ProcessBuilder redirectError(Redirect destination) {
+        if (destination.type() == Redirect.Type.READ)
+            throw new IllegalArgumentException(
+                "Redirect invalid for writing: " + destination);
+        redirects()[2] = destination;
+        return this;
+    }
+
+    /**
+     * Sets this process builder's standard input source to a file.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     * {@code redirectInput(file)}
+     * behaves in exactly the same way as the invocation
+     * {@link #redirectInput(Redirect) redirectInput}
+     * {@code (Redirect.from(file))}.
+     *
+     * @param  file the new standard input source
+     * @return this process builder
+     * @since  1.7
+     */
+    public ProcessBuilder redirectInput(File file) {
+        return redirectInput(Redirect.from(file));
+    }
+
+    /**
+     * Sets this process builder's standard output destination to a file.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     * {@code redirectOutput(file)}
+     * behaves in exactly the same way as the invocation
+     * {@link #redirectOutput(Redirect) redirectOutput}
+     * {@code (Redirect.to(file))}.
+     *
+     * @param  file the new standard output destination
+     * @return this process builder
+     * @since  1.7
+     */
+    public ProcessBuilder redirectOutput(File file) {
+        return redirectOutput(Redirect.to(file));
+    }
+
+    /**
+     * Sets this process builder's standard error destination to a file.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     * {@code redirectError(file)}
+     * behaves in exactly the same way as the invocation
+     * {@link #redirectError(Redirect) redirectError}
+     * {@code (Redirect.to(file))}.
+     *
+     * @param  file the new standard error destination
+     * @return this process builder
+     * @since  1.7
+     */
+    public ProcessBuilder redirectError(File file) {
+        return redirectError(Redirect.to(file));
+    }
+
+    /**
+     * Returns this process builder's standard input source.
+     *
+     * Subprocesses subsequently started by this object's {@link #start()}
+     * method obtain their standard input from this source.
+     * The initial value is {@link Redirect#PIPE Redirect.PIPE}.
+     *
+     * @return this process builder's standard input source
+     * @since  1.7
+     */
+    public Redirect redirectInput() {
+        return (redirects == null) ? Redirect.PIPE : redirects[0];
+    }
+
+    /**
+     * Returns this process builder's standard output destination.
+     *
+     * Subprocesses subsequently started by this object's {@link #start()}
+     * method redirect their standard output to this destination.
+     * The initial value is {@link Redirect#PIPE Redirect.PIPE}.
+     *
+     * @return this process builder's standard output destination
+     * @since  1.7
+     */
+    public Redirect redirectOutput() {
+        return (redirects == null) ? Redirect.PIPE : redirects[1];
+    }
+
+    /**
+     * Returns this process builder's standard error destination.
+     *
+     * Subprocesses subsequently started by this object's {@link #start()}
+     * method redirect their standard error to this destination.
+     * The initial value is {@link Redirect#PIPE Redirect.PIPE}.
+     *
+     * @return this process builder's standard error destination
+     * @since  1.7
+     */
+    public Redirect redirectError() {
+        return (redirects == null) ? Redirect.PIPE : redirects[2];
+    }
+
+    /**
+     * Sets the source and destination for subprocess standard I/O
+     * to be the same as those of the current Java process.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     *  <pre> {@code
+     * pb.inheritIO()
+     * }</pre>
+     * behaves in exactly the same way as the invocation
+     *  <pre> {@code
+     * pb.redirectInput(Redirect.INHERIT)
+     *   .redirectOutput(Redirect.INHERIT)
+     *   .redirectError(Redirect.INHERIT)
+     * }</pre>
+     *
+     * This gives behavior equivalent to most operating system
+     * command interpreters, or the standard C library function
+     * {@code system()}.
+     *
+     * @return this process builder
+     * @since  1.7
+     */
+    public ProcessBuilder inheritIO() {
+        Arrays.fill(redirects(), Redirect.INHERIT);
+        return this;
+    }
+
     /**
      * Tells whether this process builder merges standard error and
      * standard output.
      *
-     * <p>If this property is <code>true</code>, then any error output
+     * <p>If this property is {@code true}, then any error output
      * generated by subprocesses subsequently started by this object's
      * {@link #start()} method will be merged with the standard
      * output, so that both can be read using the
      * {@link Process#getInputStream()} method.  This makes it easier
      * to correlate error messages with the corresponding output.
-     * The initial value is <code>false</code>.</p>
+     * The initial value is {@code false}.
      *
-     * @return  This process builder's <code>redirectErrorStream</code> property
+     * @return this process builder's {@code redirectErrorStream} property
      */
     public boolean redirectErrorStream() {
         return redirectErrorStream;
     }
 
     /**
-     * Sets this process builder's <code>redirectErrorStream</code> property.
+     * Sets this process builder's {@code redirectErrorStream} property.
      *
-     * <p>If this property is <code>true</code>, then any error output
+     * <p>If this property is {@code true}, then any error output
      * generated by subprocesses subsequently started by this object's
      * {@link #start()} method will be merged with the standard
      * output, so that both can be read using the
      * {@link Process#getInputStream()} method.  This makes it easier
      * to correlate error messages with the corresponding output.
-     * The initial value is <code>false</code>.</p>
+     * The initial value is {@code false}.
      *
-     * @param   redirectErrorStream  The new property value
-     * @return  This process builder
+     * @param  redirectErrorStream the new property value
+     * @return this process builder
      */
     public ProcessBuilder redirectErrorStream(boolean redirectErrorStream) {
         this.redirectErrorStream = redirectErrorStream;
@@ -410,7 +937,7 @@
      * <p>If there is a security manager, its
      * {@link SecurityManager#checkExec checkExec}
      * method is called with the first component of this object's
-     * <code>command</code> array as its argument. This may result in
+     * {@code command} array as its argument. This may result in
      * a {@link SecurityException} being thrown.
      *
      * <p>Starting an operating system process is highly system-dependent.
@@ -426,26 +953,42 @@
      * subclass of {@link IOException}.
      *
      * <p>Subsequent modifications to this process builder will not
-     * affect the returned {@link Process}.</p>
+     * affect the returned {@link Process}.
      *
-     * @return  A new {@link Process} object for managing the subprocess
+     * @return a new {@link Process} object for managing the subprocess
+     *
+     * @throws NullPointerException
+     *         if an element of the command list is null
      *
-     * @throws  NullPointerException
-     *          If an element of the command list is null
+     * @throws IndexOutOfBoundsException
+     *         if the command is an empty list (has size {@code 0})
      *
-     * @throws  IndexOutOfBoundsException
-     *          If the command is an empty list (has size <code>0</code>)
+     * @throws SecurityException
+     *         if a security manager exists and
+     *         <ul>
+     *
+     *         <li>its
+     *         {@link SecurityManager#checkExec checkExec}
+     *         method doesn't allow creation of the subprocess, or
      *
-     * @throws  SecurityException
-     *          If a security manager exists and its
-     *          {@link SecurityManager#checkExec checkExec}
-     *          method doesn't allow creation of the subprocess
+     *         <li>the standard input to the subprocess was
+     *         {@linkplain #redirectInput redirected from a file}
+     *         and the security manager's
+     *         {@link SecurityManager#checkRead checkRead} method
+     *         denies read access to the file, or
      *
-     * @throws  IOException
-     *          If an I/O error occurs
+     *         <li>the standard output or standard error of the
+     *         subprocess was
+     *         {@linkplain #redirectOutput redirected to a file}
+     *         and the security manager's
+     *         {@link SecurityManager#checkWrite checkWrite} method
+     *         denies write access to the file
      *
-     * @see     Runtime#exec(String[], String[], java.io.File)
-     * @see     SecurityManager#checkExec(String)
+     *         </ul>
+     *
+     * @throws IOException if an I/O error occurs
+     *
+     * @see Runtime#exec(String[], String[], java.io.File)
      */
     public Process start() throws IOException {
         // Must convert to array first -- a malicious user-supplied
@@ -467,6 +1010,7 @@
             return ProcessImpl.start(cmdarray,
                                      environment,
                                      dir,
+                                     redirects,
                                      redirectErrorStream);
         } catch (IOException e) {
             // It's much easier for us to create a high-quality error
--- a/src/share/classes/java/lang/StringCoding.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/lang/StringCoding.java	Mon Apr 14 11:34:15 2008 -0700
@@ -53,22 +53,23 @@
 
     private StringCoding() { }
 
-    /* The cached coders for each thread
-     */
-    private static ThreadLocal decoder = new ThreadLocal();
-    private static ThreadLocal encoder = new ThreadLocal();
+    /** The cached coders for each thread */
+    private final static ThreadLocal<SoftReference<StringDecoder>> decoder =
+        new ThreadLocal<SoftReference<StringDecoder>>();
+    private final static ThreadLocal<SoftReference<StringEncoder>> encoder =
+        new ThreadLocal<SoftReference<StringEncoder>>();
 
     private static boolean warnUnsupportedCharset = true;
 
-    private static Object deref(ThreadLocal tl) {
-        SoftReference sr = (SoftReference)tl.get();
+    private static <T> T deref(ThreadLocal<SoftReference<T>> tl) {
+        SoftReference<T> sr = tl.get();
         if (sr == null)
             return null;
         return sr.get();
     }
 
-    private static void set(ThreadLocal tl, Object ob) {
-        tl.set(new SoftReference(ob));
+    private static <T> void set(ThreadLocal<SoftReference<T>> tl, T ob) {
+        tl.set(new SoftReference<T>(ob));
     }
 
     // Trim the given byte array to the given length
@@ -174,7 +175,7 @@
     static char[] decode(String charsetName, byte[] ba, int off, int len)
         throws UnsupportedEncodingException
     {
-        StringDecoder sd = (StringDecoder)deref(decoder);
+        StringDecoder sd = deref(decoder);
         String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
         if ((sd == null) || !(csn.equals(sd.requestedCharsetName())
                               || csn.equals(sd.charsetName()))) {
@@ -193,8 +194,7 @@
 
     static char[] decode(Charset cs, byte[] ba, int off, int len) {
         StringDecoder sd = new StringDecoder(cs, cs.name());
-        byte[] b = Arrays.copyOf(ba, ba.length);
-        return sd.decode(b, off, len);
+        return sd.decode(Arrays.copyOfRange(ba, off, off + len), 0, len);
     }
 
     static char[] decode(byte[] ba, int off, int len) {
@@ -273,7 +273,7 @@
     static byte[] encode(String charsetName, char[] ca, int off, int len)
         throws UnsupportedEncodingException
     {
-        StringEncoder se = (StringEncoder)deref(encoder);
+        StringEncoder se = deref(encoder);
         String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
         if ((se == null) || !(csn.equals(se.requestedCharsetName())
                               || csn.equals(se.charsetName()))) {
@@ -292,8 +292,7 @@
 
     static byte[] encode(Charset cs, char[] ca, int off, int len) {
         StringEncoder se = new StringEncoder(cs, cs.name());
-        char[] c = Arrays.copyOf(ca, ca.length);
-        return se.encode(c, off, len);
+        return se.encode(Arrays.copyOfRange(ca, off, off + len), 0, len);
     }
 
     static byte[] encode(char[] ca, int off, int len) {
--- a/src/share/classes/java/lang/ref/Finalizer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/lang/ref/Finalizer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -121,8 +121,9 @@
        invokers of these methods from a stalled or deadlocked finalizer thread.
      */
     private static void forkSecondaryFinalizer(final Runnable proc) {
-        PrivilegedAction pa = new PrivilegedAction() {
-            public Object run() {
+        AccessController.doPrivileged(
+            new PrivilegedAction<Void>() {
+                public Void run() {
                 ThreadGroup tg = Thread.currentThread().getThreadGroup();
                 for (ThreadGroup tgn = tg;
                      tgn != null;
@@ -135,8 +136,7 @@
                     /* Ignore */
                 }
                 return null;
-            }};
-        AccessController.doPrivileged(pa);
+                }});
     }
 
     /* Called by Runtime.runFinalization() */
--- a/src/share/classes/java/lang/reflect/AccessibleObject.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/lang/reflect/AccessibleObject.java	Mon Apr 14 11:34:15 2008 -0700
@@ -165,9 +165,9 @@
     // Reflection factory used by subclasses for creating field,
     // method, and constructor accessors. Note that this is called
     // very early in the bootstrapping process.
-    static final ReflectionFactory reflectionFactory = (ReflectionFactory)
-        AccessController.doPrivileged
-            (new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
+    static final ReflectionFactory reflectionFactory =
+        AccessController.doPrivileged(
+            new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
 
     /**
      * @throws NullPointerException {@inheritDoc}
--- a/src/share/classes/java/lang/reflect/Modifier.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/lang/reflect/Modifier.java	Mon Apr 14 11:34:15 2008 -0700
@@ -58,9 +58,8 @@
      */
     static {
         sun.reflect.ReflectionFactory factory =
-            (sun.reflect.ReflectionFactory) AccessController.doPrivileged(
-                new ReflectionFactory.GetReflectionFactoryAction()
-            );
+            AccessController.doPrivileged(
+                new ReflectionFactory.GetReflectionFactoryAction());
         factory.setLangReflectAccess(new java.lang.reflect.ReflectAccess());
     }
 
--- a/src/share/classes/java/lang/reflect/Proxy.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/lang/reflect/Proxy.java	Mon Apr 14 11:34:15 2008 -0700
@@ -33,6 +33,7 @@
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.List;
 import java.util.WeakHashMap;
 import sun.misc.ProxyGenerator;
 
@@ -230,7 +231,8 @@
         { InvocationHandler.class };
 
     /** maps a class loader to the proxy class cache for that loader */
-    private static Map loaderToCache = new WeakHashMap();
+    private static Map<ClassLoader, Map<List<String>, Object>> loaderToCache
+        = new WeakHashMap<ClassLoader, Map<List<String>, Object>>();
 
     /** marks that a particular proxy class is currently being generated */
     private static Object pendingGenerationMarker = new Object();
@@ -240,8 +242,8 @@
     private static Object nextUniqueNumberLock = new Object();
 
     /** set of all generated proxy classes, for isProxyClass implementation */
-    private static Map proxyClasses =
-        Collections.synchronizedMap(new WeakHashMap());
+    private static Map<Class<?>, Void> proxyClasses =
+        Collections.synchronizedMap(new WeakHashMap<Class<?>, Void>());
 
     /**
      * the invocation handler for this proxy instance.
@@ -353,7 +355,8 @@
         /* collect interface names to use as key for proxy class cache */
         String[] interfaceNames = new String[interfaces.length];
 
-        Set interfaceSet = new HashSet();       // for detecting duplicates
+        // for detecting duplicates
+        Set<Class<?>> interfaceSet = new HashSet<Class<?>>();
 
         for (int i = 0; i < interfaces.length; i++) {
             /*
@@ -401,16 +404,16 @@
          * representation of a class makes for an implicit weak
          * reference to the class.
          */
-        Object key = Arrays.asList(interfaceNames);
+        List<String> key = Arrays.asList(interfaceNames);
 
         /*
          * Find or create the proxy class cache for the class loader.
          */
-        Map cache;
+        Map<List<String>, Object> cache;
         synchronized (loaderToCache) {
-            cache = (Map) loaderToCache.get(loader);
+            cache = loaderToCache.get(loader);
             if (cache == null) {
-                cache = new HashMap();
+                cache = new HashMap<List<String>, Object>();
                 loaderToCache.put(loader, cache);
             }
             /*
@@ -442,7 +445,7 @@
             do {
                 Object value = cache.get(key);
                 if (value instanceof Reference) {
-                    proxyClass = (Class) ((Reference) value).get();
+                    proxyClass = (Class<?>) ((Reference) value).get();
                 }
                 if (proxyClass != null) {
                     // proxy class already generated: return it
@@ -544,7 +547,7 @@
              */
             synchronized (cache) {
                 if (proxyClass != null) {
-                    cache.put(key, new WeakReference(proxyClass));
+                    cache.put(key, new WeakReference<Class<?>>(proxyClass));
                 } else {
                     cache.remove(key);
                 }
@@ -595,14 +598,14 @@
         /*
          * Look up or generate the designated proxy class.
          */
-        Class cl = getProxyClass(loader, interfaces);
+        Class<?> cl = getProxyClass(loader, interfaces);
 
         /*
          * Invoke its constructor with the designated invocation handler.
          */
         try {
             Constructor cons = cl.getConstructor(constructorParams);
-            return (Object) cons.newInstance(new Object[] { h });
+            return cons.newInstance(new Object[] { h });
         } catch (NoSuchMethodException e) {
             throw new InternalError(e.toString());
         } catch (IllegalAccessException e) {
--- a/src/share/classes/java/net/AbstractPlainSocketImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/net/AbstractPlainSocketImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -664,7 +664,6 @@
     abstract void socketSetOption(int cmd, boolean on, Object value)
         throws SocketException;
     abstract int socketGetOption(int opt, Object iaContainerObj) throws SocketException;
-    abstract int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) throws SocketException;
     abstract void socketSendUrgentData(int data)
         throws IOException;
 
--- a/src/share/classes/java/net/DatagramSocket.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/net/DatagramSocket.java	Mon Apr 14 11:34:15 2008 -0700
@@ -287,8 +287,9 @@
         // DatagramSocketImpl.peekdata() is a protected method, therefore we need to use
         // getDeclaredMethod, therefore we need permission to access the member
         try {
-            AccessController.doPrivileged(new PrivilegedExceptionAction() {
-                    public Object run() throws NoSuchMethodException {
+            AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Void>() {
+                    public Void run() throws NoSuchMethodException {
                         Class[] cl = new Class[1];
                         cl[0] = DatagramPacket.class;
                         impl.getClass().getDeclaredMethod("peekData", cl);
--- a/src/share/classes/java/net/InterfaceAddress.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/net/InterfaceAddress.java	Mon Apr 14 11:34:15 2008 -0700
@@ -103,11 +103,9 @@
             return false;
         }
         InterfaceAddress cmp = (InterfaceAddress) obj;
-        if ((address != null & cmp.address == null) ||
-            (!address.equals(cmp.address)))
+        if ( !(address == null ? cmp.address == null : address.equals(cmp.address)) )
             return false;
-        if ((broadcast != null & cmp.broadcast == null) ||
-            (!broadcast.equals(cmp.broadcast)))
+        if ( !(broadcast  == null ? cmp.broadcast == null : broadcast.equals(cmp.broadcast)) )
             return false;
         if (maskLength != cmp.maskLength)
             return false;
--- a/src/share/classes/java/net/NetworkInterface.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/net/NetworkInterface.java	Mon Apr 14 11:34:15 2008 -0700
@@ -425,8 +425,6 @@
         return virtual;
     }
 
-    private native static long getSubnet0(String name, int ind) throws SocketException;
-    private native static Inet4Address getBroadcast0(String name, int ind) throws SocketException;
     private native static boolean isUp0(String name, int ind) throws SocketException;
     private native static boolean isLoopback0(String name, int ind) throws SocketException;
     private native static boolean supportsMulticast0(String name, int ind) throws SocketException;
--- a/src/share/classes/java/net/ServerSocket.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/net/ServerSocket.java	Mon Apr 14 11:34:15 2008 -0700
@@ -247,8 +247,9 @@
         // SocketImpl.connect() is a protected method, therefore we need to use
         // getDeclaredMethod, therefore we need permission to access the member
         try {
-            AccessController.doPrivileged(new PrivilegedExceptionAction() {
-                    public Object run() throws NoSuchMethodException {
+            AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Void>() {
+                    public Void run() throws NoSuchMethodException {
                         Class[] cl = new Class[2];
                         cl[0] = SocketAddress.class;
                         cl[1] = Integer.TYPE;
--- a/src/share/classes/java/net/Socket.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/net/Socket.java	Mon Apr 14 11:34:15 2008 -0700
@@ -731,7 +731,8 @@
      * then this method will continue to return the connected address
      * after the socket is closed.
      *
-     * @return a <code>SocketAddress</code> reprensenting the remote endpoint of this
+
+     * @return a <code>SocketAddress</code> representing the remote endpoint of this
      *         socket, or <code>null</code> if it is not connected yet.
      * @see #getInetAddress()
      * @see #getPort()
@@ -847,9 +848,9 @@
         final Socket s = this;
         InputStream is = null;
         try {
-            is = (InputStream)
-                AccessController.doPrivileged(new PrivilegedExceptionAction() {
-                    public Object run() throws IOException {
+            is = AccessController.doPrivileged(
+                new PrivilegedExceptionAction<InputStream>() {
+                    public InputStream run() throws IOException {
                         return impl.getInputStream();
                     }
                 });
@@ -887,9 +888,9 @@
         final Socket s = this;
         OutputStream os = null;
         try {
-            os = (OutputStream)
-                AccessController.doPrivileged(new PrivilegedExceptionAction() {
-                    public Object run() throws IOException {
+            os = AccessController.doPrivileged(
+                new PrivilegedExceptionAction<OutputStream>() {
+                    public OutputStream run() throws IOException {
                         return impl.getOutputStream();
                     }
                 });
--- a/src/share/classes/java/net/SocksSocketImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/net/SocksSocketImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -78,8 +78,8 @@
     {
         try {
             AccessController.doPrivileged(
-                  new java.security.PrivilegedExceptionAction() {
-                          public Object run() throws IOException {
+                new java.security.PrivilegedExceptionAction<Void>() {
+                    public Void run() throws IOException {
                               superConnectServer(host, port, timeout);
                               cmdIn = getInputStream();
                               cmdOut = getOutputStream();
@@ -129,10 +129,10 @@
             String userName;
             String password = null;
             final InetAddress addr = InetAddress.getByName(server);
-            PasswordAuthentication pw = (PasswordAuthentication)
+            PasswordAuthentication pw =
                 java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedAction() {
-                            public Object run() {
+                    new java.security.PrivilegedAction<PasswordAuthentication>() {
+                        public PasswordAuthentication run() {
                                 return Authenticator.requestPasswordAuthentication(
                                        server, addr, port, "SOCKS5", "SOCKS authentication", null);
                             }
@@ -339,10 +339,9 @@
             // This is the general case
             // server is not null only when the socket was created with a
             // specified proxy in which case it does bypass the ProxySelector
-            ProxySelector sel = (ProxySelector)
-                java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedAction() {
-                        public Object run() {
+            ProxySelector sel = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<ProxySelector>() {
+                    public ProxySelector run() {
                             return ProxySelector.getDefault();
                         }
                     });
@@ -652,10 +651,9 @@
             // This is the general case
             // server is not null only when the socket was created with a
             // specified proxy in which case it does bypass the ProxySelector
-            ProxySelector sel = (ProxySelector)
-                java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedAction() {
-                        public Object run() {
+            ProxySelector sel = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<ProxySelector>() {
+                    public ProxySelector run() {
                             return ProxySelector.getDefault();
                         }
                     });
@@ -701,8 +699,9 @@
 
                 // Connects to the SOCKS server
                 try {
-                    AccessController.doPrivileged(new PrivilegedExceptionAction() {
-                            public Object run() throws Exception {
+                    AccessController.doPrivileged(
+                        new PrivilegedExceptionAction<Void>() {
+                            public Void run() throws Exception {
                                 cmdsock = new Socket(new PlainSocketImpl());
                                 cmdsock.connect(new InetSocketAddress(server, port));
                                 cmdIn = cmdsock.getInputStream();
@@ -731,8 +730,9 @@
             }
         } else {
             try {
-                AccessController.doPrivileged(new PrivilegedExceptionAction() {
-                        public Object run() throws Exception {
+                AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<Void>() {
+                        public Void run() throws Exception {
                             cmdsock = new Socket(new PlainSocketImpl());
                             cmdsock.connect(new InetSocketAddress(server, port));
                             cmdIn = cmdsock.getInputStream();
--- a/src/share/classes/java/net/URLClassLoader.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/net/URLClassLoader.java	Mon Apr 14 11:34:15 2008 -0700
@@ -205,9 +205,9 @@
          throws ClassNotFoundException
     {
         try {
-            return (Class)
-                AccessController.doPrivileged(new PrivilegedExceptionAction() {
-                    public Object run() throws ClassNotFoundException {
+            return AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Class>() {
+                    public Class run() throws ClassNotFoundException {
                         String path = name.replace('.', '/').concat(".class");
                         Resource res = ucp.getResource(path, false);
                         if (res != null) {
@@ -376,9 +376,9 @@
         /*
          * The same restriction to finding classes applies to resources
          */
-        URL url =
-            (URL) AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+        URL url = AccessController.doPrivileged(
+            new PrivilegedAction<URL>() {
+                public URL run() {
                     return ucp.findResource(name, true);
                 }
             }, acc);
@@ -397,7 +397,7 @@
     public Enumeration<URL> findResources(final String name)
         throws IOException
     {
-        final Enumeration e = ucp.findResources(name, true);
+        final Enumeration<URL> e = ucp.findResources(name, true);
 
         return new Enumeration<URL>() {
             private URL url = null;
@@ -407,9 +407,9 @@
                     return true;
                 }
                 do {
-                    URL u = (URL)
-                        AccessController.doPrivileged(new PrivilegedAction() {
-                            public Object run() {
+                    URL u = AccessController.doPrivileged(
+                        new PrivilegedAction<URL>() {
+                            public URL run() {
                                 if (!e.hasMoreElements())
                                     return null;
                                 return e.nextElement();
@@ -515,8 +515,8 @@
             final SecurityManager sm = System.getSecurityManager();
             if (sm != null) {
                 final Permission fp = p;
-                AccessController.doPrivileged(new PrivilegedAction() {
-                    public Object run() throws SecurityException {
+                AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    public Void run() throws SecurityException {
                         sm.checkPermission(fp);
                         return null;
                     }
@@ -544,9 +544,9 @@
         // Save the caller's context
         AccessControlContext acc = AccessController.getContext();
         // Need a privileged block to create the class loader
-        URLClassLoader ucl =
-            (URLClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+        URLClassLoader ucl = AccessController.doPrivileged(
+            new PrivilegedAction<URLClassLoader>() {
+                public URLClassLoader run() {
                     return new FactoryURLClassLoader(urls, parent);
                 }
             });
@@ -571,9 +571,9 @@
         // Save the caller's context
         AccessControlContext acc = AccessController.getContext();
         // Need a privileged block to create the class loader
-        URLClassLoader ucl = (URLClassLoader)
-            AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+        URLClassLoader ucl = AccessController.doPrivileged(
+            new PrivilegedAction<URLClassLoader>() {
+                public URLClassLoader run() {
                     return new FactoryURLClassLoader(urls);
                 }
             });
--- a/src/share/classes/java/net/URLConnection.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/net/URLConnection.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1072,7 +1072,7 @@
      * properties to be appended into a single property.
      *
      * @param   key     the keyword by which the request is known
-     *                  (e.g., "<code>accept</code>").
+     *                  (e.g., "<code>Accept</code>").
      * @param   value   the value associated with it.
      * @throws IllegalStateException if already connected
      * @throws NullPointerException if key is <CODE>null</CODE>
@@ -1096,7 +1096,7 @@
      * existing values associated with the same key.
      *
      * @param   key     the keyword by which the request is known
-     *                  (e.g., "<code>accept</code>").
+     *                  (e.g., "<code>Accept</code>").
      * @param   value  the value associated with it.
      * @throws IllegalStateException if already connected
      * @throws NullPointerException if key is null
@@ -1120,7 +1120,7 @@
      * Returns the value of the named general request property for this
      * connection.
      *
-     * @param key the keyword by which the request is known (e.g., "accept").
+     * @param key the keyword by which the request is known (e.g., "Accept").
      * @return  the value of the named general request property for this
      *           connection. If key is null, then null is returned.
      * @throws IllegalStateException if already connected
@@ -1164,7 +1164,7 @@
      * these properties.
      *
      * @param   key     the keyword by which the request is known
-     *                  (e.g., "<code>accept</code>").
+     *                  (e.g., "<code>Accept</code>").
      * @param   value   the value associated with the key.
      *
      * @see java.net.URLConnection#setRequestProperty(java.lang.String,java.lang.String)
@@ -1183,7 +1183,7 @@
      * Returns the value of the default request property. Default request
      * properties are set for every connection.
      *
-     * @param key the keyword by which the request is known (e.g., "accept").
+     * @param key the keyword by which the request is known (e.g., "Accept").
      * @return  the value of the default request property
      * for the specified key.
      *
--- a/src/share/classes/java/nio/StringCharBuffer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/nio/StringCharBuffer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -60,16 +60,9 @@
         str = s;
     }
 
-    private StringCharBuffer(CharSequence s, int mark,
-                             int pos, int limit, int cap)
-    {
-        super(mark, pos, limit, cap);
-        str = s;
-    }
-
     public CharBuffer duplicate() {
         return new StringCharBuffer(str, markValue(),
-                                    position(), limit(), capacity());
+                                    position(), limit(), capacity(), offset);
     }
 
     public CharBuffer asReadOnlyBuffer() {
@@ -77,11 +70,11 @@
     }
 
     public final char get() {
-        return str.charAt(nextGetIndex());
+        return str.charAt(nextGetIndex() + offset);
     }
 
     public final char get(int index) {
-        return str.charAt(checkIndex(index));
+        return str.charAt(checkIndex(index) + offset);
     }
 
     // ## Override bulk get methods for better performance
@@ -103,15 +96,16 @@
     }
 
     final String toString(int start, int end) {
-        return str.toString().substring(start, end);
+        return str.toString().substring(start + offset, end + offset);
     }
 
     public final CharSequence subSequence(int start, int end) {
         try {
             int pos = position();
-            return new StringCharBuffer(str,
+            return new StringCharBuffer(str, -1,
                                         pos + checkIndex(start, pos),
-                                        pos + checkIndex(end, pos));
+                                        pos + checkIndex(end, pos),
+                                        remaining(), offset);
         } catch (IllegalArgumentException x) {
             throw new IndexOutOfBoundsException();
         }
--- a/src/share/classes/java/nio/channels/Channels.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/nio/channels/Channels.java	Mon Apr 14 11:34:15 2008 -0700
@@ -66,7 +66,27 @@
     private Channels() { }              // No instantiation
 
 
-    private static int write(WritableByteChannel ch, ByteBuffer bb)
+    /**
+     * Write all remaining bytes in buffer to the given channel.
+     * If the channel is selectable then it must be configured blocking.
+     */
+    private static void writeFullyImpl(WritableByteChannel ch, ByteBuffer bb)
+        throws IOException
+    {
+        while (bb.remaining() > 0) {
+            int n = ch.write(bb);
+            if (n <= 0)
+                throw new RuntimeException("no bytes written");
+        }
+    }
+
+    /**
+     * Write all remaining bytes in buffer to the given channel.
+     *
+     * @throws  IllegalBlockingException
+     *          If the channel is selectable and configured non-blocking.
+     */
+    private static void writeFully(WritableByteChannel ch, ByteBuffer bb)
         throws IOException
     {
         if (ch instanceof SelectableChannel) {
@@ -74,14 +94,13 @@
             synchronized (sc.blockingLock()) {
                 if (!sc.isBlocking())
                     throw new IllegalBlockingModeException();
-                return ch.write(bb);
+                writeFullyImpl(ch, bb);
             }
         } else {
-            return ch.write(bb);
+            writeFullyImpl(ch, bb);
         }
     }
 
-
     // -- Byte streams from channels --
 
     /**
@@ -148,7 +167,7 @@
                     bb.position(off);
                     this.bb = bb;
                     this.bs = bs;
-                    Channels.write(ch, bb);
+                    Channels.writeFully(ch, bb);
                 }
 
                 public void close() throws IOException {
--- a/src/share/classes/java/nio/channels/spi/SelectorProvider.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/nio/channels/spi/SelectorProvider.java	Mon Apr 14 11:34:15 2008 -0700
@@ -167,9 +167,9 @@
         synchronized (lock) {
             if (provider != null)
                 return provider;
-            return (SelectorProvider)AccessController
-                .doPrivileged(new PrivilegedAction() {
-                        public Object run() {
+            return AccessController.doPrivileged(
+                new PrivilegedAction<SelectorProvider>() {
+                    public SelectorProvider run() {
                             if (loadProviderFromProperty())
                                 return provider;
                             if (loadProviderAsService())
--- a/src/share/classes/java/nio/charset/Charset.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/nio/charset/Charset.java	Mon Apr 14 11:34:15 2008 -0700
@@ -212,36 +212,47 @@
  *
  * <h4>Terminology</h4>
  *
- * <p> The name of this class is taken from the terms used in <a
- * href="http://www.ietf.org/rfc/rfc2278.txt""><i>RFC&nbsp;2278</i></a>.  In that
- * document a <i>charset</i> is defined as the combination of a coded character
- * set and a character-encoding scheme.
+ * <p> The name of this class is taken from the terms used in
+ * <a href="http://www.ietf.org/rfc/rfc2278.txt"><i>RFC&nbsp;2278</i></a>.
+ * In that document a <i>charset</i> is defined as the combination of
+ * one or more coded character sets and a character-encoding scheme.
+ * (This definition is confusing; some other software systems define
+ * <i>charset</i> as a synonym for <i>coded character set</i>.)
  *
  * <p> A <i>coded character set</i> is a mapping between a set of abstract
  * characters and a set of integers.  US-ASCII, ISO&nbsp;8859-1,
- * JIS&nbsp;X&nbsp;0201, and full Unicode, which is the same as
- * ISO&nbsp;10646-1, are examples of coded character sets.
+ * JIS&nbsp;X&nbsp;0201, and Unicode are examples of coded character sets.
+ *
+ * <p> Some standards have defined a <i>character set</i> to be simply a
+ * set of abstract characters without an associated assigned numbering.
+ * An alphabet is an example of such a character set.  However, the subtle
+ * distinction between <i>character set</i> and <i>coded character set</i>
+ * is rarely used in practice; the former has become a short form for the
+ * latter, including in the Java API specification.
  *
- * <p> A <i>character-encoding scheme</i> is a mapping between a coded
- * character set and a set of octet (eight-bit byte) sequences.  UTF-8, UCS-2,
- * UTF-16, ISO&nbsp;2022, and EUC are examples of character-encoding schemes.
- * Encoding schemes are often associated with a particular coded character set;
- * UTF-8, for example, is used only to encode Unicode.  Some schemes, however,
- * are associated with multiple character sets; EUC, for example, can be used
- * to encode characters in a variety of Asian character sets.
+ * <p> A <i>character-encoding scheme</i> is a mapping between one or more
+ * coded character sets and a set of octet (eight-bit byte) sequences.
+ * UTF-8, UTF-16, ISO&nbsp;2022, and EUC are examples of
+ * character-encoding schemes.  Encoding schemes are often associated with
+ * a particular coded character set; UTF-8, for example, is used only to
+ * encode Unicode.  Some schemes, however, are associated with multiple
+ * coded character sets; EUC, for example, can be used to encode
+ * characters in a variety of Asian coded character sets.
  *
  * <p> When a coded character set is used exclusively with a single
- * character-encoding scheme then the corresponding charset is usually named
- * for the character set; otherwise a charset is usually named for the encoding
- * scheme and, possibly, the locale of the character sets that it supports.
- * Hence <tt>US-ASCII</tt> is the name of the charset for US-ASCII while
+ * character-encoding scheme then the corresponding charset is usually
+ * named for the coded character set; otherwise a charset is usually named
+ * for the encoding scheme and, possibly, the locale of the coded
+ * character sets that it supports.  Hence <tt>US-ASCII</tt> is both the
+ * name of a coded character set and of the charset that encodes it, while
  * <tt>EUC-JP</tt> is the name of the charset that encodes the
  * JIS&nbsp;X&nbsp;0201, JIS&nbsp;X&nbsp;0208, and JIS&nbsp;X&nbsp;0212
- * character sets.
+ * coded character sets for the Japanese language.
  *
  * <p> The native character encoding of the Java programming language is
- * UTF-16.  A charset in the Java platform therefore defines a mapping between
- * sequences of sixteen-bit UTF-16 code units and sequences of bytes. </p>
+ * UTF-16.  A charset in the Java platform therefore defines a mapping
+ * between sequences of sixteen-bit UTF-16 code units (that is, sequences
+ * of chars) and sequences of bytes. </p>
  *
  *
  * @author Mark Reinhold
--- a/src/share/classes/java/rmi/activation/ActivationGroupDesc.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/rmi/activation/ActivationGroupDesc.java	Mon Apr 14 11:34:15 2008 -0700
@@ -263,7 +263,7 @@
          * @since 1.2
          */
         public String[] getCommandOptions() {
-            return (String[]) options.clone();
+            return options.clone();
         }
 
         /**
--- a/src/share/classes/java/rmi/dgc/VMID.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/rmi/dgc/VMID.java	Mon Apr 14 11:34:15 2008 -0700
@@ -136,9 +136,9 @@
         /*
          * Get the local host's IP address.
          */
-        byte[] addr = (byte[]) java.security.AccessController.doPrivileged(
-            new PrivilegedAction() {
-            public Object run() {
+        byte[] addr = java.security.AccessController.doPrivileged(
+            new PrivilegedAction<byte[]>() {
+            public byte[] run() {
                 try {
                     return InetAddress.getLocalHost().getAddress();
                 } catch (Exception e) {
--- a/src/share/classes/java/security/AccessControlContext.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/security/AccessControlContext.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -322,7 +322,7 @@
                     debug.println("access denied " + perm);
                 }
 
-                if (Debug.isOn("failure")) {
+                if (Debug.isOn("failure") && debug != null) {
                     // Want to make sure this is always displayed for failure,
                     // but do not want to display again if already displayed
                     // above.
--- a/src/share/classes/java/security/KeyStore.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/security/KeyStore.java	Mon Apr 14 11:34:15 2008 -0700
@@ -789,7 +789,7 @@
      * @param alias the alias name
      *
      * @return the certificate chain (ordered with the user's certificate first
-     * and the root certificate authority last), or null if the given alias
+     * followed by zero or more certificate authorities), or null if the given alias
      * does not exist or does not contain a certificate chain
      *
      * @exception KeyStoreException if the keystore has not been initialized
--- a/src/share/classes/java/security/cert/TrustAnchor.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/security/cert/TrustAnchor.java	Mon Apr 14 11:34:15 2008 -0700
@@ -275,7 +275,7 @@
             ncBytes = null;
             nc = null;
         } else {
-            ncBytes = (byte []) bytes.clone();
+            ncBytes = bytes.clone();
             // validate DER encoding
             try {
                 nc = new NameConstraintsExtension(Boolean.FALSE, bytes);
@@ -309,7 +309,7 @@
      *         or <code>null</code> if not set.
      */
     public final byte [] getNameConstraints() {
-        return (ncBytes == null ? null : (byte []) ncBytes.clone());
+        return ncBytes == null ? null : ncBytes.clone();
     }
 
     /**
--- a/src/share/classes/java/security/cert/X509CertSelector.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/security/cert/X509CertSelector.java	Mon Apr 14 11:34:15 2008 -0700
@@ -381,7 +381,7 @@
         if (subjectKeyID == null) {
             this.subjectKeyID = null;
         } else {
-            this.subjectKeyID = (byte[])subjectKeyID.clone();
+            this.subjectKeyID = subjectKeyID.clone();
         }
     }
 
@@ -442,7 +442,7 @@
         if (authorityKeyID == null) {
             this.authorityKeyID = null;
         } else {
-            this.authorityKeyID = (byte[])authorityKeyID.clone();
+            this.authorityKeyID = authorityKeyID.clone();
         }
     }
 
@@ -566,7 +566,7 @@
             subjectPublicKey = null;
             subjectPublicKeyBytes = null;
         } else {
-            subjectPublicKeyBytes = (byte[])key.clone();
+            subjectPublicKeyBytes = key.clone();
             subjectPublicKey = X509Key.parse(new DerValue(subjectPublicKeyBytes));
         }
     }
@@ -590,7 +590,7 @@
         if (keyUsage == null) {
             this.keyUsage = null;
         } else {
-            this.keyUsage = (boolean[])keyUsage.clone();
+            this.keyUsage = keyUsage.clone();
         }
     }
 
@@ -1041,7 +1041,7 @@
             ncBytes = null;
             nc = null;
         } else {
-            ncBytes = (byte[])bytes.clone();
+            ncBytes = bytes.clone();
             nc = new NameConstraintsExtension(FALSE, bytes);
         }
     }
@@ -1438,7 +1438,7 @@
         if (subjectKeyID == null) {
             return null;
         }
-        return (byte[])subjectKeyID.clone();
+        return subjectKeyID.clone();
     }
 
     /**
@@ -1457,7 +1457,7 @@
         if (authorityKeyID == null) {
           return null;
         }
-        return (byte[])authorityKeyID.clone();
+        return authorityKeyID.clone();
     }
 
     /**
@@ -1546,7 +1546,7 @@
         if (keyUsage == null) {
             return null;
         }
-        return (boolean[])keyUsage.clone();
+        return keyUsage.clone();
     }
 
     /**
@@ -1736,7 +1736,7 @@
         if (ncBytes == null) {
             return null;
         } else {
-            return (byte[]) ncBytes.clone();
+            return ncBytes.clone();
         }
     }
 
--- a/src/share/classes/java/util/ArrayList.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/ArrayList.java	Mon Apr 14 11:34:15 2008 -0700
@@ -892,7 +892,7 @@
         private final AbstractList<E> parent;
         private final int parentOffset;
         private final int offset;
-        private int size;
+        int size;
 
         SubList(AbstractList<E> parent,
                 int offset, int fromIndex, int toIndex) {
@@ -971,6 +971,7 @@
         public ListIterator<E> listIterator(final int index) {
             checkForComodification();
             rangeCheckForAdd(index);
+            final int offset = this.offset;
 
             return new ListIterator<E>() {
                 int cursor = index;
--- a/src/share/classes/java/util/Arrays.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/Arrays.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1088,7 +1088,7 @@
      *          <i>mutually comparable</i> (for example, strings and integers).
      */
     public static void sort(Object[] a) {
-        Object[] aux = (Object[])a.clone();
+        Object[] aux = a.clone();
         mergeSort(aux, a, 0, a.length, 0);
     }
 
@@ -1216,7 +1216,7 @@
      *          not <i>mutually comparable</i> using the specified comparator.
      */
     public static <T> void sort(T[] a, Comparator<? super T> c) {
-        T[] aux = (T[])a.clone();
+        T[] aux = a.clone();
         if (c==null)
             mergeSort(aux, a, 0, a.length, 0);
         else
@@ -1257,7 +1257,7 @@
     public static <T> void sort(T[] a, int fromIndex, int toIndex,
                                 Comparator<? super T> c) {
         rangeCheck(a.length, fromIndex, toIndex);
-        T[] aux = (T[])copyOfRange(a, fromIndex, toIndex);
+        T[] aux = copyOfRange(a, fromIndex, toIndex);
         if (c==null)
             mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
         else
@@ -4128,7 +4128,7 @@
         if (a.length != 0 && bufLen <= 0)
             bufLen = Integer.MAX_VALUE;
         StringBuilder buf = new StringBuilder(bufLen);
-        deepToString(a, buf, new HashSet());
+        deepToString(a, buf, new HashSet<Object[]>());
         return buf.toString();
     }
 
--- a/src/share/classes/java/util/EnumMap.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/EnumMap.java	Mon Apr 14 11:34:15 2008 -0700
@@ -140,7 +140,7 @@
     public EnumMap(EnumMap<K, ? extends V> m) {
         keyType = m.keyType;
         keyUniverse = m.keyUniverse;
-        vals = (Object[]) m.vals.clone();
+        vals = m.vals.clone();
         size = m.size;
     }
 
@@ -161,7 +161,7 @@
             EnumMap<K, ? extends V> em = (EnumMap<K, ? extends V>) m;
             keyType = em.keyType;
             keyUniverse = em.keyUniverse;
-            vals = (Object[]) em.vals.clone();
+            vals = em.vals.clone();
             size = em.size;
         } else {
             if (m.isEmpty())
@@ -257,7 +257,7 @@
     public V put(K key, V value) {
         typeCheck(key);
 
-        int index = ((Enum)key).ordinal();
+        int index = key.ordinal();
         Object oldValue = vals[index];
         vals[index] = maskNull(value);
         if (oldValue == null)
@@ -662,7 +662,7 @@
         } catch(CloneNotSupportedException e) {
             throw new AssertionError();
         }
-        result.vals = (Object[]) result.vals.clone();
+        result.vals = result.vals.clone();
         return result;
     }
 
--- a/src/share/classes/java/util/HashMap.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/HashMap.java	Mon Apr 14 11:34:15 2008 -0700
@@ -173,7 +173,7 @@
      * rehash).  This field is used to make iterators on Collection-views of
      * the HashMap fail-fast.  (See ConcurrentModificationException).
      */
-    transient volatile int modCount;
+    transient int modCount;
 
     /**
      * Constructs an empty <tt>HashMap</tt> with the specified initial
--- a/src/share/classes/java/util/Hashtable.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/Hashtable.java	Mon Apr 14 11:34:15 2008 -0700
@@ -27,7 +27,7 @@
 import java.io.*;
 
 /**
- * This class implements a hashtable, which maps keys to values. Any
+ * This class implements a hash table, which maps keys to values. Any
  * non-<code>null</code> object can be used as a key or as a value. <p>
  *
  * To successfully store and retrieve objects from a hashtable, the
@@ -100,9 +100,15 @@
  *
  * <p>As of the Java 2 platform v1.2, this class was retrofitted to
  * implement the {@link Map} interface, making it a member of the
- * <a href="{@docRoot}/../technotes/guides/collections/index.html"> Java
- * Collections Framework</a>.  Unlike the new collection
- * implementations, {@code Hashtable} is synchronized.
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ *
+ * Java Collections Framework</a>.  Unlike the new collection
+ * implementations, {@code Hashtable} is synchronized.  If a
+ * thread-safe implementation is not needed, it is recommended to use
+ * {@link HashMap} in place of {@code Hashtable}.  If a thread-safe
+ * highly-concurrent implementation is desired, then it is recommended
+ * to use {@link java.util.concurrent.ConcurrentHashMap} in place of
+ * {@code Hashtable}.
  *
  * @author  Arthur van Hoff
  * @author  Josh Bloch
--- a/src/share/classes/java/util/IdentityHashMap.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/IdentityHashMap.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -173,7 +173,7 @@
     /**
      * The number of modifications, to support fast-fail iterators
      */
-    private transient volatile int modCount;
+    private transient int modCount;
 
     /**
      * The next size value at which to resize (capacity * load factor).
@@ -701,7 +701,7 @@
         try {
             IdentityHashMap<K,V> m = (IdentityHashMap<K,V>) super.clone();
             m.entrySet = null;
-            m.table = (Object[])table.clone();
+            m.table = table.clone();
             return m;
         } catch (CloneNotSupportedException e) {
             throw new InternalError();
@@ -749,7 +749,6 @@
             expectedModCount = ++modCount;
             int deletedSlot = lastReturnedIndex;
             lastReturnedIndex = -1;
-            size--;
             // back up index to revisit new contents after deletion
             index = deletedSlot;
             indexValid = false;
@@ -782,6 +781,8 @@
                 return;
             }
 
+            size--;
+
             Object item;
             for (int i = nextKeyIndex(d, len); (item = tab[i]) != null;
                  i = nextKeyIndex(i, len)) {
@@ -975,7 +976,7 @@
          */
         public boolean removeAll(Collection<?> c) {
             boolean modified = false;
-            for (Iterator i = iterator(); i.hasNext(); ) {
+            for (Iterator<K> i = iterator(); i.hasNext(); ) {
                 if (c.contains(i.next())) {
                     i.remove();
                     modified = true;
@@ -1033,7 +1034,7 @@
             return containsValue(o);
         }
         public boolean remove(Object o) {
-            for (Iterator i = iterator(); i.hasNext(); ) {
+            for (Iterator<V> i = iterator(); i.hasNext(); ) {
                 if (i.next() == o) {
                     i.remove();
                     return true;
@@ -1121,7 +1122,7 @@
          */
         public boolean removeAll(Collection<?> c) {
             boolean modified = false;
-            for (Iterator i = iterator(); i.hasNext(); ) {
+            for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); ) {
                 if (c.contains(i.next())) {
                     i.remove();
                     modified = true;
--- a/src/share/classes/java/util/JumboEnumSet.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/JumboEnumSet.java	Mon Apr 14 11:34:15 2008 -0700
@@ -364,7 +364,7 @@
 
     public EnumSet<E> clone() {
         JumboEnumSet<E> result = (JumboEnumSet<E>) super.clone();
-        result.elements = (long[]) result.elements.clone();
+        result.elements = result.elements.clone();
         return result;
     }
 }
--- a/src/share/classes/java/util/Random.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/Random.java	Mon Apr 14 11:34:15 2008 -0700
@@ -504,7 +504,7 @@
 
         // The seed is read in as {@code long} for
         // historical reasons, but it is converted to an AtomicLong.
-        long seedVal = (long) fields.get("seed", -1L);
+        long seedVal = fields.get("seed", -1L);
         if (seedVal < 0)
           throw new java.io.StreamCorruptedException(
                               "Random: invalid seed");
--- a/src/share/classes/java/util/TreeSet.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/TreeSet.java	Mon Apr 14 11:34:15 2008 -0700
@@ -195,7 +195,7 @@
      * @since 1.6
      */
     public NavigableSet<E> descendingSet() {
-        return new TreeSet(m.descendingMap());
+        return new TreeSet<E>(m.descendingMap());
     }
 
     /**
@@ -505,8 +505,8 @@
         s.writeInt(m.size());
 
         // Write out all elements in the proper order.
-        for (Iterator i=m.keySet().iterator(); i.hasNext(); )
-            s.writeObject(i.next());
+        for (E e : m.keySet())
+            s.writeObject(e);
     }
 
     /**
--- a/src/share/classes/java/util/Vector.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/Vector.java	Mon Apr 14 11:34:15 2008 -0700
@@ -64,15 +64,15 @@
  *
  * <p>As of the Java 2 platform v1.2, this class was retrofitted to
  * implement the {@link List} interface, making it a member of the
- * <a href="{@docRoot}/../technotes/guides/collections/index.html"> Java
- * Collections Framework</a>.  Unlike the new collection
- * implementations, {@code Vector} is synchronized.
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.  Unlike the new collection
+ * implementations, {@code Vector} is synchronized.  If a thread-safe
+ * implementation is not needed, it is recommended to use {@link
+ * ArrayList} in place of {@code Vector}.
  *
  * @author  Lee Boynton
  * @author  Jonathan Payne
  * @see Collection
- * @see List
- * @see ArrayList
  * @see LinkedList
  * @since   JDK1.0
  */
--- a/src/share/classes/java/util/WeakHashMap.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/WeakHashMap.java	Mon Apr 14 11:34:15 2008 -0700
@@ -29,7 +29,8 @@
 
 
 /**
- * A hashtable-based <tt>Map</tt> implementation with <em>weak keys</em>.
+ * Hash table based implementation of the <tt>Map</tt> interface, with
+ * <em>weak keys</em>.
  * An entry in a <tt>WeakHashMap</tt> will automatically be removed when
  * its key is no longer in ordinary use.  More precisely, the presence of a
  * mapping for a given key will not prevent the key from being discarded by the
@@ -181,7 +182,7 @@
      *
      * @see ConcurrentModificationException
      */
-    volatile int modCount;
+    int modCount;
 
     @SuppressWarnings("unchecked")
     private Entry<K,V>[] newTable(int n) {
--- a/src/share/classes/java/util/concurrent/DelayQueue.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/concurrent/DelayQueue.java	Mon Apr 14 11:34:15 2008 -0700
@@ -69,10 +69,34 @@
     implements BlockingQueue<E> {
 
     private transient final ReentrantLock lock = new ReentrantLock();
-    private transient final Condition available = lock.newCondition();
     private final PriorityQueue<E> q = new PriorityQueue<E>();
 
     /**
+     * Thread designated to wait for the element at the head of
+     * the queue.  This variant of the Leader-Follower pattern
+     * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to
+     * minimize unnecessary timed waiting.  When a thread becomes
+     * the leader, it waits only for the next delay to elapse, but
+     * other threads await indefinitely.  The leader thread must
+     * signal some other thread before returning from take() or
+     * poll(...), unless some other thread becomes leader in the
+     * interim.  Whenever the head of the queue is replaced with
+     * an element with an earlier expiration time, the leader
+     * field is invalidated by being reset to null, and some
+     * waiting thread, but not necessarily the current leader, is
+     * signalled.  So waiting threads must be prepared to acquire
+     * and lose leadership while waiting.
+     */
+    private Thread leader = null;
+
+    /**
+     * Condition signalled when a newer element becomes available
+     * at the head of the queue or a new thread may need to
+     * become leader.
+     */
+    private final Condition available = lock.newCondition();
+
+    /**
      * Creates a new <tt>DelayQueue</tt> that is initially empty.
      */
     public DelayQueue() {}
@@ -111,10 +135,11 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            E first = q.peek();
             q.offer(e);
-            if (first == null || e.compareTo(first) < 0)
-                available.signalAll();
+            if (q.peek() == e) {
+                leader = null;
+                available.signal();
+            }
             return true;
         } finally {
             lock.unlock();
@@ -160,13 +185,8 @@
             E first = q.peek();
             if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
                 return null;
-            else {
-                E x = q.poll();
-                assert x != null;
-                if (q.size() != 0)
-                    available.signalAll();
-                return x;
-            }
+            else
+                return q.poll();
         } finally {
             lock.unlock();
         }
@@ -185,23 +205,29 @@
         try {
             for (;;) {
                 E first = q.peek();
-                if (first == null) {
+                if (first == null)
                     available.await();
-                } else {
-                    long delay =  first.getDelay(TimeUnit.NANOSECONDS);
-                    if (delay > 0) {
-                        long tl = available.awaitNanos(delay);
-                    } else {
-                        E x = q.poll();
-                        assert x != null;
-                        if (q.size() != 0)
-                            available.signalAll(); // wake up other takers
-                        return x;
-
+                else {
+                    long delay = first.getDelay(TimeUnit.NANOSECONDS);
+                    if (delay <= 0)
+                        return q.poll();
+                    else if (leader != null)
+                        available.await();
+                    else {
+                        Thread thisThread = Thread.currentThread();
+                        leader = thisThread;
+                        try {
+                            available.awaitNanos(delay);
+                        } finally {
+                            if (leader == thisThread)
+                                leader = null;
+                        }
                     }
                 }
             }
         } finally {
+            if (leader == null && q.peek() != null)
+                available.signal();
             lock.unlock();
         }
     }
@@ -230,23 +256,28 @@
                         nanos = available.awaitNanos(nanos);
                 } else {
                     long delay = first.getDelay(TimeUnit.NANOSECONDS);
-                    if (delay > 0) {
-                        if (nanos <= 0)
-                            return null;
-                        if (delay > nanos)
-                            delay = nanos;
-                        long timeLeft = available.awaitNanos(delay);
-                        nanos -= delay - timeLeft;
-                    } else {
-                        E x = q.poll();
-                        assert x != null;
-                        if (q.size() != 0)
-                            available.signalAll();
-                        return x;
+                    if (delay <= 0)
+                        return q.poll();
+                    if (nanos <= 0)
+                        return null;
+                    if (nanos < delay || leader != null)
+                        nanos = available.awaitNanos(nanos);
+                    else {
+                        Thread thisThread = Thread.currentThread();
+                        leader = thisThread;
+                        try {
+                            long timeLeft = available.awaitNanos(delay);
+                            nanos -= delay - timeLeft;
+                        } finally {
+                            if (leader == thisThread)
+                                leader = null;
+                        }
                     }
                 }
             }
         } finally {
+            if (leader == null && q.peek() != null)
+                available.signal();
             lock.unlock();
         }
     }
@@ -303,8 +334,6 @@
                 c.add(q.poll());
                 ++n;
             }
-            if (n > 0)
-                available.signalAll();
             return n;
         } finally {
             lock.unlock();
@@ -335,8 +364,6 @@
                 c.add(q.poll());
                 ++n;
             }
-            if (n > 0)
-                available.signalAll();
             return n;
         } finally {
             lock.unlock();
@@ -485,6 +512,7 @@
             return cursor < array.length;
         }
 
+        @SuppressWarnings("unchecked")
         public E next() {
             if (cursor >= array.length)
                 throw new NoSuchElementException();
--- a/src/share/classes/java/util/concurrent/ExecutorService.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/concurrent/ExecutorService.java	Mon Apr 14 11:34:15 2008 -0700
@@ -145,6 +145,10 @@
      * tasks are executed, but no new tasks will be accepted.
      * Invocation has no additional effect if already shut down.
      *
+     * <p>This method does not wait for previously submitted tasks to
+     * complete execution.  Use {@link #awaitTermination awaitTermination}
+     * to do that.
+     *
      * @throws SecurityException if a security manager exists and
      *         shutting down this ExecutorService may manipulate
      *         threads that the caller is not permitted to modify
@@ -157,8 +161,12 @@
 
     /**
      * Attempts to stop all actively executing tasks, halts the
-     * processing of waiting tasks, and returns a list of the tasks that were
-     * awaiting execution.
+     * processing of waiting tasks, and returns a list of the tasks
+     * that were awaiting execution.
+     *
+     * <p>This method does not wait for actively executing tasks to
+     * terminate.  Use {@link #awaitTermination awaitTermination} to
+     * do that.
      *
      * <p>There are no guarantees beyond best-effort attempts to stop
      * processing actively executing tasks.  For example, typical
--- a/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java	Mon Apr 14 11:34:15 2008 -0700
@@ -35,6 +35,7 @@
 
 package java.util.concurrent;
 import java.util.concurrent.atomic.*;
+import java.util.concurrent.locks.*;
 import java.util.*;
 
 /**
@@ -45,12 +46,21 @@
  * flexibility or capabilities of {@link ThreadPoolExecutor} (which
  * this class extends) are required.
  *
- * <p> Delayed tasks execute no sooner than they are enabled, but
+ * <p>Delayed tasks execute no sooner than they are enabled, but
  * without any real-time guarantees about when, after they are
  * enabled, they will commence. Tasks scheduled for exactly the same
  * execution time are enabled in first-in-first-out (FIFO) order of
  * submission.
  *
+ * <p>When a submitted task is cancelled before it is run, execution
+ * is suppressed. By default, such a cancelled task is not
+ * automatically removed from the work queue until its delay
+ * elapses. While this enables further inspection and monitoring, it
+ * may also cause unbounded retention of cancelled tasks. To avoid
+ * this, set {@link #setRemoveOnCancelPolicy} to {@code true}, which
+ * causes tasks to be immediately removed from the work queue at
+ * time of cancellation.
+ *
  * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
  * of the inherited tuning methods are not useful for it. In
  * particular, because it acts as a fixed-sized pool using
@@ -111,21 +121,11 @@
      *    ScheduledExecutorService methods) which are treated as
      *    delayed tasks with a delay of zero.
      *
-     * 2. Using a custom queue (DelayedWorkQueue) based on an
+     * 2. Using a custom queue (DelayedWorkQueue), a variant of
      *    unbounded DelayQueue. The lack of capacity constraint and
      *    the fact that corePoolSize and maximumPoolSize are
      *    effectively identical simplifies some execution mechanics
-     *    (see delayedExecute) compared to ThreadPoolExecutor
-     *    version.
-     *
-     *    The DelayedWorkQueue class is defined below for the sake of
-     *    ensuring that all elements are instances of
-     *    RunnableScheduledFuture.  Since DelayQueue otherwise
-     *    requires type be Delayed, but not necessarily Runnable, and
-     *    the workQueue requires the opposite, we need to explicitly
-     *    define a class that requires both to ensure that users don't
-     *    add objects that aren't RunnableScheduledFutures via
-     *    getQueue().add() etc.
+     *    (see delayedExecute) compared to ThreadPoolExecutor.
      *
      * 3. Supporting optional run-after-shutdown parameters, which
      *    leads to overrides of shutdown methods to remove and cancel
@@ -150,6 +150,11 @@
     private volatile boolean executeExistingDelayedTasksAfterShutdown = true;
 
     /**
+     * True if ScheduledFutureTask.cancel should remove from queue
+     */
+    private volatile boolean removeOnCancel = false;
+
+    /**
      * Sequence number to break scheduling ties, and in turn to
      * guarantee FIFO order among tied entries.
      */
@@ -167,8 +172,10 @@
 
         /** Sequence number to break ties FIFO */
         private final long sequenceNumber;
+
         /** The time the task is enabled to execute in nanoTime units */
         private long time;
+
         /**
          * Period in nanoseconds for repeating tasks.  A positive
          * value indicates fixed-rate execution.  A negative value
@@ -181,6 +188,11 @@
         RunnableScheduledFuture<V> outerTask = this;
 
         /**
+         * Index into delay queue, to support faster cancellation.
+         */
+        int heapIndex;
+
+        /**
          * Creates a one-shot action with given nanoTime-based trigger time.
          */
         ScheduledFutureTask(Runnable r, V result, long ns) {
@@ -255,6 +267,13 @@
                 time = now() - p;
         }
 
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            boolean cancelled = super.cancel(mayInterruptIfRunning);
+            if (cancelled && removeOnCancel && heapIndex >= 0)
+                remove(this);
+            return cancelled;
+        }
+
         /**
          * Overrides FutureTask version so as to reset/requeue if periodic.
          */
@@ -655,14 +674,47 @@
     }
 
     /**
+     * Sets the policy on whether cancelled tasks should be immediately
+     * removed from the work queue at time of cancellation.  This value is
+     * by default {@code false}.
+     *
+     * @param value if {@code true}, remove on cancellation, else don't
+     * @see #getRemoveOnCancelPolicy
+     * @since 1.7
+     */
+    public void setRemoveOnCancelPolicy(boolean value) {
+        removeOnCancel = value;
+    }
+
+    /**
+     * Gets the policy on whether cancelled tasks should be immediately
+     * removed from the work queue at time of cancellation.  This value is
+     * by default {@code false}.
+     *
+     * @return {@code true} if cancelled tasks are immediately removed
+     *         from the queue
+     * @see #setRemoveOnCancelPolicy
+     * @since 1.7
+     */
+    public boolean getRemoveOnCancelPolicy() {
+        return removeOnCancel;
+    }
+
+    /**
      * Initiates an orderly shutdown in which previously submitted
-     * tasks are executed, but no new tasks will be accepted.  If the
-     * {@code ExecuteExistingDelayedTasksAfterShutdownPolicy} has
-     * been set {@code false}, existing delayed tasks whose delays
-     * have not yet elapsed are cancelled.  And unless the
-     * {@code ContinueExistingPeriodicTasksAfterShutdownPolicy} has
-     * been set {@code true}, future executions of existing periodic
-     * tasks will be cancelled.
+     * tasks are executed, but no new tasks will be accepted.
+     * Invocation has no additional effect if already shut down.
+     *
+     * <p>This method does not wait for previously submitted tasks to
+     * complete execution.  Use {@link #awaitTermination awaitTermination}
+     * to do that.
+     *
+     * <p>If the {@code ExecuteExistingDelayedTasksAfterShutdownPolicy}
+     * has been set {@code false}, existing delayed tasks whose delays
+     * have not yet elapsed are cancelled.  And unless the {@code
+     * ContinueExistingPeriodicTasksAfterShutdownPolicy} has been set
+     * {@code true}, future executions of existing periodic tasks will
+     * be cancelled.
      *
      * @throws SecurityException {@inheritDoc}
      */
@@ -675,6 +727,10 @@
      * processing of waiting tasks, and returns a list of the tasks
      * that were awaiting execution.
      *
+     * <p>This method does not wait for actively executing tasks to
+     * terminate.  Use {@link #awaitTermination awaitTermination} to
+     * do that.
+     *
      * <p>There are no guarantees beyond best-effort attempts to stop
      * processing actively executing tasks.  This implementation
      * cancels tasks via {@link Thread#interrupt}, so any task that
@@ -707,56 +763,478 @@
     }
 
     /**
-     * An annoying wrapper class to convince javac to use a
-     * DelayQueue<RunnableScheduledFuture> as a BlockingQueue<Runnable>
+     * Specialized delay queue. To mesh with TPE declarations, this
+     * class must be declared as a BlockingQueue<Runnable> even though
+     * it can only hold RunnableScheduledFutures.
      */
-    private static class DelayedWorkQueue
-        extends AbstractCollection<Runnable>
+    static class DelayedWorkQueue extends AbstractQueue<Runnable>
         implements BlockingQueue<Runnable> {
 
-        private final DelayQueue<RunnableScheduledFuture> dq = new DelayQueue<RunnableScheduledFuture>();
-        public Runnable poll() { return dq.poll(); }
-        public Runnable peek() { return dq.peek(); }
-        public Runnable take() throws InterruptedException { return dq.take(); }
-        public Runnable poll(long timeout, TimeUnit unit) throws InterruptedException {
-            return dq.poll(timeout, unit);
+        /*
+         * A DelayedWorkQueue is based on a heap-based data structure
+         * like those in DelayQueue and PriorityQueue, except that
+         * every ScheduledFutureTask also records its index into the
+         * heap array. This eliminates the need to find a task upon
+         * cancellation, greatly speeding up removal (down from O(n)
+         * to O(log n)), and reducing garbage retention that would
+         * otherwise occur by waiting for the element to rise to top
+         * before clearing. But because the queue may also hold
+         * RunnableScheduledFutures that are not ScheduledFutureTasks,
+         * we are not guaranteed to have such indices available, in
+         * which case we fall back to linear search. (We expect that
+         * most tasks will not be decorated, and that the faster cases
+         * will be much more common.)
+         *
+         * All heap operations must record index changes -- mainly
+         * within siftUp and siftDown. Upon removal, a task's
+         * heapIndex is set to -1. Note that ScheduledFutureTasks can
+         * appear at most once in the queue (this need not be true for
+         * other kinds of tasks or work queues), so are uniquely
+         * identified by heapIndex.
+         */
+
+        private static final int INITIAL_CAPACITY = 16;
+        private RunnableScheduledFuture[] queue =
+            new RunnableScheduledFuture[INITIAL_CAPACITY];
+        private final ReentrantLock lock = new ReentrantLock();
+        private int size = 0;
+
+        /**
+         * Thread designated to wait for the task at the head of the
+         * queue.  This variant of the Leader-Follower pattern
+         * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to
+         * minimize unnecessary timed waiting.  When a thread becomes
+         * the leader, it waits only for the next delay to elapse, but
+         * other threads await indefinitely.  The leader thread must
+         * signal some other thread before returning from take() or
+         * poll(...), unless some other thread becomes leader in the
+         * interim.  Whenever the head of the queue is replaced with a
+         * task with an earlier expiration time, the leader field is
+         * invalidated by being reset to null, and some waiting
+         * thread, but not necessarily the current leader, is
+         * signalled.  So waiting threads must be prepared to acquire
+         * and lose leadership while waiting.
+         */
+        private Thread leader = null;
+
+        /**
+         * Condition signalled when a newer task becomes available at the
+         * head of the queue or a new thread may need to become leader.
+         */
+        private final Condition available = lock.newCondition();
+
+        /**
+         * Set f's heapIndex if it is a ScheduledFutureTask.
+         */
+        private void setIndex(RunnableScheduledFuture f, int idx) {
+            if (f instanceof ScheduledFutureTask)
+                ((ScheduledFutureTask)f).heapIndex = idx;
+        }
+
+        /**
+         * Sift element added at bottom up to its heap-ordered spot.
+         * Call only when holding lock.
+         */
+        private void siftUp(int k, RunnableScheduledFuture key) {
+            while (k > 0) {
+                int parent = (k - 1) >>> 1;
+                RunnableScheduledFuture e = queue[parent];
+                if (key.compareTo(e) >= 0)
+                    break;
+                queue[k] = e;
+                setIndex(e, k);
+                k = parent;
+            }
+            queue[k] = key;
+            setIndex(key, k);
+        }
+
+        /**
+         * Sift element added at top down to its heap-ordered spot.
+         * Call only when holding lock.
+         */
+        private void siftDown(int k, RunnableScheduledFuture key) {
+            int half = size >>> 1;
+            while (k < half) {
+                int child = (k << 1) + 1;
+                RunnableScheduledFuture c = queue[child];
+                int right = child + 1;
+                if (right < size && c.compareTo(queue[right]) > 0)
+                    c = queue[child = right];
+                if (key.compareTo(c) <= 0)
+                    break;
+                queue[k] = c;
+                setIndex(c, k);
+                k = child;
+            }
+            queue[k] = key;
+            setIndex(key, k);
+        }
+
+        /**
+         * Resize the heap array.  Call only when holding lock.
+         */
+        private void grow() {
+            int oldCapacity = queue.length;
+            int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50%
+            if (newCapacity < 0) // overflow
+                newCapacity = Integer.MAX_VALUE;
+            queue = Arrays.copyOf(queue, newCapacity);
+        }
+
+        /**
+         * Find index of given object, or -1 if absent
+         */
+        private int indexOf(Object x) {
+            if (x != null) {
+                if (x instanceof ScheduledFutureTask) {
+                    int i = ((ScheduledFutureTask) x).heapIndex;
+                    // Sanity check; x could conceivably be a
+                    // ScheduledFutureTask from some other pool.
+                    if (i >= 0 && i < size && queue[i] == x)
+                        return i;
+                } else {
+                    for (int i = 0; i < size; i++)
+                        if (x.equals(queue[i]))
+                            return i;
+                }
+            }
+            return -1;
+        }
+
+        public boolean contains(Object x) {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                return indexOf(x) != -1;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public boolean remove(Object x) {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                int i = indexOf(x);
+                if (i < 0)
+                    return false;
+
+                setIndex(queue[i], -1);
+                int s = --size;
+                RunnableScheduledFuture replacement = queue[s];
+                queue[s] = null;
+                if (s != i) {
+                    siftDown(i, replacement);
+                    if (queue[i] == replacement)
+                        siftUp(i, replacement);
+                }
+                return true;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public int size() {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                return size;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public int remainingCapacity() {
+            return Integer.MAX_VALUE;
+        }
+
+        public RunnableScheduledFuture peek() {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                return queue[0];
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public boolean offer(Runnable x) {
+            if (x == null)
+                throw new NullPointerException();
+            RunnableScheduledFuture e = (RunnableScheduledFuture)x;
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                int i = size;
+                if (i >= queue.length)
+                    grow();
+                size = i + 1;
+                if (i == 0) {
+                    queue[0] = e;
+                    setIndex(e, 0);
+                } else {
+                    siftUp(i, e);
+                }
+                if (queue[0] == e) {
+                    leader = null;
+                    available.signal();
+                }
+            } finally {
+                lock.unlock();
+            }
+            return true;
+        }
+
+        public void put(Runnable e) {
+            offer(e);
+        }
+
+        public boolean add(Runnable e) {
+            return offer(e);
         }
 
-        public boolean add(Runnable x) {
-            return dq.add((RunnableScheduledFuture)x);
+        public boolean offer(Runnable e, long timeout, TimeUnit unit) {
+            return offer(e);
         }
-        public boolean offer(Runnable x) {
-            return dq.offer((RunnableScheduledFuture)x);
+
+        /**
+         * Performs common bookkeeping for poll and take: Replaces
+         * first element with last and sifts it down.  Call only when
+         * holding lock.
+         * @param f the task to remove and return
+         */
+        private RunnableScheduledFuture finishPoll(RunnableScheduledFuture f) {
+            int s = --size;
+            RunnableScheduledFuture x = queue[s];
+            queue[s] = null;
+            if (s != 0)
+                siftDown(0, x);
+            setIndex(f, -1);
+            return f;
+        }
+
+        public RunnableScheduledFuture poll() {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                RunnableScheduledFuture first = queue[0];
+                if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
+                    return null;
+                else
+                    return finishPoll(first);
+            } finally {
+                lock.unlock();
+            }
         }
-        public void put(Runnable x) {
-            dq.put((RunnableScheduledFuture)x);
+
+        public RunnableScheduledFuture take() throws InterruptedException {
+            final ReentrantLock lock = this.lock;
+            lock.lockInterruptibly();
+            try {
+                for (;;) {
+                    RunnableScheduledFuture first = queue[0];
+                    if (first == null)
+                        available.await();
+                    else {
+                        long delay = first.getDelay(TimeUnit.NANOSECONDS);
+                        if (delay <= 0)
+                            return finishPoll(first);
+                        else if (leader != null)
+                            available.await();
+                        else {
+                            Thread thisThread = Thread.currentThread();
+                            leader = thisThread;
+                            try {
+                                available.awaitNanos(delay);
+                            } finally {
+                                if (leader == thisThread)
+                                    leader = null;
+                            }
+                        }
+                    }
+                }
+            } finally {
+                if (leader == null && queue[0] != null)
+                    available.signal();
+                lock.unlock();
+            }
         }
-        public boolean offer(Runnable x, long timeout, TimeUnit unit) {
-            return dq.offer((RunnableScheduledFuture)x, timeout, unit);
+
+        public RunnableScheduledFuture poll(long timeout, TimeUnit unit)
+            throws InterruptedException {
+            long nanos = unit.toNanos(timeout);
+            final ReentrantLock lock = this.lock;
+            lock.lockInterruptibly();
+            try {
+                for (;;) {
+                    RunnableScheduledFuture first = queue[0];
+                    if (first == null) {
+                        if (nanos <= 0)
+                            return null;
+                        else
+                            nanos = available.awaitNanos(nanos);
+                    } else {
+                        long delay = first.getDelay(TimeUnit.NANOSECONDS);
+                        if (delay <= 0)
+                            return finishPoll(first);
+                        if (nanos <= 0)
+                            return null;
+                        if (nanos < delay || leader != null)
+                            nanos = available.awaitNanos(nanos);
+                        else {
+                            Thread thisThread = Thread.currentThread();
+                            leader = thisThread;
+                            try {
+                                long timeLeft = available.awaitNanos(delay);
+                                nanos -= delay - timeLeft;
+                            } finally {
+                                if (leader == thisThread)
+                                    leader = null;
+                            }
+                        }
+                    }
+                }
+            } finally {
+                if (leader == null && queue[0] != null)
+                    available.signal();
+                lock.unlock();
+            }
         }
 
-        public Runnable remove() { return dq.remove(); }
-        public Runnable element() { return dq.element(); }
-        public void clear() { dq.clear(); }
-        public int drainTo(Collection<? super Runnable> c) { return dq.drainTo(c); }
-        public int drainTo(Collection<? super Runnable> c, int maxElements) {
-            return dq.drainTo(c, maxElements);
+        public void clear() {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                for (int i = 0; i < size; i++) {
+                    RunnableScheduledFuture t = queue[i];
+                    if (t != null) {
+                        queue[i] = null;
+                        setIndex(t, -1);
+                    }
+                }
+                size = 0;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        /**
+         * Return and remove first element only if it is expired.
+         * Used only by drainTo.  Call only when holding lock.
+         */
+        private RunnableScheduledFuture pollExpired() {
+            RunnableScheduledFuture first = queue[0];
+            if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
+                return null;
+            return finishPoll(first);
+        }
+
+        public int drainTo(Collection<? super Runnable> c) {
+            if (c == null)
+                throw new NullPointerException();
+            if (c == this)
+                throw new IllegalArgumentException();
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                RunnableScheduledFuture first;
+                int n = 0;
+                while ((first = pollExpired()) != null) {
+                    c.add(first);
+                    ++n;
+                }
+                return n;
+            } finally {
+                lock.unlock();
+            }
         }
 
-        public int remainingCapacity() { return dq.remainingCapacity(); }
-        public boolean remove(Object x) { return dq.remove(x); }
-        public boolean contains(Object x) { return dq.contains(x); }
-        public int size() { return dq.size(); }
-        public boolean isEmpty() { return dq.isEmpty(); }
-        public Object[] toArray() { return dq.toArray(); }
-        public <T> T[] toArray(T[] array) { return dq.toArray(array); }
+        public int drainTo(Collection<? super Runnable> c, int maxElements) {
+            if (c == null)
+                throw new NullPointerException();
+            if (c == this)
+                throw new IllegalArgumentException();
+            if (maxElements <= 0)
+                return 0;
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                RunnableScheduledFuture first;
+                int n = 0;
+                while (n < maxElements && (first = pollExpired()) != null) {
+                    c.add(first);
+                    ++n;
+                }
+                return n;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public Object[] toArray() {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                return Arrays.copyOf(queue, size, Object[].class);
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        public <T> T[] toArray(T[] a) {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                if (a.length < size)
+                    return (T[]) Arrays.copyOf(queue, size, a.getClass());
+                System.arraycopy(queue, 0, a, 0, size);
+                if (a.length > size)
+                    a[size] = null;
+                return a;
+            } finally {
+                lock.unlock();
+            }
+        }
+
         public Iterator<Runnable> iterator() {
-            return new Iterator<Runnable>() {
-                private Iterator<RunnableScheduledFuture> it = dq.iterator();
-                public boolean hasNext() { return it.hasNext(); }
-                public Runnable next() { return it.next(); }
-                public void remove() { it.remove(); }
-            };
+            return new Itr(Arrays.copyOf(queue, size));
+        }
+
+        /**
+         * Snapshot iterator that works off copy of underlying q array.
+         */
+        private class Itr implements Iterator<Runnable> {
+            final RunnableScheduledFuture[] array;
+            int cursor = 0;     // index of next element to return
+            int lastRet = -1;   // index of last element, or -1 if no such
+
+            Itr(RunnableScheduledFuture[] array) {
+                this.array = array;
+            }
+
+            public boolean hasNext() {
+                return cursor < array.length;
+            }
+
+            public Runnable next() {
+                if (cursor >= array.length)
+                    throw new NoSuchElementException();
+                lastRet = cursor;
+                return array[cursor++];
+            }
+
+            public void remove() {
+                if (lastRet < 0)
+                    throw new IllegalStateException();
+                DelayedWorkQueue.this.remove(array[lastRet]);
+                lastRet = -1;
+            }
         }
     }
 }
--- a/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1342,6 +1342,10 @@
      * tasks are executed, but no new tasks will be accepted.
      * Invocation has no additional effect if already shut down.
      *
+     * <p>This method does not wait for previously submitted tasks to
+     * complete execution.  Use {@link #awaitTermination awaitTermination}
+     * to do that.
+     *
      * @throws SecurityException {@inheritDoc}
      */
     public void shutdown() {
@@ -1364,6 +1368,10 @@
      * that were awaiting execution. These tasks are drained (removed)
      * from the task queue upon return from this method.
      *
+     * <p>This method does not wait for actively executing tasks to
+     * terminate.  Use {@link #awaitTermination awaitTermination} to
+     * do that.
+     *
      * <p>There are no guarantees beyond best-effort attempts to stop
      * processing actively executing tasks.  This implementation
      * cancels tasks via {@link Thread#interrupt}, so any task that
--- a/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java	Mon Apr 14 11:34:15 2008 -0700
@@ -222,7 +222,7 @@
     /** Inner class providing writelock */
     private final ReentrantReadWriteLock.WriteLock writerLock;
     /** Performs all synchronization mechanics */
-    private final Sync sync;
+    final Sync sync;
 
     /**
      * Creates a new {@code ReentrantReadWriteLock} with
@@ -239,7 +239,7 @@
      * @param fair {@code true} if this lock should use a fair ordering policy
      */
     public ReentrantReadWriteLock(boolean fair) {
-        sync = (fair)? new FairSync() : new NonfairSync();
+        sync = fair ? new FairSync() : new NonfairSync();
         readerLock = new ReadLock(this);
         writerLock = new WriteLock(this);
     }
@@ -256,8 +256,8 @@
 
         /*
          * Read vs write count extraction constants and functions.
-         * Lock state is logically divided into two shorts: The lower
-         * one representing the exclusive (writer) lock hold count,
+         * Lock state is logically divided into two unsigned shorts:
+         * The lower one representing the exclusive (writer) lock hold count,
          * and the upper the shared (reader) hold count.
          */
 
@@ -279,13 +279,6 @@
             int count;
             // Use id, not reference, to avoid garbage retention
             final long tid = Thread.currentThread().getId();
-            /** Decrement if positive; return previous value */
-            int tryDecrement() {
-                int c = count;
-                if (c > 0)
-                    count = c - 1;
-                return c;
-            }
         }
 
         /**
@@ -303,7 +296,7 @@
          * The number of read locks held by current thread.
          * Initialized only in constructor and readObject.
          */
-        transient ThreadLocalHoldCounter readHolds;
+        private transient ThreadLocalHoldCounter readHolds;
 
         /**
          * The hold count of the last thread to successfully acquire
@@ -312,7 +305,17 @@
          * acquire. This is non-volatile since it is just used
          * as a heuristic, and would be great for threads to cache.
          */
-        transient HoldCounter cachedHoldCounter;
+        private transient HoldCounter cachedHoldCounter;
+
+        /**
+         * firstReader is the first thread to have acquired the read lock.
+         * firstReaderHoldCount is firstReader's hold count.
+         * This allows tracking of read holds for uncontended read
+         * locks to be very cheap.
+         */
+        private final static long INVALID_THREAD_ID = -1;
+        private transient long firstReader = INVALID_THREAD_ID;
+        private transient int firstReaderHoldCount;
 
         Sync() {
             readHolds = new ThreadLocalHoldCounter();
@@ -390,12 +393,25 @@
         }
 
         protected final boolean tryReleaseShared(int unused) {
-            HoldCounter rh = cachedHoldCounter;
-            Thread current = Thread.currentThread();
-            if (rh == null || rh.tid != current.getId())
-                rh = readHolds.get();
-            if (rh.tryDecrement() <= 0)
-                throw new IllegalMonitorStateException();
+            long tid = Thread.currentThread().getId();
+            if (firstReader == tid) {
+                // assert firstReaderHoldCount > 0;
+                if (firstReaderHoldCount == 1)
+                    firstReader = INVALID_THREAD_ID;
+                else
+                    firstReaderHoldCount--;
+            } else {
+                HoldCounter rh = cachedHoldCounter;
+                if (rh == null || rh.tid != tid)
+                    rh = readHolds.get();
+                int count = rh.count;
+                if (count <= 1) {
+                    readHolds.remove();
+                    if (count <= 0)
+                        throw unmatchedUnlockException();
+                }
+                --rh.count;
+            }
             for (;;) {
                 int c = getState();
                 int nextc = c - SHARED_UNIT;
@@ -404,12 +420,16 @@
             }
         }
 
+        private IllegalMonitorStateException unmatchedUnlockException() {
+            return new IllegalMonitorStateException(
+                "attempt to unlock read lock, not locked by current thread");
+        }
+
         protected final int tryAcquireShared(int unused) {
             /*
              * Walkthrough:
              * 1. If write lock held by another thread, fail.
-             * 2. If count saturated, throw error.
-             * 3. Otherwise, this thread is eligible for
+             * 2. Otherwise, this thread is eligible for
              *    lock wrt state, so ask if it should block
              *    because of queue policy. If not, try
              *    to grant by CASing state and updating count.
@@ -417,23 +437,33 @@
              *    acquires, which is postponed to full version
              *    to avoid having to check hold count in
              *    the more typical non-reentrant case.
-             * 4. If step 3 fails either because thread
-             *    apparently not eligible or CAS fails,
-             *    chain to version with full retry loop.
+             * 3. If step 2 fails either because thread
+             *    apparently not eligible or CAS fails or count
+             *    saturated, chain to version with full retry loop.
              */
             Thread current = Thread.currentThread();
             int c = getState();
             if (exclusiveCount(c) != 0 &&
                 getExclusiveOwnerThread() != current)
                 return -1;
-            if (sharedCount(c) == MAX_COUNT)
-                throw new Error("Maximum lock count exceeded");
+            int r = sharedCount(c);
             if (!readerShouldBlock() &&
+                r < MAX_COUNT &&
                 compareAndSetState(c, c + SHARED_UNIT)) {
-                HoldCounter rh = cachedHoldCounter;
-                if (rh == null || rh.tid != current.getId())
-                    cachedHoldCounter = rh = readHolds.get();
-                rh.count++;
+                long tid = current.getId();
+                if (r == 0) {
+                    firstReader = tid;
+                    firstReaderHoldCount = 1;
+                } else if (firstReader == tid) {
+                    firstReaderHoldCount++;
+                } else {
+                    HoldCounter rh = cachedHoldCounter;
+                    if (rh == null || rh.tid != tid)
+                        cachedHoldCounter = rh = readHolds.get();
+                    else if (rh.count == 0)
+                        readHolds.set(rh);
+                    rh.count++;
+                }
                 return 1;
             }
             return fullTryAcquireShared(current);
@@ -450,20 +480,56 @@
              * complicating tryAcquireShared with interactions between
              * retries and lazily reading hold counts.
              */
-            HoldCounter rh = cachedHoldCounter;
-            if (rh == null || rh.tid != current.getId())
-                rh = readHolds.get();
+            HoldCounter rh = null;
             for (;;) {
                 int c = getState();
-                int w = exclusiveCount(c);
-                if ((w != 0 && getExclusiveOwnerThread() != current) ||
-                    ((rh.count | w) == 0 && readerShouldBlock()))
-                    return -1;
+                if (exclusiveCount(c) != 0) {
+                    if (getExclusiveOwnerThread() != current)
+                        //if (removeNeeded) readHolds.remove();
+                        return -1;
+                    // else we hold the exclusive lock; blocking here
+                    // would cause deadlock.
+                } else if (readerShouldBlock()) {
+                    // Make sure we're not acquiring read lock reentrantly
+                    long tid = current.getId();
+                    if (firstReader == tid) {
+                        // assert firstReaderHoldCount > 0;
+                    } else {
+                        if (rh == null) {
+                            rh = cachedHoldCounter;
+                            if (rh == null || rh.tid != tid) {
+                                rh = readHolds.get();
+                                if (rh.count == 0)
+                                    readHolds.remove();
+                            }
+                        }
+                        if (rh.count == 0)
+                            return -1;
+                    }
+                }
                 if (sharedCount(c) == MAX_COUNT)
                     throw new Error("Maximum lock count exceeded");
                 if (compareAndSetState(c, c + SHARED_UNIT)) {
-                    cachedHoldCounter = rh; // cache for release
-                    rh.count++;
+                    long tid = current.getId();
+                    if (sharedCount(c) == 0) {
+                        firstReader = tid;
+                        firstReaderHoldCount = 1;
+                    } else if (firstReader == tid) {
+                        firstReaderHoldCount++;
+                    } else {
+                        if (rh == null) {
+                            rh = cachedHoldCounter;
+                            if (rh != null && rh.tid == tid) {
+                                if (rh.count == 0)
+                                    readHolds.set(rh);
+                            } else {
+                                rh = readHolds.get();
+                            }
+                        } else if (rh.count == 0)
+                            readHolds.set(rh);
+                        cachedHoldCounter = rh; // cache for release
+                        rh.count++;
+                    }
                     return 1;
                 }
             }
@@ -472,14 +538,14 @@
         /**
          * Performs tryLock for write, enabling barging in both modes.
          * This is identical in effect to tryAcquire except for lack
-         * of calls to writerShouldBlock
+         * of calls to writerShouldBlock.
          */
         final boolean tryWriteLock() {
             Thread current = Thread.currentThread();
             int c = getState();
             if (c != 0) {
                 int w = exclusiveCount(c);
-                if (w == 0 ||current != getExclusiveOwnerThread())
+                if (w == 0 || current != getExclusiveOwnerThread())
                     return false;
                 if (w == MAX_COUNT)
                     throw new Error("Maximum lock count exceeded");
@@ -493,7 +559,7 @@
         /**
          * Performs tryLock for read, enabling barging in both modes.
          * This is identical in effect to tryAcquireShared except for
-         * lack of calls to readerShouldBlock
+         * lack of calls to readerShouldBlock.
          */
         final boolean tryReadLock() {
             Thread current = Thread.currentThread();
@@ -502,13 +568,24 @@
                 if (exclusiveCount(c) != 0 &&
                     getExclusiveOwnerThread() != current)
                     return false;
-                if (sharedCount(c) == MAX_COUNT)
+                int r = sharedCount(c);
+                if (r == MAX_COUNT)
                     throw new Error("Maximum lock count exceeded");
                 if (compareAndSetState(c, c + SHARED_UNIT)) {
-                    HoldCounter rh = cachedHoldCounter;
-                    if (rh == null || rh.tid != current.getId())
-                        cachedHoldCounter = rh = readHolds.get();
-                    rh.count++;
+                    long tid = current.getId();
+                    if (r == 0) {
+                        firstReader = tid;
+                        firstReaderHoldCount = 1;
+                    } else if (firstReader == tid) {
+                        firstReaderHoldCount++;
+                    } else {
+                        HoldCounter rh = cachedHoldCounter;
+                        if (rh == null || rh.tid != tid)
+                            cachedHoldCounter = rh = readHolds.get();
+                        else if (rh.count == 0)
+                            readHolds.set(rh);
+                        rh.count++;
+                    }
                     return true;
                 }
             }
@@ -546,7 +623,20 @@
         }
 
         final int getReadHoldCount() {
-            return getReadLockCount() == 0? 0 : readHolds.get().count;
+            if (getReadLockCount() == 0)
+                return 0;
+
+            long tid = Thread.currentThread().getId();
+            if (firstReader == tid)
+                return firstReaderHoldCount;
+
+            HoldCounter rh = cachedHoldCounter;
+            if (rh != null && rh.tid == tid)
+                return rh.count;
+
+            int count = readHolds.get().count;
+            if (count == 0) readHolds.remove();
+            return count;
         }
 
         /**
@@ -557,6 +647,7 @@
             throws java.io.IOException, ClassNotFoundException {
             s.defaultReadObject();
             readHolds = new ThreadLocalHoldCounter();
+            firstReader = INVALID_THREAD_ID;
             setState(0); // reset to unlocked state
         }
 
--- a/src/share/classes/java/util/prefs/AbstractPreferences.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/prefs/AbstractPreferences.java	Mon Apr 14 11:34:15 2008 -0700
@@ -155,7 +155,8 @@
      * All known unremoved children of this node.  (This "cache" is consulted
      * prior to calling childSpi() or getChild().
      */
-    private Map kidCache  = new HashMap();
+    private Map<String, AbstractPreferences> kidCache
+        = new HashMap<String, AbstractPreferences>();
 
     /**
      * This field is used to keep track of whether or not this node has
@@ -712,11 +713,10 @@
             if (removed)
                 throw new IllegalStateException("Node has been removed.");
 
-            Set s = new TreeSet(kidCache.keySet());
-            String[] kids = childrenNamesSpi();
-            for(int i=0; i<kids.length; i++)
-                s.add(kids[i]);
-            return (String[]) s.toArray(EMPTY_STRING_ARRAY);
+            Set<String> s = new TreeSet<String>(kidCache.keySet());
+            for (String kid : childrenNamesSpi())
+                s.add(kid);
+            return s.toArray(EMPTY_STRING_ARRAY);
         }
     }
 
@@ -728,8 +728,7 @@
      * @return all known unremoved children of this node.
      */
     protected final AbstractPreferences[] cachedChildren() {
-        return (AbstractPreferences[]) kidCache.values().
-            toArray(EMPTY_ABSTRACT_PREFS_ARRAY);
+        return kidCache.values().toArray(EMPTY_ABSTRACT_PREFS_ARRAY);
     }
 
     private static final AbstractPreferences[] EMPTY_ABSTRACT_PREFS_ARRAY
@@ -825,7 +824,7 @@
         if (token.equals("/"))  // Check for consecutive slashes
             throw new IllegalArgumentException("Consecutive slashes in path");
         synchronized(lock) {
-            AbstractPreferences child=(AbstractPreferences)kidCache.get(token);
+            AbstractPreferences child = kidCache.get(token);
             if (child == null) {
                 if (token.length() > MAX_NAME_LENGTH)
                     throw new IllegalArgumentException(
@@ -893,7 +892,7 @@
         if (token.equals("/"))  // Check for consecutive slashes
             throw new IllegalArgumentException("Consecutive slashes in path");
         synchronized(lock) {
-            AbstractPreferences child=(AbstractPreferences)kidCache.get(token);
+            AbstractPreferences child = kidCache.get(token);
             if (child == null)
                 child = getChild(token);
             if (child==null)
@@ -964,9 +963,10 @@
                     kidCache.put(kidNames[i], childSpi(kidNames[i]));
 
             // Recursively remove all cached children
-            for (Iterator i = kidCache.values().iterator(); i.hasNext();) {
+            for (Iterator<AbstractPreferences> i = kidCache.values().iterator();
+                 i.hasNext();) {
                 try {
-                    ((AbstractPreferences)i.next()).removeNode2();
+                    i.next().removeNode2();
                     i.remove();
                 } catch (BackingStoreException x) { }
             }
@@ -1020,13 +1020,12 @@
      *         preference tree.
      */
     public boolean isUserNode() {
-        Boolean result = (Boolean)
-          AccessController.doPrivileged( new PrivilegedAction() {
-            public Object run() {
-                return Boolean.valueOf(root == Preferences.userRoot());
+        return AccessController.doPrivileged(
+            new PrivilegedAction<Boolean>() {
+                public Boolean run() {
+                    return root == Preferences.userRoot();
             }
-        });
-        return result.booleanValue();
+            }).booleanValue();
     }
 
     public void addPreferenceChangeListener(PreferenceChangeListener pcl) {
@@ -1443,7 +1442,8 @@
      * event delivery from preference activity, greatly simplifying
      * locking and reducing opportunity for deadlock.
      */
-    private static final List eventQueue = new LinkedList();
+    private static final List<EventObject> eventQueue
+        = new LinkedList<EventObject>();
 
     /**
      * These two classes are used to distinguish NodeChangeEvents on
@@ -1476,7 +1476,7 @@
                     try {
                         while (eventQueue.isEmpty())
                             eventQueue.wait();
-                        event = (EventObject) eventQueue.remove(0);
+                        event = eventQueue.remove(0);
                     } catch (InterruptedException e) {
                         // XXX Log "Event dispatch thread interrupted. Exiting"
                         return;
--- a/src/share/classes/java/util/prefs/Preferences.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/prefs/Preferences.java	Mon Apr 14 11:34:15 2008 -0700
@@ -32,9 +32,8 @@
 import java.security.Permission;
 import java.security.PrivilegedAction;
 import java.util.Iterator;
-import sun.misc.Service;
-import sun.misc.ServiceConfigurationError;
-
+import java.util.ServiceLoader;
+import java.util.ServiceConfigurationError;
 
 // These imports needed only as a workaround for a JavaDoc bug
 import java.lang.RuntimePermission;
@@ -274,12 +273,14 @@
 
     private static PreferencesFactory factory1() {
         // 2. Try service provider interface
-        Iterator i = Service.providers(PreferencesFactory.class,
-                                       ClassLoader.getSystemClassLoader());
+        Iterator<PreferencesFactory> itr = ServiceLoader
+            .load(PreferencesFactory.class, ClassLoader.getSystemClassLoader())
+            .iterator();
+
         // choose first provider instance
-        while (i.hasNext()) {
+        while (itr.hasNext()) {
             try {
-                return (PreferencesFactory) i.next();
+                return itr.next();
             } catch (ServiceConfigurationError sce) {
                 if (sce.getCause() instanceof SecurityException) {
                     // Ignore the security exception, try the next provider
--- a/src/share/classes/java/util/regex/Matcher.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/java/util/regex/Matcher.java	Mon Apr 14 11:34:15 2008 -0700
@@ -249,7 +249,7 @@
         Matcher result = new Matcher(this.parentPattern, text.toString());
         result.first = this.first;
         result.last = this.last;
-        result.groups = (int[])(this.groups.clone());
+        result.groups = this.groups.clone();
         return result;
     }
 
--- a/src/share/classes/javax/management/AndQueryExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/AndQueryExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -104,4 +104,25 @@
      return "(" + exp1 + ") and (" + exp2 + ")";
    }
 
- }
+   @Override
+   String toQueryString() {
+        // Parentheses are only added if needed to disambiguate.
+        return parens(exp1) + " and " + parens(exp2);
+   }
+
+   // Add parens if needed to disambiguate an expression such as
+   // Query.and(Query.or(a, b), c).  We need to return
+   // (a or b) and c
+   // in such a case, because
+   // a or b and c
+   // would mean
+   // a or (b and c)
+   private static String parens(QueryExp exp) {
+       String s = Query.toString(exp);
+       if (exp instanceof OrQueryExp)
+           return "(" + s + ")";
+       else
+           return s;
+   }
+
+}
--- a/src/share/classes/javax/management/AttributeValueExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/AttributeValueExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -26,12 +26,17 @@
 package javax.management;
 
 
-// RI import
-import javax.management.MBeanServer;
+import com.sun.jmx.mbeanserver.Introspector;
+import java.io.IOException;
+import java.io.ObjectInputStream;
 
 /**
- * Represents attributes used as arguments to relational constraints.
- * An <CODE>AttributeValueExp</CODE> may be used anywhere a <CODE>ValueExp</CODE> is required.
+ * <p>Represents attributes used as arguments to relational constraints.
+ * Instances of this class are usually obtained using {@link Query#attr(String)
+ * Query.attr}.</p>
+ *
+ * <p>An <CODE>AttributeValueExp</CODE> may be used anywhere a
+ * <CODE>ValueExp</CODE> is required.
  *
  * @since 1.5
  */
@@ -46,6 +51,8 @@
      */
     private String attr;
 
+    private transient int dotIndex;
+
     /**
      * An <code>AttributeValueExp</code> with a null attribute.
      * @deprecated An instance created with this constructor cannot be
@@ -64,6 +71,18 @@
      */
     public AttributeValueExp(String attr) {
         this.attr = attr;
+        setDotIndex();
+    }
+
+    private void setDotIndex() {
+        if (attr != null)
+            dotIndex = attr.indexOf('.');
+    }
+
+    private void readObject(ObjectInputStream in)
+    throws ClassNotFoundException, IOException {
+        in.defaultReadObject();
+        setDotIndex();
     }
 
     /**
@@ -76,7 +95,13 @@
     }
 
     /**
-     * Applies the <CODE>AttributeValueExp</CODE> on an MBean.
+     * <p>Applies the <CODE>AttributeValueExp</CODE> on an MBean.
+     * This method calls {@link #getAttribute getAttribute(name)} and wraps
+     * the result as a {@code ValueExp}.  The value returned by
+     * {@code getAttribute} must be a {@code Number}, {@code String},
+     * or {@code Boolean}; otherwise this method throws a
+     * {@code BadAttributeValueExpException}, which will cause
+     * the containing query to be false for this {@code name}.</p>
      *
      * @param name The name of the MBean on which the <CODE>AttributeValueExp</CODE> will be applied.
      *
@@ -88,6 +113,7 @@
      * @exception BadBinaryOpValueExpException
      *
      */
+    @Override
     public ValueExp apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException,
         BadAttributeValueExpException, InvalidApplicationException {
         Object result = getAttribute(name);
@@ -106,8 +132,9 @@
     /**
      * Returns the string representing its value.
      */
+    @Override
     public String toString()  {
-        return attr;
+        return QueryParser.quoteId(attr);
     }
 
 
@@ -115,18 +142,38 @@
      * Sets the MBean server on which the query is to be performed.
      *
      * @param s The MBean server on which the query is to be performed.
+     *
+     * @deprecated This method has no effect.  The MBean Server used to
+     * obtain an attribute value is {@link QueryEval#getMBeanServer()}.
      */
     /* There is no need for this method, because if a query is being
        evaluted an AttributeValueExp can only appear inside a QueryExp,
        and that QueryExp will itself have done setMBeanServer.  */
+    @Deprecated
+    @Override
     public void setMBeanServer(MBeanServer s)  {
     }
 
 
     /**
-     * Return the value of the given attribute in the named MBean.
+     * <p>Return the value of the given attribute in the named MBean.
      * If the attempt to access the attribute generates an exception,
-     * return null.
+     * return null.</p>
+     *
+     * <p>Let <em>n</em> be the {@linkplain #getAttributeName attribute
+     * name}. Then this method proceeds as follows. First it calls
+     * {@link MBeanServer#getAttribute getAttribute(name, <em>n</em>)}. If that
+     * generates an {@link AttributeNotFoundException}, and if <em>n</em>
+     * contains at least one dot ({@code .}), then the method calls {@code
+     * getAttribute(name, }<em>n</em>{@code .substring(0, }<em>n</em>{@code
+     * .indexOf('.')))}; in other words it calls {@code getAttribute}
+     * with the substring of <em>n</em> before the first dot. Then it
+     * extracts a component from the retrieved value, as described in the <a
+     * href="monitor/package-summary.html#complex">documentation for the {@code
+     * monitor} package</a>.</p>
+     *
+     * <p>The MBean Server used is the one returned by {@link
+     * QueryEval#getMBeanServer()}.</p>
      *
      * @param name the name of the MBean whose attribute is to be returned.
      *
@@ -139,10 +186,34 @@
 
             MBeanServer server = QueryEval.getMBeanServer();
 
+            try {
             return server.getAttribute(name, attr);
+            } catch (AttributeNotFoundException e) {
+                if (dotIndex < 0)
+                    throw e;
+            }
+
+            String toGet = attr.substring(0, dotIndex);
+
+            Object value = server.getAttribute(name, toGet);
+
+            return extractElement(value, attr.substring(dotIndex + 1));
         } catch (Exception re) {
             return null;
         }
     }
 
+    private Object extractElement(Object value, String elementWithDots)
+    throws AttributeNotFoundException {
+        while (true) {
+            int dot = elementWithDots.indexOf('.');
+            String element = (dot < 0) ?
+                elementWithDots : elementWithDots.substring(0, dot);
+            value = Introspector.elementFromComplex(value, element);
+            if (dot < 0)
+                return value;
+            elementWithDots = elementWithDots.substring(dot + 1);
+        }
+    }
+
 }
--- a/src/share/classes/javax/management/BetweenQueryExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/BetweenQueryExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -109,34 +109,25 @@
         ValueExp val1 = exp1.apply(name);
         ValueExp val2 = exp2.apply(name);
         ValueExp val3 = exp3.apply(name);
-        String sval1;
-        String sval2;
-        String sval3;
-        double dval1;
-        double dval2;
-        double dval3;
-        long lval1;
-        long lval2;
-        long lval3;
         boolean numeric = val1 instanceof NumericValueExp;
 
         if (numeric) {
             if (((NumericValueExp)val1).isLong()) {
-                lval1 = ((NumericValueExp)val1).longValue();
-                lval2 = ((NumericValueExp)val2).longValue();
-                lval3 = ((NumericValueExp)val3).longValue();
+                long lval1 = ((NumericValueExp)val1).longValue();
+                long lval2 = ((NumericValueExp)val2).longValue();
+                long lval3 = ((NumericValueExp)val3).longValue();
                 return lval2 <= lval1 && lval1 <= lval3;
             } else {
-                dval1 = ((NumericValueExp)val1).doubleValue();
-                dval2 = ((NumericValueExp)val2).doubleValue();
-                dval3 = ((NumericValueExp)val3).doubleValue();
+                double dval1 = ((NumericValueExp)val1).doubleValue();
+                double dval2 = ((NumericValueExp)val2).doubleValue();
+                double dval3 = ((NumericValueExp)val3).doubleValue();
                 return dval2 <= dval1 && dval1 <= dval3;
             }
 
         } else {
-            sval1 = ((StringValueExp)val1).toString();
-            sval2 = ((StringValueExp)val2).toString();
-            sval3 = ((StringValueExp)val3).toString();
+            String sval1 = ((StringValueExp)val1).getValue();
+            String sval2 = ((StringValueExp)val2).getValue();
+            String sval3 = ((StringValueExp)val3).getValue();
             return sval2.compareTo(sval1) <= 0 && sval1.compareTo(sval3) <= 0;
         }
     }
@@ -148,4 +139,8 @@
         return "(" + exp1 + ") between (" + exp2 + ") and (" + exp3 + ")";
     }
 
- }
+    @Override
+    String toQueryString() {
+        return exp1 + " between " + exp2 + " and " + exp3;
+    }
+}
--- a/src/share/classes/javax/management/BinaryOpValueExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/BinaryOpValueExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -167,12 +167,74 @@
      */
     public String toString()  {
         try {
-            return exp1 + " " + opString() + " " + exp2;
+            return parens(exp1, true) + " " + opString() + " " + parens(exp2, false);
         } catch (BadBinaryOpValueExpException ex) {
             return "invalid expression";
         }
     }
 
+    /*
+     * Add parentheses to the given subexpression if necessary to
+     * preserve meaning.  Suppose this BinaryOpValueExp is
+     * Query.times(Query.plus(Query.attr("A"), Query.attr("B")), Query.attr("C")).
+     * Then the original toString() logic would return A + B * C.
+     * We check precedences in order to return (A + B) * C, which is the
+     * meaning of the ValueExp.
+     *
+     * We need to add parentheses if the unparenthesized expression would
+     * be parsed as a different ValueExp from the original.
+     * We cannot omit parentheses even when mathematically
+     * the result would be equivalent, because we do not know whether the
+     * numeric values will be integer or floating-point.  Addition and
+     * multiplication are associative for integers but not always for
+     * floating-point.
+     *
+     * So the rule is that we omit parentheses if the ValueExp
+     * is (A op1 B) op2 C and the precedence of op1 is greater than or
+     * equal to that of op2; or if the ValueExp is A op1 (B op2 C) and
+     * the precedence of op2 is greater than that of op1.  (There are two
+     * precedences: that of * and / is greater than that of + and -.)
+     * The case of (A op1 B) op2 (C op3 D) applies each rule in turn.
+     *
+     * The following examples show the rules in action.  On the left,
+     * the original ValueExp.  On the right, the string representation.
+     *
+     * (A + B) + C     A + B + C
+     * (A * B) + C     A * B + C
+     * (A + B) * C     (A + B) * C
+     * (A * B) * C     A * B * C
+     * A + (B + C)     A + (B + C)
+     * A + (B * C)     A + B * C
+     * A * (B + C)     A * (B + C)
+     * A * (B * C)     A * (B * C)
+     */
+    private String parens(ValueExp subexp, boolean left)
+    throws BadBinaryOpValueExpException {
+        boolean omit;
+        if (subexp instanceof BinaryOpValueExp) {
+            int subop = ((BinaryOpValueExp) subexp).op;
+            if (left)
+                omit = (precedence(subop) >= precedence(op));
+            else
+                omit = (precedence(subop) > precedence(op));
+        } else
+            omit = true;
+
+        if (omit)
+            return subexp.toString();
+        else
+            return "(" + subexp + ")";
+    }
+
+    private int precedence(int xop) throws BadBinaryOpValueExpException {
+        switch (xop) {
+            case Query.PLUS: case Query.MINUS: return 0;
+            case Query.TIMES: case Query.DIV: return 1;
+            default:
+                throw new BadBinaryOpValueExpException(this);
+        }
+    }
+
     private String opString() throws BadBinaryOpValueExpException {
         switch (op) {
         case Query.PLUS:
@@ -188,4 +250,10 @@
         throw new BadBinaryOpValueExpException(this);
     }
 
+    @Deprecated
+    public void setMBeanServer(MBeanServer s) {
+        super.setMBeanServer(s);
  }
+
+
+ }
--- a/src/share/classes/javax/management/BinaryRelQueryExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/BinaryRelQueryExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -108,20 +108,12 @@
         BadAttributeValueExpException, InvalidApplicationException  {
         Object val1 = exp1.apply(name);
         Object val2 = exp2.apply(name);
-        String sval1;
-        String sval2;
-        double dval1;
-        double dval2;
-        long   lval1;
-        long   lval2;
-        boolean bval1;
-        boolean bval2;
         boolean numeric = val1 instanceof NumericValueExp;
         boolean bool = val1 instanceof BooleanValueExp;
         if (numeric) {
             if (((NumericValueExp)val1).isLong()) {
-                lval1 = ((NumericValueExp)val1).longValue();
-                lval2 = ((NumericValueExp)val2).longValue();
+                long lval1 = ((NumericValueExp)val1).longValue();
+                long lval2 = ((NumericValueExp)val2).longValue();
 
                 switch (relOp) {
                 case Query.GT:
@@ -136,8 +128,8 @@
                     return lval1 == lval2;
                 }
             } else {
-                dval1 = ((NumericValueExp)val1).doubleValue();
-                dval2 = ((NumericValueExp)val2).doubleValue();
+                double dval1 = ((NumericValueExp)val1).doubleValue();
+                double dval2 = ((NumericValueExp)val2).doubleValue();
 
                 switch (relOp) {
                 case Query.GT:
@@ -155,8 +147,8 @@
 
         } else if (bool) {
 
-            bval1 = ((BooleanValueExp)val1).getValue().booleanValue();
-            bval2 = ((BooleanValueExp)val2).getValue().booleanValue();
+            boolean bval1 = ((BooleanValueExp)val1).getValue().booleanValue();
+            boolean bval2 = ((BooleanValueExp)val2).getValue().booleanValue();
 
             switch (relOp) {
             case Query.GT:
@@ -172,8 +164,8 @@
             }
 
         } else {
-            sval1 = ((StringValueExp)val1).getValue();
-            sval2 = ((StringValueExp)val2).getValue();
+            String sval1 = ((StringValueExp)val1).getValue();
+            String sval2 = ((StringValueExp)val2).getValue();
 
             switch (relOp) {
             case Query.GT:
@@ -199,6 +191,11 @@
         return "(" + exp1 + ") " + relOpString() + " (" + exp2 + ")";
     }
 
+    @Override
+    String toQueryString() {
+        return exp1 + " " + relOpString() + " " + exp2;
+    }
+
     private String relOpString() {
         switch (relOp) {
         case Query.GT:
--- a/src/share/classes/javax/management/BooleanValueExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/BooleanValueExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -84,4 +84,10 @@
         return this;
     }
 
+    @Deprecated
+    public void setMBeanServer(MBeanServer s) {
+        super.setMBeanServer(s);
+    }
+
+
  }
--- a/src/share/classes/javax/management/InQueryExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/InQueryExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -91,21 +91,23 @@
      * @exception BadAttributeValueExpException
      * @exception InvalidApplicationException
      */
-    public boolean apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException,
+    public boolean apply(ObjectName name)
+    throws BadStringOperationException, BadBinaryOpValueExpException,
         BadAttributeValueExpException, InvalidApplicationException  {
         if (valueList != null) {
             ValueExp v      = val.apply(name);
             boolean numeric = v instanceof NumericValueExp;
 
-            for (int i = 0; i < valueList.length; i++) {
+            for (ValueExp element : valueList) {
+                element = element.apply(name);
                 if (numeric) {
-                    if (((NumericValueExp)valueList[i]).doubleValue() ==
-                        ((NumericValueExp)v).doubleValue()) {
+                    if (((NumericValueExp) element).doubleValue() ==
+                        ((NumericValueExp) v).doubleValue()) {
                         return true;
                     }
                 } else {
-                    if (((StringValueExp)valueList[i]).getValue().equals(
-                        ((StringValueExp)v).getValue())) {
+                    if (((StringValueExp) element).getValue().equals(
+                        ((StringValueExp) v).getValue())) {
                         return true;
                     }
                 }
--- a/src/share/classes/javax/management/MatchQueryExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/MatchQueryExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -113,7 +113,32 @@
     }
 
     private static String likeTranslate(String s) {
-        return s.replace('?', '_').replace('*', '%');
+        StringBuilder sb = new StringBuilder();
+        int c;
+        for (int i = 0; i < s.length(); i += Character.charCount(c)) {
+            c = s.codePointAt(i);
+            switch (c) {
+                case '\\':
+                    i += Character.charCount(c);
+                    sb.append('\\');
+                    if (i < s.length()) {
+                        c = s.codePointAt(i);
+                        sb.appendCodePoint(c);
+    }
+                    break;
+                case '*':
+                    sb.append('%'); break;
+                case '?':
+                    sb.append('_'); break;
+                case '%':
+                    sb.append("\\%"); break;
+                case '_':
+                    sb.append("\\_"); break;
+                default:
+                    sb.appendCodePoint(c); break;
+            }
+        }
+        return sb.toString();
     }
 
     /*
--- a/src/share/classes/javax/management/NotQueryExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/NotQueryExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -86,8 +86,14 @@
     /**
      * Returns the string representing the object.
      */
+    @Override
     public String toString()  {
         return "not (" + exp + ")";
     }
 
+    @Override
+    String toQueryString() {
+        return "not (" + Query.toString(exp) + ")";
+    }
+
  }
--- a/src/share/classes/javax/management/NumericValueExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/NumericValueExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -151,11 +151,18 @@
      * Returns the string representing the object
      */
     public String toString()  {
+      if (val == null)
+        return "null";
       if (val instanceof Long || val instanceof Integer)
       {
-        return String.valueOf(val.longValue());
+        return Long.toString(val.longValue());
       }
-      return String.valueOf(val.doubleValue());
+      double d = val.doubleValue();
+      if (Double.isInfinite(d))
+          return (d > 0) ? "(1.0 / 0.0)" : "(-1.0 / 0.0)";
+      if (Double.isNaN(d))
+          return "(0.0 / 0.0)";
+      return Double.toString(d);
     }
 
     /**
@@ -244,4 +251,10 @@
         out.defaultWriteObject();
       }
     }
+
+    @Deprecated
+    public void setMBeanServer(MBeanServer s) {
+        super.setMBeanServer(s);
+    }
+
  }
--- a/src/share/classes/javax/management/ObjectName.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/ObjectName.java	Mon Apr 14 11:34:15 2008 -0700
@@ -222,7 +222,8 @@
  * @since 1.5
  */
 @SuppressWarnings("serial") // don't complain serialVersionUID not constant
-public class ObjectName implements Comparable<ObjectName>, QueryExp {
+public class ObjectName extends ToQueryString
+        implements Comparable<ObjectName>, QueryExp {
 
     /**
      * A structure recording property structure and
@@ -1779,10 +1780,16 @@
      *
      * @return a string representation of this object name.
      */
+    @Override
     public String toString()  {
         return getSerializedNameString();
     }
 
+    @Override
+    String toQueryString() {
+        return "LIKE " + Query.value(toString());
+    }
+
     /**
      * Compares the current object name with another object name.  Two
      * ObjectName instances are equal if and only if their canonical
--- a/src/share/classes/javax/management/OrQueryExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/OrQueryExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -98,9 +98,29 @@
     }
 
     /**
-     * Returns a string representation of this AndQueryExp
+     * Returns a string representation of this OrQueryExp
      */
     public String toString() {
         return "(" + exp1 + ") or (" + exp2 + ")";
     }
+
+    @Override
+    String toQueryString() {
+        return parens(exp1) + " or " + parens(exp2);
+    }
+
+    // Add parentheses to avoid possible confusion.  If we have an expression
+    // such as Query.or(Query.and(a, b), c), then we return
+    // (a and b) or c
+    // rather than just
+    // a and b or c
+    // In fact the precedence rules are such that the parentheses are not
+    // strictly necessary, but omitting them would be confusing.
+    private static String parens(QueryExp exp) {
+        String s = Query.toString(exp);
+        if (exp instanceof AndQueryExp)
+            return "(" + s + ")";
+        else
+            return s;
+    }
 }
--- a/src/share/classes/javax/management/QualifiedAttributeValueExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/QualifiedAttributeValueExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -27,9 +27,11 @@
 
 
 /**
- * This class represents indexed attributes used as arguments to relational
- * constraints. An QualifiedAttributeValueExp may be used anywhere a
- * ValueExp is required.
+ * <p>Represents attributes used as arguments to relational constraints,
+ * where the attribute must be in an MBean of a specified {@linkplain
+ * MBeanInfo#getClassName() class}. A QualifiedAttributeValueExp may be used
+ * anywhere a ValueExp is required.
+ *
  * @serial include
  *
  * @since 1.5
@@ -48,7 +50,9 @@
 
     /**
      * Basic Constructor.
+     * @deprecated see {@link AttributeValueExp#AttributeValueExp()}
      */
+    @Deprecated
     public QualifiedAttributeValueExp() {
     }
 
@@ -81,6 +85,7 @@
      * @exception BadAttributeValueExpException
      * @exception InvalidApplicationException
      */
+    @Override
     public ValueExp apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException,
         BadAttributeValueExpException, InvalidApplicationException  {
         try {
@@ -105,9 +110,11 @@
     /**
      * Returns the string representing its value
      */
+    @Override
     public String toString()  {
         if (className != null) {
-            return className + "." + super.toString();
+            return QueryParser.quoteId(className) + "#" +
+                QueryParser.quoteId(super.toString());
         } else {
             return super.toString();
         }
--- a/src/share/classes/javax/management/Query.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/Query.java	Mon Apr 14 11:34:15 2008 -0700
@@ -27,19 +27,346 @@
 
 
 /**
- * <p>Constructs query object constraints. The static methods provided
- * return query expressions that may be used in listing and
- * enumerating MBeans. Individual constraint construction methods
- * allow only appropriate types as arguments. Composition of calls can
- * construct arbitrary nestings of constraints, as the following
- * example illustrates:</p>
+ * <p>Constructs query object constraints.</p>
+ *
+ * <p>The MBean Server can be queried for MBeans that meet a particular
+ * condition, using its {@link MBeanServer#queryNames queryNames} or
+ * {@link MBeanServer#queryMBeans queryMBeans} method.  The {@link QueryExp}
+ * parameter to the method can be any implementation of the interface
+ * {@code QueryExp}, but it is usually best to obtain the {@code QueryExp}
+ * value by calling the static methods in this class.  This is particularly
+ * true when querying a remote MBean Server: a custom implementation of the
+ * {@code QueryExp} interface might not be present in the remote MBean Server,
+ * but the methods in this class return only standard classes that are
+ * part of the JMX implementation.</p>
+ *
+ * <p>There are two ways to create {@code QueryExp} objects using the methods
+ * in this class.  The first is to build them by chaining together calls to
+ * the various methods.  The second is to use the Query Language described
+ * <a href="#ql">below</a> and produce the {@code QueryExp} by calling
+ * {@link #fromString Query.fromString}.  The two ways are equivalent:
+ * every {@code QueryExp} returned by {@code fromString} can also be
+ * constructed by chaining method calls.</p>
+ *
+ * <p>As an example, suppose you wanted to find all MBeans where the {@code
+ * Enabled} attribute is {@code true} and the {@code Owner} attribute is {@code
+ * "Duke"}. Here is how you could construct the appropriate {@code QueryExp} by
+ * chaining together method calls:</p>
+ *
+ * <pre>
+ * QueryExp query =
+ *     Query.and(Query.eq(Query.attr("Enabled"), Query.value(true)),
+ *               Query.eq(Query.attr("Owner"), Query.value("Duke")));
+ * </pre>
+ *
+ * <p>Here is how you could construct the same {@code QueryExp} using the
+ * Query Language:</p>
  *
  * <pre>
- * QueryExp exp = Query.and(Query.gt(Query.attr("age"),Query.value(5)),
- *                          Query.match(Query.attr("name"),
- *                                      Query.value("Smith")));
+ * QueryExp query = Query.fromString("Enabled = true and Owner = 'Duke'");
  * </pre>
  *
+ * <p>The principal advantage of the method-chaining approach is that the
+ * compiler will check that the query makes sense.  The principal advantage
+ * of the Query Language approach is that it is easier to write and especially
+ * read.</p>
+ *
+ *
+ * <h4 id="ql">Query Language</h4>
+ *
+ * <p>The query language is closely modeled on the WHERE clause of
+ * SQL SELECT statements. The formal specification of the language
+ * appears <a href="#formal-ql">below</a>, but it is probably easier to
+ * understand it with examples such as the following.</p>
+ *
+ * <dl>
+ * <dt>{@code Message = 'OK'}
+ * <dd>Selects MBeans that have a {@code Message} attribute whose value
+ *     is the string {@code OK}.
+ *
+ * <dt>{@code FreeSpacePercent < 10}
+ * <dd>Selects MBeans that have a {@code FreeSpacePercent} attribute whose
+ *     value is a number less than 10.
+ *
+ * <dt>{@code FreeSpacePercent < 10 and WarningSent = false}
+ * <dd>Selects the same MBeans as the previous example, but they must
+ *     also have a boolean attribute {@code WarningSent} whose value
+ *     is false.
+ *
+ * <dt>{@code SpaceUsed > TotalSpace * (2.0 / 3.0)}
+ * <dd>Selects MBeans that have {@code SpaceUsed} and {@code TotalSpace}
+ *     attributes where the first is more than two-thirds the second.
+ *
+ * <dt>{@code not (FreeSpacePercent between 10 and 90)}
+ * <dd>Selects MBeans that have a {@code FreeSpacePercent} attribute whose
+ *     value is not between 10 and 90, inclusive.
+ *
+ * <dt>{@code FreeSpacePercent not between 10 and 90}
+ * <dd>Another way of writing the previous query.
+ *
+ * <dt>{@code Status in ('STOPPED', 'STARTING', 'STARTED')}
+ * <dd>Selects MBeans that have a {@code Status} attribute whose value
+ *     is one of those three strings.
+ *
+ * <dt>{@code Message like 'OK: %'}
+ * <dd>Selects MBeans that have a {@code Message} attribute whose value
+ *     is a string beginning with {@code "OK: "}.  <b>Notice that the
+ *     wildcard characters are SQL's ones.</b>  In the query language,
+ *     {@code %} means "any sequence of characters" and {@code _}
+ *     means "any single character".  In the rest of the JMX API, these
+ *     correspond to {@code *} and {@code %} respectively.
+ *
+ * <dt>{@code instanceof 'javax.management.NotificationBroadcaster'}
+ * <dd>Selects MBeans that are instances of
+ *     {@link javax.management.NotificationBroadcaster}, as reported by
+ *     {@link javax.management.MBeanServer#isInstanceOf MBeanServer.isInstanceOf}.
+ *
+ * <dt>{@code like 'mydomain:*'}
+ * <dd>Selects MBeans whose {@link ObjectName}s have the domain {@code mydomain}.
+ *
+ * </dl>
+ *
+ * <p>The last two examples do not correspond to valid SQL syntax, but all
+ * the others do.</p>
+ *
+ * <p>The remainder of this description is a formal specification of the
+ * query language.</p>
+ *
+ *
+ * <h4 id="formal-ql">Lexical elements</h4>
+ *
+ * <p>Keywords such as <b>and</b>, <b>like</b>, and <b>between</b> are not
+ * case sensitive.  You can write <b>between</b>, <b>BETWEEN</b>, or
+ * <b>BeTwEeN</b> with the same effect.</p>
+ *
+ * <p>On the other hand, attribute names <i>are</i> case sensitive.  The
+ * attribute {@code Name} is not the same as the attribute {@code name}.</p>
+ *
+ * <p>To access an attribute whose name, ignoring case, is the same as one of
+ * the keywords {@code not}, {@code instanceof}, {@code like}, {@code true},
+ * or {@code false}, you can use double quotes, for example {@code "not"}.
+ * Double quotes can also be used to include non-identifier characters in
+ * the name of an attribute, for example {@code "attribute-name-with-hyphens"}.
+ * To include the double quote character in the attribute name, write it
+ * twice.  {@code "foo""bar""baz"} represents the attribute called
+ * {@code foo"bar"baz}.
+ *
+ * <p>String constants are written with single quotes like {@code 'this'}.  A
+ * single quote within a string constant must be doubled, for example
+ * {@code 'can''t'}.</p>
+ *
+ * <p>Integer constants are written as a sequence of decimal digits,
+ * optionally preceded by a plus or minus sign.  An integer constant must be
+ * a valid input to {@link Long#valueOf(String)}.</p>
+ *
+ * <p>Floating-point constants are written using the Java syntax.  A
+ * floating-point constant must be a valid input to
+ * {@link Double#valueOf(String)}.</p>
+ *
+ * <p>A boolean constant is either {@code true} or {@code false}, ignoring
+ * case.</p>
+ *
+ * <p>Spaces cannot appear inside identifiers (unless written with double
+ * quotes) or keywords or multi-character tokens such as {@code <=}. Spaces can
+ * appear anywhere else, but are not required except to separate tokens. For
+ * example, the query {@code a < b and 5 = c} could also be written {@code a<b
+ * and 5=c}, but no further spaces can be removed.</p>
+ *
+ *
+ * <h4 id="grammar-ql">Grammar</h4>
+ *
+ * <dl>
+ * <dt id="query">query:
+ * <dd><a href="#andquery">andquery</a> [<b>OR</b> <a href="#query">query</a>]
+ *
+ * <dt id="andquery">andquery:
+ * <dd><a href="#predicate">predicate</a> [<b>AND</b> <a href="#andquery">andquery</a>]
+ *
+ * <dt id="predicate">predicate:
+ * <dd><b>(</b> <a href="#query">query</a> <b>)</b> |<br>
+ *     <b>NOT</b> <a href="#predicate">predicate</a> |<br>
+ *     <b>INSTANCEOF</b> <a href="#stringvalue">stringvalue</a> |<br>
+ *     <b>LIKE</b> <a href="#objectnamepattern">objectnamepattern</a> |<br>
+ *     <a href="#value">value</a> <a href="#predrhs">predrhs</a>
+ *
+ * <dt id="predrhs">predrhs:
+ * <dd><a href="#compare">compare</a> <a href="#value">value</a> |<br>
+ *     [<b>NOT</b>] <b>BETWEEN</b> <a href="#value">value</a> <b>AND</b>
+ *         <a href="#value">value</a> |<br>
+ *     [<b>NOT</b>] <b>IN (</b> <a href="#value">value</a>
+ *           <a href="#commavalues">commavalues</a> <b>)</b> |<br>
+ *     [<b>NOT</b>] <b>LIKE</b> <a href="#stringvalue">stringvalue</a>
+ *
+ * <dt id="commavalues">commavalues:
+ * <dd>[ <b>,</b> <a href="#value">value</a> <a href="#commavalues">commavalues</a> ]
+ *
+ * <dt id="compare">compare:
+ * <dd><b>=</b> | <b>&lt;</b> | <b>&gt;</b> |
+ *     <b>&lt;=</b> | <b>&gt;=</b> | <b>&lt;&gt;</b> | <b>!=</b>
+ *
+ * <dt id="value">value:
+ * <dd><a href="#factor">factor</a> [<a href="#plusorminus">plusorminus</a>
+ *     <a href="#value">value</a>]
+ *
+ * <dt id="plusorminus">plusorminus:
+ * <dd><b>+</b> | <b>-</b>
+ *
+ * <dt id="factor">factor:
+ * <dd><a href="#term">term</a> [<a href="#timesordivide">timesordivide</a>
+ *     <a href="#factor">factor</a>]
+ *
+ * <dt id="timesordivide">timesordivide:
+ * <dd><b>*</b> | <b>/</b>
+ *
+ * <dt id="term">term:
+ * <dd><a href="#attr">attr</a> | <a href="#literal">literal</a> |
+ *     <b>(</b> <a href="#value">value</a> <b>)</b>
+ *
+ * <dt id="attr">attr:
+ * <dd><a href="#name">name</a> [<b>#</b> <a href="#name">name</a>]
+ *
+ * <dt id="name">name:
+ * <dd><a href="#identifier">identifier</a> [<b>.</b><a href="#name">name</a>]
+ *
+ * <dt id="identifier">identifier:
+ * <dd><i>Java-identifier</i> | <i>double-quoted-identifier</i>
+ *
+ * <dt id="literal">literal:
+ * <dd><a href="#booleanlit">booleanlit</a> | <i>longlit</i> |
+ *     <i>doublelit</i> | <i>stringlit</i>
+ *
+ * <dt id="booleanlit">booleanlit:
+ * <dd><b>FALSE</b> | <b>TRUE</b>
+ *
+ * <dt id="stringvalue">stringvalue:
+ * <dd><i>stringlit</i>
+ *
+ * <dt id="objectnamepattern">objectnamepattern:
+ * <dd><i>stringlit</i>
+ *
+ * </dl>
+ *
+ *
+ * <h4>Semantics</h4>
+ *
+ * <p>The meaning of the grammar is described in the table below.
+ * This defines a function <i>q</i> that maps a string to a Java object
+ * such as a {@link QueryExp} or a {@link ValueExp}.</p>
+ *
+ * <table border="1" cellpadding="5">
+ * <tr><th>String <i>s</i></th><th><i>q(s)</th></tr>
+ *
+ * <tr><td><i>query1</i> <b>OR</b> <i>query2</i>
+ *     <td>{@link Query#or Query.or}(<i>q(query1)</i>, <i>q(query2)</i>)
+ *
+ * <tr><td><i>query1</i> <b>AND</b> <i>query2</i>
+ *     <td>{@link Query#and Query.and}(<i>q(query1)</i>, <i>q(query2)</i>)
+ *
+ * <tr><td><b>(</b> <i>queryOrValue</i> <b>)</b>
+ *     <td><i>q(queryOrValue)</i>
+ *
+ * <tr><td><b>NOT</b> <i>query</i>
+ *     <td>{@link Query#not Query.not}(<i>q(query)</i>)
+ *
+ * <tr><td><b>INSTANCEOF</b> <i>stringLiteral</i>
+ *     <td>{@link Query#isInstanceOf Query.isInstanceOf}(<!--
+ * -->{@link Query#value(String) Query.value}(<i>q(stringLiteral)</i>))
+ *
+ * <tr><td><b>LIKE</b> <i>stringLiteral</i>
+ *     <td>{@link ObjectName#ObjectName(String) new ObjectName}(<!--
+ * --><i>q(stringLiteral)</i>)
+ *
+ * <tr><td><i>value1</i> <b>=</b> <i>value2</i>
+ *     <td>{@link Query#eq Query.eq}(<i>q(value1)</i>, <i>q(value2)</i>)
+ *
+ * <tr><td><i>value1</i> <b>&lt;</b> <i>value2</i>
+ *     <td>{@link Query#lt Query.lt}(<i>q(value1)</i>, <i>q(value2)</i>)
+ *
+ * <tr><td><i>value1</i> <b>&gt;</b> <i>value2</i>
+ *     <td>{@link Query#gt Query.gt}(<i>q(value1)</i>, <i>q(value2)</i>)
+ *
+ * <tr><td><i>value1</i> <b>&lt;=</b> <i>value2</i>
+ *     <td>{@link Query#leq Query.leq}(<i>q(value1)</i>, <i>q(value2)</i>)
+ *
+ * <tr><td><i>value1</i> <b>&gt;=</b> <i>value2</i>
+ *     <td>{@link Query#geq Query.geq}(<i>q(value1)</i>, <i>q(value2)</i>)
+ *
+ * <tr><td><i>value1</i> <b>&lt;&gt;</b> <i>value2</i>
+ *     <td>{@link Query#not Query.not}({@link Query#eq Query.eq}(<!--
+ * --><i>q(value1)</i>, <i>q(value2)</i>))
+ *
+ * <tr><td><i>value1</i> <b>!=</b> <i>value2</i>
+ *     <td>{@link Query#not Query.not}({@link Query#eq Query.eq}(<!--
+ * --><i>q(value1)</i>, <i>q(value2)</i>))
+ *
+ * <tr><td><i>value1</i> <b>BETWEEN</b> <i>value2</i> AND <i>value3</i>
+ *     <td>{@link Query#between Query.between}(<i>q(value1)</i>,
+ *         <i>q(value2)</i>, <i>q(value3)</i>)
+ *
+ * <tr><td><i>value1</i> <b>NOT BETWEEN</b> <i>value2</i> AND <i>value3</i>
+ *     <td>{@link Query#not Query.not}({@link Query#between Query.between}(<!--
+ * --><i>q(value1)</i>, <i>q(value2)</i>, <i>q(value3)</i>))
+ *
+ * <tr><td><i>value1</i> <b>IN (</b> <i>value2</i>, <i>value3</i> <b>)</b>
+ *     <td>{@link Query#in Query.in}(<i>q(value1)</i>,
+ *         <code>new ValueExp[] {</code>
+ *         <i>q(value2)</i>, <i>q(value3)</i><code>}</code>)
+ *
+ * <tr><td><i>value1</i> <b>NOT IN (</b> <i>value2</i>, <i>value3</i> <b>)</b>
+ *     <td>{@link Query#not Query.not}({@link Query#in Query.in}(<i>q(value1)</i>,
+ *         <code>new ValueExp[] {</code>
+ *         <i>q(value2)</i>, <i>q(value3)</i><code>}</code>))
+ *
+ * <tr><td><i>value</i> <b>LIKE</b> <i>stringLiteral</i>
+ *     <td>{@link Query#match Query.match}(<i>q(value)</i>,
+ *         <i><a href="#translateWildcards">translateWildcards</a>(q(stringLiteral))</i>)
+ *
+ * <tr><td><i>value</i> <b>NOT LIKE</b> <i>stringLiteral</i>
+ *     <td>{@link Query#not Query.not}({@link Query#match Query.match}(<i>q(value)</i>,
+ *         <i><a href="#translateWildcards">translateWildcards</a>(q(stringLiteral))</i>))
+ *
+ * <tr><td><i>value1</i> <b>+</b> <i>value2</i>
+ *     <td>{@link Query#plus Query.plus}(<i>q(value1)</i>, <i>q(value2)</i>)
+ *
+ * <tr><td><i>value1</i> <b>-</b> <i>value2</i>
+ *     <td>{@link Query#minus Query.minus}(<i>q(value1)</i>, <i>q(value2)</i>)
+ *
+ * <tr><td><i>value1</i> <b>*</b> <i>value2</i>
+ *     <td>{@link Query#times Query.times}(<i>q(value1)</i>, <i>q(value2)</i>)
+ *
+ * <tr><td><i>value1</i> <b>/</b> <i>value2</i>
+ *     <td>{@link Query#div Query.div}(<i>q(value1)</i>, <i>q(value2)</i>)
+ *
+ * <tr><td><i>name</i>
+ *     <td>{@link Query#attr(String) Query.attr}(<i>q(name)</i>)
+ *
+ * <tr><td><i>name1<b>#</b>name2</i>
+ *     <td>{@link Query#attr(String,String) Query.attr}(<i>q(name1)</i>,
+ *         <i>q(name2)</i>)
+ *
+ * <tr><td><b>FALSE</b>
+ *     <td>{@link Query#value(boolean) Query.value}(false)
+ *
+ * <tr><td><b>TRUE</b>
+ *     <td>{@link Query#value(boolean) Query.value}(true)
+ *
+ * <tr><td><i>decimalLiteral</i>
+ *     <td>{@link Query#value(long) Query.value}(<!--
+ * -->{@link Long#valueOf(String) Long.valueOf}(<i>decimalLiteral</i>))
+ *
+ * <tr><td><i>floatingPointLiteral</i>
+ *     <td>{@link Query#value(double) Query.value}(<!--
+ * -->{@link Double#valueOf(String) Double.valueOf}(<!--
+ * --><i>floatingPointLiteral</i>))
+ * </table>
+ *
+ * <p id="translateWildcards">Here, <i>translateWildcards</i> is a function
+ * that translates from the SQL notation for wildcards, using {@code %} and
+ * {@code _}, to the JMX API notation, using {@code *} and {@code ?}.  If the
+ * <b>LIKE</b> string already contains {@code *} or {@code ?}, these characters
+ * have their literal meanings, and will be quoted in the call to
+ * {@link Query#match Query.match}.</p>
+ *
  * @since 1.5
  */
  public class Query extends Object   {
@@ -277,16 +604,12 @@
      }
 
      /**
-      * <p>Returns a new attribute expression.</p>
-      *
-      * <p>Evaluating this expression for a given
-      * <code>objectName</code> includes performing {@link
-      * MBeanServer#getAttribute MBeanServer.getAttribute(objectName,
-      * name)}.</p>
+      * <p>Returns a new attribute expression.  See {@link AttributeValueExp}
+      * for a detailed description of the semantics of the expression.</p>
       *
       * @param name The name of the attribute.
       *
-      * @return  An attribute expression for the attribute named name.
+      * @return An attribute expression for the attribute named {@code name}.
       */
      public static AttributeValueExp attr(String name)  {
          return new AttributeValueExp(name);
@@ -628,6 +951,63 @@
      }
 
      /**
+      * <p>Return a string representation of the given query.  The string
+      * returned by this method can be converted back into an equivalent
+      * query using {@link #fromString fromString}.</p>
+      *
+      * <p>(Two queries are equivalent if they produce the same result in
+      * all cases.  Equivalent queries are not necessarily identical:
+      * for example the queries {@code Query.lt(Query.attr("A"), Query.attr("B"))}
+      * and {@code Query.not(Query.ge(Query.attr("A"), Query.attr("B")))} are
+      * equivalent but not identical.)</p>
+      *
+      * <p>The string returned by this method is only guaranteed to be converted
+      * back into an equivalent query if {@code query} was constructed, or
+      * could have been constructed, using the methods of this class.
+      * If you make a custom query {@code myQuery} by implementing
+      * {@link QueryExp} yourself then the result of
+      * {@code Query.toString(myQuery)} is unspecified.</p>
+      *
+      * @param query the query to convert.  If it is null, the result will
+      * also be null.
+      * @return the string representation of the query, or null if the
+      * query is null.
+      *
+      * @since 1.7
+      */
+     public static String toString(QueryExp query) {
+         if (query == null)
+             return null;
+
+         if (query instanceof ToQueryString)
+             return ((ToQueryString) query).toQueryString();
+
+         return query.toString();
+     }
+
+     /**
+      * <p>Produce a query from the given string.  The query returned
+      * by this method can be converted back into a string using
+      * {@link #toString(QueryExp) toString}.  The resultant string will
+      * not necessarily be equal to {@code s}.</p>
+      *
+      * @param s the string to convert.
+      *
+      * @return a {@code QueryExp} derived by parsing the string, or
+      * null if the string is null.
+      *
+      * @throws IllegalArgumentException if the string is not a valid
+      * query string.
+      *
+      * @since 1.7
+      */
+     public static QueryExp fromString(String s) {
+         if (s == null)
+             return null;
+         return new QueryParser(s).parseQuery();
+     }
+
+     /**
       * Utility method to escape strings used with
       * Query.{initial|any|final}SubString() methods.
       */
--- a/src/share/classes/javax/management/QueryEval.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/QueryEval.java	Mon Apr 14 11:34:15 2008 -0700
@@ -38,7 +38,7 @@
  *
  * @since 1.5
  */
-public abstract class QueryEval implements Serializable   {
+public abstract class QueryEval extends ToQueryString implements Serializable {
 
     /* Serial version */
     private static final long serialVersionUID = 2675899265640874796L;
--- a/src/share/classes/javax/management/QueryExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/QueryExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -30,9 +30,9 @@
 
 
 /**
- * <p>Represents relational constraints that can be used in database
- * query "where clauses".  Instances of QueryExp are returned by the
- * static methods of the {@link Query} class.</p>
+ * <p>Represents relational constraints similar to database query "where
+ * clauses". Instances of QueryExp are returned by the static methods of the
+ * {@link Query} class.</p>
  *
  * <p>It is possible, but not
  * recommended, to create custom queries by implementing this
@@ -40,6 +40,7 @@
  * QueryEval} class than to implement the interface directly, so that
  * the {@link #setMBeanServer} method works correctly.
  *
+ * @see MBeanServer#queryNames MBeanServer.queryNames
  * @since 1.5
  */
 public interface QueryExp extends Serializable {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/javax/management/QueryParser.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,663 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+import java.util.ArrayList;
+import java.util.Formatter;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * <p>Parser for JMX queries represented in an SQL-like language.</p>
+ */
+/*
+ * Note that if a query starts with ( then we don't know whether it is
+ * a predicate or just a value that is parenthesized.  So, inefficiently,
+ * we try to parse a predicate and if that doesn't work we try to parse
+ * a value.
+ */
+class QueryParser {
+    // LEXER STARTS HERE
+
+    private static class Token {
+        final String string;
+        Token(String s) {
+            this.string = s;
+        }
+
+        @Override
+        public String toString() {
+            return string;
+        }
+    }
+
+    private static final Token
+            END = new Token("<end of string>"),
+            LPAR = new Token("("), RPAR = new Token(")"),
+            COMMA = new Token(","), DOT = new Token("."), SHARP = new Token("#"),
+            PLUS = new Token("+"), MINUS = new Token("-"),
+            TIMES = new Token("*"), DIVIDE = new Token("/"),
+            LT = new Token("<"), GT = new Token(">"),
+            LE = new Token("<="), GE = new Token(">="),
+            NE = new Token("<>"), EQ = new Token("="),
+            NOT = new Id("NOT"), INSTANCEOF = new Id("INSTANCEOF"),
+            FALSE = new Id("FALSE"), TRUE = new Id("TRUE"),
+            BETWEEN = new Id("BETWEEN"), AND = new Id("AND"),
+            OR = new Id("OR"), IN = new Id("IN"),
+            LIKE = new Id("LIKE"), CLASS = new Id("CLASS");
+
+    // Keywords that can appear where an identifier can appear.
+    // If an attribute is one of these, then it must be quoted when
+    // converting a query into a string.
+    // We use a TreeSet so we can look up case-insensitively.
+    private static final Set<String> idKeywords =
+            new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
+    static {
+        for (Token t : new Token[] {NOT, INSTANCEOF, FALSE, TRUE, LIKE, CLASS})
+            idKeywords.add(t.string);
+    };
+
+    public static String quoteId(String id) {
+        if (id.contains("\"") || idKeywords.contains(id))
+            return '"' + id.replace("\"", "\"\"") + '"';
+        else
+            return id;
+    }
+
+    private static class Id extends Token {
+        Id(String id) {
+            super(id);
+        }
+
+        // All other tokens use object identity, which means e.g. that one
+        // occurrence of the string constant 'x' is not the same as another.
+        // For identifiers, we ignore case when testing for equality so that
+        // for a keyword such as AND you can also spell it as "And" or "and".
+        // But we keep the original case of the identifier, so if it's not
+        // a keyword we will distinguish between the attribute Foo and the
+        // attribute FOO.
+        @Override
+        public boolean equals(Object o) {
+            return (o instanceof Id && (((Id) o).toString().equalsIgnoreCase(toString())));
+        }
+    }
+
+    private static class QuotedId extends Token {
+        QuotedId(String id) {
+            super(id);
+        }
+
+        @Override
+        public String toString() {
+            return '"' + string.replace("\"", "\"\"") + '"';
+        }
+    }
+
+    private static class StringLit extends Token {
+        StringLit(String s) {
+            super(s);
+        }
+
+        @Override
+        public String toString() {
+            return '\'' + string.replace("'", "''") + '\'';
+        }
+    }
+
+    private static class LongLit extends Token {
+        long number;
+
+        LongLit(long number) {
+            super(Long.toString(number));
+            this.number = number;
+        }
+    }
+
+    private static class DoubleLit extends Token {
+        double number;
+
+        DoubleLit(double number) {
+            super(Double.toString(number));
+            this.number = number;
+        }
+    }
+
+    private static class Tokenizer {
+        private final String s;
+        private final int len;
+        private int i = 0;
+
+        Tokenizer(String s) {
+            this.s = s;
+            this.len = s.length();
+        }
+
+        private int thisChar() {
+            if (i == len)
+                return -1;
+            return s.codePointAt(i);
+        }
+
+        private void advance() {
+            i += Character.charCount(thisChar());
+        }
+
+        private int thisCharAdvance() {
+            int c = thisChar();
+            advance();
+            return c;
+        }
+
+        Token nextToken() {
+            // In this method, c is the character we're looking at, and
+            // thisChar() is the character after that.  Everything must
+            // preserve these invariants.  When we return we then have
+            // thisChar() being the start of the following token, so
+            // the next call to nextToken() will begin from there.
+            int c;
+
+            // Skip space
+            do {
+                if (i == len)
+                    return null;
+                c = thisCharAdvance();
+            } while (Character.isWhitespace(c));
+
+            // Now c is the first character of the token, and tokenI points
+            // to the character after that.
+            switch (c) {
+                case '(': return LPAR;
+                case ')': return RPAR;
+                case ',': return COMMA;
+                case '.': return DOT;
+                case '#': return SHARP;
+                case '*': return TIMES;
+                case '/': return DIVIDE;
+                case '=': return EQ;
+                case '-': return MINUS;
+                case '+': return PLUS;
+
+                case '>':
+                    if (thisChar() == '=') {
+                        advance();
+                        return GE;
+                    } else
+                        return GT;
+
+                case '<':
+                    c = thisChar();
+                    switch (c) {
+                        case '=': advance(); return LE;
+                        case '>': advance(); return NE;
+                        default: return LT;
+                    }
+
+                case '!':
+                    if (thisCharAdvance() != '=')
+                        throw new IllegalArgumentException("'!' must be followed by '='");
+                    return NE;
+
+                case '"':
+                case '\'': {
+                    int quote = c;
+                    StringBuilder sb = new StringBuilder();
+                    while (true) {
+                        while ((c = thisChar()) != quote) {
+                            if (c < 0) {
+                                throw new IllegalArgumentException(
+                                        "Unterminated string constant");
+                            }
+                            sb.appendCodePoint(thisCharAdvance());
+                        }
+                        advance();
+                        if (thisChar() == quote) {
+                            sb.appendCodePoint(quote);
+                            advance();
+                        } else
+                            break;
+                    }
+                    if (quote == '\'')
+                        return new StringLit(sb.toString());
+                    else
+                        return new QuotedId(sb.toString());
+                }
+            }
+
+            // Is it a numeric constant?
+            if (Character.isDigit(c) || c == '.') {
+                StringBuilder sb = new StringBuilder();
+                int lastc = -1;
+                while (true) {
+                    sb.appendCodePoint(c);
+                    c = Character.toLowerCase(thisChar());
+                    if (c == '+' || c == '-') {
+                        if (lastc != 'e')
+                            break;
+                    } else if (!Character.isDigit(c) && c != '.' && c != 'e')
+                        break;
+                    lastc = c;
+                    advance();
+                }
+                String s = sb.toString();
+                if (s.indexOf('.') >= 0 || s.indexOf('e') >= 0) {
+                    double d = parseDoubleCheckOverflow(s);
+                    return new DoubleLit(d);
+                } else {
+                    // Like the Java language, we allow the numeric constant
+                    // x where -x = Long.MIN_VALUE, even though x is not
+                    // representable as a long (it is Long.MAX_VALUE + 1).
+                    // Code in the parser will reject this value if it is
+                    // not the operand of unary minus.
+                    long l = -Long.parseLong("-" + s);
+                    return new LongLit(l);
+                }
+            }
+
+            // It must be an identifier.
+            if (!Character.isJavaIdentifierStart(c)) {
+                StringBuilder sb = new StringBuilder();
+                Formatter f = new Formatter(sb);
+                f.format("Bad character: %c (%04x)", c, c);
+                throw new IllegalArgumentException(sb.toString());
+            }
+
+            StringBuilder id = new StringBuilder();
+            while (true) { // identifier
+                id.appendCodePoint(c);
+                c = thisChar();
+                if (!Character.isJavaIdentifierPart(c))
+                    break;
+                advance();
+            }
+
+            return new Id(id.toString());
+        }
+    }
+
+    /* Parse a double as a Java compiler would do it, throwing an exception
+     * if the input does not fit in a double.  We assume that the input
+     * string is not "Infinity" and does not have a leading sign.
+     */
+    private static double parseDoubleCheckOverflow(String s) {
+        double d = Double.parseDouble(s);
+        if (Double.isInfinite(d))
+            throw new NumberFormatException("Overflow: " + s);
+        if (d == 0.0) {  // Underflow checking is hard!  CR 6604864
+            String ss = s;
+            int e = s.indexOf('e');  // we already forced E to lowercase
+            if (e > 0)
+                ss = s.substring(0, e);
+            ss = ss.replace("0", "").replace(".", "");
+            if (!ss.isEmpty())
+                throw new NumberFormatException("Underflow: " + s);
+        }
+        return d;
+    }
+
+    // PARSER STARTS HERE
+
+    private final List<Token> tokens;
+    private int tokenI;
+    // The current token is always tokens[tokenI].
+
+    QueryParser(String s) {
+        // Construct the complete list of tokens immediately and append
+        // a sentinel (END).
+        tokens = new ArrayList<Token>();
+        Tokenizer tokenizer = new Tokenizer(s);
+        Token t;
+        while ((t = tokenizer.nextToken()) != null)
+            tokens.add(t);
+        tokens.add(END);
+    }
+
+    private Token current() {
+        return tokens.get(tokenI);
+    }
+
+    // If the current token is t, then skip it and return true.
+    // Otherwise, return false.
+    private boolean skip(Token t) {
+        if (t.equals(current())) {
+            tokenI++;
+            return true;
+        }
+        return false;
+    }
+
+    // If the current token is one of the ones in 'tokens', then skip it
+    // and return its index in 'tokens'.  Otherwise, return -1.
+    private int skipOne(Token... tokens) {
+        for (int i = 0; i < tokens.length; i++) {
+            if (skip(tokens[i]))
+                return i;
+        }
+        return -1;
+    }
+
+    // If the current token is t, then skip it and return.
+    // Otherwise throw an exception.
+    private void expect(Token t) {
+        if (!skip(t))
+            throw new IllegalArgumentException("Expected " + t + ", found " + current());
+    }
+
+    private void next() {
+        tokenI++;
+    }
+
+    QueryExp parseQuery() {
+        QueryExp qe = query();
+        if (current() != END)
+            throw new IllegalArgumentException("Junk at end of query: " + current());
+        return qe;
+    }
+
+    // The remainder of this class is a classical recursive-descent parser.
+    // We only need to violate the recursive-descent scheme in one place,
+    // where parentheses make the grammar not LL(1).
+
+    private QueryExp query() {
+        QueryExp lhs = andquery();
+        while (skip(OR))
+            lhs = Query.or(lhs, andquery());
+        return lhs;
+    }
+
+    private QueryExp andquery() {
+        QueryExp lhs = predicate();
+        while (skip(AND))
+            lhs = Query.and(lhs, predicate());
+        return lhs;
+    }
+
+    private QueryExp predicate() {
+        // Grammar hack.  If we see a paren, it might be (query) or
+        // it might be (value).  We try to parse (query), and if that
+        // fails, we parse (value).  For example, if the string is
+        // "(2+3)*4 < 5" then we will try to parse the query
+        // "2+3)*4 < 5", which will fail at the ), so we'll back up to
+        // the paren and let value() handle it.
+        if (skip(LPAR)) {
+            int parenIndex = tokenI - 1;
+            try {
+                QueryExp qe = query();
+                expect(RPAR);
+                return qe;
+            } catch (IllegalArgumentException e) {
+                // OK: try parsing a value
+            }
+            tokenI = parenIndex;
+        }
+
+        if (skip(NOT))
+            return Query.not(predicate());
+
+        if (skip(INSTANCEOF))
+            return Query.isInstanceOf(stringvalue());
+
+        if (skip(LIKE)) {
+            StringValueExp sve = stringvalue();
+            String s = sve.getValue();
+            try {
+                return new ObjectName(s);
+            } catch (MalformedObjectNameException e) {
+                throw new IllegalArgumentException(
+                        "Bad ObjectName pattern after LIKE: '" + s + "'", e);
+            }
+        }
+
+        ValueExp lhs = value();
+
+        return predrhs(lhs);
+    }
+
+    // The order of elements in the following arrays is important.  The code
+    // in predrhs depends on integer indexes.  Change with caution.
+    private static final Token[] relations = {
+            EQ, LT, GT, LE, GE, NE,
+         // 0,  1,  2,  3,  4,  5,
+    };
+    private static final Token[] betweenLikeIn = {
+            BETWEEN, LIKE, IN
+         // 0,       1,    2,
+    };
+
+    private QueryExp predrhs(ValueExp lhs) {
+        Token start = current(); // for errors
+
+        // Look for < > = etc
+        int i = skipOne(relations);
+        if (i >= 0) {
+            ValueExp rhs = value();
+            switch (i) {
+                case 0: return Query.eq(lhs, rhs);
+                case 1: return Query.lt(lhs, rhs);
+                case 2: return Query.gt(lhs, rhs);
+                case 3: return Query.leq(lhs, rhs);
+                case 4: return Query.geq(lhs, rhs);
+                case 5: return Query.not(Query.eq(lhs, rhs));
+                // There is no Query.ne so <> is shorthand for the above.
+                default:
+                    throw new AssertionError();
+            }
+        }
+
+        // Must be BETWEEN LIKE or IN, optionally preceded by NOT
+        boolean not = skip(NOT);
+        i = skipOne(betweenLikeIn);
+        if (i < 0)
+            throw new IllegalArgumentException("Expected relation at " + start);
+
+        QueryExp q;
+        switch (i) {
+            case 0: { // BETWEEN
+                ValueExp lower = value();
+                expect(AND);
+                ValueExp upper = value();
+                q = Query.between(lhs, lower, upper);
+                break;
+            }
+
+            case 1: { // LIKE
+                if (!(lhs instanceof AttributeValueExp)) {
+                    throw new IllegalArgumentException(
+                            "Left-hand side of LIKE must be an attribute");
+                }
+                AttributeValueExp alhs = (AttributeValueExp) lhs;
+                StringValueExp sve = stringvalue();
+                String s = sve.getValue();
+                q = Query.match(alhs, patternValueExp(s));
+                break;
+            }
+
+            case 2: { // IN
+                expect(LPAR);
+                List<ValueExp> values = new ArrayList<ValueExp>();
+                values.add(value());
+                while (skip(COMMA))
+                    values.add(value());
+                expect(RPAR);
+                q = Query.in(lhs, values.toArray(new ValueExp[values.size()]));
+                break;
+            }
+
+            default:
+                throw new AssertionError();
+        }
+
+        if (not)
+            q = Query.not(q);
+
+        return q;
+    }
+
+    private ValueExp value() {
+        ValueExp lhs = factor();
+        int i;
+        while ((i = skipOne(PLUS, MINUS)) >= 0) {
+            ValueExp rhs = factor();
+            if (i == 0)
+                lhs = Query.plus(lhs, rhs);
+            else
+                lhs = Query.minus(lhs, rhs);
+        }
+        return lhs;
+    }
+
+    private ValueExp factor() {
+        ValueExp lhs = term();
+        int i;
+        while ((i = skipOne(TIMES, DIVIDE)) >= 0) {
+            ValueExp rhs = term();
+            if (i == 0)
+                lhs = Query.times(lhs, rhs);
+            else
+                lhs = Query.div(lhs, rhs);
+        }
+        return lhs;
+    }
+
+    private ValueExp term() {
+        boolean signed = false;
+        int sign = +1;
+        if (skip(PLUS))
+            signed = true;
+        else if (skip(MINUS)) {
+            signed = true; sign = -1;
+        }
+
+        Token t = current();
+        next();
+
+        if (t instanceof DoubleLit)
+            return Query.value(sign * ((DoubleLit) t).number);
+        if (t instanceof LongLit) {
+            long n = ((LongLit) t).number;
+            if (n == Long.MIN_VALUE && sign != -1)
+                throw new IllegalArgumentException("Illegal positive integer: " + n);
+            return Query.value(sign * n);
+        }
+        if (signed)
+            throw new IllegalArgumentException("Expected number after + or -");
+
+        if (t == LPAR) {
+            ValueExp v = value();
+            expect(RPAR);
+            return v;
+        }
+        if (t.equals(FALSE) || t.equals(TRUE)) {
+            return Query.value(t.equals(TRUE));
+        }
+        if (t.equals(CLASS))
+            return Query.classattr();
+
+        if (t instanceof StringLit)
+            return Query.value(t.string); // Not toString(), which would requote '
+
+        // At this point, all that remains is something that will call Query.attr
+
+        if (!(t instanceof Id) && !(t instanceof QuotedId))
+            throw new IllegalArgumentException("Unexpected token " + t);
+
+        String name1 = name(t);
+
+        if (skip(SHARP)) {
+            Token t2 = current();
+            next();
+            String name2 = name(t2);
+            return Query.attr(name1, name2);
+        }
+        return Query.attr(name1);
+    }
+
+    // Initially, t is the first token of a supposed name and current()
+    // is the second.
+    private String name(Token t) {
+        StringBuilder sb = new StringBuilder();
+        while (true) {
+            if (!(t instanceof Id) && !(t instanceof QuotedId))
+                throw new IllegalArgumentException("Unexpected token " + t);
+            sb.append(t.string);
+            if (current() != DOT)
+                break;
+            sb.append('.');
+            next();
+            t = current();
+            next();
+        }
+        return sb.toString();
+    }
+
+    private StringValueExp stringvalue() {
+        // Currently the only way to get a StringValueExp when constructing
+        // a QueryExp is via Query.value(String), so we only recognize
+        // string literals here.  But if we expand queries in the future
+        // that might no longer be true.
+        Token t = current();
+        next();
+        if (!(t instanceof StringLit))
+            throw new IllegalArgumentException("Expected string: " + t);
+        return Query.value(t.string);
+    }
+
+    // Convert the SQL pattern syntax, using % and _, to the Query.match
+    // syntax, using * and ?.  The tricky part is recognizing \% and
+    // \_ as literal values, and also not replacing them inside [].
+    // But Query.match does not recognize \ inside [], which makes our
+    // job a tad easier.
+    private StringValueExp patternValueExp(String s) {
+        int c;
+        for (int i = 0; i < s.length(); i += Character.charCount(c)) {
+            c = s.codePointAt(i);
+            switch (c) {
+                case '\\':
+                    i++;  // i += Character.charCount(c), but we know it's 1!
+                    if (i >= s.length())
+                        throw new IllegalArgumentException("\\ at end of pattern");
+                    break;
+                case '[':
+                    i = s.indexOf(']', i);
+                    if (i < 0)
+                        throw new IllegalArgumentException("[ without ]");
+                    break;
+                case '%':
+                    s = s.substring(0, i) + "*" + s.substring(i + 1);
+                    break;
+                case '_':
+                    s = s.substring(0, i) + "?" + s.substring(i + 1);
+                    break;
+                case '*':
+                case '?':
+                    s = s.substring(0, i) + '\\' + (char) c + s.substring(i + 1);
+                    i++;
+                    break;
+            }
+        }
+        return Query.value(s);
+    }
+}
--- a/src/share/classes/javax/management/StringValueExp.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/StringValueExp.java	Mon Apr 14 11:34:15 2008 -0700
@@ -73,7 +73,7 @@
      * Returns the string representing the object.
      */
     public String toString()  {
-        return "'" + val + "'";
+        return "'" + val.replace("'", "''") + "'";
     }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/javax/management/ToQueryString.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+/* QueryExp classes can extend this to get non-default treatment for
+ * Query.toString(q).  We're reluctant to change the public toString()
+ * methods of the classes because people might be parsing them, even
+ * though that's rather fragile.  But Query.toString(q) has no such
+ * constraint so it can use the new toQueryString() method defined here.
+ */
+class ToQueryString {
+    String toQueryString() {
+        return toString();
+    }
+}
--- a/src/share/classes/javax/management/monitor/Monitor.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/monitor/Monitor.java	Mon Apr 14 11:34:15 2008 -0700
@@ -27,13 +27,8 @@
 
 import static com.sun.jmx.defaults.JmxProperties.MONITOR_LOGGER;
 import com.sun.jmx.mbeanserver.GetPropertyAction;
-import com.sun.jmx.remote.util.EnvHelp;
-import java.beans.BeanInfo;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
+import com.sun.jmx.mbeanserver.Introspector;
 import java.io.IOException;
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationTargetException;
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -64,7 +59,6 @@
 import javax.management.ObjectName;
 import javax.management.ReflectionException;
 import static javax.management.monitor.MonitorNotification.*;
-import javax.management.openmbean.CompositeData;
 
 /**
  * Defines the part common to all monitor MBeans.
@@ -876,44 +870,13 @@
         if (isComplexTypeAttribute) {
             Object v = value;
             for (String attr : remainingAttributes)
-                v = introspect(object, attr, v);
+                v = Introspector.elementFromComplex(v, attr);
             return (Comparable<?>) v;
         } else {
             return (Comparable<?>) value;
         }
     }
 
-    Object introspect(ObjectName object,
-                      String attribute,
-                      Object value)
-        throws AttributeNotFoundException {
-        try {
-            if (value.getClass().isArray() && attribute.equals("length")) {
-                return Array.getLength(value);
-            } else if (value instanceof CompositeData) {
-                return ((CompositeData) value).get(attribute);
-            } else {
-                // Java Beans introspection
-                //
-                BeanInfo bi = Introspector.getBeanInfo(value.getClass());
-                PropertyDescriptor[] pds = bi.getPropertyDescriptors();
-                for (PropertyDescriptor pd : pds)
-                    if (pd.getName().equals(attribute))
-                        return pd.getReadMethod().invoke(value);
-                throw new AttributeNotFoundException(
-                    "Could not find the getter method for the property " +
-                    attribute + " using the Java Beans introspector");
-            }
-        } catch (InvocationTargetException e) {
-            throw new IllegalArgumentException(e);
-        } catch (AttributeNotFoundException e) {
-            throw e;
-        } catch (Exception e) {
-            throw EnvHelp.initCause(
-                new AttributeNotFoundException(e.getMessage()), e);
-        }
-    }
-
     boolean isComparableTypeValid(ObjectName object,
                                   String attribute,
                                   Comparable<?> value) {
--- a/src/share/classes/javax/management/remote/JMXServiceURL.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/management/remote/JMXServiceURL.java	Mon Apr 14 11:34:15 2008 -0700
@@ -30,6 +30,7 @@
 import com.sun.jmx.remote.util.ClassLogger;
 import com.sun.jmx.remote.util.EnvHelp;
 
+import java.beans.ConstructorProperties;
 import java.io.Serializable;
 import java.net.InetAddress;
 import java.net.MalformedURLException;
@@ -274,6 +275,7 @@
      * is not possible to find the local host name, or if
      * <code>port</code> is negative.
      */
+    @ConstructorProperties({"protocol", "host", "port", "URLPath"})
     public JMXServiceURL(String protocol, String host, int port,
                          String urlPath)
             throws MalformedURLException {
--- a/src/share/classes/javax/print/attribute/standard/ReferenceUriSchemesSupported.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/print/attribute/standard/ReferenceUriSchemesSupported.java	Mon Apr 14 11:34:15 2008 -0700
@@ -44,7 +44,7 @@
  * print request's, print job's, or print service's attribute set.
  * <P>
  * The Internet Assigned Numbers Authority maintains the
- * <A HREF="http://www.isi.edu/in-notes/iana/assignments/url-schemes">official
+ * <A HREF="http://www.iana.org/assignments/uri-schemes.html">official
  * list of URI schemes</A>.
  * <p>
  * Class ReferenceUriSchemesSupported defines enumeration values for widely
--- a/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java	Mon Apr 14 11:34:15 2008 -0700
@@ -121,7 +121,7 @@
             sslSocketFactory.createSocket(host, port);
         // Set the SSLSocket Enabled Cipher Suites
         //
-        final String enabledCipherSuites = (String)
+        final String enabledCipherSuites =
             System.getProperty("javax.rmi.ssl.client.enabledCipherSuites");
         if (enabledCipherSuites != null) {
             StringTokenizer st = new StringTokenizer(enabledCipherSuites, ",");
@@ -139,7 +139,7 @@
         }
         // Set the SSLSocket Enabled Protocols
         //
-        final String enabledProtocols = (String)
+        final String enabledProtocols =
             System.getProperty("javax.rmi.ssl.client.enabledProtocols");
         if (enabledProtocols != null) {
             StringTokenizer st = new StringTokenizer(enabledProtocols, ",");
--- a/src/share/classes/javax/rmi/ssl/SslRMIServerSocketFactory.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/rmi/ssl/SslRMIServerSocketFactory.java	Mon Apr 14 11:34:15 2008 -0700
@@ -165,9 +165,9 @@
         // Initialize the configuration parameters.
         //
         this.enabledCipherSuites = enabledCipherSuites == null ?
-            null : (String[]) enabledCipherSuites.clone();
+            null : enabledCipherSuites.clone();
         this.enabledProtocols = enabledProtocols == null ?
-            null : (String[]) enabledProtocols.clone();
+            null : enabledProtocols.clone();
         this.needClientAuth = needClientAuth;
 
         // Force the initialization of the default at construction time,
@@ -196,13 +196,11 @@
         //
         if (this.enabledCipherSuites != null) {
             sslSocket.setEnabledCipherSuites(this.enabledCipherSuites);
-            enabledCipherSuitesList =
-                    Arrays.asList((String[]) this.enabledCipherSuites);
+            enabledCipherSuitesList = Arrays.asList(this.enabledCipherSuites);
         }
         if (this.enabledProtocols != null) {
             sslSocket.setEnabledProtocols(this.enabledProtocols);
-            enabledProtocolsList =
-                    Arrays.asList((String[]) this.enabledProtocols);
+            enabledProtocolsList = Arrays.asList(this.enabledProtocols);
         }
     }
 
@@ -218,7 +216,7 @@
      */
     public final String[] getEnabledCipherSuites() {
         return enabledCipherSuites == null ?
-            null : (String[]) enabledCipherSuites.clone();
+            null : enabledCipherSuites.clone();
     }
 
     /**
@@ -234,7 +232,7 @@
      */
     public final String[] getEnabledProtocols() {
         return enabledProtocols == null ?
-            null : (String[]) enabledProtocols.clone();
+            null : enabledProtocols.clone();
     }
 
     /**
@@ -315,8 +313,8 @@
                 (enabledCipherSuites != null && that.enabledCipherSuites == null))
             return false;
         if (enabledCipherSuites != null && that.enabledCipherSuites != null) {
-            List thatEnabledCipherSuitesList =
-                    Arrays.asList((String[]) that.enabledCipherSuites);
+            List<String> thatEnabledCipherSuitesList =
+                    Arrays.asList(that.enabledCipherSuites);
             if (!enabledCipherSuitesList.equals(thatEnabledCipherSuitesList))
                 return false;
         }
@@ -327,8 +325,8 @@
                 (enabledProtocols != null && that.enabledProtocols == null))
             return false;
         if (enabledProtocols != null && that.enabledProtocols != null) {
-            List thatEnabledProtocolsList =
-                    Arrays.asList((String[]) that.enabledProtocols);
+            List<String> thatEnabledProtocolsList =
+                    Arrays.asList(that.enabledProtocols);
             if (!enabledProtocolsList.equals(thatEnabledProtocolsList))
                 return false;
         }
@@ -374,7 +372,7 @@
     private final String[] enabledCipherSuites;
     private final String[] enabledProtocols;
     private final boolean needClientAuth;
-    private List enabledCipherSuitesList;
-    private List enabledProtocolsList;
+    private List<String> enabledCipherSuitesList;
+    private List<String> enabledProtocolsList;
     private SSLContext context;
 }
--- a/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java	Mon Apr 14 11:34:15 2008 -0700
@@ -276,7 +276,7 @@
 
         if (flags != null) {
            if (flags.length >= NUM_FLAGS)
-                this.flags = (boolean[]) flags.clone();
+                this.flags = flags.clone();
            else {
                 this.flags = new boolean[NUM_FLAGS];
                 // Fill in whatever we have
@@ -304,7 +304,7 @@
         this.endTime = endTime;
 
         if (clientAddresses != null)
-           this.clientAddresses = (InetAddress[]) clientAddresses.clone();
+           this.clientAddresses = clientAddresses.clone();
     }
 
     /**
@@ -430,7 +430,7 @@
      * @return the flags associated with this ticket.
      */
     public final boolean[]  getFlags() {
-        return (flags == null? null: (boolean[]) flags.clone());
+        return (flags == null? null: flags.clone());
     }
 
     /**
@@ -479,8 +479,7 @@
      * provided.
      */
     public final java.net.InetAddress[] getClientAddresses() {
-        return (clientAddresses == null?
-                null: (InetAddress[]) clientAddresses.clone());
+        return (clientAddresses == null) ? null: clientAddresses.clone();
     }
 
     /**
@@ -491,7 +490,7 @@
     public final byte[] getEncoded() {
         if (destroyed)
             throw new IllegalStateException("This ticket is no longer valid");
-        return (byte[]) asn1Encoding.clone();
+        return asn1Encoding.clone();
     }
 
     /** Determines if this ticket is still current.  */
--- a/src/share/classes/javax/security/auth/kerberos/KeyImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/security/auth/kerberos/KeyImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -66,7 +66,7 @@
      */
     public KeyImpl(byte[] keyBytes,
                        int keyType) {
-        this.keyBytes = (byte[]) keyBytes.clone();
+        this.keyBytes = keyBytes.clone();
         this.keyType = keyType;
     }
 
@@ -151,7 +151,7 @@
     public final byte[] getEncoded() {
         if (destroyed)
             throw new IllegalStateException("This key is no longer valid");
-        return (byte[])keyBytes.clone();
+        return keyBytes.clone();
     }
 
     public void destroy() throws DestroyFailedException {
--- a/src/share/classes/javax/security/cert/X509Certificate.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/security/cert/X509Certificate.java	Mon Apr 14 11:34:15 2008 -0700
@@ -363,7 +363,7 @@
      * subject    Name
      * </pre>
      *
-     * <p>See <a href = "#getIssuerDN">getIssuerDN</a> for <code>Name</code>
+     * <p>See {@link #getIssuerDN() getIssuerDN} for <code>Name</code>
      * and other relevant definitions.
      *
      * @return a Principal whose name is the subject name.
@@ -393,7 +393,7 @@
 
     /**
      * Gets the <code>notAfter</code> date from the validity period of
-     * the certificate. See <a href = "#getNotBefore">getNotBefore</a>
+     * the certificate. See {@link #getNotBefore() getNotBefore}
      * for relevant ASN.1 definitions.
      *
      * @return the end date of the validity period.
@@ -429,7 +429,7 @@
      * For example, the string "1.2.840.10040.4.3" identifies the SHA-1
      * with DSA signature algorithm, as per the PKIX part I.
      *
-     * <p>See <a href = "#getSigAlgName">getSigAlgName</a> for
+     * <p>See {@link #getSigAlgName() getSigAlgName} for
      * relevant ASN.1 definitions.
      *
      * @return the signature algorithm OID string.
@@ -442,7 +442,7 @@
      * algorithm parameters are null; the parameters are usually
      * supplied with the certificate's public key.
      *
-     * <p>See <a href = "#getSigAlgName">getSigAlgName</a> for
+     * <p>See {@link #getSigAlgName() getSigAlgName} for
      * relevant ASN.1 definitions.
      *
      * @return the DER-encoded signature algorithm parameters, or
--- a/src/share/classes/javax/swing/plaf/synth/doc-files/synth.dtd	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/swing/plaf/synth/doc-files/synth.dtd	Mon Apr 14 11:34:15 2008 -0700
@@ -73,7 +73,7 @@
           type        (idref|boolean|dimension|insets|integer|string) "idref"
           value       CDATA                                           #REQUIRED
 >
-
+
 <!ELEMENT defaultsProperty EMPTY>
 <!ATTLIST defaultsProperty
           key         CDATA                                           #REQUIRED
--- a/src/share/classes/javax/swing/plaf/synth/package.html	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/javax/swing/plaf/synth/package.html	Mon Apr 14 11:34:15 2008 -0700
@@ -1,6 +1,6 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
 <!--
 Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -27,151 +27,151 @@
 
 
 -->
-</head>
-<body bgcolor="white">
-    <p>
-      Synth is a skinnable look and feel in which all painting is
-      delegated. Synth does not provide a default look. In
-      order to use Synth you need to specify a
-      <a href="doc-files/synthFileFormat.html">file</a>, or 
-      provide a {@link
-      javax.swing.plaf.synth.SynthStyleFactory}. Both 
-      configuration options require an 
-      understanding of the synth architecture, which is described
-      below, as well as an understanding of Swing's architecture.
-    </p>
-    <p>
-      Unless otherwise specified null is not a legal value to any of
-      the methods defined in the synth package and if passed in will
-      result in a <code>NullPointerException</code>.
-      
-
-    <h2>Synth</h2>
-    <p>
-      Each {@link javax.swing.plaf.ComponentUI} implementation in Synth associates
-      itself with one {@link
-      javax.swing.plaf.synth.SynthStyle} per {@link
-      javax.swing.plaf.synth.Region}, most
-      <code>Components</code> only have one <code>Region</code> and
-      therefor only one <code>SynthStyle</code>.
-      <code>SynthStyle</code>
-      is used to access all style related properties: fonts, colors
-      and other <code>Component</code> properties. In addition
-      <code>SynthStyle</code>s are used to obtain 
-      {@link javax.swing.plaf.synth.SynthPainter}s for painting the background, border,
-      focus and other portions of a <code>Component</code>. The <code>ComponentUI</code>s obtain
-      <code>SynthStyle</code>s from a
-      {@link javax.swing.plaf.synth.SynthStyleFactory}.
-      A <code>SynthStyleFactory</code>
-      can be provided directly by way of 
-      {@link javax.swing.plaf.synth.SynthLookAndFeel#setStyleFactory(javax.swing.plaf.synth.SynthStyleFactory)},
-      or indirectly by way of
-      {@link javax.swing.plaf.synth.SynthLookAndFeel#load}. The
-      following example uses the <code>SynthLookAndFeel.load()</code>
-      method to configure a <code>SynthLookAndFeel</code> and sets it
-      as the current look and feel:
-    </p>
-    <div class="example">
-      <pre>
-  SynthLookAndFeel laf = new SynthLookAndFeel();
+</head>
+<body bgcolor="white">
+    <p>
+      Synth is a skinnable look and feel in which all painting is
+      delegated. Synth does not provide a default look. In
+      order to use Synth you need to specify a
+      <a href="doc-files/synthFileFormat.html">file</a>, or 
+      provide a {@link
+      javax.swing.plaf.synth.SynthStyleFactory}. Both 
+      configuration options require an 
+      understanding of the synth architecture, which is described
+      below, as well as an understanding of Swing's architecture.
+    </p>
+    <p>
+      Unless otherwise specified null is not a legal value to any of
+      the methods defined in the synth package and if passed in will
+      result in a <code>NullPointerException</code>.
+      
+
+    <h2>Synth</h2>
+    <p>
+      Each {@link javax.swing.plaf.ComponentUI} implementation in Synth associates
+      itself with one {@link
+      javax.swing.plaf.synth.SynthStyle} per {@link
+      javax.swing.plaf.synth.Region}, most
+      <code>Components</code> only have one <code>Region</code> and
+      therefor only one <code>SynthStyle</code>.
+      <code>SynthStyle</code>
+      is used to access all style related properties: fonts, colors
+      and other <code>Component</code> properties. In addition
+      <code>SynthStyle</code>s are used to obtain 
+      {@link javax.swing.plaf.synth.SynthPainter}s for painting the background, border,
+      focus and other portions of a <code>Component</code>. The <code>ComponentUI</code>s obtain
+      <code>SynthStyle</code>s from a
+      {@link javax.swing.plaf.synth.SynthStyleFactory}.
+      A <code>SynthStyleFactory</code>
+      can be provided directly by way of 
+      {@link javax.swing.plaf.synth.SynthLookAndFeel#setStyleFactory(javax.swing.plaf.synth.SynthStyleFactory)},
+      or indirectly by way of
+      {@link javax.swing.plaf.synth.SynthLookAndFeel#load}. The
+      following example uses the <code>SynthLookAndFeel.load()</code>
+      method to configure a <code>SynthLookAndFeel</code> and sets it
+      as the current look and feel:
+    </p>
+    <div class="example">
+      <pre>
+  SynthLookAndFeel laf = new SynthLookAndFeel();
   laf.load(MyClass.class.getResourceAsStream("laf.xml"), MyClass.class);
-  UIManager.setLookAndFeel(laf);
-      </pre>
-    </div>
-    <p>
-      Many <code>JComponent</code>s are broken down into smaller
-      pieces and identified by the type safe enumeration in
-      {@link javax.swing.plaf.synth.Region}. For example, a <code>JTabbedPane</code>
-      consists of a <code>Region</code> for the
-      <code>JTabbedPane</code> ({@link
-      javax.swing.plaf.synth.Region#TABBED_PANE}), the content
-      area ({@link
-      javax.swing.plaf.synth.Region#TABBED_PANE_CONTENT}), the
-      area behind the tabs ({@link
-      javax.swing.plaf.synth.Region#TABBED_PANE_TAB_AREA}), and the
-      tabs ({@link
-      javax.swing.plaf.synth.Region#TABBED_PANE_TAB}). Each
-      <code>Region</code> of each
-      <code>JComponent</code> will have a
-      <code>SynthStyle</code>. This allows 
-      you to customize individual pieces of each region of each
-      <code>JComponent</code>.
-    <p>
-      Many of the Synth methods take a {@link javax.swing.plaf.synth.SynthContext}. This 
-      is used to provide information about the current
-      <code>Component</code> and includes: the
-      {@link javax.swing.plaf.synth.SynthStyle} associated with the current
-      {@link javax.swing.plaf.synth.Region}, the state of the <code>Component</code>
-      as a bitmask (refer to {@link
-      javax.swing.plaf.synth.SynthConstants} for the valid
-      states), and a {@link javax.swing.plaf.synth.Region} identifying the portion of 
-      the <code>Component</code> being painted.
-    <p>
-      All text rendering by non-<code>JTextComponent</code>s is
-      delegated to a {@link
-      javax.swing.plaf.synth.SynthGraphicsUtils}, which is
-      obtained using the {@link javax.swing.plaf.synth.SynthStyle} method
-      {@link javax.swing.plaf.synth.SynthStyle#getGraphicsUtils}. You can
-      customize text rendering 
-      by supplying your own {@link javax.swing.plaf.synth.SynthGraphicsUtils}.
-
-    </p>
-
-    <h2>Notes on specific components</h2>
-
-    <h3>JTree</h3>
-    <p>
-      Synth provides a region for the cells of a tree:
-      <code>Region.TREE_CELL</code>.  To specify the colors of the
-      renderer you'll want to provide a style for the
-      <code>TREE_CELL</code> region.  The following illustrates this:
-<pre>
-  &lt;style id="treeCellStyle">
-    &lt;opaque value="TRUE"/>
-    &lt;state>
-      &lt;color value="WHITE" type="TEXT_FOREGROUND"/>
-      &lt;color value="RED" type="TEXT_BACKGROUND"/>
-    &lt;/state>
-    &lt;state value="SELECTED">
-      &lt;color value="RED" type="TEXT_FOREGROUND"/>
-      &lt;color value="WHITE" type="BACKGROUND"/>
-    &lt;/state>
-  &lt;/style>
-  &lt;bind style="treeCellStyle" type="region" key="TreeCell"/>
-</pre>
-    <p>
-      This specifies a color combination of red on white, when
-      selected, and white on red when not selected.  To see the
-      background you need to specify that labels are not opaque.  The
-      following XML fragment does that:
-<pre>
-  &lt;style id="labelStyle">
-    &lt;opaque value="FALSE"/>
-  &lt;/style>
-  &lt;bind style="labelStyle" type="region" key="Label"/>
-</pre>
-      
-    <h3>JList and JTable</h3>
-    <p>
-      The colors that the renderers for JList and JTable use are
-      specified by way of the list and table Regions.  The following
-      XML fragment illustrates how to specify red on white, when
-      selected, and white on red when not selected:
-<pre>
-  &lt;style id="style">
-    &lt;opaque value="TRUE"/>
-    &lt;state>
-      &lt;color value="WHITE" type="TEXT_FOREGROUND"/>
-      &lt;color value="RED" type="TEXT_BACKGROUND"/>
-      &lt;color value="RED" type="BACKGROUND"/>
-    &lt;/state>
-    &lt;state value="SELECTED">
-      &lt;color value="RED" type="TEXT_FOREGROUND"/>
-      &lt;color value="WHITE" type="TEXT_BACKGROUND"/>
-    &lt;/state>
-  &lt;/style>
-  &lt;bind style="style" type="region" key="Table"/>
-  &lt;bind style="style" type="region" key="List"/>
-</pre>
-  </body>
-</html>
+  UIManager.setLookAndFeel(laf);
+      </pre>
+    </div>
+    <p>
+      Many <code>JComponent</code>s are broken down into smaller
+      pieces and identified by the type safe enumeration in
+      {@link javax.swing.plaf.synth.Region}. For example, a <code>JTabbedPane</code>
+      consists of a <code>Region</code> for the
+      <code>JTabbedPane</code> ({@link
+      javax.swing.plaf.synth.Region#TABBED_PANE}), the content
+      area ({@link
+      javax.swing.plaf.synth.Region#TABBED_PANE_CONTENT}), the
+      area behind the tabs ({@link
+      javax.swing.plaf.synth.Region#TABBED_PANE_TAB_AREA}), and the
+      tabs ({@link
+      javax.swing.plaf.synth.Region#TABBED_PANE_TAB}). Each
+      <code>Region</code> of each
+      <code>JComponent</code> will have a
+      <code>SynthStyle</code>. This allows 
+      you to customize individual pieces of each region of each
+      <code>JComponent</code>.
+    <p>
+      Many of the Synth methods take a {@link javax.swing.plaf.synth.SynthContext}. This 
+      is used to provide information about the current
+      <code>Component</code> and includes: the
+      {@link javax.swing.plaf.synth.SynthStyle} associated with the current
+      {@link javax.swing.plaf.synth.Region}, the state of the <code>Component</code>
+      as a bitmask (refer to {@link
+      javax.swing.plaf.synth.SynthConstants} for the valid
+      states), and a {@link javax.swing.plaf.synth.Region} identifying the portion of 
+      the <code>Component</code> being painted.
+    <p>
+      All text rendering by non-<code>JTextComponent</code>s is
+      delegated to a {@link
+      javax.swing.plaf.synth.SynthGraphicsUtils}, which is
+      obtained using the {@link javax.swing.plaf.synth.SynthStyle} method
+      {@link javax.swing.plaf.synth.SynthStyle#getGraphicsUtils}. You can
+      customize text rendering 
+      by supplying your own {@link javax.swing.plaf.synth.SynthGraphicsUtils}.
+
+    </p>
+
+    <h2>Notes on specific components</h2>
+
+    <h3>JTree</h3>
+    <p>
+      Synth provides a region for the cells of a tree:
+      <code>Region.TREE_CELL</code>.  To specify the colors of the
+      renderer you'll want to provide a style for the
+      <code>TREE_CELL</code> region.  The following illustrates this:
+<pre>
+  &lt;style id="treeCellStyle">
+    &lt;opaque value="TRUE"/>
+    &lt;state>
+      &lt;color value="WHITE" type="TEXT_FOREGROUND"/>
+      &lt;color value="RED" type="TEXT_BACKGROUND"/>
+    &lt;/state>
+    &lt;state value="SELECTED">
+      &lt;color value="RED" type="TEXT_FOREGROUND"/>
+      &lt;color value="WHITE" type="BACKGROUND"/>
+    &lt;/state>
+  &lt;/style>
+  &lt;bind style="treeCellStyle" type="region" key="TreeCell"/>
+</pre>
+    <p>
+      This specifies a color combination of red on white, when
+      selected, and white on red when not selected.  To see the
+      background you need to specify that labels are not opaque.  The
+      following XML fragment does that:
+<pre>
+  &lt;style id="labelStyle">
+    &lt;opaque value="FALSE"/>
+  &lt;/style>
+  &lt;bind style="labelStyle" type="region" key="Label"/>
+</pre>
+      
+    <h3>JList and JTable</h3>
+    <p>
+      The colors that the renderers for JList and JTable use are
+      specified by way of the list and table Regions.  The following
+      XML fragment illustrates how to specify red on white, when
+      selected, and white on red when not selected:
+<pre>
+  &lt;style id="style">
+    &lt;opaque value="TRUE"/>
+    &lt;state>
+      &lt;color value="WHITE" type="TEXT_FOREGROUND"/>
+      &lt;color value="RED" type="TEXT_BACKGROUND"/>
+      &lt;color value="RED" type="BACKGROUND"/>
+    &lt;/state>
+    &lt;state value="SELECTED">
+      &lt;color value="RED" type="TEXT_FOREGROUND"/>
+      &lt;color value="WHITE" type="TEXT_BACKGROUND"/>
+    &lt;/state>
+  &lt;/style>
+  &lt;bind style="style" type="region" key="Table"/>
+  &lt;bind style="style" type="region" key="List"/>
+</pre>
+  </body>
+</html>
--- a/src/share/classes/sun/awt/AppContext.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/awt/AppContext.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,8 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.HashSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.beans.PropertyChangeSupport;
 import java.beans.PropertyChangeListener;
 
@@ -126,6 +128,7 @@
  * @author  Fred Ecks
  */
 public final class AppContext {
+    private static final Logger log = Logger.getLogger("sun.awt.AppContext");
 
     /* Since the contents of an AppContext are unique to each Java
      * session, this class should never be serialized. */
@@ -143,13 +146,15 @@
      * Returns a set containing all <code>AppContext</code>s.
      */
     public static Set<AppContext> getAppContexts() {
-        return new HashSet<AppContext>(threadGroup2appContext.values());
+        synchronized (threadGroup2appContext) {
+            return new HashSet<AppContext>(threadGroup2appContext.values());
+        }
     }
 
     /* The main "system" AppContext, used by everything not otherwise
        contained in another AppContext.
      */
-    private static AppContext mainAppContext = null;
+    private static volatile AppContext mainAppContext = null;
 
     /*
      * The hash map associated with this AppContext.  A private delegate
@@ -174,31 +179,30 @@
     public static final String DISPOSED_PROPERTY_NAME = "disposed";
     public static final String GUI_DISPOSED = "guidisposed";
 
-    private boolean isDisposed = false; // true if AppContext is disposed
+    private volatile boolean isDisposed = false; // true if AppContext is disposed
 
     public boolean isDisposed() {
         return isDisposed;
     }
 
-
     static {
         // On the main Thread, we get the ThreadGroup, make a corresponding
         // AppContext, and instantiate the Java EventQueue.  This way, legacy
         // code is unaffected by the move to multiple AppContext ability.
         AccessController.doPrivileged(new PrivilegedAction() {
-          public Object run() {
-            ThreadGroup currentThreadGroup =
-                                Thread.currentThread().getThreadGroup();
-            ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
-            while (parentThreadGroup != null) {
-                // Find the root ThreadGroup to construct our main AppContext
-                currentThreadGroup = parentThreadGroup;
-                parentThreadGroup = currentThreadGroup.getParent();
+            public Object run() {
+                ThreadGroup currentThreadGroup =
+                        Thread.currentThread().getThreadGroup();
+                ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
+                while (parentThreadGroup != null) {
+                    // Find the root ThreadGroup to construct our main AppContext
+                    currentThreadGroup = parentThreadGroup;
+                    parentThreadGroup = currentThreadGroup.getParent();
+                }
+                mainAppContext = new AppContext(currentThreadGroup);
+                numAppContexts = 1;
+                return mainAppContext;
             }
-            mainAppContext = new AppContext(currentThreadGroup);
-            numAppContexts = 1;
-            return mainAppContext;
-          }
         });
     }
 
@@ -209,7 +213,7 @@
      * number is 1.  If so, it returns the sole AppContext without
      * checking Thread.currentThread().
      */
-    private static int numAppContexts;
+    private static volatile int numAppContexts;
 
     /*
      * The context ClassLoader that was used to create this AppContext.
@@ -236,14 +240,15 @@
         threadGroup2appContext.put(threadGroup, this);
 
         this.contextClassLoader =
-            (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
-                    public Object run() {
+             AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                    public ClassLoader run() {
                         return Thread.currentThread().getContextClassLoader();
                     }
                 });
     }
 
-    private static MostRecentThreadAppContext mostRecentThreadAppContext = null;
+    private static final ThreadLocal<AppContext> threadAppContext =
+            new ThreadLocal<AppContext>();
 
     /**
      * Returns the appropriate AppContext for the caller,
@@ -260,59 +265,46 @@
         if (numAppContexts == 1)   // If there's only one system-wide,
             return mainAppContext; // return the main system AppContext.
 
-        final Thread currentThread = Thread.currentThread();
-
-        AppContext appContext = null;
-
-        // Note: this most recent Thread/AppContext caching is thread-hot.
-        // A simple test using SwingSet found that 96.8% of lookups
-        // were matched using the most recent Thread/AppContext.  By
-        // instantiating a simple MostRecentThreadAppContext object on
-        // cache misses, the cache hits can be processed without
-        // synchronization.
+        AppContext appContext = threadAppContext.get();
 
-        MostRecentThreadAppContext recent = mostRecentThreadAppContext;
-        if ((recent != null) && (recent.thread == currentThread))  {
-            appContext = recent.appContext; // Cache hit
-        } else {
-          appContext = (AppContext)AccessController.doPrivileged(
-                                            new PrivilegedAction() {
-            public Object run() {
-            // Get the current ThreadGroup, and look for it and its
-            // parents in the hash from ThreadGroup to AppContext --
-            // it should be found, because we use createNewContext()
-            // when new AppContext objects are created.
-            ThreadGroup currentThreadGroup = currentThread.getThreadGroup();
-            ThreadGroup threadGroup = currentThreadGroup;
-            AppContext context = threadGroup2appContext.get(threadGroup);
-            while (context == null) {
-                threadGroup = threadGroup.getParent();
-                if (threadGroup == null) {
-                    // If we get here, we're running under a ThreadGroup that
-                    // has no AppContext associated with it.  This should never
-                    // happen, because createNewContext() should be used by the
-                    // toolkit to create the ThreadGroup that everything runs
-                    // under.
-                    throw new RuntimeException("Invalid ThreadGroup");
+        if (null == appContext) {
+            appContext = AccessController.doPrivileged(new PrivilegedAction<AppContext>()
+            {
+                public AppContext run() {
+                    // Get the current ThreadGroup, and look for it and its
+                    // parents in the hash from ThreadGroup to AppContext --
+                    // it should be found, because we use createNewContext()
+                    // when new AppContext objects are created.
+                    ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
+                    ThreadGroup threadGroup = currentThreadGroup;
+                    AppContext context = threadGroup2appContext.get(threadGroup);
+                    while (context == null) {
+                        threadGroup = threadGroup.getParent();
+                        if (threadGroup == null) {
+                            // If we get here, we're running under a ThreadGroup that
+                            // has no AppContext associated with it.  This should never
+                            // happen, because createNewContext() should be used by the
+                            // toolkit to create the ThreadGroup that everything runs
+                            // under.
+                            throw new RuntimeException("Invalid ThreadGroup");
+                        }
+                        context = threadGroup2appContext.get(threadGroup);
+                    }
+                    // In case we did anything in the above while loop, we add
+                    // all the intermediate ThreadGroups to threadGroup2appContext
+                    // so we won't spin again.
+                    for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
+                        threadGroup2appContext.put(tg, context);
+                    }
+                    // Now we're done, so we cache the latest key/value pair.
+                    // (we do this before checking with any AWTSecurityManager, so if
+                    // this Thread equates with the main AppContext in the cache, it
+                    // still will)
+                    threadAppContext.set(context);
+
+                    return context;
                 }
-                context = threadGroup2appContext.get(threadGroup);
-            }
-            // In case we did anything in the above while loop, we add
-            // all the intermediate ThreadGroups to threadGroup2appContext
-            // so we won't spin again.
-            for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
-                threadGroup2appContext.put(tg, context);
-            }
-            // Now we're done, so we cache the latest key/value pair.
-            // (we do this before checking with any AWTSecurityManager, so if
-            // this Thread equates with the main AppContext in the cache, it
-            // still will)
-            mostRecentThreadAppContext =
-                new MostRecentThreadAppContext(currentThread, context);
-
-            return context;
-          }
-         });
+            });
         }
 
         if (appContext == mainAppContext)  {
@@ -321,9 +313,9 @@
             // allow it to choose the AppContext to return.
             SecurityManager securityManager = System.getSecurityManager();
             if ((securityManager != null) &&
-                (securityManager instanceof AWTSecurityManager))  {
-                AWTSecurityManager awtSecMgr =
-                                      (AWTSecurityManager)securityManager;
+                (securityManager instanceof AWTSecurityManager))
+            {
+                AWTSecurityManager awtSecMgr = (AWTSecurityManager)securityManager;
                 AppContext secAppContext = awtSecMgr.getAppContext();
                 if (secAppContext != null)  {
                     appContext = secAppContext; // Return what we're told
@@ -385,7 +377,13 @@
             public void run() {
                 Window[] windowsToDispose = Window.getOwnerlessWindows();
                 for (Window w : windowsToDispose) {
-                    w.dispose();
+                    try {
+                        w.dispose();
+                    } catch (Throwable t) {
+                        if (log.isLoggable(Level.FINER)) {
+                            log.log(Level.FINER, "exception occured while disposing app context", t);
+                        }
+                    }
                 }
                 AccessController.doPrivileged(new PrivilegedAction() {
                         public Object run() {
@@ -444,7 +442,7 @@
         // Threads in the ThreadGroup to exit.
 
         long startTime = System.currentTimeMillis();
-        long endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT;
+        long endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
         while ((this.threadGroup.activeCount() > 0) &&
                (System.currentTimeMillis() < endTime)) {
             try {
@@ -459,7 +457,7 @@
         // Threads in the ThreadGroup to die.
 
         startTime = System.currentTimeMillis();
-        endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT;
+        endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
         while ((this.threadGroup.activeCount() > 0) &&
                (System.currentTimeMillis() < endTime)) {
             try {
@@ -478,10 +476,7 @@
         }
         threadGroup2appContext.remove(this.threadGroup);
 
-        MostRecentThreadAppContext recent = mostRecentThreadAppContext;
-        if ((recent != null) && (recent.appContext == this))
-            mostRecentThreadAppContext = null;
-                // If the "most recent" points to this, clear it for GC
+        threadAppContext.set(null);
 
         // Finally, we destroy the ThreadGroup entirely.
         try {
@@ -664,6 +659,7 @@
      * Returns a string representation of this AppContext.
      * @since   1.2
      */
+    @Override
     public String toString() {
         return getClass().getName() + "[threadGroup=" + threadGroup.getName() + "]";
     }
@@ -769,15 +765,6 @@
     }
 }
 
-final class MostRecentThreadAppContext {
-    final Thread thread;
-    final AppContext appContext;
-    MostRecentThreadAppContext(Thread key, AppContext value) {
-        thread = key;
-        appContext = value;
-    }
-}
-
 final class MostRecentKeyValue {
     Object key;
     Object value;
--- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -270,62 +270,58 @@
      * instead, null will be returned.
      */
     public static DataTransferer getInstance() {
-        if (transferer == null) {
-            synchronized (DataTransferer.class) {
-                if (transferer == null) {
-                    final String name = SunToolkit.
-                        getDataTransfererClassName();
-                    if (name != null) {
-                        PrivilegedAction action = new PrivilegedAction() {
-                          public Object run() {
-                              Class cls = null;
-                              Method method = null;
-                              Object ret = null;
+        synchronized (DataTransferer.class) {
+            if (transferer == null) {
+                final String name = SunToolkit.getDataTransfererClassName();
+                if (name != null) {
+                    PrivilegedAction<DataTransferer> action = new PrivilegedAction<DataTransferer>()
+                    {
+                      public DataTransferer run() {
+                          Class cls = null;
+                          Method method = null;
+                          DataTransferer ret = null;
 
-                              try {
-                                  cls = Class.forName(name);
-                              } catch (ClassNotFoundException e) {
-                                  ClassLoader cl = ClassLoader.
-                                      getSystemClassLoader();
-                                  if (cl != null) {
-                                      try {
-                                          cls = cl.loadClass(name);
-                                      } catch (ClassNotFoundException ee) {
-                                          ee.printStackTrace();
-                                          throw new AWTError("DataTransferer not found: " + name);
-                                      }
+                          try {
+                              cls = Class.forName(name);
+                          } catch (ClassNotFoundException e) {
+                              ClassLoader cl = ClassLoader.
+                                  getSystemClassLoader();
+                              if (cl != null) {
+                                  try {
+                                      cls = cl.loadClass(name);
+                                  } catch (ClassNotFoundException ee) {
+                                      ee.printStackTrace();
+                                      throw new AWTError("DataTransferer not found: " + name);
                                   }
                               }
-                              if (cls != null) {
-                                  try {
-                                      method = cls.getDeclaredMethod
-                                          ("getInstanceImpl");
-                                      method.setAccessible(true);
-                                  } catch (NoSuchMethodException e) {
-                                      e.printStackTrace();
-                                      throw new AWTError("Cannot instantiate DataTransferer: " + name);
-                                  } catch (SecurityException e) {
-                                      e.printStackTrace();
-                                      throw new AWTError("Access is denied for DataTransferer: " + name);
-                                  }
+                          }
+                          if (cls != null) {
+                              try {
+                                  method = cls.getDeclaredMethod("getInstanceImpl");
+                                  method.setAccessible(true);
+                              } catch (NoSuchMethodException e) {
+                                  e.printStackTrace();
+                                  throw new AWTError("Cannot instantiate DataTransferer: " + name);
+                              } catch (SecurityException e) {
+                                  e.printStackTrace();
+                                  throw new AWTError("Access is denied for DataTransferer: " + name);
                               }
-                              if (method != null) {
-                                  try {
-                                      ret = method.invoke(null);
-                                  } catch (InvocationTargetException e) {
-                                      e.printStackTrace();
-                                      throw new AWTError("Cannot instantiate DataTransferer: " + name);
-                                  } catch (IllegalAccessException e) {
-                                      e.printStackTrace();
-                                      throw new AWTError("Cannot access DataTransferer: " + name);
-                                  }
+                          }
+                          if (method != null) {
+                              try {
+                                  ret = (DataTransferer) method.invoke(null);
+                              } catch (InvocationTargetException e) {
+                                  e.printStackTrace();
+                                  throw new AWTError("Cannot instantiate DataTransferer: " + name);
+                              } catch (IllegalAccessException e) {
+                                  e.printStackTrace();
+                                  throw new AWTError("Cannot access DataTransferer: " + name);
                               }
-                              return ret;
                           }
-                        };
-                        transferer = (DataTransferer)
-                            AccessController.doPrivileged(action);
-                    }
+                          return ret;
+                      }
+                    };
+                    transferer = AccessController.doPrivileged(action);
                 }
             }
         }
--- a/src/share/classes/sun/management/ConnectorAddressLink.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/management/ConnectorAddressLink.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2004-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,13 @@
 
 package sun.management;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
-import java.util.Iterator;
-import java.util.Set;
-import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import sun.misc.Perf;
 import sun.management.counter.Units;
@@ -46,36 +47,67 @@
 public class ConnectorAddressLink {
 
     private static final String CONNECTOR_ADDRESS_COUNTER =
-        "sun.management.JMXConnectorServer.address";
+            "sun.management.JMXConnectorServer.address";
+
+    /*
+     * The format of the jvmstat counters representing the properties of
+     * a given out-of-the-box JMX remote connector will be as follows:
+     *
+     * sun.management.JMXConnectorServer.<counter>.<key>=<value>
+     *
+     * where:
+     *
+     *     counter = index computed by this class which uniquely identifies
+     *               an out-of-the-box JMX remote connector running in this
+     *               Java virtual machine.
+     *     key/value = a given key/value pair in the map supplied to the
+     *                 exportRemote() method.
+     *
+     * For example,
+     *
+     * sun.management.JMXConnectorServer.0.remoteAddress=service:jmx:rmi:///jndi/rmi://myhost:5000/jmxrmi
+     * sun.management.JMXConnectorServer.0.authenticate=false
+     * sun.management.JMXConnectorServer.0.ssl=false
+     * sun.management.JMXConnectorServer.0.sslRegistry=false
+     * sun.management.JMXConnectorServer.0.sslNeedClientAuth=false
+     */
+    private static final String REMOTE_CONNECTOR_COUNTER_PREFIX =
+            "sun.management.JMXConnectorServer.";
+
+    /*
+     * JMX remote connector counter (it will be incremented every
+     * time a new out-of-the-box JMX remote connector is created).
+     */
+    private static AtomicInteger counter = new AtomicInteger();
 
     /**
      * Exports the specified connector address to the instrumentation buffer
      * so that it can be read by this or other Java virtual machines running
      * on the same system.
      *
-     * @param   address         The connector address.
+     * @param address The connector address.
      */
     public static void export(String address) {
         if (address == null || address.length() == 0) {
             throw new IllegalArgumentException("address not specified");
         }
         Perf perf = Perf.getPerf();
-        perf.createString(CONNECTOR_ADDRESS_COUNTER, 1, Units.STRING.intValue(), address);
+        perf.createString(
+                CONNECTOR_ADDRESS_COUNTER, 1, Units.STRING.intValue(), address);
     }
 
     /**
      * Imports the connector address from the instrument buffer
      * of the specified Java virtual machine.
      *
-     * @param   vmid    an identifier that uniquely identifies a local
-     *                  Java virtual machine, or <code>0</code> to indicate
-     *                  the current Java virtual machine.
+     * @param vmid an identifier that uniquely identifies a local Java virtual
+     * machine, or <code>0</code> to indicate the current Java virtual machine.
      *
-     * @return  the value of the connector address, or <code>null</code>
-     *          if the target VM has not exported a connector address.
+     * @return the value of the connector address, or <code>null</code> if the
+     * target VM has not exported a connector address.
      *
-     * @throws  IOException     An I/O error occurred while trying to acquire
-     *                          the instrumentation buffer.
+     * @throws IOException An I/O error occurred while trying to acquire the
+     * instrumentation buffer.
      */
     public static String importFrom(int vmid) throws IOException {
         Perf perf = Perf.getPerf();
@@ -85,14 +117,65 @@
         } catch (IllegalArgumentException iae) {
             throw new IOException(iae.getMessage());
         }
-        List counters = (new PerfInstrumentation(bb)).findByPattern(CONNECTOR_ADDRESS_COUNTER);
+        List counters =
+                new PerfInstrumentation(bb).findByPattern(CONNECTOR_ADDRESS_COUNTER);
         Iterator i = counters.iterator();
         if (i.hasNext()) {
-            Counter c = (Counter)i.next();
-            return (String)c.getValue();
+            Counter c = (Counter) i.next();
+            return (String) c.getValue();
         } else {
             return null;
         }
     }
 
+    /**
+     * Exports the specified remote connector address and associated
+     * configuration properties to the instrumentation buffer so that
+     * it can be read by this or other Java virtual machines running
+     * on the same system.
+     *
+     * @param properties The remote connector address properties.
+     */
+    public static void exportRemote(Map<String, String> properties) {
+        final int index = counter.getAndIncrement();
+        Perf perf = Perf.getPerf();
+        for (Map.Entry<String, String> entry : properties.entrySet()) {
+            perf.createString(REMOTE_CONNECTOR_COUNTER_PREFIX + index + "." +
+                    entry.getKey(), 1, Units.STRING.intValue(), entry.getValue());
+        }
+    }
+
+    /**
+     * Imports the remote connector address and associated
+     * configuration properties from the instrument buffer
+     * of the specified Java virtual machine.
+     *
+     * @param vmid an identifier that uniquely identifies a local Java virtual
+     * machine, or <code>0</code> to indicate the current Java virtual machine.
+     *
+     * @return a map containing the remote connector's properties, or an empty
+     * map if the target VM has not exported the remote connector's properties.
+     *
+     * @throws IOException An I/O error occurred while trying to acquire the
+     * instrumentation buffer.
+     */
+    public static Map<String, String> importRemoteFrom(int vmid) throws IOException {
+        Perf perf = Perf.getPerf();
+        ByteBuffer bb;
+        try {
+            bb = perf.attach(vmid, "r");
+        } catch (IllegalArgumentException iae) {
+            throw new IOException(iae.getMessage());
+        }
+        List counters = new PerfInstrumentation(bb).getAllCounters();
+        Map<String, String> properties = new HashMap<String, String>();
+        for (Object c : counters) {
+            String name = ((Counter) c).getName();
+            if (name.startsWith(REMOTE_CONNECTOR_COUNTER_PREFIX) &&
+                    !name.equals(CONNECTOR_ADDRESS_COUNTER)) {
+                properties.put(name, ((Counter) c).getValue().toString());
+            }
+        }
+        return properties;
+    }
 }
--- a/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
 import java.rmi.Remote;
 import java.rmi.RemoteException;
 import java.rmi.registry.Registry;
+import java.rmi.server.RemoteObject;
 import java.rmi.server.RMIClientSocketFactory;
 import java.rmi.server.RMIServerSocketFactory;
 import java.rmi.server.UnicastRemoteObject;
@@ -70,12 +71,14 @@
 
 import javax.security.auth.Subject;
 
+import sun.rmi.server.UnicastRef;
 import sun.rmi.server.UnicastServerRef;
 import sun.rmi.server.UnicastServerRef2;
 
 import sun.management.Agent;
 import sun.management.AgentConfigurationError;
 import static sun.management.AgentConfigurationError.*;
+import sun.management.ConnectorAddressLink;
 import sun.management.FileSystem;
 import sun.management.snmp.util.MibLogger;
 
@@ -92,20 +95,22 @@
      * Default values for JMX configuration properties.
      **/
     public static interface DefaultValues {
-        public static final String PORT="0";
-        public static final String CONFIG_FILE_NAME="management.properties";
-        public static final String USE_SSL="true";
-        public static final String USE_REGISTRY_SSL="false";
-        public static final String USE_AUTHENTICATION="true";
-        public static final String PASSWORD_FILE_NAME="jmxremote.password";
-        public static final String ACCESS_FILE_NAME="jmxremote.access";
-        public static final String SSL_NEED_CLIENT_AUTH="false";
+
+        public static final String PORT = "0";
+        public static final String CONFIG_FILE_NAME = "management.properties";
+        public static final String USE_SSL = "true";
+        public static final String USE_REGISTRY_SSL = "false";
+        public static final String USE_AUTHENTICATION = "true";
+        public static final String PASSWORD_FILE_NAME = "jmxremote.password";
+        public static final String ACCESS_FILE_NAME = "jmxremote.access";
+        public static final String SSL_NEED_CLIENT_AUTH = "false";
     }
 
     /**
      * Names of JMX configuration properties.
      **/
     public static interface PropertyNames {
+
         public static final String PORT =
                 "com.sun.management.jmxremote.port";
         public static final String CONFIG_FILE_NAME =
@@ -133,6 +138,21 @@
     }
 
     /**
+     * JMXConnectorServer associated data.
+     */
+    private static class JMXConnectorServerData {
+
+        public JMXConnectorServerData(
+                JMXConnectorServer jmxConnectorServer,
+                JMXServiceURL jmxRemoteURL) {
+            this.jmxConnectorServer = jmxConnectorServer;
+            this.jmxRemoteURL = jmxRemoteURL;
+        }
+        JMXConnectorServer jmxConnectorServer;
+        JMXServiceURL jmxRemoteURL;
+    }
+
+    /**
      * <p>Prevents our RMI server objects from keeping the JVM alive.</p>
      *
      * <p>We use a private interface in Sun's JMX Remote API implementation
@@ -151,6 +171,7 @@
      * works).  Hence the somewhat misleading name of this class.</p>
      */
     private static class PermanentExporter implements RMIExporter {
+
         public Remote exportObject(Remote obj,
                 int port,
                 RMIClientSocketFactory csf,
@@ -158,24 +179,25 @@
                 throws RemoteException {
 
             synchronized (this) {
-                if (firstExported == null)
+                if (firstExported == null) {
                     firstExported = obj;
+                }
             }
 
             final UnicastServerRef ref;
-            if (csf == null && ssf == null)
+            if (csf == null && ssf == null) {
                 ref = new UnicastServerRef(port);
-            else
+            } else {
                 ref = new UnicastServerRef2(port, csf, ssf);
+            }
             return ref.exportObject(obj, null, true);
         }
 
         // Nothing special to be done for this case
         public boolean unexportObject(Remote obj, boolean force)
-        throws NoSuchObjectException {
+                throws NoSuchObjectException {
             return UnicastRemoteObject.unexportObject(obj, force);
         }
-
         Remote firstExported;
     }
 
@@ -202,19 +224,21 @@
         }
 
         private void checkAccessFileEntries(Subject subject) {
-            if (subject == null)
+            if (subject == null) {
                 throw new SecurityException(
                         "Access denied! No matching entries found in " +
                         "the access file [" + accessFile + "] as the " +
                         "authenticated Subject is null");
+            }
             final Set principals = subject.getPrincipals();
-            for (Iterator i = principals.iterator(); i.hasNext(); ) {
+            for (Iterator i = principals.iterator(); i.hasNext();) {
                 final Principal p = (Principal) i.next();
-                if (properties.containsKey(p.getName()))
+                if (properties.containsKey(p.getName())) {
                     return;
+                }
             }
             final Set<String> principalsStr = new HashSet<String>();
-            for (Iterator i = principals.iterator(); i.hasNext(); ) {
+            for (Iterator i = principals.iterator(); i.hasNext();) {
                 final Principal p = (Principal) i.next();
                 principalsStr.add(p.getName());
             }
@@ -225,16 +249,16 @@
         }
 
         private static Properties propertiesFromFile(String fname)
-        throws IOException {
+                throws IOException {
             Properties p = new Properties();
-            if (fname == null)
+            if (fname == null) {
                 return p;
+            }
             FileInputStream fin = new FileInputStream(fname);
             p.load(fin);
             fin.close();
             return p;
         }
-
         private final Map<String, Object> environment;
         private final Properties properties;
         private final String accessFile;
@@ -251,22 +275,23 @@
 
         // Load a new management properties
         final Properties props = Agent.loadManagementProperties();
-        if (props == null) return null;
+        if (props == null) {
+            return null;
+        }
 
         final String portStr = props.getProperty(PropertyNames.PORT);
 
 
         // System.out.println("initializing: {port=" + portStr + ",
         //                     properties="+props+"}");
-        return initialize(portStr,props);
+        return initialize(portStr, props);
     }
 
     /**
      * Initializes and starts a JMX Connector Server for remote
      * monitoring and management.
      **/
-    public static synchronized
-            JMXConnectorServer initialize(String portStr, Properties props) {
+    public static synchronized JMXConnectorServer initialize(String portStr, Properties props) {
 
         // Get port number
         final int port;
@@ -280,21 +305,21 @@
         }
 
         // Do we use authentication?
-        final String  useAuthenticationStr =
+        final String useAuthenticationStr =
                 props.getProperty(PropertyNames.USE_AUTHENTICATION,
                 DefaultValues.USE_AUTHENTICATION);
         final boolean useAuthentication =
                 Boolean.valueOf(useAuthenticationStr).booleanValue();
 
         // Do we use SSL?
-        final String  useSslStr =
+        final String useSslStr =
                 props.getProperty(PropertyNames.USE_SSL,
                 DefaultValues.USE_SSL);
         final boolean useSsl =
                 Boolean.valueOf(useSslStr).booleanValue();
 
         // Do we use RMI Registry SSL?
-        final String  useRegistrySslStr =
+        final String useRegistrySslStr =
                 props.getProperty(PropertyNames.USE_REGISTRY_SSL,
                 DefaultValues.USE_REGISTRY_SSL);
         final boolean useRegistrySsl =
@@ -307,7 +332,7 @@
             StringTokenizer st = new StringTokenizer(enabledCipherSuites, ",");
             int tokens = st.countTokens();
             enabledCipherSuitesList = new String[tokens];
-            for (int i = 0 ; i < tokens; i++) {
+            for (int i = 0; i < tokens; i++) {
                 enabledCipherSuitesList[i] = st.nextToken();
             }
         }
@@ -319,12 +344,12 @@
             StringTokenizer st = new StringTokenizer(enabledProtocols, ",");
             int tokens = st.countTokens();
             enabledProtocolsList = new String[tokens];
-            for (int i = 0 ; i < tokens; i++) {
+            for (int i = 0; i < tokens; i++) {
                 enabledProtocolsList[i] = st.nextToken();
             }
         }
 
-        final String  sslNeedClientAuthStr =
+        final String sslNeedClientAuthStr =
                 props.getProperty(PropertyNames.SSL_NEED_CLIENT_AUTH,
                 DefaultValues.SSL_NEED_CLIENT_AUTH);
         final boolean sslNeedClientAuth =
@@ -374,39 +399,49 @@
                     sslNeedClientAuth +
                     "\n\t" + PropertyNames.USE_AUTHENTICATION + "=" +
                     useAuthentication +
-                    (useAuthentication ?
-                        (loginConfigName == null ?
-                            ("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" +
-                    passwordFileName) :
-                            ("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" +
+                    (useAuthentication ? (loginConfigName == null ? ("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" +
+                    passwordFileName) : ("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" +
                     loginConfigName)) : "\n\t" +
                     Agent.getText("jmxremote.ConnectorBootstrap.initialize.noAuthentication")) +
-                    (useAuthentication ?
-                        ("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" +
+                    (useAuthentication ? ("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" +
                     accessFileName) : "") +
                     "");
         }
 
         final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
         JMXConnectorServer cs = null;
+        JMXServiceURL url = null;
         try {
-            cs = exportMBeanServer(mbs, port, useSsl, useRegistrySsl,
+            final JMXConnectorServerData data = exportMBeanServer(
+                    mbs, port, useSsl, useRegistrySsl,
                     sslConfigFileName, enabledCipherSuitesList,
                     enabledProtocolsList, sslNeedClientAuth,
                     useAuthentication, loginConfigName,
                     passwordFileName, accessFileName);
-
-            final JMXServiceURL url = cs.getAddress();
+            cs = data.jmxConnectorServer;
+            url = data.jmxRemoteURL;
             log.config("initialize",
                     Agent.getText("jmxremote.ConnectorBootstrap.initialize.ready",
-                    new JMXServiceURL(url.getProtocol(),
-                    url.getHost(),
-                    url.getPort(),
-                    "/jndi/rmi://"+url.getHost()+":"+port+"/"+
-                    "jmxrmi").toString()));
+                    url.toString()));
         } catch (Exception e) {
             throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
         }
+        try {
+            // Export remote connector address and associated configuration
+            // properties to the instrumentation buffer.
+            Map<String, String> properties = new HashMap<String, String>();
+            properties.put("remoteAddress", url.toString());
+            properties.put("authenticate", useAuthenticationStr);
+            properties.put("ssl", useSslStr);
+            properties.put("sslRegistry", useRegistrySslStr);
+            properties.put("sslNeedClientAuth", sslNeedClientAuthStr);
+            ConnectorAddressLink.exportRemote(properties);
+        } catch (Exception e) {
+            // Remote connector server started but unable to export remote
+            // connector address and associated configuration properties to
+            // the instrumentation buffer - non-fatal error.
+            log.debug("initialize", e);
+        }
         return cs;
     }
 
@@ -452,7 +487,7 @@
     }
 
     private static void checkPasswordFile(String passwordFileName) {
-        if (passwordFileName == null || passwordFileName.length()==0) {
+        if (passwordFileName == null || passwordFileName.length() == 0) {
             throw new AgentConfigurationError(PASSWORD_FILE_NOT_SET);
         }
         File file = new File(passwordFileName);
@@ -468,9 +503,9 @@
         try {
             if (fs.supportsFileSecurity(file)) {
                 if (!fs.isAccessUserOnly(file)) {
-                    final String msg=Agent.getText("jmxremote.ConnectorBootstrap.initialize.password.readonly",
+                    final String msg = Agent.getText("jmxremote.ConnectorBootstrap.initialize.password.readonly",
                             passwordFileName);
-                    log.config("initialize",msg);
+                    log.config("initialize", msg);
                     throw new AgentConfigurationError(PASSWORD_FILE_ACCESS_NOT_RESTRICTED,
                             passwordFileName);
                 }
@@ -482,7 +517,7 @@
     }
 
     private static void checkAccessFile(String accessFileName) {
-        if (accessFileName == null || accessFileName.length()==0) {
+        if (accessFileName == null || accessFileName.length() == 0) {
             throw new AgentConfigurationError(ACCESS_FILE_NOT_SET);
         }
         File file = new File(accessFileName);
@@ -619,7 +654,7 @@
         }
     }
 
-    private static JMXConnectorServer exportMBeanServer(
+    private static JMXConnectorServerData exportMBeanServer(
             MBeanServer mbs,
             int port,
             boolean useSsl,
@@ -697,24 +732,30 @@
         }
 
         final Registry registry;
-        if (useRegistrySsl)
+        if (useRegistrySsl) {
             registry =
                     new SingleEntryRegistry(port, csf, ssf,
                     "jmxrmi", exporter.firstExported);
-        else
+        } else {
             registry =
                     new SingleEntryRegistry(port,
                     "jmxrmi", exporter.firstExported);
+        }
+
+        JMXServiceURL remoteURL = new JMXServiceURL(
+                "service:jmx:rmi:///jndi/rmi://" + url.getHost() + ":" +
+                ((UnicastRef) ((RemoteObject) registry).getRef()).getLiveRef().getPort() +
+                "/jmxrmi");
 
         /* Our exporter remembers the first object it was asked to
-           export, which will be an RMIServerImpl appropriate for
-           publication in our special registry.  We could
-           alternatively have constructed the RMIServerImpl explicitly
-           and then constructed an RMIConnectorServer passing it as a
-           parameter, but that's quite a bit more verbose and pulls in
-           lots of knowledge of the RMI connector.  */
+        export, which will be an RMIServerImpl appropriate for
+        publication in our special registry.  We could
+        alternatively have constructed the RMIServerImpl explicitly
+        and then constructed an RMIConnectorServer passing it as a
+        parameter, but that's quite a bit more verbose and pulls in
+        lots of knowledge of the RMI connector.  */
 
-        return connServer;
+        return new JMXConnectorServerData(connServer, remoteURL);
     }
 
     /**
@@ -726,5 +767,4 @@
     // XXX Revisit: should probably clone this MibLogger....
     private static final MibLogger log =
             new MibLogger(ConnectorBootstrap.class);
-
 }
--- a/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolEntryImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolEntryImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -26,7 +26,6 @@
 
 // java imports
 //
-import java.io.Serializable;
 import java.util.Map;
 
 // jmx imports
@@ -36,9 +35,7 @@
 
 // jdmk imports
 //
-import com.sun.jmx.snmp.agent.SnmpMib;
 
-import java.lang.management.ManagementFactory;
 import java.lang.management.MemoryUsage;
 import java.lang.management.MemoryType;
 import java.lang.management.MemoryPoolMXBean;
@@ -73,7 +70,9 @@
         "jvmMemPoolEntry.getCollectionUsage";
     final static MemoryUsage ZEROS = new MemoryUsage(0,0,0,0);
 
-
+    final String entryMemoryTag;
+    final String entryPeakMemoryTag;
+    final String entryCollectMemoryTag;
 
     MemoryUsage getMemoryUsage() {
         try {
@@ -81,17 +80,17 @@
 
             if (m != null) {
                 final MemoryUsage cached = (MemoryUsage)
-                    m.get(memoryTag);
+                    m.get(entryMemoryTag);
                 if (cached != null) {
-                    log.debug("getMemoryUsage",
-                          "jvmMemPoolEntry.getUsage found in cache.");
+                    log.debug("getMemoryUsage",entryMemoryTag+
+                          " found in cache.");
                     return cached;
                 }
 
                 MemoryUsage u = pool.getUsage();
                 if (u == null) u = ZEROS;
 
-                m.put(memoryTag,u);
+                m.put(entryMemoryTag,u);
                 return u;
             }
             // Should never come here.
@@ -113,18 +112,18 @@
 
             if (m != null) {
                 final MemoryUsage cached = (MemoryUsage)
-                    m.get(peakMemoryTag);
+                    m.get(entryPeakMemoryTag);
                 if (cached != null) {
                     if (log.isDebugOn())
                         log.debug("getPeakMemoryUsage",
-                              peakMemoryTag + " found in cache.");
+                              entryPeakMemoryTag + " found in cache.");
                     return cached;
                 }
 
                 MemoryUsage u = pool.getPeakUsage();
                 if (u == null) u = ZEROS;
 
-                m.put(peakMemoryTag,u);
+                m.put(entryPeakMemoryTag,u);
                 return u;
             }
             // Should never come here.
@@ -146,18 +145,18 @@
 
             if (m != null) {
                 final MemoryUsage cached = (MemoryUsage)
-                    m.get(collectMemoryTag);
+                    m.get(entryCollectMemoryTag);
                 if (cached != null) {
                     if (log.isDebugOn())
                         log.debug("getCollectMemoryUsage",
-                                  collectMemoryTag + " found in cache.");
+                                  entryCollectMemoryTag + " found in cache.");
                     return cached;
                 }
 
                 MemoryUsage u = pool.getCollectionUsage();
                 if (u == null) u = ZEROS;
 
-                m.put(collectMemoryTag,u);
+                m.put(entryCollectMemoryTag,u);
                 return u;
             }
             // Should never come here.
@@ -179,9 +178,12 @@
     /**
      * Constructor for the "JvmMemPoolEntry" group.
      */
-    public JvmMemPoolEntryImpl(MemoryPoolMXBean mp, int index) {
+    public JvmMemPoolEntryImpl(MemoryPoolMXBean mp, final int index) {
         this.pool=mp;
         this.jvmMemPoolIndex = index;
+        this.entryMemoryTag = memoryTag + "." + index;
+        this.entryPeakMemoryTag = peakMemoryTag + "." + index;
+        this.entryCollectMemoryTag = collectMemoryTag + "." + index;
     }
 
     /**
--- a/src/share/classes/sun/misc/ClassFileTransformer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/misc/ClassFileTransformer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -46,8 +46,10 @@
 {
     // Singleton of ClassFileTransformer
     //
-    private static ArrayList transformerList = new ArrayList();
-    private static Object[] transformers = new Object[0];
+    private static ArrayList<ClassFileTransformer> transformerList
+        = new ArrayList<ClassFileTransformer>();
+    private static ClassFileTransformer[] transformers
+        = new ClassFileTransformer[0];
 
     /**
      * Add the class file transformer object.
@@ -59,7 +61,7 @@
         synchronized(transformerList)
         {
             transformerList.add(t);
-            transformers = transformerList.toArray();
+            transformers = transformerList.toArray(new ClassFileTransformer[0]);
         }
     }
 
@@ -68,7 +70,7 @@
      *
      * @return ClassFileTransformer object array
      */
-    public static Object[] getTransformers()
+    public static ClassFileTransformer[] getTransformers()
     {
         // transformers is not intended to be changed frequently,
         // so it is okay to not put synchronized block here
--- a/src/share/classes/sun/misc/Cleaner.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/misc/Cleaner.java	Mon Apr 14 11:34:15 2008 -0700
@@ -141,8 +141,8 @@
         try {
             thunk.run();
         } catch (final Throwable x) {
-            AccessController.doPrivileged(new PrivilegedAction() {
-                    public Object run() {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    public Void run() {
                         if (System.err != null)
                             new Error("Cleaner terminated abnormally", x)
                                 .printStackTrace();
--- a/src/share/classes/sun/misc/ExtensionDependency.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/misc/ExtensionDependency.java	Mon Apr 14 11:34:15 2008 -0700
@@ -284,10 +284,9 @@
         // Load the jar file ...
         Manifest man;
         try {
-            man = (Manifest) AccessController.doPrivileged
-                (
-                 new PrivilegedExceptionAction() {
-                     public Object run()
+            man = AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Manifest>() {
+                    public Manifest run()
                             throws IOException, FileNotFoundException {
                          if (!file.exists())
                              throw new FileNotFoundException(file.getName());
@@ -391,9 +390,9 @@
         final String extName = extensionName;
         final String[] fileExt = {".jar", ".zip"};
 
-        return (File) AccessController.doPrivileged
-            (new PrivilegedAction() {
-                public Object run() {
+        return AccessController.doPrivileged(
+            new PrivilegedAction<File>() {
+                public File run() {
                     try {
                         File fExtension;
                         File[] dirs = getExtDirs();
@@ -460,7 +459,7 @@
      * @return the list of files installed in all the directories
      */
     private static File[] getExtFiles(File[] dirs) throws IOException {
-        Vector urls = new Vector();
+        Vector<File> urls = new Vector<File>();
         for (int i = 0; i < dirs.length; i++) {
             String[] files = dirs[i].list(new JarFilter());
             if (files != null) {
@@ -484,16 +483,15 @@
      * </p>
      */
     private File[] getInstalledExtensions() throws IOException {
-        return (File[]) AccessController.doPrivileged
-            (
-             new PrivilegedAction() {
-                 public Object run() {
+        return AccessController.doPrivileged(
+            new PrivilegedAction<File[]>() {
+                public File[] run() {
                      try {
                          return getExtFiles(getExtDirs());
                      } catch(IOException e) {
                          debug("Cannot get list of installed extensions");
                          debugException(e);
-                         return new URL[0];
+                        return new File[0];
                      }
                  }
             });
--- a/src/share/classes/sun/misc/GC.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/misc/GC.java	Mon Apr 14 11:34:15 2008 -0700
@@ -128,8 +128,8 @@
 
         /* Create a new daemon thread in the root thread group */
         public static void create() {
-            PrivilegedAction pa = new PrivilegedAction() {
-                public Object run() {
+            PrivilegedAction<Void> pa = new PrivilegedAction<Void>() {
+                public Void run() {
                     ThreadGroup tg = Thread.currentThread().getThreadGroup();
                     for (ThreadGroup tgn = tg;
                          tgn != null;
@@ -170,13 +170,14 @@
      * method.  Given a request, the only interesting operation is that of
      * cancellation.
      */
-    public static class LatencyRequest implements Comparable {
+    public static class LatencyRequest
+        implements Comparable<LatencyRequest> {
 
         /* Instance counter, used to generate unique identifers */
         private static long counter = 0;
 
         /* Sorted set of active latency requests */
-        private static SortedSet requests = null;
+        private static SortedSet<LatencyRequest> requests = null;
 
         /* Examine the request set and reset the latency target if necessary.
          * Must be invoked while holding the lock.
@@ -187,7 +188,7 @@
                     setLatencyTarget(NO_TARGET);
                 }
             } else {
-                LatencyRequest r = (LatencyRequest)requests.first();
+                LatencyRequest r = requests.first();
                 if (r.latency != latencyTarget) {
                     setLatencyTarget(r.latency);
                 }
@@ -211,7 +212,7 @@
             synchronized (lock) {
                 this.id = ++counter;
                 if (requests == null) {
-                    requests = new TreeSet();
+                    requests = new TreeSet<LatencyRequest>();
                 }
                 requests.add(this);
                 adjustLatencyIfNeeded();
@@ -240,8 +241,7 @@
             }
         }
 
-        public int compareTo(Object o) {
-            LatencyRequest r = (LatencyRequest)o;
+        public int compareTo(LatencyRequest r) {
             long d = this.latency - r.latency;
             if (d == 0) d = this.id - r.id;
             return (d < 0) ? -1 : ((d > 0) ? +1 : 0);
--- a/src/share/classes/sun/misc/JavaIOFileDescriptorAccess.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/misc/JavaIOFileDescriptorAccess.java	Mon Apr 14 11:34:15 2008 -0700
@@ -33,4 +33,8 @@
 public interface JavaIOFileDescriptorAccess {
     public void set(FileDescriptor obj, int fd);
     public int get(FileDescriptor fd);
+
+    // Only valid on Windows
+    public void setHandle(FileDescriptor obj, long handle);
+    public long getHandle(FileDescriptor obj);
 }
--- a/src/share/classes/sun/misc/Launcher.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/misc/Launcher.java	Mon Apr 14 11:34:15 2008 -0700
@@ -135,9 +135,9 @@
                 // aa synthesized ACC via a call to the private method
                 // ExtClassLoader.getContext().
 
-                return (ExtClassLoader) AccessController.doPrivileged(
-                     new PrivilegedExceptionAction() {
-                        public Object run() throws IOException {
+                return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<ExtClassLoader>() {
+                        public ExtClassLoader run() throws IOException {
                             int len = dirs.length;
                             for (int i = 0; i < len; i++) {
                                 MetaIndex.registerDirectory(dirs[i]);
@@ -180,7 +180,7 @@
         }
 
         private static URL[] getExtURLs(File[] dirs) throws IOException {
-            Vector urls = new Vector();
+            Vector<URL> urls = new Vector<URL>();
             for (int i = 0; i < dirs.length; i++) {
                 String[] files = dirs[i].list();
                 if (files != null) {
@@ -261,9 +261,9 @@
             // when loading  classes. Specifically it prevent
             // accessClassInPackage.sun.* grants from being honored.
             //
-            return (AppClassLoader)
-                AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+            return AccessController.doPrivileged(
+                new PrivilegedAction<AppClassLoader>() {
+                    public AppClassLoader run() {
                     URL[] urls =
                         (s == null) ? new URL[0] : pathToURLs(path);
                     return new AppClassLoader(urls, extcl);
@@ -348,12 +348,12 @@
         URL[] urls;
         if (prop != null) {
             final String path = prop;
-            urls = (URL[])AccessController.doPrivileged(
-                new PrivilegedAction() {
-                    public Object run() {
+            urls = AccessController.doPrivileged(
+                new PrivilegedAction<URL[]>() {
+                    public URL[] run() {
                         File[] classPath = getClassPath(path);
                         int len = classPath.length;
-                        Set seenDirs = new HashSet();
+                        Set<File> seenDirs = new HashSet<File>();
                         for (int i = 0; i < len; i++) {
                             File curEntry = classPath[i];
                             // Negative test used to properly handle
@@ -509,8 +509,8 @@
         perms.add(new java.util.PropertyPermission("java.*",
             SecurityConstants.PROPERTY_READ_ACTION));
 
-        AccessController.doPrivileged(new PrivilegedAction() {
-            public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
                 for (int i=0; i < path.length; i++) {
                     File f = path[i];
                     String path;
@@ -553,7 +553,7 @@
         return perms.implies(permission);
     }
 
-    public java.util.Enumeration elements() {
+    public java.util.Enumeration<Permission> elements() {
         if (perms == null)
             init();
         synchronized (perms) {
--- a/src/share/classes/sun/misc/PerformanceLogger.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/misc/PerformanceLogger.java	Mon Apr 14 11:34:15 2008 -0700
@@ -78,7 +78,7 @@
 
     private static boolean perfLoggingOn = false;
     private static boolean useNanoTime = false;
-    private static Vector times;
+    private static Vector<TimeData> times;
     private static String logFileName = null;
     private static Writer logWriter = null;
 
@@ -104,8 +104,8 @@
             if (logFileName != null) {
                 if (logWriter == null) {
                     java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedAction() {
-                        public Object run() {
+                    new java.security.PrivilegedAction<Void>() {
+                        public Void run() {
                             try {
                                 File logFile = new File(logFileName);
                                 logFile.createNewFile();
@@ -124,7 +124,7 @@
                 logWriter = new OutputStreamWriter(System.out);
             }
         }
-        times = new Vector(10);
+        times = new Vector<TimeData>(10);
         // Reserve predefined slots
         for (int i = 0; i <= LAST_RESERVED; ++i) {
             times.add(new TimeData("Time " + i + " not set", 0));
@@ -207,7 +207,7 @@
      */
     public static long getStartTime() {
         if (loggingEnabled()) {
-            return ((TimeData)times.get(START_INDEX)).getTime();
+            return times.get(START_INDEX).getTime();
         } else {
             return 0;
         }
@@ -253,7 +253,7 @@
      */
     public static long getTimeAtIndex(int index) {
         if (loggingEnabled()) {
-            return ((TimeData)times.get(index)).getTime();
+            return times.get(index).getTime();
         } else {
             return 0;
         }
@@ -264,7 +264,7 @@
      */
     public static String getMessageAtIndex(int index) {
         if (loggingEnabled()) {
-            return ((TimeData)times.get(index)).getMessage();
+            return times.get(index).getMessage();
         } else {
             return null;
         }
@@ -278,7 +278,7 @@
             try {
                 synchronized(times) {
                     for (int i = 0; i < times.size(); ++i) {
-                        TimeData td = (TimeData)times.get(i);
+                        TimeData td = times.get(i);
                         if (td != null) {
                             writer.write(i + " " + td.getMessage() + ": " +
                                          td.getTime() + "\n");
--- a/src/share/classes/sun/misc/ProxyGenerator.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/misc/ProxyGenerator.java	Mon Apr 14 11:34:15 2008 -0700
@@ -324,8 +324,8 @@
 
         if (saveGeneratedFiles) {
             java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction() {
-                public Object run() {
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
                     try {
                         FileOutputStream file =
                             new FileOutputStream(dotToSlash(name) + ".class");
@@ -576,7 +576,7 @@
                      * compatibly with the throws clauses of both
                      * overridden methods.
                      */
-                    List<Class> legalExceptions = new ArrayList<Class>();
+                    List<Class<?>> legalExceptions = new ArrayList<Class<?>>();
                     collectCompatibleTypes(
                         exceptionTypes, pm.exceptionTypes, legalExceptions);
                     collectCompatibleTypes(
@@ -618,11 +618,11 @@
          * List of return types that are not yet known to be
          * assignable from ("covered" by) any of the others.
          */
-        LinkedList<Class> uncoveredReturnTypes = new LinkedList<Class>();
+        LinkedList<Class<?>> uncoveredReturnTypes = new LinkedList<Class<?>>();
 
     nextNewReturnType:
         for (ProxyMethod pm : methods) {
-            Class newReturnType = pm.returnType;
+            Class<?> newReturnType = pm.returnType;
             if (newReturnType.isPrimitive()) {
                 throw new IllegalArgumentException(
                     "methods with same signature " +
@@ -637,9 +637,9 @@
              * Compare the new return type to the existing uncovered
              * return types.
              */
-            ListIterator<Class> liter = uncoveredReturnTypes.listIterator();
+            ListIterator<Class<?>> liter = uncoveredReturnTypes.listIterator();
             while (liter.hasNext()) {
-                Class uncoveredReturnType = liter.next();
+                Class<?> uncoveredReturnType = liter.next();
 
                 /*
                  * If an existing uncovered return type is assignable
@@ -944,10 +944,10 @@
 
             tryEnd = pc = (short) minfo.code.size();
 
-            List<Class> catchList = computeUniqueCatchList(exceptionTypes);
+            List<Class<?>> catchList = computeUniqueCatchList(exceptionTypes);
             if (catchList.size() > 0) {
 
-                for (Class ex : catchList) {
+                for (Class<?> ex : catchList) {
                     minfo.exceptionTable.add(new ExceptionTableEntry(
                         tryBegin, tryEnd, pc,
                         cp.getClass(dotToSlash(ex.getName()))));
@@ -1521,8 +1521,9 @@
      * declared exceptions from duplicate methods inherited from
      * different interfaces.
      */
-    private static void collectCompatibleTypes(Class[] from, Class[] with,
-                                               List<Class> list)
+    private static void collectCompatibleTypes(Class<?>[] from,
+                                               Class<?>[] with,
+                                               List<Class<?>> list)
     {
         for (int i = 0; i < from.length; i++) {
             if (!list.contains(from[i])) {
@@ -1557,8 +1558,8 @@
      * given list of declared exceptions, indicating that no exceptions
      * need to be caught.
      */
-    private static List<Class> computeUniqueCatchList(Class[] exceptions) {
-        List<Class> uniqueList = new ArrayList<Class>();
+    private static List<Class<?>> computeUniqueCatchList(Class<?>[] exceptions) {
+        List<Class<?>> uniqueList = new ArrayList<Class<?>>();
                                                 // unique exceptions to catch
 
         uniqueList.add(Error.class);            // always catch/rethrow these
@@ -1566,7 +1567,7 @@
 
     nextException:
         for (int i = 0; i < exceptions.length; i++) {
-            Class ex = exceptions[i];
+            Class<?> ex = exceptions[i];
             if (ex.isAssignableFrom(Throwable.class)) {
                 /*
                  * If Throwable is declared to be thrown by the proxy method,
@@ -1586,7 +1587,7 @@
              * exceptions that need to be caught:
              */
             for (int j = 0; j < uniqueList.size();) {
-                Class ex2 = uniqueList.get(j);
+                Class<?> ex2 = uniqueList.get(j);
                 if (ex2.isAssignableFrom(ex)) {
                     /*
                      * if a superclass of this exception is already on
--- a/src/share/classes/sun/misc/URLClassPath.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/misc/URLClassPath.java	Mon Apr 14 11:34:15 2008 -0700
@@ -86,16 +86,16 @@
     }
 
     /* The original search path of URLs. */
-    private ArrayList path = new ArrayList();
+    private ArrayList<URL> path = new ArrayList<URL>();
 
     /* The stack of unopened URLs */
-    Stack urls = new Stack();
+    Stack<URL> urls = new Stack<URL>();
 
     /* The resulting search path of Loaders */
-    ArrayList loaders = new ArrayList();
+    ArrayList<Loader> loaders = new ArrayList<Loader>();
 
     /* Map of each URL opened to its corresponding Loader */
-    HashMap lmap = new HashMap();
+    HashMap<URL, Loader> lmap = new HashMap<URL, Loader>();
 
     /* The jar protocol handler to use when creating new URLs */
     private URLStreamHandler jarHandler;
@@ -146,7 +146,7 @@
      */
     public URL[] getURLs() {
         synchronized (urls) {
-            return (URL[])path.toArray(new URL[path.size()]);
+            return path.toArray(new URL[path.size()]);
         }
     }
 
@@ -200,9 +200,9 @@
      * @param name the resource name
      * @return an Enumeration of all the urls having the specified name
      */
-    public Enumeration findResources(final String name,
+    public Enumeration<URL> findResources(final String name,
                                      final boolean check) {
-        return new Enumeration() {
+        return new Enumeration<URL>() {
             private int index = 0;
             private URL url = null;
 
@@ -225,7 +225,7 @@
                 return next();
             }
 
-            public Object nextElement() {
+            public URL nextElement() {
                 if (!next()) {
                     throw new NoSuchElementException();
                 }
@@ -247,9 +247,9 @@
      * @param name the resource name
      * @return an Enumeration of all the resources having the specified name
      */
-    public Enumeration getResources(final String name,
+    public Enumeration<Resource> getResources(final String name,
                                     final boolean check) {
-        return new Enumeration() {
+        return new Enumeration<Resource>() {
             private int index = 0;
             private Resource res = null;
 
@@ -272,7 +272,7 @@
                 return next();
             }
 
-            public Object nextElement() {
+            public Resource nextElement() {
                 if (!next()) {
                     throw new NoSuchElementException();
                 }
@@ -283,7 +283,7 @@
         };
     }
 
-    public Enumeration getResources(final String name) {
+    public Enumeration<Resource> getResources(final String name) {
         return getResources(name, true);
     }
 
@@ -302,7 +302,7 @@
                 if (urls.empty()) {
                     return null;
                 } else {
-                    url = (URL)urls.pop();
+                    url = urls.pop();
                 }
             }
             // Skip this URL if it already has a Loader. (Loader
@@ -329,7 +329,7 @@
             loaders.add(loader);
             lmap.put(url, loader);
         }
-        return (Loader)loaders.get(index);
+        return loaders.get(index);
     }
 
     /*
@@ -337,9 +337,9 @@
      */
     private Loader getLoader(final URL url) throws IOException {
         try {
-            return (Loader)java.security.AccessController.doPrivileged
-                (new java.security.PrivilegedExceptionAction() {
-                public Object run() throws IOException {
+            return java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedExceptionAction<Loader>() {
+                public Loader run() throws IOException {
                     String file = url.getFile();
                     if (file != null && file.endsWith("/")) {
                         if ("file".equals(url.getProtocol())) {
@@ -561,13 +561,14 @@
         private JarIndex index;
         private MetaIndex metaIndex;
         private URLStreamHandler handler;
-        private HashMap lmap;
+        private HashMap<URL, Loader> lmap;
 
         /*
          * Creates a new JarLoader for the specified URL referring to
          * a JAR file.
          */
-        JarLoader(URL url, URLStreamHandler jarHandler, HashMap loaderMap)
+        JarLoader(URL url, URLStreamHandler jarHandler,
+                  HashMap<URL, Loader> loaderMap)
             throws IOException
         {
             super(new URL("jar", "", -1, url + "!/", jarHandler));
@@ -615,8 +616,8 @@
             if (jar == null) {
                 try {
                     java.security.AccessController.doPrivileged(
-                        new java.security.PrivilegedExceptionAction() {
-                            public Object run() throws IOException {
+                        new java.security.PrivilegedExceptionAction<Void>() {
+                            public Void run() throws IOException {
                                 if (DEBUG) {
                                     System.err.println("Opening " + csu);
                                     Thread.dumpStack();
@@ -732,9 +733,9 @@
 
             String entryName;
             ZipEntry entry;
-            Enumeration enum_ = jar.entries();
+            Enumeration<JarEntry> enum_ = jar.entries();
             while (enum_.hasMoreElements()) {
-                entry = (ZipEntry)enum_.nextElement();
+                entry = enum_.nextElement();
                 entryName = entry.getName();
                 if((pos = entryName.lastIndexOf("/")) != -1)
                     entryName = entryName.substring(0, pos);
@@ -778,7 +779,7 @@
             if (index == null)
                 return null;
 
-            HashSet visited = new HashSet();
+            HashSet<URL> visited = new HashSet<URL>();
             return getResource(name, check, visited);
         }
 
@@ -790,7 +791,7 @@
          * non-existent resource
          */
         Resource getResource(final String name, boolean check,
-                Set visited) {
+                             Set<URL> visited) {
 
             Resource res;
             Object[] jarFiles;
@@ -819,10 +820,9 @@
                             /* no loader has been set up for this jar file
                              * before
                              */
-                            newLoader = (JarLoader)
-                                AccessController.doPrivileged(
-                                    new PrivilegedExceptionAction() {
-                                    public Object run() throws IOException {
+                            newLoader = AccessController.doPrivileged(
+                                new PrivilegedExceptionAction<JarLoader>() {
+                                    public JarLoader run() throws IOException {
                                         return new JarLoader(url, handler,
                                             lmap);
                                     }
--- a/src/share/classes/sun/net/NetProperties.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/NetProperties.java	Mon Apr 14 11:34:15 2008 -0700
@@ -42,8 +42,8 @@
     static private Properties props = new Properties();
     static {
         AccessController.doPrivileged(
-            new PrivilegedAction() {
-                public Object run() {
+            new PrivilegedAction<Void>() {
+                public Void run() {
                     loadDefaultProperties();
                     return null;
                 }});
--- a/src/share/classes/sun/net/NetworkClient.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/NetworkClient.java	Mon Apr 14 11:34:15 2008 -0700
@@ -64,8 +64,8 @@
         final String encs[] = { null };
 
         AccessController.doPrivileged(
-                new PrivilegedAction() {
-                    public Object run() {
+                new PrivilegedAction<Void>() {
+                    public Void run() {
                         vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 0).intValue();
                         vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0).intValue();
                         encs[0] = System.getProperty("file.encoding", "ISO8859_1");
@@ -152,9 +152,9 @@
         Socket s;
         if (proxy != null) {
             if (proxy.type() == Proxy.Type.SOCKS) {
-                s = (Socket) AccessController.doPrivileged(
-                               new PrivilegedAction() {
-                                   public Object run() {
+                s = AccessController.doPrivileged(
+                    new PrivilegedAction<Socket>() {
+                        public Socket run() {
                                        return new Socket(proxy);
                                    }});
             } else
--- a/src/share/classes/sun/net/ftp/FtpClient.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/ftp/FtpClient.java	Mon Apr 14 11:34:15 2008 -0700
@@ -117,8 +117,8 @@
     public static int getFtpProxyPort() {
         final int result[] = {80};
         java.security.AccessController.doPrivileged(
-          new java.security.PrivilegedAction() {
-            public Object run() {
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
 
                 String tmp = System.getProperty("ftp.proxyPort");
                 if (tmp == null) {
@@ -343,9 +343,9 @@
         Socket s;
         if (proxy != null) {
             if (proxy.type() == Proxy.Type.SOCKS) {
-                s = (Socket) AccessController.doPrivileged(
-                                            new PrivilegedAction() {
-                              public Object run() {
+                s = AccessController.doPrivileged(
+                    new PrivilegedAction<Socket>() {
+                        public Socket run() {
                                   return new Socket(proxy);
                               }});
             } else
--- a/src/share/classes/sun/net/spi/DefaultProxySelector.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/spi/DefaultProxySelector.java	Mon Apr 14 11:34:15 2008 -0700
@@ -82,9 +82,9 @@
 
     static {
         final String key = "java.net.useSystemProxies";
-        Boolean b = (Boolean) AccessController.doPrivileged(
-            new PrivilegedAction() {
-                public Object run() {
+        Boolean b = AccessController.doPrivileged(
+            new PrivilegedAction<Boolean>() {
+                public Boolean run() {
                     return NetProperties.getBoolean(key);
                 }});
         if (b != null && b.booleanValue()) {
@@ -197,9 +197,9 @@
          * System properties it does help having only 1 call to doPrivileged.
          * Be mindful what you do in here though!
          */
-        Proxy p = (Proxy) AccessController.doPrivileged(
-            new PrivilegedAction() {
-                public Object run() {
+        Proxy p = AccessController.doPrivileged(
+            new PrivilegedAction<Proxy>() {
+                public Proxy run() {
                     int i, j;
                     String phost =  null;
                     int pport = 0;
--- a/src/share/classes/sun/net/www/MessageHeader.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/www/MessageHeader.java	Mon Apr 14 11:34:15 2008 -0700
@@ -138,7 +138,7 @@
         return null;
     }
 
-    class HeaderIterator implements Iterator {
+    class HeaderIterator implements Iterator<String> {
         int index = 0;
         int next = -1;
         String key;
@@ -165,7 +165,7 @@
                 return false;
             }
         }
-        public Object next() {
+        public String next() {
             synchronized (lock) {
                 if (haveNext) {
                     haveNext = false;
@@ -187,17 +187,17 @@
      * return an Iterator that returns all values of a particular
      * key in sequence
      */
-    public Iterator multiValueIterator (String k) {
+    public Iterator<String> multiValueIterator (String k) {
         return new HeaderIterator (k, this);
     }
 
-    public synchronized Map getHeaders() {
+    public synchronized Map<String, List<String>> getHeaders() {
         return getHeaders(null);
     }
 
-    public synchronized Map getHeaders(String[] excludeList) {
+    public synchronized Map<String, List<String>> getHeaders(String[] excludeList) {
         boolean skipIt = false;
-        Map m = new HashMap();
+        Map<String, List<String>> m = new HashMap<String, List<String>>();
         for (int i = nkeys; --i >= 0;) {
             if (excludeList != null) {
                 // check if the key is in the excludeList.
@@ -211,9 +211,9 @@
                 }
             }
             if (!skipIt) {
-                List l = (List)m.get(keys[i]);
+                List<String> l = m.get(keys[i]);
                 if (l == null) {
-                    l = new ArrayList();
+                    l = new ArrayList<String>();
                     m.put(keys[i], l);
                 }
                 l.add(values[i]);
@@ -223,11 +223,8 @@
             }
         }
 
-        Set keySet = m.keySet();
-        for (Iterator i = keySet.iterator(); i.hasNext();) {
-            Object key = i.next();
-            List l = (List)m.get(key);
-            m.put(key, Collections.unmodifiableList(l));
+        for (String key : m.keySet()) {
+            m.put(key, Collections.unmodifiableList(m.get(key)));
         }
 
         return Collections.unmodifiableMap(m);
--- a/src/share/classes/sun/net/www/MimeTable.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/www/MimeTable.java	Mon Apr 14 11:34:15 2008 -0700
@@ -37,18 +37,20 @@
 
 public class MimeTable implements FileNameMap {
     /** Keyed by content type, returns MimeEntries */
-    private Hashtable entries = new Hashtable();
+    private Hashtable<String, MimeEntry> entries
+        = new Hashtable<String, MimeEntry>();
 
     /** Keyed by file extension (with the .), returns MimeEntries */
-    private Hashtable extensionMap = new Hashtable();
+    private Hashtable<String, MimeEntry> extensionMap
+        = new Hashtable<String, MimeEntry>();
 
     // Will be reset if in the platform-specific data file
     private static String tempFileTemplate;
 
     static {
         java.security.AccessController.doPrivileged(
-                                   new java.security.PrivilegedAction() {
-            public Object run() {
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
                 tempFileTemplate =
                     System.getProperty("content.types.temp.file.template",
                                        "/tmp/%s");
@@ -60,7 +62,8 @@
                     "/usr/etc/mailcap",
                     "/usr/local/etc/mailcap",
                     System.getProperty("hotjava.home",
-                                       "/usr/local/hotjava") + "/lib/mailcap",
+                                           "/usr/local/hotjava")
+                        + "/lib/mailcap",
                 };
                 return null;
             }
@@ -83,8 +86,8 @@
     public static MimeTable getDefaultTable() {
         if (defaultInstance == null) {
             java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction() {
-                public Object run() {
+                new java.security.PrivilegedAction<Void>() {
+                    public Void run() {
                     defaultInstance = new MimeTable();
                     URLConnection.setFileNameMap(defaultInstance);
                     return null;
@@ -130,7 +133,7 @@
     }
 
     public synchronized MimeEntry remove(String type) {
-        MimeEntry entry = (MimeEntry)entries.get(type);
+        MimeEntry entry = entries.get(type);
         return remove(entry);
     }
 
@@ -142,16 +145,16 @@
             }
         }
 
-        return (MimeEntry)entries.remove(entry.getType());
+        return entries.remove(entry.getType());
     }
 
     public synchronized MimeEntry find(String type) {
-        MimeEntry entry = (MimeEntry)entries.get(type);
+        MimeEntry entry = entries.get(type);
         if (entry == null) {
             // try a wildcard lookup
-            Enumeration e = entries.elements();
+            Enumeration<MimeEntry> e = entries.elements();
             while (e.hasMoreElements()) {
-                MimeEntry wild = (MimeEntry)e.nextElement();
+                MimeEntry wild = e.nextElement();
                 if (wild.matches(type)) {
                     return wild;
                 }
@@ -191,13 +194,13 @@
      * with it.
      */
     public synchronized MimeEntry findByExt(String fileExtension) {
-        return (MimeEntry)extensionMap.get(fileExtension);
+        return extensionMap.get(fileExtension);
     }
 
     public synchronized MimeEntry findByDescription(String description) {
-        Enumeration e = elements();
+        Enumeration<MimeEntry> e = elements();
         while (e.hasMoreElements()) {
-            MimeEntry entry = (MimeEntry)e.nextElement();
+            MimeEntry entry = e.nextElement();
             if (description.equals(entry.getDescription())) {
                 return entry;
             }
@@ -211,7 +214,7 @@
         return tempFileTemplate;
     }
 
-    public synchronized Enumeration elements() {
+    public synchronized Enumeration<MimeEntry> elements() {
         return entries.elements();
     }
 
@@ -269,7 +272,7 @@
         }
 
         // now, parse the mime-type spec's
-        Enumeration types = entries.propertyNames();
+        Enumeration<?> types = entries.propertyNames();
         while (types.hasMoreElements()) {
             String type = (String)types.nextElement();
             String attrs = entries.getProperty(type);
@@ -392,9 +395,9 @@
 
     public Properties getAsProperties() {
         Properties properties = new Properties();
-        Enumeration e = elements();
+        Enumeration<MimeEntry> e = elements();
         while (e.hasMoreElements()) {
-            MimeEntry entry = (MimeEntry)e.nextElement();
+            MimeEntry entry = e.nextElement();
             properties.put(entry.getType(), entry.toProperty());
         }
 
--- a/src/share/classes/sun/net/www/http/ChunkedOutputStream.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/www/http/ChunkedOutputStream.java	Mon Apr 14 11:34:15 2008 -0700
@@ -177,14 +177,23 @@
             return;
         }
 
-        if (len > MAX_BUF_SIZE) {
+        int l = preferredChunkSize - count;
+
+        if ((len > MAX_BUF_SIZE) && (len > l)) {
+            /* current chunk is empty just write the data */
+            if (count == 0) {
+                count = len;
+                flush (b, false, off);
+                return;
+            }
+
             /* first finish the current chunk */
-            int l = preferredChunkSize - count;
             if (l > 0) {
                 System.arraycopy(b, off, buf, count, l);
                 count = preferredChunkSize;
                 flush(buf, false);
             }
+
             count = len - l;
             /* Now write the rest of the data */
             flush (b, false, l+off);
--- a/src/share/classes/sun/net/www/http/HttpClient.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/www/http/HttpClient.java	Mon Apr 14 11:34:15 2008 -0700
@@ -230,9 +230,9 @@
         setConnectTimeout(to);
 
         // get the cookieHandler if there is any
-        cookieHandler = (CookieHandler)java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction() {
-                public Object run() {
+        cookieHandler = java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<CookieHandler>() {
+                public CookieHandler run() {
                     return CookieHandler.getDefault();
                 }
             });
@@ -297,7 +297,7 @@
         HttpClient ret = null;
         /* see if one's already around */
         if (useCache) {
-            ret = (HttpClient) kac.get(url, null);
+            ret = kac.get(url, null);
             if (ret != null) {
                 if ((ret.proxy != null && ret.proxy.equals(p)) ||
                     (ret.proxy == null && p == null)) {
@@ -389,7 +389,7 @@
      * cache).
      */
     public void closeIdleConnection() {
-        HttpClient http = (HttpClient) kac.get(url, null);
+        HttpClient http = kac.get(url, null);
         if (http != null) {
             http.closeServer();
         }
@@ -447,8 +447,8 @@
     {
         try {
             java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedExceptionAction() {
-                public Object run() throws IOException {
+                new java.security.PrivilegedExceptionAction<Void>() {
+                    public Void run() throws IOException {
                     openServer(server.getHostString(), server.getPort());
                     return null;
                 }
@@ -477,9 +477,8 @@
     {
         try {
             java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedExceptionAction() {
-                public Object run() throws IOException
-                {
+                new java.security.PrivilegedExceptionAction<Void>() {
+                    public Void run() throws IOException {
                     superOpenServer(proxyHost, proxyPort);
                     return null;
                 }
@@ -686,7 +685,7 @@
                     // So we do put the cast in as a workaround until
                     // it is resolved.
                     if (uri != null)
-                        cookieHandler.put(uri, (Map<java.lang.String,java.util.List<java.lang.String>>)responses.getHeaders());
+                        cookieHandler.put(uri, responses.getHeaders());
                 }
 
                 /* decide if we're keeping alive:
--- a/src/share/classes/sun/net/www/http/KeepAliveCache.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/www/http/KeepAliveCache.java	Mon Apr 14 11:34:15 2008 -0700
@@ -38,7 +38,9 @@
  * @author Stephen R. Pietrowicz (NCSA)
  * @author Dave Brown
  */
-public class KeepAliveCache extends ConcurrentHashMap implements Runnable {
+public class KeepAliveCache
+    extends ConcurrentHashMap<KeepAliveKey, ClientVector>
+    implements Runnable {
     private static final long serialVersionUID = -2937172892064557949L;
 
     /* maximum # keep-alive connections to maintain at once
@@ -88,12 +90,12 @@
              * back from the server.  If I'm connected through a Netscape proxy
              * to a server that sent me a keep-alive
              * time of 15 sec, the proxy unilaterally terminates my connection
-             * The robustness to to get around this is in HttpClient.parseHTTP()
+             * The robustness to get around this is in HttpClient.parseHTTP()
              */
             final KeepAliveCache cache = this;
             java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction() {
-                public Object run() {
+                new java.security.PrivilegedAction<Void>() {
+                public Void run() {
                    // We want to create the Keep-Alive-Timer in the
                     // system threadgroup
                     ThreadGroup grp = Thread.currentThread().getThreadGroup();
@@ -112,7 +114,7 @@
         }
 
         KeepAliveKey key = new KeepAliveKey(url, obj);
-        ClientVector v = (ClientVector)super.get(key);
+        ClientVector v = super.get(key);
 
         if (v == null) {
             int keepAliveTimeout = http.getKeepAliveTimeout();
@@ -125,10 +127,10 @@
         }
     }
 
-    /* remove an obsolete HttpClient from it's VectorCache */
+    /* remove an obsolete HttpClient from its VectorCache */
     public synchronized void remove (HttpClient h, Object obj) {
         KeepAliveKey key = new KeepAliveKey(h.url, obj);
-        ClientVector v = (ClientVector)super.get(key);
+        ClientVector v = super.get(key);
         if (v != null) {
             v.remove(h);
             if (v.empty()) {
@@ -137,7 +139,7 @@
         }
     }
 
-    /* called by a clientVector thread when all it's connections have timed out
+    /* called by a clientVector thread when all its connections have timed out
      * and that vector of connections should be removed.
      */
     synchronized void removeVector(KeepAliveKey k) {
@@ -147,10 +149,10 @@
     /**
      * Check to see if this URL has a cached HttpClient
      */
-    public synchronized Object get(URL url, Object obj) {
+    public synchronized HttpClient get(URL url, Object obj) {
 
         KeepAliveKey key = new KeepAliveKey(url, obj);
-        ClientVector v = (ClientVector)super.get(key);
+        ClientVector v = super.get(key);
         if (v == null) { // nothing in cache yet
             return null;
         }
@@ -180,17 +182,16 @@
 
                 long currentTime = System.currentTimeMillis();
 
-                Iterator itr = keySet().iterator();
-                ArrayList keysToRemove = new ArrayList();
+                ArrayList<KeepAliveKey> keysToRemove
+                    = new ArrayList<KeepAliveKey>();
 
-                while (itr.hasNext()) {
-                    KeepAliveKey key = (KeepAliveKey)itr.next();
-                    ClientVector v = (ClientVector)get(key);
+                for (KeepAliveKey key : keySet()) {
+                    ClientVector v = get(key);
                     synchronized (v) {
                         int i;
 
                         for (i = 0; i < v.size(); i++) {
-                            KeepAliveEntry e = (KeepAliveEntry)v.elementAt(i);
+                            KeepAliveEntry e = v.elementAt(i);
                             if ((currentTime - e.idleStartTime) > v.nap) {
                                 HttpClient h = e.hc;
                                 h.closeServer();
@@ -205,9 +206,9 @@
                         }
                     }
                 }
-                itr = keysToRemove.iterator();
-                while (itr.hasNext()) {
-                    removeVector((KeepAliveKey)itr.next());
+
+                for (KeepAliveKey key : keysToRemove) {
+                    removeVector(key);
                 }
             }
         } while (size() > 0);
@@ -234,7 +235,7 @@
  */
 
 
-class ClientVector extends java.util.Stack {
+class ClientVector extends java.util.Stack<KeepAliveEntry> {
     private static final long serialVersionUID = -8680532108106489459L;
 
     // sleep time in milliseconds, before cache clear
@@ -254,7 +255,7 @@
             HttpClient hc = null;
             long currentTime = System.currentTimeMillis();
             do {
-                KeepAliveEntry e = (KeepAliveEntry)pop();
+                KeepAliveEntry e = pop();
                 if ((currentTime - e.idleStartTime) > nap) {
                     e.hc.closeServer();
                 } else {
--- a/src/share/classes/sun/net/www/http/KeepAliveStream.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/www/http/KeepAliveStream.java	Mon Apr 14 11:34:15 2008 -0700
@@ -174,8 +174,8 @@
 
         if (startCleanupThread) {
             java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction() {
-                public Object run() {
+                new java.security.PrivilegedAction<Void>() {
+                public Void run() {
                     // We want to create the Keep-Alive-SocketCleaner in the
                     // system threadgroup
                     ThreadGroup grp = Thread.currentThread().getThreadGroup();
--- a/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java	Mon Apr 14 11:34:15 2008 -0700
@@ -59,19 +59,19 @@
 
     static {
         final String maxDataKey = "http.KeepAlive.remainingData";
-        int maxData = ((Integer) AccessController.doPrivileged(
-            new PrivilegedAction() {
-                public Object run() {
-                    return new Integer(NetProperties.getInteger(maxDataKey, MAX_DATA_REMAINING));
-                }})).intValue() * 1024;
+        int maxData = AccessController.doPrivileged(
+            new PrivilegedAction<Integer>() {
+                public Integer run() {
+                    return NetProperties.getInteger(maxDataKey, MAX_DATA_REMAINING);
+                }}).intValue() * 1024;
         MAX_DATA_REMAINING = maxData;
 
         final String maxCapacityKey = "http.KeepAlive.queuedConnections";
-        int maxCapacity = ((Integer) AccessController.doPrivileged(
-            new PrivilegedAction() {
-                public Object run() {
-                    return new Integer(NetProperties.getInteger(maxCapacityKey, MAX_CAPACITY));
-                }})).intValue();
+        int maxCapacity = AccessController.doPrivileged(
+            new PrivilegedAction<Integer>() {
+                public Integer run() {
+                    return NetProperties.getInteger(maxCapacityKey, MAX_CAPACITY);
+                }}).intValue();
         MAX_CAPACITY = maxCapacity;
 
     }
--- a/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Mon Apr 14 11:34:15 2008 -0700
@@ -215,12 +215,11 @@
         Proxy p = null;
         if (instProxy == null) { // no per connection proxy specified
             /**
-             * Do we have to use a proxie?
+             * Do we have to use a proxy?
              */
-            ProxySelector sel = (ProxySelector)
-                java.security.AccessController.doPrivileged(
-                        new java.security.PrivilegedAction() {
-                            public Object run() {
+            ProxySelector sel = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<ProxySelector>() {
+                    public ProxySelector run() {
                                 return ProxySelector.getDefault();
                             }
                             });
--- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Mon Apr 14 11:34:15 2008 -0700
@@ -64,11 +64,6 @@
 import java.util.TimeZone;
 import java.net.MalformedURLException;
 import java.nio.ByteBuffer;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.WritableByteChannel;
-import java.nio.channels.Selector;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.SelectableChannel;
 import java.lang.reflect.*;
 
 /**
@@ -144,8 +139,8 @@
 
     static {
         maxRedirects = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetIntegerAction("http.maxRedirects",
-                defaultmaxRedirects)).intValue();
+            new sun.security.action.GetIntegerAction(
+                "http.maxRedirects", defaultmaxRedirects)).intValue();
         version = java.security.AccessController.doPrivileged(
                     new sun.security.action.GetPropertyAction("java.version"));
         String agent = java.security.AccessController.doPrivileged(
@@ -291,10 +286,9 @@
                             final String scheme,
                             final URL url,
                             final RequestorType authType) {
-        return (PasswordAuthentication)
-            java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction() {
-                public Object run() {
+        return java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<PasswordAuthentication>() {
+                public PasswordAuthentication run() {
                     return Authenticator.requestPasswordAuthentication(
                         host, addr, port, protocol,
                         prompt, scheme, url, authType);
@@ -559,15 +553,15 @@
         responses = new MessageHeader();
         this.handler = handler;
         instProxy = p;
-        cookieHandler = (CookieHandler)java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction() {
-            public Object run() {
+        cookieHandler = java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<CookieHandler>() {
+                public CookieHandler run() {
                 return CookieHandler.getDefault();
             }
         });
-        cacheHandler = (ResponseCache)java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction() {
-            public Object run() {
+        cacheHandler = java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<ResponseCache>() {
+                public ResponseCache run() {
                 return ResponseCache.getDefault();
             }
         });
@@ -650,8 +644,8 @@
         final boolean result[] = {false};
 
         java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction() {
-            public Object run() {
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
                 try {
                     InetAddress a1 = InetAddress.getByName(h1);
                     InetAddress a2 = InetAddress.getByName(h2);
@@ -729,10 +723,10 @@
                 /**
                  * Do we have to use a proxy?
                  */
-                ProxySelector sel = (ProxySelector)
+                ProxySelector sel =
                     java.security.AccessController.doPrivileged(
-                             new java.security.PrivilegedAction() {
-                                 public Object run() {
+                        new java.security.PrivilegedAction<ProxySelector>() {
+                            public ProxySelector run() {
                                      return ProxySelector.getDefault();
                                  }
                              });
@@ -824,6 +818,7 @@
      * - get input, [read input,] get output, [write output]
      */
 
+    @Override
     public synchronized OutputStream getOutputStream() throws IOException {
 
         try {
@@ -908,30 +903,28 @@
 
             URI uri = ParseUtil.toURI(url);
             if (uri != null) {
-                Map cookies = cookieHandler.get(uri, requests.getHeaders(EXCLUDE_HEADERS));
+                Map<String, List<String>> cookies
+                    = cookieHandler.get(
+                        uri, requests.getHeaders(EXCLUDE_HEADERS));
                 if (!cookies.isEmpty()) {
-                    Set s = cookies.entrySet();
-                    Iterator k_itr = s.iterator();
-                    while (k_itr.hasNext()) {
-                        Map.Entry entry = (Map.Entry)k_itr.next();
-                        String key = (String)entry.getKey();
+                    for (Map.Entry<String, List<String>> entry :
+                             cookies.entrySet()) {
+                        String key = entry.getKey();
                         // ignore all entries that don't have "Cookie"
                         // or "Cookie2" as keys
                         if (!"Cookie".equalsIgnoreCase(key) &&
                             !"Cookie2".equalsIgnoreCase(key)) {
                             continue;
                         }
-                        List l = (List)entry.getValue();
+                        List<String> l = entry.getValue();
                         if (l != null && !l.isEmpty()) {
-                            Iterator v_itr = l.iterator();
                             StringBuilder cookieValue = new StringBuilder();
-                            while (v_itr.hasNext()) {
-                                String value = (String)v_itr.next();
-                                cookieValue.append(value).append(';');
+                            for (String value : l) {
+                                cookieValue.append(value).append("; ");
                             }
-                            // strip off the ending ;-sign
+                            // strip off the trailing '; '
                             try {
-                                requests.add(key, cookieValue.substring(0, cookieValue.length() - 1));
+                                requests.add(key, cookieValue.substring(0, cookieValue.length() - 2));
                             } catch (StringIndexOutOfBoundsException ignored) {
                                 // no-op
                             }
@@ -950,6 +943,8 @@
         } // end of getting cookies
     }
 
+    @Override
+    @SuppressWarnings("empty-statement")
     public synchronized InputStream getInputStream() throws IOException {
 
         if (!doInput) {
@@ -1363,29 +1358,27 @@
      * original exception and with the same message. Right now,
      * there is no convenient APIs for doing so.
      */
-    private IOException getChainedException(IOException rememberedException) {
+    private IOException getChainedException(final IOException rememberedException) {
         try {
-            final IOException originalException = rememberedException;
-            final Class[] cls = new Class[1];
-            cls[0] = String.class;
-            final String[] args = new String[1];
-            args[0] = originalException.getMessage();
-            IOException chainedException = (IOException)
-                java.security.AccessController.doPrivileged
-                (new java.security.PrivilegedExceptionAction() {
-                        public Object run()
-                            throws Exception {
-                            Constructor ctr = originalException.getClass().getConstructor(cls);
-                            return (IOException)ctr.newInstance((Object[])args);
+            final Object[] args = { rememberedException.getMessage() };
+            IOException chainedException =
+                java.security.AccessController.doPrivileged(
+                    new java.security.PrivilegedExceptionAction<IOException>() {
+                        public IOException run() throws Exception {
+                            return (IOException)
+                                rememberedException.getClass()
+                                .getConstructor(new Class[] { String.class })
+                                .newInstance(args);
                         }
                     });
-            chainedException.initCause(originalException);
+            chainedException.initCause(rememberedException);
             return chainedException;
         } catch (Exception ignored) {
             return rememberedException;
         }
     }
 
+    @Override
     public InputStream getErrorStream() {
         if (connected && responseCode >= 400) {
             // Client Error 4xx and Server Error 5xx
@@ -1629,10 +1622,9 @@
                     InetAddress addr = null;
                     try {
                         final String finalHost = host;
-                        addr = (InetAddress)
-                            java.security.AccessController.doPrivileged
-                                (new java.security.PrivilegedExceptionAction() {
-                                public Object run()
+                        addr = java.security.AccessController.doPrivileged(
+                            new java.security.PrivilegedExceptionAction<InetAddress>() {
+                                public InetAddress run()
                                     throws java.net.UnknownHostException {
                                     return InetAddress.getByName(finalHost);
                                 }
@@ -2054,6 +2046,7 @@
      */
     private void disconnectInternal() {
         responseCode = -1;
+        inputStream = null;
         if (pi != null) {
             pi.finishTracking();
             pi = null;
@@ -2152,6 +2145,7 @@
      * Gets a header field by name. Returns null if not known.
      * @param name the name of the header field
      */
+    @Override
     public String getHeaderField(String name) {
         try {
             getInputStream();
@@ -2174,7 +2168,8 @@
      * @return a Map of header fields
      * @since 1.4
      */
-    public Map getHeaderFields() {
+    @Override
+    public Map<String, List<String>> getHeaderFields() {
         try {
             getInputStream();
         } catch (IOException e) {}
@@ -2190,6 +2185,7 @@
      * Gets a header field by index. Returns null if not known.
      * @param n the index of the header field
      */
+    @Override
     public String getHeaderField(int n) {
         try {
             getInputStream();
@@ -2205,6 +2201,7 @@
      * Gets a header field by index. Returns null if not known.
      * @param n the index of the header field
      */
+    @Override
     public String getHeaderFieldKey(int n) {
         try {
             getInputStream();
@@ -2222,6 +2219,7 @@
      * exists, overwrite its value with the new value.
      * @param value the value to be set
      */
+    @Override
     public void setRequestProperty(String key, String value) {
         if (connected)
             throw new IllegalStateException("Already connected");
@@ -2243,6 +2241,7 @@
      * @see #getRequestProperties(java.lang.String)
      * @since 1.4
      */
+    @Override
     public void addRequestProperty(String key, String value) {
         if (connected)
             throw new IllegalStateException("Already connected");
@@ -2262,6 +2261,7 @@
         requests.set(key, value);
     }
 
+    @Override
     public String getRequestProperty (String key) {
         // don't return headers containing security sensitive information
         if (key != null) {
@@ -2286,7 +2286,8 @@
      * @throws IllegalStateException if already connected
      * @since 1.4
      */
-    public Map getRequestProperties() {
+    @Override
+    public Map<String, List<String>> getRequestProperties() {
         if (connected)
             throw new IllegalStateException("Already connected");
 
@@ -2294,6 +2295,7 @@
         return requests.getHeaders(EXCLUDE_HEADERS);
     }
 
+    @Override
     public void setConnectTimeout(int timeout) {
         if (timeout < 0)
             throw new IllegalArgumentException("timeouts can't be negative");
@@ -2313,6 +2315,7 @@
      * @see java.net.URLConnection#connect()
      * @since 1.5
      */
+    @Override
     public int getConnectTimeout() {
         return (connectTimeout < 0 ? 0 : connectTimeout);
     }
@@ -2337,6 +2340,7 @@
      * @see java.io.InputStream#read()
      * @since 1.5
      */
+    @Override
     public void setReadTimeout(int timeout) {
         if (timeout < 0)
             throw new IllegalArgumentException("timeouts can't be negative");
@@ -2354,10 +2358,12 @@
      * @see java.io.InputStream#read()
      * @since 1.5
      */
+    @Override
     public int getReadTimeout() {
         return readTimeout < 0 ? 0 : readTimeout;
     }
 
+    @Override
     protected void finalize() {
         // this should do nothing.  The stream finalizer will close
         // the fd
@@ -2367,20 +2373,15 @@
         return method;
     }
 
-    private MessageHeader mapToMessageHeader(Map map) {
+    private MessageHeader mapToMessageHeader(Map<String, List<String>> map) {
         MessageHeader headers = new MessageHeader();
         if (map == null || map.isEmpty()) {
             return headers;
         }
-        Set entries = map.entrySet();
-        Iterator itr1 = entries.iterator();
-        while (itr1.hasNext()) {
-            Map.Entry entry = (Map.Entry)itr1.next();
-            String key = (String)entry.getKey();
-            List values = (List)entry.getValue();
-            Iterator itr2 = values.iterator();
-            while (itr2.hasNext()) {
-                String value = (String)itr2.next();
+        for (Map.Entry<String, List<String>> entry : map.entrySet()) {
+            String key = entry.getKey();
+            List<String> values = entry.getValue();
+            for (String value : values) {
                 if (key == null) {
                     headers.prepend(key, value);
                 } else {
@@ -2437,6 +2438,7 @@
          * @see     java.io.FilterInputStream#in
          * @see     java.io.FilterInputStream#reset()
          */
+        @Override
         public synchronized void mark(int readlimit) {
             super.mark(readlimit);
             if (cacheRequest != null) {
@@ -2466,6 +2468,7 @@
          * @see        java.io.FilterInputStream#in
          * @see        java.io.FilterInputStream#mark(int)
          */
+        @Override
         public synchronized void reset() throws IOException {
             super.reset();
             if (cacheRequest != null) {
@@ -2474,6 +2477,7 @@
             }
         }
 
+        @Override
         public int read() throws IOException {
             try {
                 byte[] b = new byte[1];
@@ -2487,10 +2491,12 @@
             }
         }
 
+        @Override
         public int read(byte[] b) throws IOException {
             return read(b, 0, b.length);
         }
 
+        @Override
         public int read(byte[] b, int off, int len) throws IOException {
             try {
                 int newLen = super.read(b, off, len);
@@ -2521,6 +2527,7 @@
             }
         }
 
+        @Override
         public void close () throws IOException {
             try {
                 if (outputStream != null) {
@@ -2565,6 +2572,7 @@
             error = false;
         }
 
+        @Override
         public void write (int b) throws IOException {
             checkError();
             written ++;
@@ -2574,10 +2582,12 @@
             out.write (b);
         }
 
+        @Override
         public void write (byte[] b) throws IOException {
             write (b, 0, b.length);
         }
 
+        @Override
         public void write (byte[] b, int off, int len) throws IOException {
             checkError();
             written += len;
@@ -2608,6 +2618,7 @@
             return closed && ! error;
         }
 
+        @Override
         public void close () throws IOException {
             if (closed) {
                 return;
@@ -2726,6 +2737,7 @@
             }
         }
 
+        @Override
         public int available() throws IOException {
             if (is == null) {
                 return buffer.remaining();
@@ -2740,10 +2752,12 @@
             return (ret == -1? ret : (b[0] & 0x00FF));
         }
 
+        @Override
         public int read(byte[] b) throws IOException {
             return read(b, 0, b.length);
         }
 
+        @Override
         public int read(byte[] b, int off, int len) throws IOException {
             int rem = buffer.remaining();
             if (rem > 0) {
@@ -2759,6 +2773,7 @@
             }
         }
 
+        @Override
         public void close() throws IOException {
             buffer = null;
             if (is != null) {
@@ -2775,6 +2790,7 @@
 
 class EmptyInputStream extends InputStream {
 
+    @Override
     public int available() {
         return 0;
     }
--- a/src/share/classes/sun/net/www/protocol/https/HttpsClient.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/www/protocol/https/HttpsClient.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -518,6 +518,16 @@
         kac.put(url, sslSocketFactory, this);
     }
 
+    /*
+     * Close an idle connection to this URL (if it exists in the cache).
+     */
+    public void closeIdleConnection() {
+        HttpClient http = (HttpClient) kac.get(url, sslSocketFactory);
+        if (http != null) {
+            http.closeServer();
+        }
+    }
+
     /**
      * Returns the cipher suite in use on this connection.
      */
--- a/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java	Mon Apr 14 11:34:15 2008 -0700
@@ -55,7 +55,7 @@
 
     private Manifest superMan;
     private Attributes superAttr;
-    private Map superEntries;
+    private Map<String, Attributes> superEntries;
 
     static JarFile getJarFile(URL url) throws IOException {
         return getJarFile(url, null);
@@ -146,12 +146,10 @@
 
         // now deep copy the manifest entries
         if (superEntries != null) {
-            Map entries = man.getEntries();
-            Iterator it = superEntries.keySet().iterator();
-            while (it.hasNext()) {
-                Object key = it.next();
-                Attributes at = (Attributes)superEntries.get(key);
-                entries.put(key, at.clone());
+            Map<String, Attributes> entries = man.getEntries();
+            for (String key : superEntries.keySet()) {
+                Attributes at = superEntries.get(key);
+                entries.put(key, (Attributes) at.clone());
             }
         }
 
@@ -213,9 +211,9 @@
             final InputStream in =  url.openConnection().getInputStream();
 
             try {
-                result = (JarFile)
-                    AccessController.doPrivileged(new PrivilegedExceptionAction() {
-                        public Object run() throws IOException {
+                result = AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<JarFile>() {
+                        public JarFile run() throws IOException {
                             OutputStream out = null;
                             File tmpFile = null;
                             try {
@@ -273,9 +271,9 @@
 
         public Attributes getAttributes() throws IOException {
             if (URLJarFile.this.isSuperMan()) {
-                Map e = URLJarFile.this.superEntries;
+                Map<String, Attributes> e = URLJarFile.this.superEntries;
                 if (e != null) {
-                    Attributes a = (Attributes)e.get(getName());
+                    Attributes a = e.get(getName());
                     if (a != null)
                         return  (Attributes)a.clone();
                 }
--- a/src/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java	Mon Apr 14 11:34:15 2008 -0700
@@ -29,9 +29,6 @@
 import java.net.InetAddress;
 import java.net.SocketPermission;
 import java.io.*;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.StringTokenizer;
 import java.security.Permission;
 import sun.net.www.*;
 import sun.net.smtp.SmtpClient;
@@ -86,11 +83,11 @@
     }
 
     public void connect() throws IOException {
-        System.err.println("connect. Timeout = " + connectTimeout);
         client = new SmtpClient(connectTimeout);
         client.setReadTimeout(readTimeout);
     }
 
+    @Override
     public synchronized OutputStream getOutputStream() throws IOException {
         if (os != null) {
             return os;
@@ -107,6 +104,7 @@
         return os;
     }
 
+    @Override
     public Permission getPermission() throws IOException {
         if (permission == null) {
             connect();
@@ -116,22 +114,26 @@
         return permission;
     }
 
+    @Override
     public void setConnectTimeout(int timeout) {
         if (timeout < 0)
             throw new IllegalArgumentException("timeouts can't be negative");
         connectTimeout = timeout;
     }
 
+    @Override
     public int getConnectTimeout() {
         return (connectTimeout < 0 ? 0 : connectTimeout);
     }
 
+    @Override
     public void setReadTimeout(int timeout) {
         if (timeout < 0)
             throw new IllegalArgumentException("timeouts can't be negative");
         readTimeout = timeout;
     }
 
+    @Override
     public int getReadTimeout() {
         return readTimeout < 0 ? 0 : readTimeout;
     }
--- a/src/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/nio/ch/FileChannelImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -52,39 +52,37 @@
 {
 
     // Used to make native read and write calls
-    private static NativeDispatcher nd;
+    private static final NativeDispatcher nd;
 
     // Memory allocation size for mapping buffers
-    private static long allocationGranularity;
+    private static final long allocationGranularity;
 
     // Cached field for MappedByteBuffer.isAMappedBuffer
-    private static Field isAMappedBufferField;
+    private static final Field isAMappedBufferField;
 
     // File descriptor
-    private FileDescriptor fd;
+    private final FileDescriptor fd;
 
     // File access mode (immutable)
-    private boolean writable;
-    private boolean readable;
-    private boolean appending;
+    private final boolean writable;
+    private final boolean readable;
 
     // Required to prevent finalization of creating stream (immutable)
-    private Object parent;
+    private final Object parent;
 
     // Thread-safe set of IDs of native threads, for signalling
-    private NativeThreadSet threads = new NativeThreadSet(2);
+    private final NativeThreadSet threads = new NativeThreadSet(2);
 
     // Lock for operations involving position and size
-    private Object positionLock = new Object();
+    private final Object positionLock = new Object();
 
     private FileChannelImpl(FileDescriptor fd, boolean readable,
-                            boolean writable, Object parent, boolean append)
+                            boolean writable, Object parent)
     {
         this.fd = fd;
         this.readable = readable;
         this.writable = writable;
         this.parent = parent;
-        this.appending = append;
     }
 
     // Invoked by getChannel() methods
@@ -94,14 +92,7 @@
                                    boolean readable, boolean writable,
                                    Object parent)
     {
-        return new FileChannelImpl(fd, readable, writable, parent, false);
-    }
-
-    public static FileChannel open(FileDescriptor fd,
-                                   boolean readable, boolean writable,
-                                   Object parent, boolean append)
-    {
-        return new FileChannelImpl(fd, readable, writable, parent, append);
+        return new FileChannelImpl(fd, readable, writable, parent);
     }
 
     private void ensureOpen() throws IOException {
@@ -134,15 +125,7 @@
             // superclass AbstractInterruptibleChannel, but the isOpen logic in
             // that method will prevent this method from being reinvoked.
             //
-            if (parent instanceof FileInputStream)
-                ((FileInputStream)parent).close();
-            else if (parent instanceof FileOutputStream)
-                ((FileOutputStream)parent).close();
-            else if (parent instanceof RandomAccessFile)
-                ((RandomAccessFile)parent).close();
-            else
-                assert false;
-
+            ((java.io.Closeable)parent).close();
         } else {
             nd.close(fd);
         }
@@ -218,8 +201,6 @@
                 if (!isOpen())
                     return 0;
                 ti = threads.add();
-                if (appending)
-                    position(size());
                 do {
                     n = IOUtil.write(fd, src, -1, nd, positionLock);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
@@ -244,8 +225,6 @@
                 if (!isOpen())
                     return 0;
                 ti = threads.add();
-                if (appending)
-                    position(size());
                 do {
                     n = IOUtil.write(fd, srcs, nd);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
@@ -1051,7 +1030,7 @@
         private FileKey fileKey;
 
         FileLockReference(FileLock referent,
-                          ReferenceQueue queue,
+                          ReferenceQueue<FileLock> queue,
                           FileKey key) {
             super(referent, queue);
             this.fileKey = key;
@@ -1073,7 +1052,7 @@
             new ConcurrentHashMap<FileKey, ArrayList<FileLockReference>>();
 
         // reference queue for cleared refs
-        private static ReferenceQueue queue = new ReferenceQueue();
+        private static ReferenceQueue<FileLock> queue = new ReferenceQueue<FileLock>();
 
         // the enclosing file channel
         private FileChannelImpl fci;
--- a/src/share/classes/sun/nio/ch/Reflect.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/nio/ch/Reflect.java	Mon Apr 14 11:34:15 2008 -0700
@@ -43,8 +43,8 @@
     }
 
     private static void setAccessible(final AccessibleObject ao) {
-        AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
                     ao.setAccessible(true);
                     return null;
                 }});
@@ -54,7 +54,7 @@
                                          Class[] paramTypes)
     {
         try {
-            Class cl = Class.forName(className);
+            Class<?> cl = Class.forName(className);
             Constructor c = cl.getDeclaredConstructor(paramTypes);
             setAccessible(c);
             return c;
@@ -82,7 +82,7 @@
                                Class[] paramTypes)
     {
         try {
-            Class cl = Class.forName(className);
+            Class<?> cl = Class.forName(className);
             Method m = cl.getDeclaredMethod(methodName, paramTypes);
             setAccessible(m);
             return m;
--- a/src/share/classes/sun/nio/ch/SocketAdaptor.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/nio/ch/SocketAdaptor.java	Mon Apr 14 11:34:15 2008 -0700
@@ -242,9 +242,9 @@
             throw new SocketException("Socket input is shutdown");
         if (socketInputStream == null) {
             try {
-                socketInputStream = (InputStream)AccessController.doPrivileged(
-                    new PrivilegedExceptionAction() {
-                        public Object run() throws IOException {
+                socketInputStream = AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<InputStream>() {
+                        public InputStream run() throws IOException {
                             return new SocketInputStream();
                         }
                     });
@@ -264,9 +264,9 @@
             throw new SocketException("Socket output is shutdown");
         OutputStream os = null;
         try {
-            os = (OutputStream)
-                AccessController.doPrivileged(new PrivilegedExceptionAction() {
-                    public Object run() throws IOException {
+            os = AccessController.doPrivileged(
+                new PrivilegedExceptionAction<OutputStream>() {
+                    public OutputStream run() throws IOException {
                         return Channels.newOutputStream(sc);
                     }
                 });
--- a/src/share/classes/sun/nio/ch/Util.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/nio/ch/Util.java	Mon Apr 14 11:34:15 2008 -0700
@@ -49,20 +49,21 @@
     private static final int TEMP_BUF_POOL_SIZE = 3;
 
     // Per-thread soft cache of the last temporary direct buffer
-    private static ThreadLocal[] bufferPool;
+    private static ThreadLocal<SoftReference<ByteBuffer>>[] bufferPool;
 
     static {
-        bufferPool = new ThreadLocal[TEMP_BUF_POOL_SIZE];
+        bufferPool = (ThreadLocal<SoftReference<ByteBuffer>>[])
+            new ThreadLocal[TEMP_BUF_POOL_SIZE];
         for (int i=0; i<TEMP_BUF_POOL_SIZE; i++)
-            bufferPool[i] = new ThreadLocal();
+            bufferPool[i] = new ThreadLocal<SoftReference<ByteBuffer>>();
     }
 
     static ByteBuffer getTemporaryDirectBuffer(int size) {
         ByteBuffer buf = null;
         // Grab a buffer if available
         for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
-            SoftReference ref = (SoftReference)(bufferPool[i].get());
-            if ((ref != null) && ((buf = (ByteBuffer)ref.get()) != null) &&
+            SoftReference<ByteBuffer> ref = bufferPool[i].get();
+            if ((ref != null) && ((buf = ref.get()) != null) &&
                 (buf.capacity() >= size)) {
                 buf.rewind();
                 buf.limit(size);
@@ -80,18 +81,18 @@
             return;
         // Put it in an empty slot if such exists
         for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
-            SoftReference ref = (SoftReference)(bufferPool[i].get());
+            SoftReference<ByteBuffer> ref = bufferPool[i].get();
             if ((ref == null) || (ref.get() == null)) {
-                bufferPool[i].set(new SoftReference(buf));
+                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 ref = (SoftReference)(bufferPool[i].get());
-            ByteBuffer inCacheBuf = (ByteBuffer)ref.get();
+            SoftReference<ByteBuffer> ref = bufferPool[i].get();
+            ByteBuffer inCacheBuf = ref.get();
             if ((inCacheBuf == null) || (buf.capacity() > inCacheBuf.capacity())) {
-                bufferPool[i].set(new SoftReference(buf));
+                bufferPool[i].set(new SoftReference<ByteBuffer>(buf));
                 return;
             }
         }
@@ -120,10 +121,12 @@
     }
 
     // Per-thread cached selector
-    private static ThreadLocal localSelector = new ThreadLocal();
+    private static ThreadLocal<SoftReference<SelectorWrapper>> localSelector
+        = new ThreadLocal<SoftReference<SelectorWrapper>>();
     // Hold a reference to the selWrapper object to prevent it from
     // being cleaned when the temporary selector wrapped is on lease.
-    private static ThreadLocal localSelectorWrapper = new ThreadLocal();
+    private static ThreadLocal<SelectorWrapper> localSelectorWrapper
+        = new ThreadLocal<SelectorWrapper>();
 
     // When finished, invoker must ensure that selector is empty
     // by cancelling any related keys and explicitly releasing
@@ -131,15 +134,16 @@
     static Selector getTemporarySelector(SelectableChannel sc)
         throws IOException
     {
-        SoftReference ref = (SoftReference)localSelector.get();
+        SoftReference<SelectorWrapper> ref = localSelector.get();
         SelectorWrapper selWrapper = null;
         Selector sel = null;
         if (ref == null
-            || ((selWrapper = (SelectorWrapper) ref.get()) == null)
+            || ((selWrapper = ref.get()) == null)
             || ((sel = selWrapper.get()) == null)
             || (sel.provider() != sc.provider())) {
             sel = sc.provider().openSelector();
-            localSelector.set(new SoftReference(new SelectorWrapper(sel)));
+            localSelector.set(new SoftReference<SelectorWrapper>(
+                                  new SelectorWrapper(sel)));
         } else {
             localSelectorWrapper.set(selWrapper);
         }
@@ -235,10 +239,10 @@
     private static volatile Constructor directByteBufferConstructor = null;
 
     private static void initDBBConstructor() {
-        AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
                     try {
-                        Class cl = Class.forName("java.nio.DirectByteBuffer");
+                        Class<?> cl = Class.forName("java.nio.DirectByteBuffer");
                         Constructor ctor = cl.getDeclaredConstructor(
                             new Class[] { int.class,
                                           long.class,
@@ -282,10 +286,10 @@
     private static volatile Constructor directByteBufferRConstructor = null;
 
     private static void initDBBRConstructor() {
-        AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
                     try {
-                        Class cl = Class.forName("java.nio.DirectByteBufferR");
+                        Class<?> cl = Class.forName("java.nio.DirectByteBufferR");
                         Constructor ctor = cl.getDeclaredConstructor(
                             new Class[] { int.class,
                                           long.class,
--- a/src/share/classes/sun/reflect/ClassDefiner.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/reflect/ClassDefiner.java	Mon Apr 14 11:34:15 2008 -0700
@@ -54,9 +54,9 @@
     static Class defineClass(String name, byte[] bytes, int off, int len,
                              final ClassLoader parentClassLoader)
     {
-        ClassLoader newLoader = (ClassLoader)
-            AccessController.doPrivileged(new PrivilegedAction() {
-                    public Object run() {
+        ClassLoader newLoader = AccessController.doPrivileged(
+            new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
                         return new DelegatingClassLoader(parentClassLoader);
                     }
                 });
--- a/src/share/classes/sun/reflect/MethodAccessorGenerator.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/reflect/MethodAccessorGenerator.java	Mon Apr 14 11:34:15 2008 -0700
@@ -392,11 +392,12 @@
         // same namespace as the target class. Since the generated code
         // is privileged anyway, the protection domain probably doesn't
         // matter.
-        return (MagicAccessorImpl)
-            AccessController.doPrivileged(new PrivilegedAction() {
-                    public Object run() {
+        return AccessController.doPrivileged(
+            new PrivilegedAction<MagicAccessorImpl>() {
+                public MagicAccessorImpl run() {
                         try {
-                            return ClassDefiner.defineClass
+                        return (MagicAccessorImpl)
+                        ClassDefiner.defineClass
                                 (generatedName,
                                  bytes,
                                  0,
--- a/src/share/classes/sun/reflect/ReflectionFactory.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/reflect/ReflectionFactory.java	Mon Apr 14 11:34:15 2008 -0700
@@ -84,8 +84,8 @@
      * <code>AccessController.doPrivileged</code>.
      */
     public static final class GetReflectionFactoryAction
-        implements PrivilegedAction {
-        public Object run() {
+        implements PrivilegedAction<ReflectionFactory> {
+        public ReflectionFactory run() {
             return getReflectionFactory();
         }
     }
@@ -164,7 +164,7 @@
     public ConstructorAccessor newConstructorAccessor(Constructor c) {
         checkInitted();
 
-        Class declaringClass = c.getDeclaringClass();
+        Class<?> declaringClass = c.getDeclaringClass();
         if (Modifier.isAbstract(declaringClass.getModifiers())) {
             return new InstantiationExceptionConstructorAccessorImpl(null);
         }
@@ -204,9 +204,9 @@
 
     /** Creates a new java.lang.reflect.Field. Access checks as per
         java.lang.reflect.AccessibleObject are not overridden. */
-    public Field newField(Class declaringClass,
+    public Field newField(Class<?> declaringClass,
                           String name,
-                          Class type,
+                          Class<?> type,
                           int modifiers,
                           int slot,
                           String signature,
@@ -223,11 +223,11 @@
 
     /** Creates a new java.lang.reflect.Method. Access checks as per
         java.lang.reflect.AccessibleObject are not overridden. */
-    public Method newMethod(Class declaringClass,
+    public Method newMethod(Class<?> declaringClass,
                             String name,
-                            Class[] parameterTypes,
-                            Class returnType,
-                            Class[] checkedExceptions,
+                            Class<?>[] parameterTypes,
+                            Class<?> returnType,
+                            Class<?>[] checkedExceptions,
                             int modifiers,
                             int slot,
                             String signature,
@@ -250,9 +250,9 @@
 
     /** Creates a new java.lang.reflect.Constructor. Access checks as
         per java.lang.reflect.AccessibleObject are not overridden. */
-    public Constructor newConstructor(Class declaringClass,
-                                      Class[] parameterTypes,
-                                      Class[] checkedExceptions,
+    public Constructor newConstructor(Class<?> declaringClass,
+                                      Class<?>[] parameterTypes,
+                                      Class<?>[] checkedExceptions,
                                       int modifiers,
                                       int slot,
                                       String signature,
@@ -310,7 +310,7 @@
     /** Makes a copy of the passed constructor. The returned
         constructor is a "child" of the passed one; see the comments
         in Constructor.java for details. */
-    public Constructor copyConstructor(Constructor arg) {
+    public <T> Constructor<T> copyConstructor(Constructor<T> arg) {
         return langReflectAccess().copyConstructor(arg);
     }
 
@@ -321,7 +321,7 @@
     //
 
     public Constructor newConstructorForSerialization
-        (Class classToInstantiate, Constructor constructorToCall)
+        (Class<?> classToInstantiate, Constructor constructorToCall)
     {
         // Fast path
         if (constructorToCall.getDeclaringClass() == classToInstantiate) {
@@ -366,8 +366,9 @@
         run, before the system properties are set up. */
     private static void checkInitted() {
         if (initted) return;
-        AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+        AccessController.doPrivileged(
+            new PrivilegedAction<Void>() {
+                public Void run() {
                     // Tests to ensure the system properties table is fully
                     // initialized. This is needed because reflection code is
                     // called very early in the initialization process (before
--- a/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java	Mon Apr 14 11:34:15 2008 -0700
@@ -273,8 +273,8 @@
     private Method[] getMemberMethods() {
         if (memberMethods == null) {
             final Method[] mm = type.getDeclaredMethods();
-            AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
                     AccessibleObject.setAccessible(mm, true);
                     return null;
                 }
--- a/src/share/classes/sun/reflect/misc/MethodUtil.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/reflect/misc/MethodUtil.java	Mon Apr 14 11:34:15 2008 -0700
@@ -67,7 +67,7 @@
         super();
     }
 
-    public static Method getMethod(Class cls, String name, Class[] args)
+    public static Method getMethod(Class<?> cls, String name, Class[] args)
         throws NoSuchMethodException {
         ReflectUtil.checkPackageAccess(cls);
         return cls.getMethod(name, args);
@@ -89,7 +89,7 @@
         if (System.getSecurityManager() == null) {
             return cls.getMethods();
         }
-        Map sigs = new HashMap();
+        Map<Signature, Method> sigs = new HashMap<Signature, Method>();
         while (cls != null) {
             boolean done = getInternalPublicMethods(cls, sigs);
             if (done) {
@@ -98,14 +98,14 @@
             getInterfaceMethods(cls, sigs);
             cls = cls.getSuperclass();
         }
-        Collection c = sigs.values();
-        return (Method[]) c.toArray(new Method[c.size()]);
+        return sigs.values().toArray(new Method[sigs.size()]);
     }
 
     /*
      * Process the immediate interfaces of this class or interface.
      */
-    private static void getInterfaceMethods(Class cls, Map sigs) {
+    private static void getInterfaceMethods(Class cls,
+                                            Map<Signature, Method> sigs) {
         Class[] intfs = cls.getInterfaces();
         for (int i=0; i < intfs.length; i++) {
             Class intf = intfs[i];
@@ -120,7 +120,8 @@
      *
      * Process the methods in this class or interface
      */
-    private static boolean getInternalPublicMethods(Class cls, Map sigs) {
+    private static boolean getInternalPublicMethods(Class cls,
+                                                    Map<Signature, Method> sigs) {
         Method[] methods = null;
         try {
             /*
@@ -178,7 +179,7 @@
         return done;
     }
 
-    private static void addMethod(Map sigs, Method method) {
+    private static void addMethod(Map<Signature, Method> sigs, Method method) {
         Signature signature = new Signature(method);
         if (!sigs.containsKey(signature)) {
             sigs.put(signature, method);
@@ -186,7 +187,7 @@
             /*
              * Superclasses beat interfaces.
              */
-            Method old = (Method)sigs.get(signature);
+            Method old = sigs.get(signature);
             if (old.getDeclaringClass().isInterface()) {
                 sigs.put(signature, method);
             }
@@ -280,17 +281,15 @@
     }
 
     private static Method getTrampoline() {
-        Method tramp = null;
-
         try {
-            tramp = (Method) AccessController.doPrivileged(new PrivilegedExceptionAction() {
-                public Object run() throws Exception {
-                    Class[] types;
-                    Class t = getTrampolineClass();
-                    Method b;
-
-                    types = new Class[] {Method.class, Object.class, Object[].class};
-                    b = t.getDeclaredMethod("invoke", types);
+            return AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Method>() {
+                    public Method run() throws Exception {
+                        Class<?> t = getTrampolineClass();
+                        Class[] types = {
+                            Method.class, Object.class, Object[].class
+                        };
+                        Method b = t.getDeclaredMethod("invoke", types);
                     ((AccessibleObject)b).setAccessible(true);
                     return b;
                 }
@@ -298,7 +297,6 @@
         } catch (Exception e) {
             throw new InternalError("bouncer cannot be found");
         }
-        return tramp;
     }
 
 
--- a/src/share/classes/sun/rmi/log/ReliableLog.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/log/ReliableLog.java	Mon Apr 14 11:34:15 2008 -0700
@@ -140,8 +140,8 @@
         throws IOException
     {
         super();
-        this.Debug = ((Boolean) AccessController.doPrivileged(
-            new GetBooleanAction("sun.rmi.log.debug"))).booleanValue();
+        this.Debug = AccessController.doPrivileged(
+            new GetBooleanAction("sun.rmi.log.debug")).booleanValue();
         dir = new File(dirPath);
         if (!(dir.exists() && dir.isDirectory())) {
             // create directory
@@ -333,8 +333,8 @@
     private static Constructor<? extends LogFile>
         getLogClassConstructor() {
 
-        String logClassName =  ((String) AccessController.doPrivileged(
-            new GetPropertyAction("sun.rmi.log.class")));
+        String logClassName = AccessController.doPrivileged(
+            new GetPropertyAction("sun.rmi.log.class"));
         if (logClassName != null) {
             try {
                 ClassLoader loader =
--- a/src/share/classes/sun/rmi/registry/RegistryImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/registry/RegistryImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -66,8 +66,10 @@
 
     /* indicate compatibility with JDK 1.1.x version of class */
     private static final long serialVersionUID = 4666870661827494597L;
-    private Hashtable bindings = new Hashtable(101);
-    private static Hashtable allowedAccessCache = new Hashtable(3);
+    private Hashtable<String, Remote> bindings
+        = new Hashtable<String, Remote>(101);
+    private static Hashtable<InetAddress, InetAddress> allowedAccessCache
+        = new Hashtable<InetAddress, InetAddress>(3);
     private static RegistryImpl registry;
     private static ObjID id = new ObjID(ObjID.REGISTRY_ID);
 
@@ -119,7 +121,7 @@
         throws RemoteException, NotBoundException
     {
         synchronized (bindings) {
-            Remote obj = (Remote)bindings.get(name);
+            Remote obj = bindings.get(name);
             if (obj == null)
                 throw new NotBoundException(name);
             return obj;
@@ -136,7 +138,7 @@
     {
         checkAccess("Registry.bind");
         synchronized (bindings) {
-            Remote curr = (Remote)bindings.get(name);
+            Remote curr = bindings.get(name);
             if (curr != null)
                 throw new AlreadyBoundException(name);
             bindings.put(name, obj);
@@ -153,7 +155,7 @@
     {
         checkAccess("Registry.unbind");
         synchronized (bindings) {
-            Remote obj = (Remote)bindings.get(name);
+            Remote obj = bindings.get(name);
             if (obj == null)
                 throw new NotBoundException(name);
             bindings.remove(name);
@@ -203,10 +205,9 @@
             InetAddress clientHost;
 
             try {
-                clientHost = (InetAddress)
-                    java.security.AccessController.doPrivileged(
-                        new java.security.PrivilegedExceptionAction() {
-                        public Object run()
+                clientHost = java.security.AccessController.doPrivileged(
+                    new java.security.PrivilegedExceptionAction<InetAddress>() {
+                        public InetAddress run()
                             throws java.net.UnknownHostException
                         {
                             return InetAddress.getByName(clientHostName);
@@ -228,8 +229,8 @@
                     final InetAddress finalClientHost = clientHost;
 
                     java.security.AccessController.doPrivileged(
-                        new java.security.PrivilegedExceptionAction() {
-                            public Object run() throws java.io.IOException {
+                        new java.security.PrivilegedExceptionAction<Void>() {
+                            public Void run() throws java.io.IOException {
                                 /*
                                  * if a ServerSocket can be bound to the client's
                                  * address then that address must be local
--- a/src/share/classes/sun/rmi/rmic/RemoteClass.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/rmic/RemoteClass.java	Mon Apr 14 11:34:15 2008 -0700
@@ -103,7 +103,7 @@
      * in the array).
      */
     public ClassDefinition[] getRemoteInterfaces() {
-        return (ClassDefinition[]) remoteInterfaces.clone();
+        return remoteInterfaces.clone();
     }
 
     /**
@@ -118,7 +118,7 @@
      * stub/skeleton protocol.
      */
     public Method[] getRemoteMethods() {
-        return (Method[]) remoteMethods.clone();
+        return remoteMethods.clone();
     }
 
     /**
@@ -204,8 +204,8 @@
          * chain, add each directly-implemented interface that
          * somehow extends Remote to a list.
          */
-        Vector remotesImplemented =     // list of remote interfaces found
-            new Vector();
+        Vector<ClassDefinition> remotesImplemented = // list of remote interfaces found
+            new Vector<ClassDefinition>();
         for (ClassDefinition classDef = implClassDef;
              classDef != null;)
             {
@@ -307,13 +307,13 @@
          * Now we collect the methods from all of the remote interfaces
          * into a hashtable.
          */
-        Hashtable methods = new Hashtable();
+        Hashtable<String, Method> methods = new Hashtable<String, Method>();
         boolean errors = false;
-        for (Enumeration enumeration = remotesImplemented.elements();
+        for (Enumeration<ClassDefinition> enumeration
+                 = remotesImplemented.elements();
              enumeration.hasMoreElements();)
             {
-                ClassDefinition interfaceDef =
-                    (ClassDefinition) enumeration.nextElement();
+                ClassDefinition interfaceDef = enumeration.nextElement();
                 if (!collectRemoteMethods(interfaceDef, methods))
                     errors = true;
             }
@@ -336,10 +336,10 @@
          */
         String[] orderedKeys = new String[methods.size()];
         int count = 0;
-        for (Enumeration enumeration = methods.elements();
+        for (Enumeration<Method> enumeration = methods.elements();
              enumeration.hasMoreElements();)
             {
-                Method m = (Method) enumeration.nextElement();
+                Method m = enumeration.nextElement();
                 String key = m.getNameAndDescriptor();
                 int i;
                 for (i = count; i > 0; --i) {
@@ -353,7 +353,7 @@
             }
         remoteMethods = new Method[methods.size()];
         for (int i = 0; i < remoteMethods.length; i++) {
-            remoteMethods[i] = (Method) methods.get(orderedKeys[i]);
+            remoteMethods[i] = methods.get(orderedKeys[i]);
             /***** <DEBUG> */
             if (env.verbose()) {
                 System.out.print("[found remote method <" + i + ">: " +
@@ -388,7 +388,7 @@
      * or false if an error occurred.
      */
     private boolean collectRemoteMethods(ClassDefinition interfaceDef,
-                                         Hashtable table)
+                                         Hashtable<String, Method> table)
     {
         if (!interfaceDef.isInterface()) {
             throw new Error(
@@ -529,7 +529,7 @@
                          * the new method (see bugid 4070653).
                          */
                         String key = newMethod.getNameAndDescriptor();
-                        Method oldMethod = (Method) table.get(key);
+                        Method oldMethod = table.get(key);
                         if (oldMethod != null) {
                             newMethod = newMethod.mergeWith(oldMethod);
                             if (newMethod == null) {
@@ -684,7 +684,7 @@
          * methods that can be legally thrown in each of them.
          */
         public ClassDeclaration[] getExceptions() {
-            return (ClassDeclaration[]) exceptions.clone();
+            return exceptions.clone();
         }
 
         /**
@@ -789,7 +789,8 @@
                                     getNameAndDescriptor());
                 }
 
-            Vector legalExceptions = new Vector();
+            Vector<ClassDeclaration> legalExceptions
+                = new Vector<ClassDeclaration>();
             try {
                 collectCompatibleExceptions(
                                             other.exceptions, exceptions, legalExceptions);
@@ -814,7 +815,7 @@
          */
         private void collectCompatibleExceptions(ClassDeclaration[] from,
                                                  ClassDeclaration[] with,
-                                                 Vector list)
+                                                 Vector<ClassDeclaration> list)
             throws ClassNotFound
         {
             for (int i = 0; i < from.length; i++) {
--- a/src/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java	Mon Apr 14 11:34:15 2008 -0700
@@ -121,7 +121,7 @@
      * in the array).
      **/
     ClassDoc[] remoteInterfaces() {
-        return (ClassDoc[]) remoteInterfaces.clone();
+        return remoteInterfaces.clone();
     }
 
     /**
@@ -136,7 +136,7 @@
      * stub/skeleton protocol.
      **/
     Method[] remoteMethods() {
-        return (Method[]) remoteMethods.clone();
+        return remoteMethods.clone();
     }
 
     /**
@@ -559,7 +559,7 @@
          * methods that can be legally thrown by all of them.
          **/
         ClassDoc[] exceptionTypes() {
-            return (ClassDoc[]) exceptionTypes.clone();
+            return exceptionTypes.clone();
         }
 
         /**
--- a/src/share/classes/sun/rmi/runtime/Log.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/runtime/Log.java	Mon Apr 14 11:34:15 2008 -0700
@@ -71,7 +71,7 @@
     private static final LogFactory logFactory;
     static {
         boolean useOld =
-            Boolean.valueOf((String) java.security.AccessController.
+            Boolean.valueOf(java.security.AccessController.
                 doPrivileged(new sun.security.action.GetPropertyAction(
                     "sun.rmi.log.useOld"))).booleanValue();
 
@@ -179,17 +179,16 @@
     private static class LoggerLog extends Log {
 
         /* alternate console handler for RMI loggers */
-        private static final Handler alternateConsole = (Handler)
+        private static final Handler alternateConsole =
                 java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedAction() {
-                        public Object run() {
+                new java.security.PrivilegedAction<Handler>() {
+                    public Handler run() {
                             InternalStreamHandler alternate =
                                 new InternalStreamHandler(System.err);
                             alternate.setLevel(Level.ALL);
                             return alternate;
                         }
-                    }
-                );
+                });
 
         /** handler to which messages are copied */
         private InternalStreamHandler copyHandler = null;
@@ -206,8 +205,8 @@
 
             if (level != null){
                 java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedAction() {
-                        public Object run() {
+                    new java.security.PrivilegedAction<Void>() {
+                        public Void run() {
                             if (!logger.isLoggable(level)) {
                                 logger.setLevel(level);
                             }
--- a/src/share/classes/sun/rmi/server/LoaderHandler.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/server/LoaderHandler.java	Mon Apr 14 11:34:15 2008 -0700
@@ -70,7 +70,7 @@
 
     /** RMI class loader log level */
     static final int logLevel = LogStream.parseLevel(
-        (String) java.security.AccessController.doPrivileged(
+        java.security.AccessController.doPrivileged(
             new GetPropertyAction("sun.rmi.loader.logLevel")));
 
     /* loader system log */
@@ -83,7 +83,7 @@
      */
     private static String codebaseProperty = null;
     static {
-        String prop = (String) java.security.AccessController.doPrivileged(
+        String prop = java.security.AccessController.doPrivileged(
             new GetPropertyAction("java.rmi.server.codebase"));
         if (prop != null && prop.trim().length() > 0) {
             codebaseProperty = prop;
@@ -94,8 +94,8 @@
     private static URL[] codebaseURLs = null;
 
     /** table of class loaders that use codebase property for annotation */
-    private static final Map codebaseLoaders =
-        Collections.synchronizedMap(new IdentityHashMap(5));
+    private static final Map<ClassLoader, Void> codebaseLoaders =
+        Collections.synchronizedMap(new IdentityHashMap<ClassLoader, Void>(5));
     static {
         for (ClassLoader codebaseLoader = ClassLoader.getSystemClassLoader();
              codebaseLoader != null;
@@ -111,10 +111,12 @@
      * references, so this table does not prevent loaders from being
      * garbage collected.
      */
-    private static final HashMap loaderTable = new HashMap(5);
+    private static final HashMap<LoaderKey, LoaderEntry> loaderTable
+        = new HashMap<LoaderKey, LoaderEntry>(5);
 
     /** reference queue for cleared class loader entries */
-    private static final ReferenceQueue refQueue = new ReferenceQueue();
+    private static final ReferenceQueue<Loader> refQueue
+        = new ReferenceQueue<Loader>();
 
     /*
      * Disallow anyone from creating one of these.
@@ -757,7 +759,7 @@
         throws MalformedURLException
     {
         synchronized (pathToURLsCache) {
-            Object[] v = (Object[]) pathToURLsCache.get(path);
+            Object[] v = pathToURLsCache.get(path);
             if (v != null) {
                 return ((URL[])v[0]);
             }
@@ -769,13 +771,14 @@
         }
         synchronized (pathToURLsCache) {
             pathToURLsCache.put(path,
-                                new Object[] {urls, new SoftReference(path)});
+                                new Object[] {urls, new SoftReference<String>(path)});
         }
         return urls;
     }
 
     /** map from weak(key=string) to [URL[], soft(key)] */
-    private static final Map pathToURLsCache = new WeakHashMap(5);
+    private static final Map<String, Object[]> pathToURLsCache
+        = new WeakHashMap<String, Object[]>(5);
 
     /**
      * Convert an array of URL objects into a corresponding string
@@ -853,9 +856,9 @@
              * in the table of RMI class loaders.
              */
             LoaderKey key = new LoaderKey(urls, parent);
-            entry = (LoaderEntry) loaderTable.get(key);
+            entry = loaderTable.get(key);
 
-            if (entry == null || (loader = (Loader) entry.get()) == null) {
+            if (entry == null || (loader = entry.get()) == null) {
                 /*
                  * If entry was in table but it's weak reference was cleared,
                  * remove it from the table and mark it as explicitly cleared,
@@ -876,9 +879,9 @@
                  * necessary to load classes from its codebase URL path.
                  */
                 AccessControlContext acc = getLoaderAccessControlContext(urls);
-                loader = (Loader) java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedAction() {
-                        public Object run() {
+                loader = java.security.AccessController.doPrivileged(
+                    new java.security.PrivilegedAction<Loader>() {
+                        public Loader run() {
                             return new Loader(urls, parent);
                         }
                     }, acc);
@@ -954,7 +957,7 @@
      * loader key for the loader so that the mapping can be removed from
      * the table efficiently when the weak reference is cleared.
      */
-    private static class LoaderEntry extends WeakReference {
+    private static class LoaderEntry extends WeakReference<Loader> {
 
         public LoaderKey key;
 
@@ -983,10 +986,10 @@
          * getAccessControlContext() in the sun.applet.AppletPanel class.
          */
         // begin with permissions granted to all code in current policy
-        PermissionCollection perms = (PermissionCollection)
+        PermissionCollection perms =
             java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction() {
-                public Object run() {
+                new java.security.PrivilegedAction<PermissionCollection>() {
+                public PermissionCollection run() {
                     CodeSource codesource = new CodeSource(null,
                         (java.security.cert.Certificate[]) null);
                     Policy p = java.security.Policy.getPolicy();
--- a/src/share/classes/sun/rmi/server/MarshalInputStream.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/server/MarshalInputStream.java	Mon Apr 14 11:34:15 2008 -0700
@@ -59,18 +59,20 @@
      * as cached at class initialization time.
      */
     private static final boolean useCodebaseOnlyProperty =
-        ((Boolean) java.security.AccessController.doPrivileged(
+        java.security.AccessController.doPrivileged(
             new sun.security.action.GetBooleanAction(
-                "java.rmi.server.useCodebaseOnly"))).booleanValue();
+                "java.rmi.server.useCodebaseOnly")).booleanValue();
 
     /** table to hold sun classes to which access is explicitly permitted */
-    protected static Map permittedSunClasses = new HashMap(3);
+    protected static Map<String, Class<?>> permittedSunClasses
+        = new HashMap<String, Class<?>>(3);
 
     /** if true, don't try superclass first in resolveClass() */
     private boolean skipDefaultResolveClass = false;
 
     /** callbacks to make when done() called: maps Object to Runnable */
-    private final Map doneCallbacks = new HashMap(3);
+    private final Map<Object, Runnable> doneCallbacks
+        = new HashMap<Object, Runnable>(3);
 
     /**
      * if true, load classes (if not available locally) only from the
@@ -130,7 +132,7 @@
      * with that key.
      */
     public Runnable getDoneCallback(Object key) {
-        return (Runnable) doneCallbacks.get(key);       // not thread-safe
+        return doneCallbacks.get(key);                 // not thread-safe
     }
 
     /**
@@ -153,9 +155,9 @@
      * the superclass's close method.
      */
     public void done() {
-        Iterator iter = doneCallbacks.values().iterator();
+        Iterator<Runnable> iter = doneCallbacks.values().iterator();
         while (iter.hasNext()) {                        // not thread-safe
-            Runnable callback = (Runnable) iter.next();
+            Runnable callback = iter.next();
             callback.run();
         }
         doneCallbacks.clear();
@@ -276,8 +278,7 @@
             name = perm.getName();
         }
 
-        Class resolvedClass =
-            (Class) permittedSunClasses.get(className);
+        Class<?> resolvedClass = permittedSunClasses.get(className);
 
         // if class not permitted, throw the SecurityException
         if ((name == null) ||
--- a/src/share/classes/sun/rmi/server/MarshalOutputStream.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/server/MarshalOutputStream.java	Mon Apr 14 11:34:15 2008 -0700
@@ -64,8 +64,8 @@
         super(out);
         this.useProtocolVersion(protocolVersion);
         java.security.AccessController.doPrivileged(
-                                    new java.security.PrivilegedAction() {
-            public Object run() {
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
                 enableReplaceObject(true);
                 return null;
             }
--- a/src/share/classes/sun/rmi/server/Util.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/server/Util.java	Mon Apr 14 11:34:15 2008 -0700
@@ -67,7 +67,7 @@
 
     /** "server" package log level */
     static final int logLevel = LogStream.parseLevel(
-        (String) AccessController.doPrivileged(
+        AccessController.doPrivileged(
             new GetPropertyAction("sun.rmi.server.logLevel")));
 
     /** server reference log */
@@ -76,13 +76,13 @@
 
     /** cached value of property java.rmi.server.ignoreStubClasses */
     private static final boolean ignoreStubClasses =
-        ((Boolean) AccessController.doPrivileged(
-            new GetBooleanAction("java.rmi.server.ignoreStubClasses"))).
+        AccessController.doPrivileged(
+            new GetBooleanAction("java.rmi.server.ignoreStubClasses")).
             booleanValue();
 
     /** cache of  impl classes that have no corresponding stub class */
-    private static final Map withoutStubs =
-        Collections.synchronizedMap(new WeakHashMap(11));
+    private static final Map<Class<?>, Void> withoutStubs =
+        Collections.synchronizedMap(new WeakHashMap<Class<?>, Void>(11));
 
     /** parameter types for stub constructor */
     private static final Class[] stubConsParamTypes = { RemoteRef.class };
@@ -207,9 +207,9 @@
      * @throws  NullPointerException if remoteClass is null
      */
     private static Class[] getRemoteInterfaces(Class remoteClass) {
-        ArrayList list = new ArrayList();
+        ArrayList<Class<?>> list = new ArrayList<Class<?>>();
         getRemoteInterfaces(list, remoteClass);
-        return (Class []) list.toArray(new Class[list.size()]);
+        return list.toArray(new Class<?>[list.size()]);
     }
 
     /**
@@ -220,7 +220,7 @@
      *          any illegal remote interfaces
      * @throws  NullPointerException if the specified class or list is null
      */
-    private static void getRemoteInterfaces(ArrayList list, Class cl) {
+    private static void getRemoteInterfaces(ArrayList<Class<?>> list, Class cl) {
         Class superclass = cl.getSuperclass();
         if (superclass != null) {
             getRemoteInterfaces(list, superclass);
@@ -254,7 +254,7 @@
      * @throws IllegalArgumentException if m is an illegal remote method
      */
     private static void checkMethod(Method m) {
-        Class[] ex = m.getExceptionTypes();
+        Class<?>[] ex = m.getExceptionTypes();
         for (int i = 0; i < ex.length; i++) {
             if (ex[i].isAssignableFrom(RemoteException.class))
                 return;
@@ -283,7 +283,7 @@
          * pickle methods
          */
         try {
-            Class stubcl =
+            Class<?> stubcl =
                 Class.forName(stubname, false, remoteClass.getClassLoader());
             Constructor cons = stubcl.getConstructor(stubConsParamTypes);
             return (RemoteStub) cons.newInstance(new Object[] { ref });
--- a/src/share/classes/sun/rmi/server/WeakClassHashMap.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/server/WeakClassHashMap.java	Mon Apr 14 11:34:15 2008 -0700
@@ -69,7 +69,7 @@
         synchronized (valueCell) {
             V value = null;
             if (valueCell.ref != null) {
-                value = (V) valueCell.ref.get();
+                value = valueCell.ref.get();
             }
             if (value == null) {
                 value = computeValue(remoteClass);
--- a/src/share/classes/sun/rmi/transport/DGCClient.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/transport/DGCClient.java	Mon Apr 14 11:34:15 2008 -0700
@@ -85,21 +85,21 @@
 
     /** lease duration to request (usually ignored by server) */
     private static final long leaseValue =              // default 10 minutes
-        ((Long) AccessController.doPrivileged(
+        AccessController.doPrivileged(
             new GetLongAction("java.rmi.dgc.leaseValue",
-                              600000))).longValue();
+                              600000)).longValue();
 
     /** maximum interval between retries of failed clean calls */
     private static final long cleanInterval =           // default 3 minutes
-        ((Long) AccessController.doPrivileged(
+        AccessController.doPrivileged(
             new GetLongAction("sun.rmi.dgc.cleanInterval",
-                              180000))).longValue();
+                              180000)).longValue();
 
     /** maximum interval between complete garbage collections of local heap */
     private static final long gcInterval =              // default 1 hour
-        ((Long) AccessController.doPrivileged(
+        AccessController.doPrivileged(
             new GetLongAction("sun.rmi.dgc.client.gcInterval",
-                              3600000))).longValue();
+                              3600000)).longValue();
 
     /** minimum retry count for dirty calls that fail */
     private static final int dirtyFailureRetries = 5;
@@ -243,7 +243,7 @@
             } catch (RemoteException e) {
                 throw new Error("internal error creating DGC stub");
             }
-            renewCleanThread = (Thread) AccessController.doPrivileged(
+            renewCleanThread =  AccessController.doPrivileged(
                 new NewThreadAction(new RenewCleanThread(),
                                     "RenewClean-" + endpoint, true));
             renewCleanThread.start();
@@ -473,8 +473,9 @@
             if (newRenewTime < renewTime) {
                 renewTime = newRenewTime;
                 if (interruptible) {
-                    AccessController.doPrivileged(new PrivilegedAction() {
-                        public Object run() {
+                    AccessController.doPrivileged(
+                        new PrivilegedAction<Void>() {
+                            public Void run() {
                             renewCleanThread.interrupt();
                             return null;
                         }
--- a/src/share/classes/sun/rmi/transport/Target.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/transport/Target.java	Mon Apr 14 11:34:15 2008 -0700
@@ -321,7 +321,7 @@
             Remote obj = getImpl();
             if (obj instanceof Unreferenced) {
                 final Unreferenced unrefObj = (Unreferenced) obj;
-                final Thread t = (Thread)
+                final Thread t =
                     java.security.AccessController.doPrivileged(
                         new NewThreadAction(new Runnable() {
                             public void run() {
@@ -334,8 +334,8 @@
                  * for threads that may invoke user code (see bugid 4171278).
                  */
                 java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedAction() {
-                    public Object run() {
+                    new java.security.PrivilegedAction<Void>() {
+                        public Void run() {
                         t.setContextClassLoader(ccl);
                         return null;
                     }
--- a/src/share/classes/sun/rmi/transport/Transport.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/transport/Transport.java	Mon Apr 14 11:34:15 2008 -0700
@@ -53,7 +53,7 @@
     static final int logLevel = LogStream.parseLevel(getLogLevel());
 
     private static String getLogLevel() {
-        return (String) java.security.AccessController.doPrivileged(
+        return java.security.AccessController.doPrivileged(
             new sun.security.action.GetPropertyAction("sun.rmi.transport.logLevel"));
     }
 
@@ -171,8 +171,8 @@
                     currentTransport.set(this);
                     try {
                         java.security.AccessController.doPrivileged(
-                                new java.security.PrivilegedExceptionAction() {
-                            public Object run() throws IOException {
+                            new java.security.PrivilegedExceptionAction<Void>() {
+                            public Void run() throws IOException {
                                 checkAcceptPermission(acc);
                                 disp.dispatch(impl, call);
                                 return null;
--- a/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java	Mon Apr 14 11:34:15 2008 -0700
@@ -89,8 +89,8 @@
 
     static {
         java.security.AccessController.doPrivileged(
-                            new java.security.PrivilegedAction() {
-            public Object run() {
+            new java.security.PrivilegedAction<Void>() {
+            public Void run() {
                 ContentLength =
                     Integer.getInteger("CONTENT_LENGTH", 0).intValue();
                 QueryString = System.getProperty("QUERY_STRING", "");
--- a/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java	Mon Apr 14 11:34:15 2008 -0700
@@ -78,7 +78,7 @@
      * property at the moment that the socket was created.
      */
     private String lineSeparator =
-        (String) java.security.AccessController.doPrivileged(
+        java.security.AccessController.doPrivileged(
             new sun.security.action.GetPropertyAction("line.separator"));
 
     /**
--- a/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java	Mon Apr 14 11:34:15 2008 -0700
@@ -50,7 +50,7 @@
     static int logLevel = LogStream.parseLevel(getLogLevel());
 
     private static String getLogLevel() {
-        return (String) java.security.AccessController.doPrivileged(
+        return java.security.AccessController.doPrivileged(
             new sun.security.action.GetPropertyAction("sun.rmi.transport.proxy.logLevel"));
     }
 
@@ -63,15 +63,15 @@
     private static long connectTimeout = getConnectTimeout();
 
     private static long getConnectTimeout() {
-        return ((Long) java.security.AccessController.doPrivileged(
+        return java.security.AccessController.doPrivileged(
                 new GetLongAction("sun.rmi.transport.proxy.connectTimeout",
-                                  15000))).longValue(); // default: 15 seconds
+                              15000)).longValue(); // default: 15 seconds
     }
 
     /** whether to fallback to HTTP on general connect failures */
-    private static final boolean eagerHttpFallback = ((Boolean)
+    private static final boolean eagerHttpFallback =
         java.security.AccessController.doPrivileged(new GetBooleanAction(
-            "sun.rmi.transport.proxy.eagerHttpFallback"))).booleanValue();
+            "sun.rmi.transport.proxy.eagerHttpFallback")).booleanValue();
 
     /** table of hosts successfully connected to and the factory used */
     private Hashtable successTable = new Hashtable();
@@ -100,14 +100,14 @@
 
         try {
             String proxyHost;
-            proxyHost = (String) java.security.AccessController.doPrivileged(
+            proxyHost = java.security.AccessController.doPrivileged(
                 new sun.security.action.GetPropertyAction("http.proxyHost"));
 
             if (proxyHost == null)
-                proxyHost=(String)java.security.AccessController.doPrivileged(
+                proxyHost = java.security.AccessController.doPrivileged(
                     new sun.security.action.GetPropertyAction("proxyHost"));
 
-            Boolean tmp = (Boolean)java.security.AccessController.doPrivileged(
+            Boolean tmp = java.security.AccessController.doPrivileged(
                 new sun.security.action.GetBooleanAction("java.rmi.server.disableHttp"));
 
             if (!tmp.booleanValue() &&
@@ -178,10 +178,8 @@
         try {
             synchronized (connector) {
 
-                Thread t = (Thread)
-                    java.security.AccessController.doPrivileged(
-                        new NewThreadAction(connector, "AsyncConnector",
-                                            true));
+                Thread t = java.security.AccessController.doPrivileged(
+                    new NewThreadAction(connector, "AsyncConnector", true));
                 t.start();
 
                 try {
--- a/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -49,7 +49,7 @@
     static int logLevel = LogStream.parseLevel(getLogLevel());
 
     private static String getLogLevel() {
-        return (String) java.security.AccessController.doPrivileged(
+        return java.security.AccessController.doPrivileged(
             new sun.security.action.GetPropertyAction("sun.rmi.transport.tcp.multiplex.logLevel"));
     }
 
--- a/src/share/classes/sun/security/jgss/GSSManagerImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/jgss/GSSManagerImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -83,7 +83,7 @@
     public Oid[] getNamesForMech(Oid mech)
         throws GSSException {
         MechanismFactory factory = list.getMechFactory(mech);
-        return (Oid[])factory.getNameTypes().clone();
+        return factory.getNameTypes().clone();
     }
 
     public Oid[] getMechsForName(Oid nameType){
--- a/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java	Mon Apr 14 11:34:15 2008 -0700
@@ -103,8 +103,7 @@
         apReq = new KrbApReq(apReqBytes, keys, addr);
         //debug("\nReceived AP-REQ and authenticated it.\n");
 
-        EncryptionKey sessionKey
-            = (EncryptionKey) apReq.getCreds().getSessionKey();
+        EncryptionKey sessionKey = apReq.getCreds().getSessionKey();
 
         /*
           System.out.println("\n\nSession key from service ticket is: " +
--- a/src/share/classes/sun/security/krb5/Config.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/Config.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1040,11 +1040,12 @@
      * Check if need to use DNS to locate Kerberos services
      */
     public boolean useDNS(String name) {
-        boolean value = getDefaultBooleanValue(name, "libdefaults");
-        if (value == false) {
-            value = getDefaultBooleanValue("dns_fallback", "libdefaults");
+        String value = getDefault(name, "libdefaults");
+        if (value == null) {
+            return getDefaultBooleanValue("dns_fallback", "libdefaults");
+        } else {
+            return value.equalsIgnoreCase("true");
         }
-        return value;
     }
 
     /**
--- a/src/share/classes/sun/security/krb5/KrbTgsReq.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/KrbTgsReq.java	Mon Apr 14 11:34:15 2008 -0700
@@ -75,107 +75,107 @@
             null); // EncryptionKey subSessionKey
     }
 
-     // Called by Credentials, KrbCred
-         KrbTgsReq(
-                KDCOptions options,
-                Credentials asCreds,
-                PrincipalName sname,
-                KerberosTime from,
-                KerberosTime till,
-                KerberosTime rtime,
-                int[] eTypes,
-                HostAddresses addresses,
-                AuthorizationData authorizationData,
-                Ticket[] additionalTickets,
-                EncryptionKey subKey) throws KrbException, IOException {
+    // Called by Credentials, KrbCred
+    KrbTgsReq(
+            KDCOptions options,
+            Credentials asCreds,
+            PrincipalName sname,
+            KerberosTime from,
+            KerberosTime till,
+            KerberosTime rtime,
+            int[] eTypes,
+            HostAddresses addresses,
+            AuthorizationData authorizationData,
+            Ticket[] additionalTickets,
+            EncryptionKey subKey) throws KrbException, IOException {
 
-                princName = asCreds.client;
-                servName = sname;
-                ctime = new KerberosTime(KerberosTime.NOW);
+        princName = asCreds.client;
+        servName = sname;
+        ctime = new KerberosTime(KerberosTime.NOW);
 
 
-                // check if they are valid arguments. The optional fields
-                // should be  consistent with settings in KDCOptions.
-                if (options.get(KDCOptions.FORWARDABLE) &&
-                        (!(asCreds.flags.get(Krb5.TKT_OPTS_FORWARDABLE)))) {
-                    throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
-                }
-                if (options.get(KDCOptions.FORWARDED)) {
-                    if (!(asCreds.flags.get(KDCOptions.FORWARDABLE)))
-                        throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
-                }
-                if (options.get(KDCOptions.PROXIABLE) &&
-                        (!(asCreds.flags.get(Krb5.TKT_OPTS_PROXIABLE)))) {
-                    throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
-                }
-                if (options.get(KDCOptions.PROXY)) {
-                    if (!(asCreds.flags.get(KDCOptions.PROXIABLE)))
-                        throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
-                }
-                if (options.get(KDCOptions.ALLOW_POSTDATE) &&
-                        (!(asCreds.flags.get(Krb5.TKT_OPTS_MAY_POSTDATE)))) {
-                    throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
-                }
-                if (options.get(KDCOptions.RENEWABLE) &&
-                        (!(asCreds.flags.get(Krb5.TKT_OPTS_RENEWABLE)))) {
-                    throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
-                }
+        // check if they are valid arguments. The optional fields
+        // should be  consistent with settings in KDCOptions.
+        if (options.get(KDCOptions.FORWARDABLE) &&
+                (!(asCreds.flags.get(Krb5.TKT_OPTS_FORWARDABLE)))) {
+            throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
+        }
+        if (options.get(KDCOptions.FORWARDED)) {
+            if (!(asCreds.flags.get(KDCOptions.FORWARDABLE)))
+                throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
+        }
+        if (options.get(KDCOptions.PROXIABLE) &&
+                (!(asCreds.flags.get(Krb5.TKT_OPTS_PROXIABLE)))) {
+            throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
+        }
+        if (options.get(KDCOptions.PROXY)) {
+            if (!(asCreds.flags.get(KDCOptions.PROXIABLE)))
+                throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
+        }
+        if (options.get(KDCOptions.ALLOW_POSTDATE) &&
+                (!(asCreds.flags.get(Krb5.TKT_OPTS_MAY_POSTDATE)))) {
+            throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
+        }
+        if (options.get(KDCOptions.RENEWABLE) &&
+                (!(asCreds.flags.get(Krb5.TKT_OPTS_RENEWABLE)))) {
+            throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
+        }
 
-                if (options.get(KDCOptions.POSTDATED)) {
-                    if (!(asCreds.flags.get(KDCOptions.POSTDATED)))
-                        throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
-                } else {
-                    if (from != null)  from = null;
-                }
-                if (options.get(KDCOptions.RENEWABLE)) {
-                    if (!(asCreds.flags.get(KDCOptions.RENEWABLE)))
-                        throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
-                } else {
-                    if (rtime != null)  rtime = null;
-                }
-                if (options.get(KDCOptions.ENC_TKT_IN_SKEY)) {
-                    if (additionalTickets == null)
-                        throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
-                    // in TGS_REQ there could be more than one additional
-                    // tickets,  but in file-based credential cache,
-                    // there is only one additional ticket field.
-                        secondTicket = additionalTickets[0];
-                } else {
-                    if (additionalTickets != null)
-                        additionalTickets = null;
-                }
+        if (options.get(KDCOptions.POSTDATED)) {
+            if (!(asCreds.flags.get(KDCOptions.POSTDATED)))
+                throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
+        } else {
+            if (from != null)  from = null;
+        }
+        if (options.get(KDCOptions.RENEWABLE)) {
+            if (!(asCreds.flags.get(KDCOptions.RENEWABLE)))
+                throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
+        } else {
+            if (rtime != null)  rtime = null;
+        }
+        if (options.get(KDCOptions.ENC_TKT_IN_SKEY)) {
+            if (additionalTickets == null)
+                throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
+            // in TGS_REQ there could be more than one additional
+            // tickets,  but in file-based credential cache,
+            // there is only one additional ticket field.
+                secondTicket = additionalTickets[0];
+        } else {
+            if (additionalTickets != null)
+                additionalTickets = null;
+        }
 
-                tgsReqMessg = createRequest(
-                        options,
-                        asCreds.ticket,
-                        asCreds.key,
-                        ctime,
-                        princName,
-                        princName.getRealm(),
-                        servName,
-                        from,
-                        till,
-                        rtime,
-                        eTypes,
-                        addresses,
-                        authorizationData,
-                        additionalTickets,
-                        subKey);
-                obuf = tgsReqMessg.asn1Encode();
+        tgsReqMessg = createRequest(
+                options,
+                asCreds.ticket,
+                asCreds.key,
+                ctime,
+                princName,
+                princName.getRealm(),
+                servName,
+                from,
+                till,
+                rtime,
+                eTypes,
+                addresses,
+                authorizationData,
+                additionalTickets,
+                subKey);
+        obuf = tgsReqMessg.asn1Encode();
 
-                // XXX We need to revisit this to see if can't move it
-                // up such that FORWARDED flag set in the options
-                // is included in the marshaled request.
-                /*
-                 * If this is based on a forwarded ticket, record that in the
-                 * options, because the returned TgsRep will contain the
-                 * FORWARDED flag set.
-                 */
-                if (asCreds.flags.get(KDCOptions.FORWARDED))
-                    options.set(KDCOptions.FORWARDED, true);
+        // XXX We need to revisit this to see if can't move it
+        // up such that FORWARDED flag set in the options
+        // is included in the marshaled request.
+        /*
+         * If this is based on a forwarded ticket, record that in the
+         * options, because the returned TgsRep will contain the
+         * FORWARDED flag set.
+         */
+        if (asCreds.flags.get(KDCOptions.FORWARDED))
+            options.set(KDCOptions.FORWARDED, true);
 
 
-        }
+    }
 
     /**
      * Sends a TGS request to the realm of the target.
--- a/src/share/classes/sun/security/krb5/internal/APRep.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/APRep.java	Mon Apr 14 11:34:15 2008 -0700
@@ -54,81 +54,88 @@
  * http://www.ietf.org/rfc/rfc4120.txt</a>.
  */
 public class APRep {
-        public int pvno;
-        public int msgType;
-        public EncryptedData encPart;
+
+    public int pvno;
+    public int msgType;
+    public EncryptedData encPart;
 
-        public APRep(EncryptedData new_encPart) {
-                pvno = Krb5.PVNO;
-                msgType = Krb5.KRB_AP_REP;
-                encPart = new_encPart;
-        }
+    public APRep(EncryptedData new_encPart) {
+        pvno = Krb5.PVNO;
+        msgType = Krb5.KRB_AP_REP;
+        encPart = new_encPart;
+    }
 
-        public APRep(byte[] data) throws Asn1Exception,
-                KrbApErrException, IOException {
-                init(new DerValue(data));
-        }
+    public APRep(byte[] data) throws Asn1Exception,
+            KrbApErrException, IOException {
+        init(new DerValue(data));
+    }
 
     public APRep(DerValue encoding) throws Asn1Exception,
-                KrbApErrException, IOException {
-                init(encoding);
-        }
-
-        /**
-         * Initializes an APRep object.
-         * @param encoding a single DER-encoded value.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         * @exception KrbApErrException if the value read from the DER-encoded data
-         *  stream does not match the pre-defined value.
-         */
-    private void init(DerValue encoding) throws Asn1Exception,
-                KrbApErrException, IOException {
+            KrbApErrException, IOException {
+        init(encoding);
+    }
 
-                if (((encoding.getTag() & (byte)(0x1F)) != Krb5.KRB_AP_REP)
-             || (encoding.isApplication() != true)
-                        || (encoding.isConstructed() != true))
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                DerValue der = encoding.getData().getDerValue();
-        if (der.getTag() != DerValue.tag_Sequence)
-            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                DerValue subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & (byte)0x1F) != (byte)0x00)
+    /**
+     * Initializes an APRep object.
+     * @param encoding a single DER-encoded value.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     * @exception KrbApErrException if the value read from the DER-encoded data
+     *  stream does not match the pre-defined value.
+     */
+    private void init(DerValue encoding) throws Asn1Exception,
+            KrbApErrException, IOException {
+
+        if (((encoding.getTag() & (byte) (0x1F)) != Krb5.KRB_AP_REP)
+                || (encoding.isApplication() != true)
+                || (encoding.isConstructed() != true)) {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-        pvno = subDer.getData().getBigInteger().intValue();
-        if (pvno != Krb5.PVNO)
-                                throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
-                subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & (byte)0x1F) != (byte)0x01)
+        }
+        DerValue der = encoding.getData().getDerValue();
+        if (der.getTag() != DerValue.tag_Sequence) {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                msgType = subDer.getData().getBigInteger().intValue();
-                if (msgType != Krb5.KRB_AP_REP)
-                                throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
-                encPart = EncryptedData.parse(der.getData(), (byte)0x02, false);
-                if (der.getData().available() > 0)
+        }
+        DerValue subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x00) {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
+        pvno = subDer.getData().getBigInteger().intValue();
+        if (pvno != Krb5.PVNO) {
+            throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
+        }
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x01) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        msgType = subDer.getData().getBigInteger().intValue();
+        if (msgType != Krb5.KRB_AP_REP) {
+            throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
+        }
+        encPart = EncryptedData.parse(der.getData(), (byte) 0x02, false);
+        if (der.getData().available() > 0) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+    }
 
-        /**
-         * Encodes an APRep object.
-         * @return byte array of encoded APRep object.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         */
-        public byte[] asn1Encode() throws Asn1Exception, IOException {
+    /**
+     * Encodes an APRep object.
+     * @return byte array of encoded APRep object.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    public byte[] asn1Encode() throws Asn1Exception, IOException {
         DerOutputStream bytes = new DerOutputStream();
-            DerOutputStream temp = new DerOutputStream();
-                temp.putInteger(BigInteger.valueOf(pvno));
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
-                temp = new DerOutputStream();
-                temp.putInteger(BigInteger.valueOf(msgType));
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), encPart.asn1Encode());
-                temp = new DerOutputStream();
-                temp.write(DerValue.tag_Sequence, bytes);
-                DerOutputStream aprep = new DerOutputStream();
-                aprep.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x0F), temp);
-                return aprep.toByteArray();
-        }
-
+        DerOutputStream temp = new DerOutputStream();
+        temp.putInteger(BigInteger.valueOf(pvno));
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp);
+        temp = new DerOutputStream();
+        temp.putInteger(BigInteger.valueOf(msgType));
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), temp);
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), encPart.asn1Encode());
+        temp = new DerOutputStream();
+        temp.write(DerValue.tag_Sequence, bytes);
+        DerOutputStream aprep = new DerOutputStream();
+        aprep.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x0F), temp);
+        return aprep.toByteArray();
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/APReq.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/APReq.java	Mon Apr 14 11:34:15 2008 -0700
@@ -54,94 +54,98 @@
  * <a href="http://www.ietf.org/rfc/rfc4120.txt">
  * http://www.ietf.org/rfc/rfc4120.txt</a>.
  */
+public class APReq {
 
-public class APReq {
-        public int pvno;
-        public int msgType;
-        public APOptions apOptions;
-        public Ticket ticket;
-        public EncryptedData authenticator;
+    public int pvno;
+    public int msgType;
+    public APOptions apOptions;
+    public Ticket ticket;
+    public EncryptedData authenticator;
 
-        public APReq(
-                APOptions new_apOptions,
-                Ticket new_ticket,
-                EncryptedData new_authenticator
-        ) {
-                pvno = Krb5.PVNO;
-                msgType = Krb5.KRB_AP_REQ;
-                apOptions = new_apOptions;
-                ticket = new_ticket;
-                authenticator = new_authenticator;
-        }
+    public APReq(
+            APOptions new_apOptions,
+            Ticket new_ticket,
+            EncryptedData new_authenticator) {
+        pvno = Krb5.PVNO;
+        msgType = Krb5.KRB_AP_REQ;
+        apOptions = new_apOptions;
+        ticket = new_ticket;
+        authenticator = new_authenticator;
+    }
 
-        public APReq(byte[] data) throws Asn1Exception,IOException, KrbApErrException, RealmException {
+    public APReq(byte[] data) throws Asn1Exception, IOException, KrbApErrException, RealmException {
         init(new DerValue(data));
-        }
+    }
 
     public APReq(DerValue encoding) throws Asn1Exception, IOException, KrbApErrException, RealmException {
-                init(encoding);
-        }
+        init(encoding);
+    }
 
-        /**
-         * Initializes an APReq object.
-         * @param encoding a single DER-encoded value.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         * @exception KrbApErrException if the value read from the DER-encoded data stream does not match the pre-defined value.
-         * @exception RealmException if an error occurs while parsing a Realm object.
-         */
-        private void init(DerValue encoding) throws Asn1Exception,
-           IOException, KrbApErrException, RealmException {
-                DerValue der, subDer;
-        if (((encoding.getTag() & (byte)0x1F) != Krb5.KRB_AP_REQ)
-                        || (encoding.isApplication() != true)
-                        || (encoding.isConstructed() != true))
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                der = encoding.getData().getDerValue();
-                if (der.getTag() != DerValue.tag_Sequence)
-                   throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                subDer = der.getData().getDerValue();
-        if ((subDer.getTag() & (byte)0x1F) != (byte)0x00)
+    /**
+     * Initializes an APReq object.
+     * @param encoding a single DER-encoded value.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     * @exception KrbApErrException if the value read from the DER-encoded data stream does not match the pre-defined value.
+     * @exception RealmException if an error occurs while parsing a Realm object.
+     */
+    private void init(DerValue encoding) throws Asn1Exception,
+            IOException, KrbApErrException, RealmException {
+        DerValue der, subDer;
+        if (((encoding.getTag() & (byte) 0x1F) != Krb5.KRB_AP_REQ)
+                || (encoding.isApplication() != true)
+                || (encoding.isConstructed() != true)) {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        der = encoding.getData().getDerValue();
+        if (der.getTag() != DerValue.tag_Sequence) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x00) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
         pvno = subDer.getData().getBigInteger().intValue();
-        if (pvno != Krb5.PVNO)
-                                throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
-                subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & (byte)0x1F) != (byte)0x01)
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                msgType = subDer.getData().getBigInteger().intValue();
-                if (msgType != Krb5.KRB_AP_REQ)
-                         throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
-                apOptions = APOptions.parse(der.getData(), (byte)0x02, false);
-                ticket = Ticket.parse(der.getData(), (byte)0x03, false);
-                authenticator = EncryptedData.parse(der.getData(), (byte)0x04, false);
-                if (der.getData().available() > 0)
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        if (pvno != Krb5.PVNO) {
+            throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
+        }
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x01) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
+        msgType = subDer.getData().getBigInteger().intValue();
+        if (msgType != Krb5.KRB_AP_REQ) {
+            throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
+        }
+        apOptions = APOptions.parse(der.getData(), (byte) 0x02, false);
+        ticket = Ticket.parse(der.getData(), (byte) 0x03, false);
+        authenticator = EncryptedData.parse(der.getData(), (byte) 0x04, false);
+        if (der.getData().available() > 0) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+    }
 
-        /**
-         * Encodes an APReq object.
-         * @return byte array of encoded APReq object.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         */
-        public byte[] asn1Encode() throws Asn1Exception, IOException {
+    /**
+     * Encodes an APReq object.
+     * @return byte array of encoded APReq object.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    public byte[] asn1Encode() throws Asn1Exception, IOException {
         DerOutputStream bytes = new DerOutputStream();
-            DerOutputStream temp = new DerOutputStream();
-                temp.putInteger(BigInteger.valueOf(pvno));
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
-                temp = new DerOutputStream();
-                temp.putInteger(BigInteger.valueOf(msgType));
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), apOptions.asn1Encode());
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), ticket.asn1Encode());
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), authenticator.asn1Encode());
-            temp = new DerOutputStream();
-                temp.write(DerValue.tag_Sequence, bytes);
-                DerOutputStream apreq = new DerOutputStream();
-                apreq.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x0E), temp);
-                return apreq.toByteArray();
-
-        }
-
+        DerOutputStream temp = new DerOutputStream();
+        temp.putInteger(BigInteger.valueOf(pvno));
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp);
+        temp = new DerOutputStream();
+        temp.putInteger(BigInteger.valueOf(msgType));
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), temp);
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), apOptions.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), ticket.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), authenticator.asn1Encode());
+        temp = new DerOutputStream();
+        temp.write(DerValue.tag_Sequence, bytes);
+        DerOutputStream apreq = new DerOutputStream();
+        apreq.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x0E), temp);
+        return apreq.toByteArray();
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/ASRep.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/ASRep.java	Mon Apr 14 11:34:15 2008 -0700
@@ -40,30 +40,28 @@
 
 public class ASRep extends KDCRep {
 
-        public ASRep(
-                PAData[] new_pAData,
-                Realm new_crealm,
-                PrincipalName new_cname,
-                Ticket new_ticket,
-                EncryptedData new_encPart
-        ) throws IOException {
-                super(new_pAData, new_crealm, new_cname, new_ticket,
-                        new_encPart, Krb5.KRB_AS_REP);
-        }
+    public ASRep(
+            PAData[] new_pAData,
+            Realm new_crealm,
+            PrincipalName new_cname,
+            Ticket new_ticket,
+            EncryptedData new_encPart) throws IOException {
+        super(new_pAData, new_crealm, new_cname, new_ticket,
+                new_encPart, Krb5.KRB_AS_REP);
+    }
 
-        public ASRep(byte[] data) throws Asn1Exception,
-                RealmException, KrbApErrException, IOException {
-                init(new DerValue(data));
-        }
+    public ASRep(byte[] data) throws Asn1Exception,
+            RealmException, KrbApErrException, IOException {
+        init(new DerValue(data));
+    }
 
-     public ASRep(DerValue encoding) throws Asn1Exception,
-                RealmException, KrbApErrException, IOException {
-                init(encoding);
-        }
+    public ASRep(DerValue encoding) throws Asn1Exception,
+            RealmException, KrbApErrException, IOException {
+        init(encoding);
+    }
 
-        private void init(DerValue encoding) throws Asn1Exception,
-                RealmException, KrbApErrException, IOException {
-                init(encoding, Krb5.KRB_AS_REP);
-        }
-
+    private void init(DerValue encoding) throws Asn1Exception,
+            RealmException, KrbApErrException, IOException {
+        init(encoding, Krb5.KRB_AS_REP);
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/ASReq.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/ASReq.java	Mon Apr 14 11:34:15 2008 -0700
@@ -36,20 +36,19 @@
 
 public class ASReq extends KDCReq {
 
-        public ASReq(PAData[] new_pAData, KDCReqBody new_reqBody) throws IOException {
-                super(new_pAData, new_reqBody, Krb5.KRB_AS_REQ);
-        }
+    public ASReq(PAData[] new_pAData, KDCReqBody new_reqBody) throws IOException {
+        super(new_pAData, new_reqBody, Krb5.KRB_AS_REQ);
+    }
 
-        public ASReq(byte[] data) throws Asn1Exception, KrbException, IOException {
-                init(new DerValue(data));
-        }
+    public ASReq(byte[] data) throws Asn1Exception, KrbException, IOException {
+        init(new DerValue(data));
+    }
 
     public ASReq(DerValue encoding) throws Asn1Exception, KrbException, IOException {
-                init(encoding);
-        }
+        init(encoding);
+    }
 
-        private void init(DerValue encoding) throws Asn1Exception, IOException, KrbException {
-                super.init(encoding, Krb5.KRB_AS_REQ);
-        }
-
+    private void init(DerValue encoding) throws Asn1Exception, IOException, KrbException {
+        super.init(encoding, Krb5.KRB_AS_REQ);
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/Authenticator.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/Authenticator.java	Mon Apr 14 11:34:15 2008 -0700
@@ -34,6 +34,7 @@
 import java.util.Vector;
 import java.io.IOException;
 import java.math.BigInteger;
+
 /**
  * Implements the ASN.1 Authenticator type.
  *
@@ -58,6 +59,7 @@
  * http://www.ietf.org/rfc/rfc4120.txt</a>.
  */
 public class Authenticator {
+
     public int authenticator_vno;
     public Realm crealm;
     public PrincipalName cname;
@@ -68,137 +70,145 @@
     Integer seqNumber; //optional
     public AuthorizationData authorizationData; //optional
 
-        public Authenticator (
-                Realm new_crealm,
-                PrincipalName new_cname,
-                Checksum new_cksum,
-                int new_cusec,
-                KerberosTime new_ctime,
-                EncryptionKey new_subKey,
-                Integer new_seqNumber,
-                AuthorizationData new_authorizationData
-        ) {
-                authenticator_vno = Krb5.AUTHNETICATOR_VNO;
-                crealm = new_crealm;
-                cname = new_cname;
-                cksum = new_cksum;
-                cusec = new_cusec;
-                ctime = new_ctime;
-                subKey = new_subKey;
-                seqNumber = new_seqNumber;
-                authorizationData = new_authorizationData;
-        }
+    public Authenticator(
+            Realm new_crealm,
+            PrincipalName new_cname,
+            Checksum new_cksum,
+            int new_cusec,
+            KerberosTime new_ctime,
+            EncryptionKey new_subKey,
+            Integer new_seqNumber,
+            AuthorizationData new_authorizationData) {
+        authenticator_vno = Krb5.AUTHNETICATOR_VNO;
+        crealm = new_crealm;
+        cname = new_cname;
+        cksum = new_cksum;
+        cusec = new_cusec;
+        ctime = new_ctime;
+        subKey = new_subKey;
+        seqNumber = new_seqNumber;
+        authorizationData = new_authorizationData;
+    }
 
-        public Authenticator(byte[] data)
-                throws Asn1Exception, IOException, KrbApErrException, RealmException {
-                init(new DerValue(data));
-        }
+    public Authenticator(byte[] data)
+            throws Asn1Exception, IOException, KrbApErrException, RealmException {
+        init(new DerValue(data));
+    }
 
-        public Authenticator(DerValue encoding)
-                throws Asn1Exception,IOException, KrbApErrException, RealmException {
-                init(encoding);
-        }
+    public Authenticator(DerValue encoding)
+            throws Asn1Exception, IOException, KrbApErrException, RealmException {
+        init(encoding);
+    }
 
-        /**
-         * Initializes an Authenticator object.
-         * @param encoding a single DER-encoded value.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         * @exception KrbApErrException if the value read from the DER-encoded data
-         *  stream does not match the pre-defined value.
-         * @exception RealmException if an error occurs while parsing a Realm object.
-         */
-        private void init(DerValue encoding)
-                throws Asn1Exception, IOException, KrbApErrException, RealmException {
-                DerValue der, subDer;
-                        //may not be the correct error code for a tag
-                        //mismatch on an encrypted structure
-        if (((encoding.getTag() & (byte)0x1F) != (byte)0x02)
-             || (encoding.isApplication() != true)
-                        || (encoding.isConstructed() != true))
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                der = encoding.getData().getDerValue();
-        if (der.getTag() != DerValue.tag_Sequence)
+    /**
+     * Initializes an Authenticator object.
+     * @param encoding a single DER-encoded value.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     * @exception KrbApErrException if the value read from the DER-encoded data
+     *  stream does not match the pre-defined value.
+     * @exception RealmException if an error occurs while parsing a Realm object.
+     */
+    private void init(DerValue encoding)
+            throws Asn1Exception, IOException, KrbApErrException, RealmException {
+        DerValue der, subDer;
+        //may not be the correct error code for a tag
+        //mismatch on an encrypted structure
+        if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x02)
+                || (encoding.isApplication() != true)
+                || (encoding.isConstructed() != true)) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        der = encoding.getData().getDerValue();
+        if (der.getTag() != DerValue.tag_Sequence) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x00) {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & (byte)0x1F) != (byte)0x00)
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
         authenticator_vno = subDer.getData().getBigInteger().intValue();
-                if (authenticator_vno != 5)
+        if (authenticator_vno != 5) {
             throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
-                crealm = Realm.parse(der.getData(), (byte)0x01, false);
-                cname = PrincipalName.parse(der.getData(), (byte)0x02, false);
-                cksum = Checksum.parse(der.getData(), (byte)0x03, true);
+        }
+        crealm = Realm.parse(der.getData(), (byte) 0x01, false);
+        cname = PrincipalName.parse(der.getData(), (byte) 0x02, false);
+        cksum = Checksum.parse(der.getData(), (byte) 0x03, true);
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & (byte) 0x1F) == 0x04) {
+            cusec = subDer.getData().getBigInteger().intValue();
+        } else {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        ctime = KerberosTime.parse(der.getData(), (byte) 0x05, false);
+        if (der.getData().available() > 0) {
+            subKey = EncryptionKey.parse(der.getData(), (byte) 0x06, true);
+        } else {
+            subKey = null;
+            seqNumber = null;
+            authorizationData = null;
+        }
+        if (der.getData().available() > 0) {
+            if ((der.getData().peekByte() & 0x1F) == 0x07) {
                 subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & (byte)0x1F) == 0x04) {
-                        cusec = subDer.getData().getBigInteger().intValue();
+                if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x07) {
+                    seqNumber = new Integer(subDer.getData().getBigInteger().intValue());
                 }
-                else throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                ctime = KerberosTime.parse(der.getData(), (byte)0x05, false);
-                if (der.getData().available() > 0) {
-                        subKey = EncryptionKey.parse(der.getData(), (byte)0x06, true);
-                }
-                else {
-                        subKey = null;
-                        seqNumber = null;
-                        authorizationData = null;
-                }
-                if (der.getData().available() > 0) {
-                        if ((der.getData().peekByte() & 0x1F) == 0x07) {
-                                subDer = der.getData().getDerValue();
-                                if ((subDer.getTag() & (byte)0x1F) == (byte)0x07)
-                                        seqNumber = new Integer(subDer.getData().getBigInteger().intValue());
-                        }
-                }
-                else {
-                        seqNumber = null;
-                        authorizationData = null;
-                }
-                if (der.getData().available() > 0) {
-                        authorizationData = AuthorizationData.parse(der.getData(), (byte)0x08, true);
-                }
-                else authorizationData = null;
-                if (der.getData().available() > 0)
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+            }
+        } else {
+            seqNumber = null;
+            authorizationData = null;
         }
+        if (der.getData().available() > 0) {
+            authorizationData = AuthorizationData.parse(der.getData(), (byte) 0x08, true);
+        } else {
+            authorizationData = null;
+        }
+        if (der.getData().available() > 0) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+    }
 
-        /**
-         * Encodes an Authenticator object.
-         * @return byte array of encoded Authenticator object.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         */
-        public byte[] asn1Encode() throws Asn1Exception, IOException {
-                Vector<DerValue> v = new Vector<DerValue> ();
-                DerOutputStream temp = new DerOutputStream();
-                temp.putInteger(BigInteger.valueOf(authenticator_vno));
-                v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp.toByteArray()));
-                v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), crealm.asn1Encode()));
-                v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), cname.asn1Encode()));
-                if (cksum != null)
-                        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), cksum.asn1Encode()));
-                temp = new DerOutputStream();
-                temp.putInteger(BigInteger.valueOf(cusec));
-                v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), temp.toByteArray()));
-                v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), ctime.asn1Encode()));
-                if (subKey != null)
-                        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), subKey.asn1Encode()));
-                if (seqNumber != null)   {
-                        temp = new DerOutputStream();
-                        // encode as an unsigned integer (UInt32)
-                        temp.putInteger(BigInteger.valueOf(seqNumber.longValue()));
-                        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), temp.toByteArray()));
-                }
-                if (authorizationData != null)
-                        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), authorizationData.asn1Encode()));
-                DerValue der[] = new DerValue[v.size()];
-                v.copyInto(der);
-                temp = new DerOutputStream();
-                temp.putSequence(der);
-                DerOutputStream out = new DerOutputStream();
-                out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x02), temp);
-                return out.toByteArray();
+    /**
+     * Encodes an Authenticator object.
+     * @return byte array of encoded Authenticator object.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    public byte[] asn1Encode() throws Asn1Exception, IOException {
+        Vector<DerValue> v = new Vector<DerValue>();
+        DerOutputStream temp = new DerOutputStream();
+        temp.putInteger(BigInteger.valueOf(authenticator_vno));
+        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp.toByteArray()));
+        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), crealm.asn1Encode()));
+        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), cname.asn1Encode()));
+        if (cksum != null) {
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), cksum.asn1Encode()));
         }
+        temp = new DerOutputStream();
+        temp.putInteger(BigInteger.valueOf(cusec));
+        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), temp.toByteArray()));
+        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x05), ctime.asn1Encode()));
+        if (subKey != null) {
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x06), subKey.asn1Encode()));
+        }
+        if (seqNumber != null) {
+            temp = new DerOutputStream();
+            // encode as an unsigned integer (UInt32)
+            temp.putInteger(BigInteger.valueOf(seqNumber.longValue()));
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x07), temp.toByteArray()));
+        }
+        if (authorizationData != null) {
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x08), authorizationData.asn1Encode()));
+        }
+        DerValue der[] = new DerValue[v.size()];
+        v.copyInto(der);
+        temp = new DerOutputStream();
+        temp.putSequence(der);
+        DerOutputStream out = new DerOutputStream();
+        out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x02), temp);
+        return out.toByteArray();
+    }
 
     public final Checksum getChecksum() {
         return cksum;
@@ -211,5 +221,4 @@
     public final EncryptionKey getSubKey() {
         return subKey;
     }
-
 }
--- a/src/share/classes/sun/security/krb5/internal/AuthorizationData.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/AuthorizationData.java	Mon Apr 14 11:34:15 2008 -0700
@@ -53,82 +53,81 @@
  * }
  */
 public class AuthorizationData implements Cloneable {
-        private AuthorizationDataEntry[] entry = null;
+
+    private AuthorizationDataEntry[] entry = null;
 
-        private AuthorizationData() {
-        }
+    private AuthorizationData() {
+    }
 
-        public AuthorizationData(
-                AuthorizationDataEntry[] new_entries
-        ) throws IOException {
-                if (new_entries != null) {
-                   entry = new AuthorizationDataEntry[new_entries.length];
-                   for (int i = 0; i < new_entries.length; i++) {
-                        if (new_entries[i] == null) {
-                           throw new IOException("Cannot create an AuthorizationData");
-                        } else {
-                           entry[i] = (AuthorizationDataEntry)new_entries[i].clone();
-                        }
-                   }
-                }
-        }
-
-        public AuthorizationData(
-                AuthorizationDataEntry new_entry
-        ) {
-                entry = new AuthorizationDataEntry[1];
-                entry[0] = new_entry;
-        }
-
-        public Object clone() {
-                AuthorizationData new_authorizationData =
-                        new AuthorizationData();
-                if (entry != null) {
-                        new_authorizationData.entry =
-                                new AuthorizationDataEntry[entry.length];
-                        for (int i = 0; i < entry.length; i++)
-                                new_authorizationData.entry[i] =
-                                        (AuthorizationDataEntry)entry[i].clone();
+    public AuthorizationData(AuthorizationDataEntry[] new_entries)
+            throws IOException {
+        if (new_entries != null) {
+            entry = new AuthorizationDataEntry[new_entries.length];
+            for (int i = 0; i < new_entries.length; i++) {
+                if (new_entries[i] == null) {
+                    throw new IOException("Cannot create an AuthorizationData");
+                } else {
+                    entry[i] = (AuthorizationDataEntry) new_entries[i].clone();
                 }
-                return new_authorizationData;
+            }
         }
+    }
+
+    public AuthorizationData(AuthorizationDataEntry new_entry) {
+        entry = new AuthorizationDataEntry[1];
+        entry[0] = new_entry;
+    }
+
+    public Object clone() {
+        AuthorizationData new_authorizationData =
+                new AuthorizationData();
+        if (entry != null) {
+            new_authorizationData.entry =
+                    new AuthorizationDataEntry[entry.length];
+            for (int i = 0; i < entry.length; i++) {
+                new_authorizationData.entry[i] =
+                        (AuthorizationDataEntry) entry[i].clone();
+            }
+        }
+        return new_authorizationData;
+    }
 
-        /**
-         * Constructs a new <code>AuthorizationData,</code> instance.
-         * @param der a single DER-encoded value.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         */
-        public AuthorizationData(DerValue der) throws Asn1Exception, IOException {
-                Vector<AuthorizationDataEntry> v =
-                    new Vector<AuthorizationDataEntry> ();
-                if (der.getTag() != DerValue.tag_Sequence) {
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                }
-                while (der.getData().available() > 0) {
-                        v.addElement(new AuthorizationDataEntry(der.getData().getDerValue()));
-                }
-                if (v.size() > 0) {
-                        entry = new AuthorizationDataEntry[v.size()];
-                        v.copyInto(entry);
-                }
+    /**
+     * Constructs a new <code>AuthorizationData,</code> instance.
+     * @param der a single DER-encoded value.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    public AuthorizationData(DerValue der) throws Asn1Exception, IOException {
+        Vector<AuthorizationDataEntry> v =
+                new Vector<AuthorizationDataEntry>();
+        if (der.getTag() != DerValue.tag_Sequence) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        while (der.getData().available() > 0) {
+            v.addElement(new AuthorizationDataEntry(der.getData().getDerValue()));
         }
+        if (v.size() > 0) {
+            entry = new AuthorizationDataEntry[v.size()];
+            v.copyInto(entry);
+        }
+    }
 
-        /**
-         * Encodes an <code>AuthorizationData</code> object.
-         * @return byte array of encoded <code>AuthorizationData</code> object.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         */
-        public byte[] asn1Encode() throws Asn1Exception, IOException {
-                DerOutputStream bytes = new DerOutputStream();
-                DerValue der[] = new DerValue[entry.length];
-                for (int i = 0; i < entry.length; i++) {
-                        der[i] = new DerValue(entry[i].asn1Encode());
-                }
-                bytes.putSequence(der);
-                return bytes.toByteArray();
+    /**
+     * Encodes an <code>AuthorizationData</code> object.
+     * @return byte array of encoded <code>AuthorizationData</code> object.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    public byte[] asn1Encode() throws Asn1Exception, IOException {
+        DerOutputStream bytes = new DerOutputStream();
+        DerValue der[] = new DerValue[entry.length];
+        for (int i = 0; i < entry.length; i++) {
+            der[i] = new DerValue(entry[i].asn1Encode());
         }
+        bytes.putSequence(der);
+        return bytes.toByteArray();
+    }
 
     /**
      * Parse (unmarshal) an <code>AuthorizationData</code> object from a DER input stream.
@@ -143,31 +142,30 @@
      * @return an instance of AuthorizationData.
      *
      */
-        public static AuthorizationData parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException{
-                if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag)) {
-                        return null;
-                }
-                DerValue der = data.getDerValue();
-                if (explicitTag != (der.getTag() & (byte)0x1F))  {
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                }
-                else {
-                        DerValue subDer = der.getData().getDerValue();
-                        return new AuthorizationData(subDer);
-                }
+    public static AuthorizationData parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException {
+        if ((optional) && (((byte) data.peekByte() & (byte) 0x1F) != explicitTag)) {
+            return null;
+        }
+        DerValue der = data.getDerValue();
+        if (explicitTag != (der.getTag() & (byte) 0x1F)) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        } else {
+            DerValue subDer = der.getData().getDerValue();
+            return new AuthorizationData(subDer);
         }
+    }
 
-        /**
-         * Writes <code>AuthorizationData</code> data fields to a output stream.
-         *
-         * @param cos a <code>CCacheOutputStream</code> to be written to.
-         * @exception IOException if an I/O exception occurs.
-         */
-        public void writeAuth(CCacheOutputStream cos) throws IOException {
-                for (int i = 0; i < entry.length; i++) {
-                        entry[i].writeEntry(cos);
-                }
+    /**
+     * Writes <code>AuthorizationData</code> data fields to a output stream.
+     *
+     * @param cos a <code>CCacheOutputStream</code> to be written to.
+     * @exception IOException if an I/O exception occurs.
+     */
+    public void writeAuth(CCacheOutputStream cos) throws IOException {
+        for (int i = 0; i < entry.length; i++) {
+            entry[i].writeEntry(cos);
         }
+    }
 
     public String toString() {
         String retVal = "AuthorizationData:\n";
--- a/src/share/classes/sun/security/krb5/internal/AuthorizationDataEntry.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/AuthorizationDataEntry.java	Mon Apr 14 11:34:15 2008 -0700
@@ -35,90 +35,90 @@
 import sun.security.krb5.internal.ccache.CCacheOutputStream;
 
 public class AuthorizationDataEntry implements Cloneable {
-        public int adType;
-        public byte[] adData;
 
-        private AuthorizationDataEntry() {
-        }
+    public int adType;
+    public byte[] adData;
+
+    private AuthorizationDataEntry() {
+    }
 
-        public AuthorizationDataEntry(
-                int new_adType,
-                byte[] new_adData
-        ) {
-                adType = new_adType;
-                adData = new_adData;
-        }
+    public AuthorizationDataEntry(
+            int new_adType,
+            byte[] new_adData) {
+        adType = new_adType;
+        adData = new_adData;
+    }
 
-        public Object clone() {
-                AuthorizationDataEntry new_authorizationDataEntry =
-                        new AuthorizationDataEntry();
-                new_authorizationDataEntry.adType = adType;
-                if (adData != null) {
-                        new_authorizationDataEntry.adData = new byte[adData.length];
-                        System.arraycopy(adData, 0,
-                                new_authorizationDataEntry.adData, 0, adData.length);
-                }
-                return new_authorizationDataEntry;
+    public Object clone() {
+        AuthorizationDataEntry new_authorizationDataEntry =
+                new AuthorizationDataEntry();
+        new_authorizationDataEntry.adType = adType;
+        if (adData != null) {
+            new_authorizationDataEntry.adData = new byte[adData.length];
+            System.arraycopy(adData, 0,
+                    new_authorizationDataEntry.adData, 0, adData.length);
         }
+        return new_authorizationDataEntry;
+    }
 
-        /**
-         * Constructs an instance of AuthorizationDataEntry.
-         * @param encoding a single DER-encoded value.
-         */
-        public AuthorizationDataEntry(DerValue encoding) throws Asn1Exception, IOException {
-                DerValue der;
+    /**
+     * Constructs an instance of AuthorizationDataEntry.
+     * @param encoding a single DER-encoded value.
+     */
+    public AuthorizationDataEntry(DerValue encoding) throws Asn1Exception, IOException {
+        DerValue der;
         if (encoding.getTag() != DerValue.tag_Sequence) {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                }
-                der = encoding.getData().getDerValue();
-        if ((der.getTag() & (byte)0x1F) == (byte)0x00) {
-                        adType = der.getData().getBigInteger().intValue();
-                }
-                else
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        der = encoding.getData().getDerValue();
+        if ((der.getTag() & (byte) 0x1F) == (byte) 0x00) {
+            adType = der.getData().getBigInteger().intValue();
+        } else {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
         der = encoding.getData().getDerValue();
-        if ((der.getTag() & (byte)0x1F) == (byte)0x01) {
-                        adData = der.getData().getOctetString();
-                }
-                else
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-        if (encoding.getData().available() > 0)
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        if ((der.getTag() & (byte) 0x1F) == (byte) 0x01) {
+            adData = der.getData().getOctetString();
+        } else {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
+        if (encoding.getData().available() > 0) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+    }
 
-        /**
-         * Encodes an AuthorizationDataEntry object.
-         * @return byte array of encoded AuthorizationDataEntry object.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         */
-        public byte[] asn1Encode() throws Asn1Exception, IOException {
+    /**
+     * Encodes an AuthorizationDataEntry object.
+     * @return byte array of encoded AuthorizationDataEntry object.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    public byte[] asn1Encode() throws Asn1Exception, IOException {
         DerOutputStream bytes = new DerOutputStream();
-                DerOutputStream temp = new DerOutputStream();
-                temp.putInteger(adType);
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
-                temp = new DerOutputStream();
-                temp.putOctetString(adData);
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
-                temp = new DerOutputStream();
-                temp.write(DerValue.tag_Sequence, bytes);
-                return temp.toByteArray();
-        }
+        DerOutputStream temp = new DerOutputStream();
+        temp.putInteger(adType);
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp);
+        temp = new DerOutputStream();
+        temp.putOctetString(adData);
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), temp);
+        temp = new DerOutputStream();
+        temp.write(DerValue.tag_Sequence, bytes);
+        return temp.toByteArray();
+    }
 
-        /**
-         * Writes the entry's data fields in FCC format to an output stream.
-         *
-         * @param cos a <code>CCacheOutputStream</code>.
-         * @exception IOException if an I/O exception occurs.
-         */
-        public void writeEntry(CCacheOutputStream cos) throws IOException {
-                cos.write16(adType);
-                cos.write32(adData.length);
-                cos.write(adData, 0, adData.length);
-        }
+    /**
+     * Writes the entry's data fields in FCC format to an output stream.
+     *
+     * @param cos a <code>CCacheOutputStream</code>.
+     * @exception IOException if an I/O exception occurs.
+     */
+    public void writeEntry(CCacheOutputStream cos) throws IOException {
+        cos.write16(adType);
+        cos.write32(adData.length);
+        cos.write(adData, 0, adData.length);
+    }
 
     public String toString() {
         return ("adType=" + adType + " adData.length=" + adData.length);
     }
-
 }
--- a/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java	Mon Apr 14 11:34:15 2008 -0700
@@ -100,16 +100,16 @@
 
         // salt
         if (encoding.getData().available() > 0) {
-            der = encoding.getData().getDerValue();
-            if ((der.getTag() & 0x1F) == 0x01) {
+            if ((encoding.getData().peekByte() & 0x1F) == 0x01) {
+                der = encoding.getData().getDerValue();
                 this.saltStr = der.getData().getGeneralString();
             }
         }
 
         // s2kparams
         if (encoding.getData().available() > 0) {
-            der = encoding.getData().getDerValue();
-            if ((der.getTag() & 0x1F) == 0x02) {
+            if ((encoding.getData().peekByte() & 0x1F) == 0x02) {
+                der = encoding.getData().getDerValue();
                 this.s2kparams = der.getData().getOctetString();
             }
         }
--- a/src/share/classes/sun/security/krb5/internal/EncAPRepPart.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/EncAPRepPart.java	Mon Apr 14 11:34:15 2008 -0700
@@ -55,102 +55,111 @@
  * http://www.ietf.org/rfc/rfc4120.txt</a>.
  */
 public class EncAPRepPart {
-        public KerberosTime ctime;
-        public int cusec;
+
+    public KerberosTime ctime;
+    public int cusec;
     EncryptionKey subKey; //optional
     Integer seqNumber; //optional
 
-        public EncAPRepPart(
-                KerberosTime new_ctime,
-                int new_cusec,
-                EncryptionKey new_subKey,
-                Integer new_seqNumber
-        ) {
-                ctime = new_ctime;
-                cusec = new_cusec;
-                subKey = new_subKey;
-                seqNumber = new_seqNumber;
-        }
+    public EncAPRepPart(
+            KerberosTime new_ctime,
+            int new_cusec,
+            EncryptionKey new_subKey,
+            Integer new_seqNumber) {
+        ctime = new_ctime;
+        cusec = new_cusec;
+        subKey = new_subKey;
+        seqNumber = new_seqNumber;
+    }
 
-        public EncAPRepPart(byte[] data)
-                throws Asn1Exception, IOException {
-                init(new DerValue(data));
-        }
+    public EncAPRepPart(byte[] data)
+            throws Asn1Exception, IOException {
+        init(new DerValue(data));
+    }
+
+    public EncAPRepPart(DerValue encoding)
+            throws Asn1Exception, IOException {
+        init(encoding);
+    }
 
-        public EncAPRepPart(DerValue encoding)
-                throws Asn1Exception, IOException {
-                init(encoding);
+    /**
+     * Initializes an EncaPRepPart object.
+     * @param encoding a single DER-encoded value.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    private void init(DerValue encoding) throws Asn1Exception, IOException {
+        DerValue der, subDer;
+        if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1B)
+                || (encoding.isApplication() != true)
+                || (encoding.isConstructed() != true)) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
-
-        /**
-         * Initializes an EncaPRepPart object.
-         * @param encoding a single DER-encoded value.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         */
-        private void init(DerValue encoding) throws Asn1Exception, IOException {
-                DerValue der, subDer;
-        if (((encoding.getTag() & (byte)0x1F) != (byte)0x1B)
-             || (encoding.isApplication() != true)
-                        || (encoding.isConstructed() != true))
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         der = encoding.getData().getDerValue();
-        if (der.getTag() != DerValue.tag_Sequence)
+        if (der.getTag() != DerValue.tag_Sequence) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        ctime = KerberosTime.parse(der.getData(), (byte) 0x00, true);
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x01) {
+            cusec = subDer.getData().getBigInteger().intValue();
+        } else {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                ctime = KerberosTime.parse(der.getData(), (byte)0x00, true);
-                subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & (byte)0x1F) == (byte)0x01) {
-                        cusec = subDer.getData().getBigInteger().intValue();
-                }
-        else
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                if (der.getData().available() > 0) {
-                        subKey = EncryptionKey.parse(der.getData(), (byte)0x02, true);
-                }
-                else {
-                        subKey = null;
-                        seqNumber = null;
-                }
-                if (der.getData().available() > 0) {
-                        subDer = der.getData().getDerValue();
-                        if ((subDer.getTag() & 0x1F) != 0x03) {
-                                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                        }
-                        seqNumber = new Integer(subDer.getData().getBigInteger().intValue());
-                }
-                else seqNumber = null;
-                if (der.getData().available() > 0)
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        if (der.getData().available() > 0) {
+            subKey = EncryptionKey.parse(der.getData(), (byte) 0x02, true);
+        } else {
+            subKey = null;
+            seqNumber = null;
         }
+        if (der.getData().available() > 0) {
+            subDer = der.getData().getDerValue();
+            if ((subDer.getTag() & 0x1F) != 0x03) {
+                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+            }
+            seqNumber = new Integer(subDer.getData().getBigInteger().intValue());
+        } else {
+            seqNumber = null;
+        }
+        if (der.getData().available() > 0) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+    }
 
-        /**
-         * Encodes an EncAPRepPart object.
-         * @return byte array of encoded EncAPRepPart object.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         */
-        public byte[] asn1Encode() throws Asn1Exception, IOException{
-                Vector<DerValue> v = new Vector<DerValue> ();
+    /**
+     * Encodes an EncAPRepPart object.
+     * @return byte array of encoded EncAPRepPart object.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    public byte[] asn1Encode() throws Asn1Exception, IOException {
+        Vector<DerValue> v = new Vector<DerValue>();
         DerOutputStream temp = new DerOutputStream();
-                v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), ctime.asn1Encode()));
-                temp.putInteger(BigInteger.valueOf(cusec));
-                v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp.toByteArray()));
-                if (subKey != null)
-                        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), subKey.asn1Encode()));
-                if (seqNumber != null) {
-                        temp = new DerOutputStream();
-                        // encode as an unsigned integer (UInt32)
-                        temp.putInteger(BigInteger.valueOf(seqNumber.longValue()));
-                        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp.toByteArray()));
-                }
-                DerValue der[] = new DerValue[v.size()];
-                v.copyInto(der);
-                temp = new DerOutputStream();
-                temp.putSequence(der);
+        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x00), ctime.asn1Encode()));
+        temp.putInteger(BigInteger.valueOf(cusec));
+        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x01), temp.toByteArray()));
+        if (subKey != null) {
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x02), subKey.asn1Encode()));
+        }
+        if (seqNumber != null) {
+            temp = new DerOutputStream();
+            // encode as an unsigned integer (UInt32)
+            temp.putInteger(BigInteger.valueOf(seqNumber.longValue()));
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x03), temp.toByteArray()));
+        }
+        DerValue der[] = new DerValue[v.size()];
+        v.copyInto(der);
+        temp = new DerOutputStream();
+        temp.putSequence(der);
         DerOutputStream out = new DerOutputStream();
-        out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x1B), temp);
-                return out.toByteArray();
-        }
+        out.write(DerValue.createTag(DerValue.TAG_APPLICATION,
+                true, (byte) 0x1B), temp);
+        return out.toByteArray();
+    }
 
     public final EncryptionKey getSubKey() {
         return subKey;
@@ -159,5 +168,4 @@
     public final Integer getSeqNumber() {
         return seqNumber;
     }
-
 }
--- a/src/share/classes/sun/security/krb5/internal/EncASRepPart.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/EncASRepPart.java	Mon Apr 14 11:34:15 2008 -0700
@@ -36,57 +36,55 @@
 
 public class EncASRepPart extends EncKDCRepPart {
 
-        public EncASRepPart(
-                EncryptionKey new_key,
-                LastReq new_lastReq,
-                int new_nonce,
-                KerberosTime new_keyExpiration,
-                TicketFlags new_flags,
-                KerberosTime new_authtime,
-                KerberosTime new_starttime,
-                KerberosTime new_endtime,
-                KerberosTime new_renewTill,
-                Realm new_srealm,
-                PrincipalName new_sname,
-                HostAddresses new_caddr
-        ) {
-                super(
-                        new_key,
-                        new_lastReq,
-                        new_nonce,
-                        new_keyExpiration,
-                        new_flags,
-                        new_authtime,
-                        new_starttime,
-                        new_endtime,
-                        new_renewTill,
-                        new_srealm,
-                        new_sname,
-                        new_caddr,
-                        Krb5.KRB_ENC_AS_REP_PART
-                        //may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic
-                        //behavior of other implementaions, instead of above
+    public EncASRepPart(
+            EncryptionKey new_key,
+            LastReq new_lastReq,
+            int new_nonce,
+            KerberosTime new_keyExpiration,
+            TicketFlags new_flags,
+            KerberosTime new_authtime,
+            KerberosTime new_starttime,
+            KerberosTime new_endtime,
+            KerberosTime new_renewTill,
+            Realm new_srealm,
+            PrincipalName new_sname,
+            HostAddresses new_caddr) {
+        super(
+                new_key,
+                new_lastReq,
+                new_nonce,
+                new_keyExpiration,
+                new_flags,
+                new_authtime,
+                new_starttime,
+                new_endtime,
+                new_renewTill,
+                new_srealm,
+                new_sname,
+                new_caddr,
+                Krb5.KRB_ENC_AS_REP_PART
                 );
-        }
+        //may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic
+        //behavior of other implementaions, instead of above
+    }
 
-        public EncASRepPart(byte[] data) throws Asn1Exception,
-                IOException, KrbException {
-         init(new DerValue(data));
-        }
-
-        public EncASRepPart(DerValue encoding) throws Asn1Exception,
-                IOException, KrbException {
-                init(encoding);
-        }
+    public EncASRepPart(byte[] data) throws Asn1Exception,
+            IOException, KrbException {
+        init(new DerValue(data));
+    }
 
-        private void init(DerValue encoding) throws Asn1Exception,
-                IOException, KrbException {
-                init(encoding, Krb5.KRB_ENC_AS_REP_PART);
-        }
+    public EncASRepPart(DerValue encoding) throws Asn1Exception,
+            IOException, KrbException {
+        init(encoding);
+    }
 
-        public byte[] asn1Encode() throws Asn1Exception,
-                IOException {
-                return asn1Encode(Krb5.KRB_ENC_AS_REP_PART);
-        }
+    private void init(DerValue encoding) throws Asn1Exception,
+            IOException, KrbException {
+        init(encoding, Krb5.KRB_ENC_AS_REP_PART);
+    }
 
+    public byte[] asn1Encode() throws Asn1Exception,
+            IOException {
+        return asn1Encode(Krb5.KRB_ENC_AS_REP_PART);
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java	Mon Apr 14 11:34:15 2008 -0700
@@ -36,6 +36,7 @@
 import java.util.Vector;
 import java.io.IOException;
 import java.math.BigInteger;
+
 /**
  * Implements the ASN.1 EncKDCRepPart type.
  *
@@ -63,143 +64,163 @@
  * http://www.ietf.org/rfc/rfc4120.txt</a>.
  */
 public class EncKDCRepPart {
-        public EncryptionKey key;
-        public LastReq lastReq;
-        public int nonce;
-        public KerberosTime keyExpiration; //optional
-        public TicketFlags flags;
-        public KerberosTime authtime;
-        public KerberosTime starttime; //optional
-        public KerberosTime endtime;
-        public KerberosTime renewTill; //optional
-        public Realm srealm;
-        public PrincipalName sname;
-        public HostAddresses caddr; //optional
-        public int msgType; //not included in sequence
+
+    public EncryptionKey key;
+    public LastReq lastReq;
+    public int nonce;
+    public KerberosTime keyExpiration; //optional
+    public TicketFlags flags;
+    public KerberosTime authtime;
+    public KerberosTime starttime; //optional
+    public KerberosTime endtime;
+    public KerberosTime renewTill; //optional
+    public Realm srealm;
+    public PrincipalName sname;
+    public HostAddresses caddr; //optional
+    public int msgType; //not included in sequence
 
-        public EncKDCRepPart(
-                EncryptionKey new_key,
-                LastReq new_lastReq,
-                int new_nonce,
-                KerberosTime new_keyExpiration,
-                TicketFlags new_flags,
-                KerberosTime new_authtime,
-                KerberosTime new_starttime,
-                KerberosTime new_endtime,
-                KerberosTime new_renewTill,
-                Realm new_srealm,
-                PrincipalName new_sname,
-                HostAddresses new_caddr,
-                int new_msgType
-        ) {
-                key = new_key;
-                lastReq = new_lastReq;
-                nonce = new_nonce;
-                keyExpiration = new_keyExpiration;
-                flags = new_flags;
-                authtime = new_authtime;
-                starttime = new_starttime;
-                endtime = new_endtime;
-                renewTill = new_renewTill;
-                srealm = new_srealm;
-                sname = new_sname;
-                caddr = new_caddr;
-                msgType = new_msgType;
-        }
+    public EncKDCRepPart(
+            EncryptionKey new_key,
+            LastReq new_lastReq,
+            int new_nonce,
+            KerberosTime new_keyExpiration,
+            TicketFlags new_flags,
+            KerberosTime new_authtime,
+            KerberosTime new_starttime,
+            KerberosTime new_endtime,
+            KerberosTime new_renewTill,
+            Realm new_srealm,
+            PrincipalName new_sname,
+            HostAddresses new_caddr,
+            int new_msgType) {
+        key = new_key;
+        lastReq = new_lastReq;
+        nonce = new_nonce;
+        keyExpiration = new_keyExpiration;
+        flags = new_flags;
+        authtime = new_authtime;
+        starttime = new_starttime;
+        endtime = new_endtime;
+        renewTill = new_renewTill;
+        srealm = new_srealm;
+        sname = new_sname;
+        caddr = new_caddr;
+        msgType = new_msgType;
+    }
 
-        public EncKDCRepPart() {
-        }
+    public EncKDCRepPart() {
+    }
 
-        public EncKDCRepPart(byte[] data, int rep_type)
-                throws Asn1Exception, IOException, RealmException{
-                init(new DerValue(data), rep_type);
-        }
+    public EncKDCRepPart(byte[] data, int rep_type)
+            throws Asn1Exception, IOException, RealmException {
+        init(new DerValue(data), rep_type);
+    }
+
+    public EncKDCRepPart(DerValue encoding, int rep_type)
+            throws Asn1Exception, IOException, RealmException {
+        init(encoding, rep_type);
+    }
 
-        public EncKDCRepPart(DerValue encoding, int rep_type)
-                throws Asn1Exception, IOException, RealmException
-                {
-                init(encoding, rep_type);
+    /**
+     * Initializes an EncKDCRepPart object.
+     *
+     * @param encoding a single DER-encoded value.
+     * @param rep_type type of the encrypted reply message.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     * @exception RealmException if an error occurs while decoding an Realm object.
+     */
+    protected void init(DerValue encoding, int rep_type)
+            throws Asn1Exception, IOException, RealmException {
+        DerValue der, subDer;
+        //implementations return the incorrect tag value, so
+        //we don't use the above line; instead we use the following
+        msgType = (encoding.getTag() & (byte) 0x1F);
+        if (msgType != Krb5.KRB_ENC_AS_REP_PART &&
+                msgType != Krb5.KRB_ENC_TGS_REP_PART) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
-
-        /**
-         * Initializes an EncKDCRepPart object.
-         *
-         * @param encoding a single DER-encoded value.
-         * @param rep_type type of the encrypted reply message.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         * @exception RealmException if an error occurs while decoding an Realm object.
-         */
-        protected void init(DerValue encoding, int rep_type)
-                throws Asn1Exception, IOException, RealmException
-                 {
-                DerValue der, subDer;
-                //implementations return the incorrect tag value, so
-                //we don't use the above line; instead we use the following
-                msgType = (encoding.getTag() & (byte)0x1F);
-        if (msgType != Krb5.KRB_ENC_AS_REP_PART &&
-                        msgType != Krb5.KRB_ENC_TGS_REP_PART)
-            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                der = encoding.getData().getDerValue();
-        if (der.getTag() != DerValue.tag_Sequence)
+        der = encoding.getData().getDerValue();
+        if (der.getTag() != DerValue.tag_Sequence) {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                key = EncryptionKey.parse(der.getData(), (byte)0x00, false);
-                lastReq = LastReq.parse(der.getData(), (byte)0x01, false);
-                subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & (byte)0x1F) == (byte)0x02)
-                        nonce = subDer.getData().getBigInteger().intValue();
-                else  throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                keyExpiration = KerberosTime.parse(der.getData(), (byte)0x03, true);
-                flags = TicketFlags.parse(der.getData(), (byte)0x04, false);
-                authtime =      KerberosTime.parse(der.getData(), (byte)0x05, false);
-                starttime = KerberosTime.parse(der.getData(), (byte)0x06, true);
-                endtime = KerberosTime.parse(der.getData(), (byte)0x07, false);
-                renewTill = KerberosTime.parse(der.getData(), (byte)0x08, true);
-                srealm = Realm.parse(der.getData(), (byte)0x09, false);
-                sname = PrincipalName.parse(der.getData(), (byte)0x0A, false);
-                if (der.getData().available() > 0)
-                        caddr = HostAddresses.parse(der.getData(), (byte)0x0B, true);
-                if (der.getData().available() > 0)
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        key = EncryptionKey.parse(der.getData(), (byte) 0x00, false);
+        lastReq = LastReq.parse(der.getData(), (byte) 0x01, false);
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x02) {
+            nonce = subDer.getData().getBigInteger().intValue();
+        } else {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
+        keyExpiration = KerberosTime.parse(der.getData(), (byte) 0x03, true);
+        flags = TicketFlags.parse(der.getData(), (byte) 0x04, false);
+        authtime = KerberosTime.parse(der.getData(), (byte) 0x05, false);
+        starttime = KerberosTime.parse(der.getData(), (byte) 0x06, true);
+        endtime = KerberosTime.parse(der.getData(), (byte) 0x07, false);
+        renewTill = KerberosTime.parse(der.getData(), (byte) 0x08, true);
+        srealm = Realm.parse(der.getData(), (byte) 0x09, false);
+        sname = PrincipalName.parse(der.getData(), (byte) 0x0A, false);
+        if (der.getData().available() > 0) {
+            caddr = HostAddresses.parse(der.getData(), (byte) 0x0B, true);
+        }
+        if (der.getData().available() > 0) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+    }
 
-        /**
-         * Encodes an EncKDCRepPart object.
-         * @param rep_type type of encrypted reply message.
-         * @return byte array of encoded EncKDCRepPart object.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         */
-        public byte[] asn1Encode(int rep_type) throws Asn1Exception,
-                IOException {
+    /**
+     * Encodes an EncKDCRepPart object.
+     * @param rep_type type of encrypted reply message.
+     * @return byte array of encoded EncKDCRepPart object.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    public byte[] asn1Encode(int rep_type) throws Asn1Exception,
+            IOException {
         DerOutputStream temp = new DerOutputStream();
         DerOutputStream bytes = new DerOutputStream();
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), key.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), lastReq.asn1Encode());
-                temp.putInteger(BigInteger.valueOf(nonce));
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp);
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x00), key.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x01), lastReq.asn1Encode());
+        temp.putInteger(BigInteger.valueOf(nonce));
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x02), temp);
 
-                if (keyExpiration != null)
-                        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), keyExpiration.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), flags.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), authtime.asn1Encode());
-                if (starttime != null)
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), starttime.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), endtime.asn1Encode());
-                if (renewTill != null)
-             bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), renewTill.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), srealm.asn1Encode());
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), sname.asn1Encode());
-                if (caddr != null)
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0B), caddr.asn1Encode());
-                //should use the rep_type to build the encoding
-                //but other implementations do not; it is ignored and
-                //the cached msgType is used instead
-                temp = new DerOutputStream();
-                temp.write(DerValue.tag_Sequence, bytes);
-                bytes = new DerOutputStream();
-                bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)msgType), temp);
-                return bytes.toByteArray();
+        if (keyExpiration != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x03), keyExpiration.asn1Encode());
+        }
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x04), flags.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x05), authtime.asn1Encode());
+        if (starttime != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x06), starttime.asn1Encode());
+        }
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x07), endtime.asn1Encode());
+        if (renewTill != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x08), renewTill.asn1Encode());
         }
-
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x09), srealm.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x0A), sname.asn1Encode());
+        if (caddr != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x0B), caddr.asn1Encode());
+        }
+        //should use the rep_type to build the encoding
+        //but other implementations do not; it is ignored and
+        //the cached msgType is used instead
+        temp = new DerOutputStream();
+        temp.write(DerValue.tag_Sequence, bytes);
+        bytes = new DerOutputStream();
+        bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION,
+                true, (byte) msgType), temp);
+        return bytes.toByteArray();
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/EncKrbCredPart.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/EncKrbCredPart.java	Mon Apr 14 11:34:15 2008 -0700
@@ -36,6 +36,7 @@
 import java.util.Vector;
 import java.io.IOException;
 import java.math.BigInteger;
+
 /**
  * Implements the ASN.1 EncKrbCredPart type.
  *
@@ -57,148 +58,158 @@
  * http://www.ietf.org/rfc/rfc4120.txt</a>.
  */
 public class EncKrbCredPart {
-        public KrbCredInfo[] ticketInfo = null;
-        public KerberosTime timeStamp; //optional
 
-        private Integer nonce; //optional
-        private Integer usec; //optional
-        private HostAddress sAddress; //optional
-        private HostAddresses rAddress; //optional
+    public KrbCredInfo[] ticketInfo = null;
+    public KerberosTime timeStamp; //optional
+    private Integer nonce; //optional
+    private Integer usec; //optional
+    private HostAddress sAddress; //optional
+    private HostAddresses rAddress; //optional
 
-        public EncKrbCredPart(
-                KrbCredInfo[] new_ticketInfo,
-                KerberosTime new_timeStamp,
-                Integer new_usec,
-                Integer new_nonce,
-                HostAddress new_sAddress,
-                HostAddresses new_rAddress
-        ) throws IOException {
-                if (new_ticketInfo != null) {
-                   ticketInfo = new KrbCredInfo[new_ticketInfo.length];
-                   for (int i = 0; i < new_ticketInfo.length; i++) {
-                        if (new_ticketInfo[i] == null) {
-                           throw new IOException("Cannot create a EncKrbCredPart");
-                        } else {
-                           ticketInfo[i] = (KrbCredInfo)new_ticketInfo[i].clone();
-                        }
-                   }
+    public EncKrbCredPart(
+            KrbCredInfo[] new_ticketInfo,
+            KerberosTime new_timeStamp,
+            Integer new_usec,
+            Integer new_nonce,
+            HostAddress new_sAddress,
+            HostAddresses new_rAddress) throws IOException {
+        if (new_ticketInfo != null) {
+            ticketInfo = new KrbCredInfo[new_ticketInfo.length];
+            for (int i = 0; i < new_ticketInfo.length; i++) {
+                if (new_ticketInfo[i] == null) {
+                    throw new IOException("Cannot create a EncKrbCredPart");
+                } else {
+                    ticketInfo[i] = (KrbCredInfo) new_ticketInfo[i].clone();
                 }
-                timeStamp = new_timeStamp;
-                usec = new_usec;
-                nonce = new_nonce;
-                sAddress = new_sAddress;
-                rAddress = new_rAddress;
-        }
-
-        public EncKrbCredPart(byte[] data) throws Asn1Exception,
-                IOException, RealmException {
-                init(new DerValue(data));
-        }
-
-        public EncKrbCredPart(DerValue encoding) throws Asn1Exception,
-                IOException, RealmException {
-                init(encoding);
+            }
         }
+        timeStamp = new_timeStamp;
+        usec = new_usec;
+        nonce = new_nonce;
+        sAddress = new_sAddress;
+        rAddress = new_rAddress;
+    }
 
-        /**
-         * Initializes an EncKrbCredPart object.
-         * @param encoding a single DER-encoded value.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         * @exception RealmException if an error occurs while parsing a Realm object.
-         */
-        private void init(DerValue encoding) throws Asn1Exception,
-                IOException, RealmException {
-                DerValue der, subDer;
-                        //may not be the correct error code for a tag
-                        //mismatch on an encrypted structure
-                nonce = null;
-                timeStamp = null;
-                usec= null;
+    public EncKrbCredPart(byte[] data) throws Asn1Exception,
+            IOException, RealmException {
+        init(new DerValue(data));
+    }
+
+    public EncKrbCredPart(DerValue encoding) throws Asn1Exception,
+            IOException, RealmException {
+        init(encoding);
+    }
+
+    /**
+     * Initializes an EncKrbCredPart object.
+     * @param encoding a single DER-encoded value.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     * @exception RealmException if an error occurs while parsing a Realm object.
+     */
+    private void init(DerValue encoding) throws Asn1Exception,
+            IOException, RealmException {
+        DerValue der, subDer;
+        //may not be the correct error code for a tag
+        //mismatch on an encrypted structure
+        nonce = null;
+        timeStamp = null;
+        usec = null;
         sAddress = null;
         rAddress = null;
-        if (((encoding.getTag() & (byte)0x1F) != (byte)0x1D)
-             || (encoding.isApplication() != true)
-                        || (encoding.isConstructed() != true))
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-        der = encoding.getData().getDerValue();
-        if (der.getTag() != DerValue.tag_Sequence)
+        if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1D)
+                || (encoding.isApplication() != true)
+                || (encoding.isConstructed() != true)) {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-
-                subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & (byte)0x1F) == (byte)0x00) {
-           DerValue derValues[] = subDer.getData().getSequence(1);
-                   ticketInfo = new KrbCredInfo[derValues.length];
-                   for (int i = 0; i < derValues.length; i++) {
-                           ticketInfo[i] = new KrbCredInfo(derValues[i]);
-                   }
-                }
-        else
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                if (der.getData().available() > 0) {
-                        if (((byte)(der.getData().peekByte()) & (byte)0x1F) == (byte)0x01) {
-                                subDer = der.getData().getDerValue();
-                                nonce = new Integer(subDer.getData().getBigInteger().intValue());
-                        }
-                }
-                if (der.getData().available() >0) {
-                        timeStamp = KerberosTime.parse(der.getData(), (byte)0x02, true);
-                }
-        if (der.getData().available() >0) {
-                        if (((byte)(der.getData().peekByte()) & (byte)0x1F) == (byte)0x03) {
-                                subDer = der.getData().getDerValue();
-                                usec = new Integer(subDer.getData().getBigInteger().intValue());
-                        }
-                }
-        if (der.getData().available() >0) {
-                        sAddress = HostAddress.parse(der.getData(), (byte)0x04, true);
-                }
-        if (der.getData().available() >0) {
-                        rAddress = HostAddresses.parse(der.getData(), (byte)0x05, true);
-                }
-        if (der.getData().available() >0)
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        der = encoding.getData().getDerValue();
+        if (der.getTag() != DerValue.tag_Sequence) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
 
-       /**
-        * Encodes an EncKrbCredPart object.
-        * @return byte array of encoded EncKrbCredPart object.
-        * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-        * @exception IOException if an I/O error occurs while reading encoded data.
-        *
-        */
-        public byte[] asn1Encode() throws Asn1Exception, IOException{
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x00) {
+            DerValue derValues[] = subDer.getData().getSequence(1);
+            ticketInfo = new KrbCredInfo[derValues.length];
+            for (int i = 0; i < derValues.length; i++) {
+                ticketInfo[i] = new KrbCredInfo(derValues[i]);
+            }
+        } else {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        if (der.getData().available() > 0) {
+            if (((byte) (der.getData().peekByte()) & (byte) 0x1F) == (byte) 0x01) {
+                subDer = der.getData().getDerValue();
+                nonce = new Integer(subDer.getData().getBigInteger().intValue());
+            }
+        }
+        if (der.getData().available() > 0) {
+            timeStamp = KerberosTime.parse(der.getData(), (byte) 0x02, true);
+        }
+        if (der.getData().available() > 0) {
+            if (((byte) (der.getData().peekByte()) & (byte) 0x1F) == (byte) 0x03) {
+                subDer = der.getData().getDerValue();
+                usec = new Integer(subDer.getData().getBigInteger().intValue());
+            }
+        }
+        if (der.getData().available() > 0) {
+            sAddress = HostAddress.parse(der.getData(), (byte) 0x04, true);
+        }
+        if (der.getData().available() > 0) {
+            rAddress = HostAddresses.parse(der.getData(), (byte) 0x05, true);
+        }
+        if (der.getData().available() > 0) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+    }
+
+    /**
+     * Encodes an EncKrbCredPart object.
+     * @return byte array of encoded EncKrbCredPart object.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     *
+     */
+    public byte[] asn1Encode() throws Asn1Exception, IOException {
         DerOutputStream bytes = new DerOutputStream();
-            DerOutputStream temp = new DerOutputStream();
-                DerValue[] tickets = new DerValue[ticketInfo.length];
-                for (int i = 0; i < ticketInfo.length; i++)
-                        tickets[i] = new DerValue(ticketInfo[i].asn1Encode());
-                temp.putSequence(tickets);
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
+        DerOutputStream temp = new DerOutputStream();
+        DerValue[] tickets = new DerValue[ticketInfo.length];
+        for (int i = 0; i < ticketInfo.length; i++) {
+            tickets[i] = new DerValue(ticketInfo[i].asn1Encode());
+        }
+        temp.putSequence(tickets);
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x00), temp);
 
-                if (nonce != null) {
+        if (nonce != null) {
             temp = new DerOutputStream();
-                        temp.putInteger(BigInteger.valueOf(nonce.intValue()));
-                        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
-                }
+            temp.putInteger(BigInteger.valueOf(nonce.intValue()));
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x01), temp);
+        }
         if (timeStamp != null) {
-                        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), timeStamp.asn1Encode());
-                }
-                if (usec != null) {
-                        temp = new DerOutputStream();
-                        temp.putInteger(BigInteger.valueOf(usec.intValue()));
-                        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp);
-                }
-                if (sAddress != null) {
-                        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), sAddress.asn1Encode());
-                }
-                if (rAddress != null) {
-                        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), rAddress.asn1Encode());
-                }
-                temp = new DerOutputStream();
-                temp.write(DerValue.tag_Sequence, bytes);
-                bytes = new DerOutputStream();
-                bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x1D), temp);
-                return bytes.toByteArray();
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x02), timeStamp.asn1Encode());
+        }
+        if (usec != null) {
+            temp = new DerOutputStream();
+            temp.putInteger(BigInteger.valueOf(usec.intValue()));
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x03), temp);
+        }
+        if (sAddress != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x04), sAddress.asn1Encode());
         }
+        if (rAddress != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x05), rAddress.asn1Encode());
+        }
+        temp = new DerOutputStream();
+        temp.write(DerValue.tag_Sequence, bytes);
+        bytes = new DerOutputStream();
+        bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION,
+                true, (byte) 0x1D), temp);
+        return bytes.toByteArray();
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/EncKrbPrivPart.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/EncKrbPrivPart.java	Mon Apr 14 11:34:15 2008 -0700
@@ -55,114 +55,119 @@
  * <a href="http://www.ietf.org/rfc/rfc4120.txt">
  * http://www.ietf.org/rfc/rfc4120.txt</a>.
  */
+public class EncKrbPrivPart {
 
-public class EncKrbPrivPart {
-        public byte[] userData = null;
-        public KerberosTime timestamp; //optional
-        public Integer usec; //optional
-        public Integer seqNumber; //optional
-        public HostAddress sAddress; //optional
-        public HostAddress rAddress; //optional
+    public byte[] userData = null;
+    public KerberosTime timestamp; //optional
+    public Integer usec; //optional
+    public Integer seqNumber; //optional
+    public HostAddress sAddress; //optional
+    public HostAddress rAddress; //optional
 
-        public EncKrbPrivPart(
-                byte[] new_userData,
-                KerberosTime new_timestamp,
-                Integer new_usec,
-                Integer new_seqNumber,
-                HostAddress new_sAddress,
-                HostAddress new_rAddress
-        ) {
-                if (new_userData != null) {
-                   userData = new_userData.clone();
-                }
-                timestamp = new_timestamp;
-                usec = new_usec;
-                seqNumber = new_seqNumber;
-                sAddress = new_sAddress;
-                rAddress = new_rAddress;
+    public EncKrbPrivPart(
+            byte[] new_userData,
+            KerberosTime new_timestamp,
+            Integer new_usec,
+            Integer new_seqNumber,
+            HostAddress new_sAddress,
+            HostAddress new_rAddress) {
+        if (new_userData != null) {
+            userData = new_userData.clone();
         }
+        timestamp = new_timestamp;
+        usec = new_usec;
+        seqNumber = new_seqNumber;
+        sAddress = new_sAddress;
+        rAddress = new_rAddress;
+    }
 
-        public EncKrbPrivPart(byte[] data) throws Asn1Exception, IOException {
-                init(new DerValue(data));
-        }
+    public EncKrbPrivPart(byte[] data) throws Asn1Exception, IOException {
+        init(new DerValue(data));
+    }
 
-        public EncKrbPrivPart(DerValue encoding) throws Asn1Exception, IOException {
-                init(encoding);
-        }
+    public EncKrbPrivPart(DerValue encoding) throws Asn1Exception, IOException {
+        init(encoding);
+    }
 
-        /**
-         * Initializes an EncKrbPrivPart object.
-         * @param encoding a single DER-encoded value.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         */
-        private void init(DerValue encoding) throws Asn1Exception, IOException {
+    /**
+     * Initializes an EncKrbPrivPart object.
+     * @param encoding a single DER-encoded value.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    private void init(DerValue encoding) throws Asn1Exception, IOException {
         DerValue der, subDer;
-                if (((encoding.getTag() & (byte)0x1F) != (byte)0x1C)
-                        || (encoding.isApplication() != true)
-                        || (encoding.isConstructed() != true))
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                der = encoding.getData().getDerValue();
-        if (der.getTag() != DerValue.tag_Sequence)
+        if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1C)
+                || (encoding.isApplication() != true)
+                || (encoding.isConstructed() != true)) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        der = encoding.getData().getDerValue();
+        if (der.getTag() != DerValue.tag_Sequence) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x00) {
+            userData = subDer.getData().getOctetString();
+        } else {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & (byte)0x1F) == (byte)0x00) {
-                        userData = subDer.getData().getOctetString();
-                }
-        else
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                timestamp = KerberosTime.parse(der.getData(), (byte)0x01, true);
-                if ((der.getData().peekByte() & 0x1F) == 0x02) {
-                        subDer = der.getData().getDerValue();
-                        usec = new Integer(subDer.getData().getBigInteger().intValue());
-                }
-                else usec = null;
-                if ((der.getData().peekByte() & 0x1F) == 0x03 ) {
-                        subDer = der.getData().getDerValue();
-                        seqNumber = new Integer(subDer.getData().getBigInteger().intValue());
-                }
-                else seqNumber = null;
-                sAddress = HostAddress.parse(der.getData(), (byte)0x04, false);
-                if (der.getData().available() > 0) {
-                        rAddress = HostAddress.parse(der.getData(), (byte)0x05, true);
-                }
-                if (der.getData().available() > 0)
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        timestamp = KerberosTime.parse(der.getData(), (byte) 0x01, true);
+        if ((der.getData().peekByte() & 0x1F) == 0x02) {
+            subDer = der.getData().getDerValue();
+            usec = new Integer(subDer.getData().getBigInteger().intValue());
+        } else {
+            usec = null;
+        }
+        if ((der.getData().peekByte() & 0x1F) == 0x03) {
+            subDer = der.getData().getDerValue();
+            seqNumber = new Integer(subDer.getData().getBigInteger().intValue());
+        } else {
+            seqNumber = null;
         }
+        sAddress = HostAddress.parse(der.getData(), (byte) 0x04, false);
+        if (der.getData().available() > 0) {
+            rAddress = HostAddress.parse(der.getData(), (byte) 0x05, true);
+        }
+        if (der.getData().available() > 0) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+    }
 
-       /**
-        * Encodes an EncKrbPrivPart object.
-        * @return byte array of encoded EncKrbPrivPart object.
-        * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-        * @exception IOException if an I/O error occurs while reading encoded data.
-        */
-        public byte[] asn1Encode() throws Asn1Exception, IOException {
+    /**
+     * Encodes an EncKrbPrivPart object.
+     * @return byte array of encoded EncKrbPrivPart object.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    public byte[] asn1Encode() throws Asn1Exception, IOException {
         DerOutputStream temp = new DerOutputStream();
         DerOutputStream bytes = new DerOutputStream();
 
-                temp.putOctetString(userData);
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
-                if (timestamp != null)
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), timestamp.asn1Encode());
-                if (usec != null) {
-                        temp = new DerOutputStream();
-                        temp.putInteger(BigInteger.valueOf(usec.intValue()));
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp);
-                }
-                if (seqNumber != null) {
-                        temp = new DerOutputStream();
-                        // encode as an unsigned integer (UInt32)
-                        temp.putInteger(BigInteger.valueOf(seqNumber.longValue()));
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp);
-                }
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), sAddress.asn1Encode());
-                if (rAddress != null) {
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), rAddress.asn1Encode());
-                }
-                temp = new DerOutputStream();
-                temp.write(DerValue.tag_Sequence, bytes);
-                bytes = new DerOutputStream();
-                bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x1C), temp);
-                return bytes.toByteArray();
+        temp.putOctetString(userData);
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp);
+        if (timestamp != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), timestamp.asn1Encode());
+        }
+        if (usec != null) {
+            temp = new DerOutputStream();
+            temp.putInteger(BigInteger.valueOf(usec.intValue()));
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), temp);
         }
+        if (seqNumber != null) {
+            temp = new DerOutputStream();
+            // encode as an unsigned integer (UInt32)
+            temp.putInteger(BigInteger.valueOf(seqNumber.longValue()));
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), temp);
+        }
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), sAddress.asn1Encode());
+        if (rAddress != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x05), rAddress.asn1Encode());
+        }
+        temp = new DerOutputStream();
+        temp.write(DerValue.tag_Sequence, bytes);
+        bytes = new DerOutputStream();
+        bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x1C), temp);
+        return bytes.toByteArray();
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java	Mon Apr 14 11:34:15 2008 -0700
@@ -35,55 +35,52 @@
 
 public class EncTGSRepPart extends EncKDCRepPart {
 
-        public EncTGSRepPart(
-                EncryptionKey new_key,
-                LastReq new_lastReq,
-                int new_nonce,
-                KerberosTime new_keyExpiration,
-                TicketFlags new_flags,
-                KerberosTime new_authtime,
-                KerberosTime new_starttime,
-                KerberosTime new_endtime,
-                KerberosTime new_renewTill,
-                Realm new_srealm,
-                PrincipalName new_sname,
-                HostAddresses new_caddr
-        ) {
-                super(
-                        new_key,
-                        new_lastReq,
-                        new_nonce,
-                        new_keyExpiration,
-                        new_flags,
-                        new_authtime,
-                        new_starttime,
-                        new_endtime,
-                        new_renewTill,
-                        new_srealm,
-                        new_sname,
-                        new_caddr,
-                        Krb5.KRB_ENC_TGS_REP_PART
-                );
-        }
+    public EncTGSRepPart(
+            EncryptionKey new_key,
+            LastReq new_lastReq,
+            int new_nonce,
+            KerberosTime new_keyExpiration,
+            TicketFlags new_flags,
+            KerberosTime new_authtime,
+            KerberosTime new_starttime,
+            KerberosTime new_endtime,
+            KerberosTime new_renewTill,
+            Realm new_srealm,
+            PrincipalName new_sname,
+            HostAddresses new_caddr) {
+        super(
+                new_key,
+                new_lastReq,
+                new_nonce,
+                new_keyExpiration,
+                new_flags,
+                new_authtime,
+                new_starttime,
+                new_endtime,
+                new_renewTill,
+                new_srealm,
+                new_sname,
+                new_caddr,
+                Krb5.KRB_ENC_TGS_REP_PART);
+    }
 
-        public EncTGSRepPart(byte[] data) throws Asn1Exception,
-                IOException, KrbException {
-                init(new DerValue(data));
-        }
+    public EncTGSRepPart(byte[] data) throws Asn1Exception,
+            IOException, KrbException {
+        init(new DerValue(data));
+    }
 
-        public EncTGSRepPart(DerValue encoding) throws Asn1Exception,
-                IOException, KrbException {
-                init(encoding);
-        }
+    public EncTGSRepPart(DerValue encoding) throws Asn1Exception,
+            IOException, KrbException {
+        init(encoding);
+    }
 
-        private void init(DerValue encoding) throws Asn1Exception,
-                IOException, KrbException {
-                init(encoding, Krb5.KRB_ENC_TGS_REP_PART);
-        }
+    private void init(DerValue encoding) throws Asn1Exception,
+            IOException, KrbException {
+        init(encoding, Krb5.KRB_ENC_TGS_REP_PART);
+    }
 
-        public byte[] asn1Encode() throws Asn1Exception,
-                IOException {
-                return asn1Encode(Krb5.KRB_ENC_TGS_REP_PART);
-        }
-
+    public byte[] asn1Encode() throws Asn1Exception,
+            IOException {
+        return asn1Encode(Krb5.KRB_ENC_TGS_REP_PART);
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/EncTicketPart.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/EncTicketPart.java	Mon Apr 14 11:34:15 2008 -0700
@@ -62,69 +62,68 @@
  * http://www.ietf.org/rfc/rfc4120.txt</a>.
  */
 public class EncTicketPart {
-        public TicketFlags flags;
-        public EncryptionKey key;
-        public Realm crealm;
-        public PrincipalName cname;
-        public TransitedEncoding transited;
-        public KerberosTime authtime;
-        public KerberosTime starttime; //optional
-        public KerberosTime endtime;
-        public KerberosTime renewTill; //optional
-        public HostAddresses caddr; //optional
-        public AuthorizationData authorizationData; //optional
+
+    public TicketFlags flags;
+    public EncryptionKey key;
+    public Realm crealm;
+    public PrincipalName cname;
+    public TransitedEncoding transited;
+    public KerberosTime authtime;
+    public KerberosTime starttime; //optional
+    public KerberosTime endtime;
+    public KerberosTime renewTill; //optional
+    public HostAddresses caddr; //optional
+    public AuthorizationData authorizationData; //optional
 
-        public EncTicketPart(
-                TicketFlags new_flags,
-                EncryptionKey new_key,
-                Realm new_crealm,
-                PrincipalName new_cname,
-                TransitedEncoding new_transited,
-                KerberosTime new_authtime,
-                KerberosTime new_starttime,
-                KerberosTime new_endtime,
-                KerberosTime new_renewTill,
-                HostAddresses new_caddr,
-                AuthorizationData new_authorizationData
-        ) {
-                flags = new_flags;
-                key = new_key;
-                crealm = new_crealm;
-                cname = new_cname;
-                transited = new_transited;
-                authtime = new_authtime;
-                starttime = new_starttime;
-                endtime = new_endtime;
-                renewTill = new_renewTill;
-                caddr = new_caddr;
-                authorizationData = new_authorizationData;
-        }
+    public EncTicketPart(
+            TicketFlags new_flags,
+            EncryptionKey new_key,
+            Realm new_crealm,
+            PrincipalName new_cname,
+            TransitedEncoding new_transited,
+            KerberosTime new_authtime,
+            KerberosTime new_starttime,
+            KerberosTime new_endtime,
+            KerberosTime new_renewTill,
+            HostAddresses new_caddr,
+            AuthorizationData new_authorizationData) {
+        flags = new_flags;
+        key = new_key;
+        crealm = new_crealm;
+        cname = new_cname;
+        transited = new_transited;
+        authtime = new_authtime;
+        starttime = new_starttime;
+        endtime = new_endtime;
+        renewTill = new_renewTill;
+        caddr = new_caddr;
+        authorizationData = new_authorizationData;
+    }
 
-        public EncTicketPart(byte[] data)
-                throws Asn1Exception, KrbException, IOException {
-                init(new DerValue(data));
-        }
+    public EncTicketPart(byte[] data)
+            throws Asn1Exception, KrbException, IOException {
+        init(new DerValue(data));
+    }
 
-        public EncTicketPart(DerValue encoding)
-                throws Asn1Exception, KrbException, IOException {
-                init(encoding);
-        }
+    public EncTicketPart(DerValue encoding)
+            throws Asn1Exception, KrbException, IOException {
+        init(encoding);
+    }
 
-   /**
-    * Initializes an EncTicketPart object.
-    * @param encoding a single DER-encoded value.
-    * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-    * @exception IOException if an I/O error occurs while reading encoded data.
-    * @exception RealmException if an error occurs while parsing a Realm object.
-    */
-
+    /**
+     * Initializes an EncTicketPart object.
+     * @param encoding a single DER-encoded value.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     * @exception RealmException if an error occurs while parsing a Realm object.
+     */
     private static String getHexBytes(byte[] bytes, int len)
-        throws IOException {
+            throws IOException {
 
         StringBuffer sb = new StringBuffer();
         for (int i = 0; i < len; i++) {
 
-            int b1 = (bytes[i]>>4) & 0x0f;
+            int b1 = (bytes[i] >> 4) & 0x0f;
             int b2 = bytes[i] & 0x0f;
 
             sb.append(Integer.toHexString(b1));
@@ -134,73 +133,91 @@
         return sb.toString();
     }
 
-        private void init(DerValue encoding)
-                throws Asn1Exception, IOException, RealmException {
-            DerValue der, subDer;
+    private void init(DerValue encoding)
+            throws Asn1Exception, IOException, RealmException {
+        DerValue der, subDer;
 
-            renewTill = null;
-            caddr = null;
-            authorizationData = null;
-            if (((encoding.getTag() & (byte)0x1F) != (byte)0x03)
+        renewTill = null;
+        caddr = null;
+        authorizationData = null;
+        if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x03)
                 || (encoding.isApplication() != true)
-                || (encoding.isConstructed() != true))
-                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-            der = encoding.getData().getDerValue();
-            if (der.getTag() != DerValue.tag_Sequence)
-                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-            flags = TicketFlags.parse(der.getData(), (byte)0x00, false);
-            key = EncryptionKey.parse(der.getData(), (byte)0x01, false);
-            crealm = Realm.parse(der.getData(), (byte)0x02, false);
-            cname = PrincipalName.parse(der.getData(), (byte)0x03, false);
-            transited = TransitedEncoding.parse(der.getData(), (byte)0x04, false);
-            authtime = KerberosTime.parse(der.getData(), (byte)0x05, false);
-            starttime = KerberosTime.parse(der.getData(), (byte)0x06, true);
-            endtime = KerberosTime.parse(der.getData(), (byte)0x07, false);
-            if (der.getData().available() > 0) {
-                renewTill = KerberosTime.parse(der.getData(), (byte)0x08, true);
-            }
-            if (der.getData().available() > 0) {
-                caddr = HostAddresses.parse(der.getData(), (byte)0x09, true);
-            }
-            if (der.getData().available() > 0) {
-                authorizationData = AuthorizationData.parse(der.getData(), (byte)0x0A, true);
-            }
-            if (der.getData().available() > 0)
-                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-
+                || (encoding.isConstructed() != true)) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        der = encoding.getData().getDerValue();
+        if (der.getTag() != DerValue.tag_Sequence) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        flags = TicketFlags.parse(der.getData(), (byte) 0x00, false);
+        key = EncryptionKey.parse(der.getData(), (byte) 0x01, false);
+        crealm = Realm.parse(der.getData(), (byte) 0x02, false);
+        cname = PrincipalName.parse(der.getData(), (byte) 0x03, false);
+        transited = TransitedEncoding.parse(der.getData(), (byte) 0x04, false);
+        authtime = KerberosTime.parse(der.getData(), (byte) 0x05, false);
+        starttime = KerberosTime.parse(der.getData(), (byte) 0x06, true);
+        endtime = KerberosTime.parse(der.getData(), (byte) 0x07, false);
+        if (der.getData().available() > 0) {
+            renewTill = KerberosTime.parse(der.getData(), (byte) 0x08, true);
+        }
+        if (der.getData().available() > 0) {
+            caddr = HostAddresses.parse(der.getData(), (byte) 0x09, true);
+        }
+        if (der.getData().available() > 0) {
+            authorizationData = AuthorizationData.parse(der.getData(), (byte) 0x0A, true);
+        }
+        if (der.getData().available() > 0) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
 
-       /**
-        * Encodes an EncTicketPart object.
-        * @return byte array of encoded EncTicketPart object.
-        * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-        * @exception IOException if an I/O error occurs while reading encoded data.
-        */
+    }
 
-        public byte[] asn1Encode() throws Asn1Exception, IOException {
+    /**
+     * Encodes an EncTicketPart object.
+     * @return byte array of encoded EncTicketPart object.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    public byte[] asn1Encode() throws Asn1Exception, IOException {
         DerOutputStream bytes = new DerOutputStream();
-            DerOutputStream temp = new DerOutputStream();
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), flags.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), key.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), crealm.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), cname.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), transited.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), authtime.asn1Encode());
-                if (starttime != null)
-           bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), starttime.asn1Encode());
-        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), endtime.asn1Encode());
+        DerOutputStream temp = new DerOutputStream();
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x00), flags.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x01), key.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x02), crealm.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x03), cname.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x04), transited.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x05), authtime.asn1Encode());
+        if (starttime != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x06), starttime.asn1Encode());
+        }
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x07), endtime.asn1Encode());
 
-                if (renewTill != null)
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), renewTill.asn1Encode());
+        if (renewTill != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x08), renewTill.asn1Encode());
+        }
 
-                if (caddr != null)
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), caddr.asn1Encode());
+        if (caddr != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x09), caddr.asn1Encode());
+        }
 
-                if (authorizationData != null)
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), authorizationData.asn1Encode());
-                temp.write(DerValue.tag_Sequence, bytes);
-                bytes = new DerOutputStream();
-                bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x03), temp);
-                return bytes.toByteArray();
+        if (authorizationData != null) {
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x0A), authorizationData.asn1Encode());
         }
+        temp.write(DerValue.tag_Sequence, bytes);
+        bytes = new DerOutputStream();
+        bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION,
+                true, (byte) 0x03), temp);
+        return bytes.toByteArray();
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/KDCRep.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/KDCRep.java	Mon Apr 14 11:34:15 2008 -0700
@@ -35,6 +35,7 @@
 import java.util.Vector;
 import java.io.IOException;
 import java.math.BigInteger;
+
 /**
  * Implements the ASN.1 KDC-REP type.
  *
@@ -59,163 +60,168 @@
  * <a href="http://www.ietf.org/rfc/rfc4120.txt">
  * http://www.ietf.org/rfc/rfc4120.txt</a>.
  */
+public class KDCRep {
 
-public class KDCRep {
-        public Realm crealm;
-        public PrincipalName cname;
-        public Ticket ticket;
-        public EncryptedData encPart;
-        public EncKDCRepPart encKDCRepPart; //not part of ASN.1 encoding
-
-        private int pvno;
-        private int msgType;
-        private PAData[] pAData = null; //optional
-        private boolean DEBUG = Krb5.DEBUG;
+    public Realm crealm;
+    public PrincipalName cname;
+    public Ticket ticket;
+    public EncryptedData encPart;
+    public EncKDCRepPart encKDCRepPart; //not part of ASN.1 encoding
+    private int pvno;
+    private int msgType;
+    private PAData[] pAData = null; //optional
+    private boolean DEBUG = Krb5.DEBUG;
 
-        public KDCRep(
-                PAData[] new_pAData,
-                Realm new_crealm,
-                PrincipalName new_cname,
-                Ticket new_ticket,
-                EncryptedData new_encPart,
-                int req_type
-        ) throws IOException {
-                pvno = Krb5.PVNO;
-                msgType = req_type;
-                if (new_pAData != null) {
-                    pAData = new PAData[new_pAData.length];
-                    for (int i = 0; i < new_pAData.length; i++) {
-                        if (new_pAData[i] == null) {
-                            throw new IOException("Cannot create a KDCRep");
-                        } else {
-                            pAData[i] = (PAData)new_pAData[i].clone();
-                        }
-                    }
+    public KDCRep(
+            PAData[] new_pAData,
+            Realm new_crealm,
+            PrincipalName new_cname,
+            Ticket new_ticket,
+            EncryptedData new_encPart,
+            int req_type) throws IOException {
+        pvno = Krb5.PVNO;
+        msgType = req_type;
+        if (new_pAData != null) {
+            pAData = new PAData[new_pAData.length];
+            for (int i = 0; i < new_pAData.length; i++) {
+                if (new_pAData[i] == null) {
+                    throw new IOException("Cannot create a KDCRep");
+                } else {
+                    pAData[i] = (PAData) new_pAData[i].clone();
                 }
-                crealm = new_crealm;
-                cname = new_cname;
-                ticket = new_ticket;
-                encPart = new_encPart;
+            }
         }
-
-        public KDCRep() {
-        }
+        crealm = new_crealm;
+        cname = new_cname;
+        ticket = new_ticket;
+        encPart = new_encPart;
+    }
 
-        public KDCRep(byte[] data, int req_type) throws Asn1Exception, KrbApErrException, RealmException, IOException {
-                init(new DerValue(data), req_type);
-        }
+    public KDCRep() {
+    }
 
-        public KDCRep(DerValue encoding, int req_type) throws Asn1Exception,
-                RealmException, KrbApErrException, IOException {
-                init(encoding, req_type);
-        }
+    public KDCRep(byte[] data, int req_type) throws Asn1Exception,
+            KrbApErrException, RealmException, IOException {
+        init(new DerValue(data), req_type);
+    }
+
+    public KDCRep(DerValue encoding, int req_type) throws Asn1Exception,
+            RealmException, KrbApErrException, IOException {
+        init(encoding, req_type);
+    }
 
     /*
     // Not used? Don't know what keyusage to use here %%%
-
-        public void decrypt(EncryptionKey key) throws Asn1Exception,
-                IOException, KrbException, RealmException {
-                encKDCRepPart = new EncKDCRepPart(encPart.decrypt(key),
-                        msgType);
-        }
-*/
-
-        /**
-         * Initializes an KDCRep object.
-         *
-         * @param encoding a single DER-encoded value.
-         * @param req_type reply message type.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         * @exception RealmException if an error occurs while constructing a Realm object from DER-encoded data.
-         * @exception KrbApErrException if the value read from the DER-encoded data stream does not match the pre-defined value.
-         *
-         */
-        protected void init(DerValue encoding, int req_type)
+    public void decrypt(EncryptionKey key) throws Asn1Exception,
+            IOException, KrbException, RealmException {
+        encKDCRepPart = new EncKDCRepPart(encPart.decrypt(key), msgType);
+    }
+     */
+    /**
+     * Initializes an KDCRep object.
+     *
+     * @param encoding a single DER-encoded value.
+     * @param req_type reply message type.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     * @exception RealmException if an error occurs while constructing
+     * a Realm object from DER-encoded data.
+     * @exception KrbApErrException if the value read from the DER-encoded
+     * data stream does not match the pre-defined value.
+     *
+     */
+    protected void init(DerValue encoding, int req_type)
             throws Asn1Exception, RealmException, IOException,
-                   KrbApErrException {
-            DerValue der, subDer;
-            if ((encoding.getTag() & 0x1F) != req_type) {
-                if (DEBUG) {
-                    System.out.println(">>> KDCRep: init() " +
-                                       "encoding tag is " +
-                                       encoding.getTag() +
-                                       " req type is " + req_type);
-                }
-                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-            }
-            der = encoding.getData().getDerValue();
-            if (der.getTag() != DerValue.tag_Sequence) {
-                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+            KrbApErrException {
+        DerValue der, subDer;
+        if ((encoding.getTag() & 0x1F) != req_type) {
+            if (DEBUG) {
+                System.out.println(">>> KDCRep: init() " +
+                        "encoding tag is " +
+                        encoding.getTag() +
+                        " req type is " + req_type);
             }
-            subDer = der.getData().getDerValue();
-            if ((subDer.getTag() & 0x1F) == 0x00) {
-                pvno = subDer.getData().getBigInteger().intValue();
-                if (pvno != Krb5.PVNO)
-                    throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
-            } else {
-                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        der = encoding.getData().getDerValue();
+        if (der.getTag() != DerValue.tag_Sequence) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & 0x1F) == 0x00) {
+            pvno = subDer.getData().getBigInteger().intValue();
+            if (pvno != Krb5.PVNO) {
+                throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
             }
-            subDer = der.getData().getDerValue();
-            if ((subDer.getTag() & 0x1F) == 0x01) {
-                msgType = subDer.getData().getBigInteger().intValue();
-                if (msgType != req_type) {
-                    throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
-                }
-            } else {
-                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        } else {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & 0x1F) == 0x01) {
+            msgType = subDer.getData().getBigInteger().intValue();
+            if (msgType != req_type) {
+                throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
             }
-            if ((der.getData().peekByte() & 0x1F) == 0x02) {
-                subDer = der.getData().getDerValue();
-                DerValue[] padata = subDer.getData().getSequence(1);
-                pAData = new PAData[padata.length];
-                for (int i = 0; i < padata.length; i++) {
-                    pAData[i] = new PAData(padata[i]);
-                }
-            } else {
-                pAData = null;
+        } else {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        if ((der.getData().peekByte() & 0x1F) == 0x02) {
+            subDer = der.getData().getDerValue();
+            DerValue[] padata = subDer.getData().getSequence(1);
+            pAData = new PAData[padata.length];
+            for (int i = 0; i < padata.length; i++) {
+                pAData[i] = new PAData(padata[i]);
             }
-            crealm = Realm.parse(der.getData(), (byte)0x03, false);
-            cname = PrincipalName.parse(der.getData(), (byte)0x04, false);
-            ticket = Ticket.parse(der.getData(), (byte)0x05, false);
-            encPart = EncryptedData.parse(der.getData(), (byte)0x06, false);
-            if (der.getData().available() > 0) {
-                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-            }
+        } else {
+            pAData = null;
+        }
+        crealm = Realm.parse(der.getData(), (byte) 0x03, false);
+        cname = PrincipalName.parse(der.getData(), (byte) 0x04, false);
+        ticket = Ticket.parse(der.getData(), (byte) 0x05, false);
+        encPart = EncryptedData.parse(der.getData(), (byte) 0x06, false);
+        if (der.getData().available() > 0) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
+    }
 
+    /**
+     * Encodes this object to a byte array.
+     * @return byte array of encoded APReq object.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     *
+     */
+    public byte[] asn1Encode() throws Asn1Exception, IOException {
 
-        /**
-         * Encodes this object to a byte array.
-         * @return byte array of encoded APReq object.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         *
-         */
-        public byte[] asn1Encode() throws Asn1Exception, IOException {
-
-            DerOutputStream bytes = new DerOutputStream();
-            DerOutputStream temp = new DerOutputStream();
-            temp.putInteger(BigInteger.valueOf(pvno));
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
+        DerOutputStream bytes = new DerOutputStream();
+        DerOutputStream temp = new DerOutputStream();
+        temp.putInteger(BigInteger.valueOf(pvno));
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x00), temp);
+        temp = new DerOutputStream();
+        temp.putInteger(BigInteger.valueOf(msgType));
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x01), temp);
+        if (pAData != null && pAData.length > 0) {
+            DerOutputStream padata_stream = new DerOutputStream();
+            for (int i = 0; i < pAData.length; i++) {
+                padata_stream.write(pAData[i].asn1Encode());
+            }
             temp = new DerOutputStream();
-            temp.putInteger(BigInteger.valueOf(msgType));
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
-            if (pAData != null && pAData.length > 0) {
-                DerOutputStream padata_stream = new DerOutputStream();
-                for (int i = 0; i < pAData.length; i++) {
-                    padata_stream.write(pAData[i].asn1Encode());
-                }
-                temp = new DerOutputStream();
-                temp.write(DerValue.tag_SequenceOf, padata_stream);
-                bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp);
-            }
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), crealm.asn1Encode());
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), cname.asn1Encode());
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), ticket.asn1Encode());
-            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), encPart.asn1Encode());
-            temp = new DerOutputStream();
-            temp.write(DerValue.tag_Sequence, bytes);
-            return temp.toByteArray();
+            temp.write(DerValue.tag_SequenceOf, padata_stream);
+            bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x02), temp);
         }
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x03), crealm.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x04), cname.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x05), ticket.asn1Encode());
+        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x06), encPart.asn1Encode());
+        temp = new DerOutputStream();
+        temp.write(DerValue.tag_Sequence, bytes);
+        return temp.toByteArray();
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/KDCReq.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/KDCReq.java	Mon Apr 14 11:34:15 2008 -0700
@@ -56,155 +56,160 @@
  * <a href="http://www.ietf.org/rfc/rfc4120.txt">
  * http://www.ietf.org/rfc/rfc4120.txt</a>.
  */
-
 public class KDCReq {
-        public KDCReqBody reqBody;
 
-        private int pvno;
-        private int msgType;
-        private PAData[] pAData = null; //optional
+    public KDCReqBody reqBody;
+    private int pvno;
+    private int msgType;
+    private PAData[] pAData = null; //optional
 
-        public KDCReq(PAData[] new_pAData, KDCReqBody new_reqBody,
-                int req_type) throws IOException {
-                pvno = Krb5.PVNO;
-                msgType = req_type;
-                if (new_pAData != null) {
-                    pAData = new PAData[new_pAData.length];
-                    for (int i = 0; i < new_pAData.length; i++) {
-                        if (new_pAData[i] == null) {
-                            throw new IOException("Cannot create a KDCRep");
-                        } else {
-                            pAData[i] = (PAData)new_pAData[i].clone();
-                        }
-                    }
+    public KDCReq(PAData[] new_pAData, KDCReqBody new_reqBody,
+            int req_type) throws IOException {
+        pvno = Krb5.PVNO;
+        msgType = req_type;
+        if (new_pAData != null) {
+            pAData = new PAData[new_pAData.length];
+            for (int i = 0; i < new_pAData.length; i++) {
+                if (new_pAData[i] == null) {
+                    throw new IOException("Cannot create a KDCRep");
+                } else {
+                    pAData[i] = (PAData) new_pAData[i].clone();
                 }
-                reqBody = new_reqBody;
-        }
-
-        public KDCReq() {
+            }
         }
+        reqBody = new_reqBody;
+    }
 
-        public KDCReq(byte[] data, int req_type) throws Asn1Exception,
-                IOException, KrbException {
+    public KDCReq() {
+    }
+
+    public KDCReq(byte[] data, int req_type) throws Asn1Exception,
+            IOException, KrbException {
         init(new DerValue(data), req_type);
-        }
+    }
+
+    /**
+     * Creates an KDCReq object from a DerValue object and asn1 type.
+     *
+     * @param der a DER value of an KDCReq object.
+     * @param req_type a encoded asn1 type value.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     * @exceptoin KrbErrException
+     */
+    public KDCReq(DerValue der, int req_type) throws Asn1Exception,
+            IOException, KrbException {
+        init(der, req_type);
+    }
 
     /**
-         * Creates an KDCReq object from a DerValue object and asn1 type.
-         *
-         * @param der a DER value of an KDCReq object.
-         * @param req_type a encoded asn1 type value.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         * @exceptoin KrbErrException
-         */
-    public KDCReq(DerValue der, int req_type) throws Asn1Exception,
-                IOException, KrbException {
-                init(der, req_type);
+     * Initializes a KDCReq object from a DerValue.  The DER encoding
+     * must be in the format specified by the KRB_KDC_REQ ASN.1 notation.
+     *
+     * @param encoding a DER-encoded KDCReq object.
+     * @param req_type an int indicating whether it's KRB_AS_REQ or KRB_TGS_REQ type
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     * @exception KrbException if an error occurs while constructing a Realm object,
+     * or a Krb object from DER-encoded data.
+     */
+    protected void init(DerValue encoding, int req_type) throws Asn1Exception,
+            IOException, KrbException {
+        DerValue der, subDer;
+        BigInteger bint;
+        if ((encoding.getTag() & 0x1F) != req_type) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
-
-   /**
-    * Initializes a KDCReq object from a DerValue.  The DER encoding
-    * must be in the format specified by the KRB_KDC_REQ ASN.1 notation.
-    *
-    * @param encoding a DER-encoded KDCReq object.
-    * @param req_type an int indicating whether it's KRB_AS_REQ or KRB_TGS_REQ type
-    * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-    * @exception IOException if an I/O error occurs while reading encoded data.
-    * @exception KrbException if an error occurs while constructing a Realm object,
-    * or a Krb object from DER-encoded data.
-    */
-    protected void init(DerValue encoding, int req_type) throws Asn1Exception,
-                IOException, KrbException {
-                DerValue der, subDer;
-                BigInteger bint;
-                if ((encoding.getTag() & 0x1F) != req_type) {
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                }
-                der = encoding.getData().getDerValue();
-                if (der.getTag() != DerValue.tag_Sequence) {
+        der = encoding.getData().getDerValue();
+        if (der.getTag() != DerValue.tag_Sequence) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & 0x01F) == 0x01) {
+            bint = subDer.getData().getBigInteger();
+            this.pvno = bint.intValue();
+            if (this.pvno != Krb5.PVNO) {
+                throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
+            }
+        } else {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & 0x01F) == 0x02) {
+            bint = subDer.getData().getBigInteger();
+            this.msgType = bint.intValue();
+            if (this.msgType != req_type) {
+                throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
+            }
+        } else {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                }
-                subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & 0x01F) == 0x01) {
-                        bint = subDer.getData().getBigInteger();
-                        this.pvno = bint.intValue();
-            if (this.pvno != Krb5.PVNO)
-                                throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
-                }
-                else
-                 throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & 0x01F) == 0x02) {
-                        bint = subDer.getData().getBigInteger();
-                        this.msgType = bint.intValue();
-            if (this.msgType != req_type)
-                                throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
-                }
-                else
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & 0x01F) == 0x03) {
-                        DerValue subsubDer = subDer.getData().getDerValue();
-                        if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
-                                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                        }
-                        Vector<PAData> v = new Vector<PAData> ();
-                        while (subsubDer.getData().available() > 0) {
-                                v.addElement(new PAData(subsubDer.getData().getDerValue()));
-                        }
-                        if (v.size() > 0) {
-                                pAData = new PAData[v.size()];
-                                v.copyInto(pAData);
-                        }
-                }
-                else pAData = null;
-                subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & 0x01F) == 0x04) {
-                        DerValue subsubDer = subDer.getData().getDerValue();
-                        reqBody = new KDCReqBody(subsubDer, msgType);
-                }
-                else
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        if ((der.getData().peekByte() & 0x1F) == 0x03) {
+            subDer = der.getData().getDerValue();
+            DerValue subsubDer = subDer.getData().getDerValue();
+            if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
+                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+            }
+            Vector<PAData> v = new Vector<PAData>();
+            while (subsubDer.getData().available() > 0) {
+                v.addElement(new PAData(subsubDer.getData().getDerValue()));
+            }
+            if (v.size() > 0) {
+                pAData = new PAData[v.size()];
+                v.copyInto(pAData);
+            }
+        } else {
+            pAData = null;
+        }
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & 0x01F) == 0x04) {
+            DerValue subsubDer = subDer.getData().getDerValue();
+            reqBody = new KDCReqBody(subsubDer, msgType);
+        } else {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
+    }
 
-   /**
-    * Encodes this object to a byte array.
-    *
-    * @return an byte array of encoded data.
-    * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-    * @exception IOException if an I/O error occurs while reading encoded data.
-    *
-    */
+    /**
+     * Encodes this object to a byte array.
+     *
+     * @return an byte array of encoded data.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     *
+     */
     public byte[] asn1Encode() throws Asn1Exception, IOException {
-                DerOutputStream temp, bytes, out;
-                temp = new DerOutputStream();
-                temp.putInteger(BigInteger.valueOf(pvno));
-                out = new DerOutputStream();
-                out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
-                temp = new DerOutputStream();
-                temp.putInteger(BigInteger.valueOf(msgType));
-                out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp);
+        DerOutputStream temp, bytes, out;
+        temp = new DerOutputStream();
+        temp.putInteger(BigInteger.valueOf(pvno));
+        out = new DerOutputStream();
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x01), temp);
+        temp = new DerOutputStream();
+        temp.putInteger(BigInteger.valueOf(msgType));
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x02), temp);
         if (pAData != null && pAData.length > 0) {
-                        temp = new DerOutputStream();
-                        for (int i = 0; i < pAData.length; i++) {
-                                temp.write(pAData[i].asn1Encode());
-                        }
-                        bytes = new DerOutputStream();
-                        bytes.write(DerValue.tag_SequenceOf, temp);
-                        out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), bytes);
-                }
-                out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), reqBody.asn1Encode(msgType));
-                bytes = new DerOutputStream();
-                bytes.write(DerValue.tag_Sequence, out);
-                out = new DerOutputStream();
-                out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)msgType), bytes);
-                return out.toByteArray();
+            temp = new DerOutputStream();
+            for (int i = 0; i < pAData.length; i++) {
+                temp.write(pAData[i].asn1Encode());
+            }
+            bytes = new DerOutputStream();
+            bytes.write(DerValue.tag_SequenceOf, temp);
+            out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                    true, (byte) 0x03), bytes);
         }
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x04), reqBody.asn1Encode(msgType));
+        bytes = new DerOutputStream();
+        bytes.write(DerValue.tag_Sequence, out);
+        out = new DerOutputStream();
+        out.write(DerValue.createTag(DerValue.TAG_APPLICATION,
+                true, (byte) msgType), bytes);
+        return out.toByteArray();
+    }
 
-        public byte[] asn1EncodeReqBody() throws Asn1Exception, IOException
-        {
-                return reqBody.asn1Encode(msgType);
-        }
-
+    public byte[] asn1EncodeReqBody() throws Asn1Exception, IOException {
+        return reqBody.asn1Encode(msgType);
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/KRBCred.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/KRBCred.java	Mon Apr 14 11:34:15 2008 -0700
@@ -56,128 +56,134 @@
  * <a href="http://www.ietf.org/rfc/rfc4120.txt">
  * http://www.ietf.org/rfc/rfc4120.txt</a>.
  */
+public class KRBCred {
 
-public class KRBCred {
-        public Ticket[] tickets = null;
-        public EncryptedData encPart;
-
-        private int pvno;
-        private int msgType;
+    public Ticket[] tickets = null;
+    public EncryptedData encPart;
+    private int pvno;
+    private int msgType;
 
-        public KRBCred(Ticket[] new_tickets, EncryptedData new_encPart) throws IOException {
-                pvno = Krb5.PVNO;
-                msgType = Krb5.KRB_CRED;
-                if (new_tickets != null) {
-                    tickets = new Ticket[new_tickets.length];
-                    for (int i = 0; i < new_tickets.length; i++) {
-                        if (new_tickets[i] == null) {
-                            throw new IOException("Cannot create a KRBCred");
-                        } else {
-                            tickets[i] = (Ticket)new_tickets[i].clone();
-                        }
-                    }
+    public KRBCred(Ticket[] new_tickets, EncryptedData new_encPart) throws IOException {
+        pvno = Krb5.PVNO;
+        msgType = Krb5.KRB_CRED;
+        if (new_tickets != null) {
+            tickets = new Ticket[new_tickets.length];
+            for (int i = 0; i < new_tickets.length; i++) {
+                if (new_tickets[i] == null) {
+                    throw new IOException("Cannot create a KRBCred");
+                } else {
+                    tickets[i] = (Ticket) new_tickets[i].clone();
                 }
-                encPart = new_encPart;
+            }
         }
+        encPart = new_encPart;
+    }
 
-        public KRBCred(byte[] data) throws Asn1Exception,
-                RealmException, KrbApErrException, IOException {
-                init(new DerValue(data));
-        }
+    public KRBCred(byte[] data) throws Asn1Exception,
+            RealmException, KrbApErrException, IOException {
+        init(new DerValue(data));
+    }
 
-        public KRBCred(DerValue encoding) throws Asn1Exception,
-                RealmException, KrbApErrException, IOException {
-                init(encoding);
-        }
+    public KRBCred(DerValue encoding) throws Asn1Exception,
+            RealmException, KrbApErrException, IOException {
+        init(encoding);
+    }
 
-        /**
-         * Initializes an KRBCred object.
-         * @param encoding a single DER-encoded value.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         * @exception KrbApErrException if the value read from the DER-encoded data
-         *  stream does not match the pre-defined value.
-         * @exception RealmException if an error occurs while parsing a Realm object.
-         */
-        private void init(DerValue encoding) throws Asn1Exception,
-                RealmException, KrbApErrException, IOException {
-        if (((encoding.getTag() & (byte)0x1F) != (byte)0x16)
-                        || (encoding.isApplication() != true)
-                        || (encoding.isConstructed() != true))
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+    /**
+     * Initializes an KRBCred object.
+     * @param encoding a single DER-encoded value.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     * @exception KrbApErrException if the value read from the DER-encoded data
+     *  stream does not match the pre-defined value.
+     * @exception RealmException if an error occurs while parsing a Realm object.
+     */
+    private void init(DerValue encoding) throws Asn1Exception,
+            RealmException, KrbApErrException, IOException {
+        if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x16)
+                || (encoding.isApplication() != true)
+                || (encoding.isConstructed() != true)) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
         DerValue der, subDer;
-                der = encoding.getData().getDerValue();
-                if (der.getTag() != DerValue.tag_Sequence)
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                subDer = der.getData().getDerValue();
-            if ((subDer.getTag() & 0x1F) == 0x00) {
-                        pvno = subDer.getData().getBigInteger().intValue();
-                        if (pvno != Krb5.PVNO) {
+        der = encoding.getData().getDerValue();
+        if (der.getTag() != DerValue.tag_Sequence) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & 0x1F) == 0x00) {
+            pvno = subDer.getData().getBigInteger().intValue();
+            if (pvno != Krb5.PVNO) {
                 throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
-                        }
-                }
-        else
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & 0x1F) == 0x01) {
-                        msgType = subDer.getData().getBigInteger().intValue();
-            if (msgType != Krb5.KRB_CRED)
+            }
+        } else {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        subDer = der.getData().getDerValue();
+        if ((subDer.getTag() & 0x1F) == 0x01) {
+            msgType = subDer.getData().getBigInteger().intValue();
+            if (msgType != Krb5.KRB_CRED) {
                 throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE);
-                }
-                else
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+            }
+        } else {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
         subDer = der.getData().getDerValue();
-                if ((subDer.getTag() & 0x1F) == 0x02) {
-                        DerValue subsubDer = subDer.getData().getDerValue();
+        if ((subDer.getTag() & 0x1F) == 0x02) {
+            DerValue subsubDer = subDer.getData().getDerValue();
             if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
-                                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                        }
-            Vector<Ticket> v = new Vector<Ticket> ();
+                throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+            }
+            Vector<Ticket> v = new Vector<Ticket>();
             while (subsubDer.getData().available() > 0) {
-                                v.addElement(new Ticket(subsubDer.getData().getDerValue()));
-                        }
+                v.addElement(new Ticket(subsubDer.getData().getDerValue()));
+            }
             if (v.size() > 0) {
-                                tickets = new Ticket[v.size()];
-                                v.copyInto(tickets);
-                        }
-                }
-                else
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
-                encPart = EncryptedData.parse(der.getData(), (byte)0x03, false);
+                tickets = new Ticket[v.size()];
+                v.copyInto(tickets);
+            }
+        } else {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        }
+        encPart = EncryptedData.parse(der.getData(), (byte) 0x03, false);
 
-                if (der.getData().available() > 0)
-                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
+        if (der.getData().available() > 0) {
+            throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
-
+    }
 
-        /**
-         * Encodes an KRBCred object.
-         * @return the data of encoded EncAPRepPart object.
-         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
-         * @exception IOException if an I/O error occurs while reading encoded data.
-         */
-        public byte[] asn1Encode() throws Asn1Exception, IOException {
+    /**
+     * Encodes an KRBCred object.
+     * @return the data of encoded EncAPRepPart object.
+     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
+     * @exception IOException if an I/O error occurs while reading encoded data.
+     */
+    public byte[] asn1Encode() throws Asn1Exception, IOException {
         DerOutputStream temp, bytes, out;
         temp = new DerOutputStream();
         temp.putInteger(BigInteger.valueOf(pvno));
         out = new DerOutputStream();
-        out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);
-                temp = new DerOutputStream();
-                temp.putInteger(BigInteger.valueOf(msgType));
-                out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x00), temp);
         temp = new DerOutputStream();
-                for (int i = 0; i < tickets.length; i++) {
-                        temp.write(tickets[i].asn1Encode());
-                }
+        temp.putInteger(BigInteger.valueOf(msgType));
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x01), temp);
+        temp = new DerOutputStream();
+        for (int i = 0; i < tickets.length; i++) {
+            temp.write(tickets[i].asn1Encode());
+        }
         bytes = new DerOutputStream();
         bytes.write(DerValue.tag_SequenceOf, temp);
-        out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), bytes);
-                out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), encPart.asn1Encode());
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x02), bytes);
+        out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte) 0x03), encPart.asn1Encode());
         bytes = new DerOutputStream();
         bytes.write(DerValue.tag_Sequence, out);
-                out = new DerOutputStream();
-                out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x16), bytes);
-                return out.toByteArray();
-        }
-
+        out = new DerOutputStream();
+        out.write(DerValue.createTag(DerValue.TAG_APPLICATION,
+                true, (byte) 0x16), bytes);
+        return out.toByteArray();
+    }
 }
--- a/src/share/classes/sun/security/krb5/internal/KrbCredInfo.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/KrbCredInfo.java	Mon Apr 14 11:34:15 2008 -0700
@@ -111,7 +111,7 @@
      * @exception RealmException if an error occurs while parsing a Realm object.
      */
     public KrbCredInfo(DerValue encoding)
-        throws Asn1Exception, IOException, RealmException{
+            throws Asn1Exception, IOException, RealmException{
         if (encoding.getTag() != DerValue.tag_Sequence) {
             throw new Asn1Exception(Krb5.ASN1_BAD_ID);
         }
@@ -160,25 +160,25 @@
         Vector<DerValue> v = new Vector<DerValue> ();
         v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), key.asn1Encode()));
         if (prealm != null)
-        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), prealm.asn1Encode()));
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), prealm.asn1Encode()));
         if (pname != null)
-        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), pname.asn1Encode()));
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), pname.asn1Encode()));
         if (flags != null)
-        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), flags.asn1Encode()));
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), flags.asn1Encode()));
         if (authtime != null)
-        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), authtime.asn1Encode()));
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), authtime.asn1Encode()));
         if (starttime != null)
-        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), starttime.asn1Encode()));
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), starttime.asn1Encode()));
         if (endtime != null)
-        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), endtime.asn1Encode()));
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), endtime.asn1Encode()));
         if (renewTill != null)
-        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), renewTill.asn1Encode()));
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), renewTill.asn1Encode()));
         if (srealm != null)
-        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), srealm.asn1Encode()));
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), srealm.asn1Encode()));
         if (sname != null)
-        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), sname.asn1Encode()));
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), sname.asn1Encode()));
         if (caddr != null)
-        v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), caddr.asn1Encode()));
+            v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), caddr.asn1Encode()));
         DerValue der[] = new DerValue[v.size()];
         v.copyInto(der);
         DerOutputStream out = new DerOutputStream();
--- a/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java	Mon Apr 14 11:34:15 2008 -0700
@@ -215,7 +215,9 @@
                 addrType = read(2);
                 addrLength = read(4);
                 if (!(addrLength == 4 || addrLength == 16)) {
-                    System.out.println("Incorrect address format.");
+                    if (DEBUG) {
+                        System.out.println("Incorrect address format.");
+                    }
                     return null;
                 }
                 byte[] result = new byte[addrLength];
@@ -338,15 +340,19 @@
             System.out.println(">>>DEBUG <CCacheInputStream> key type: " + key.getEType());
         long times[] = readTimes();
         KerberosTime authtime = new KerberosTime(times[0]);
-        KerberosTime starttime = new KerberosTime(times[1]);
+        KerberosTime starttime =
+                (times[1]==0) ? null : new KerberosTime(times[1]);
         KerberosTime endtime = new KerberosTime(times[2]);
-        KerberosTime renewTill = new KerberosTime(times[3]);
+        KerberosTime renewTill =
+                (times[3]==0) ? null : new KerberosTime(times[3]);
 
         if (DEBUG) {
             System.out.println(">>>DEBUG <CCacheInputStream> auth time: " + authtime.toDate().toString());
-            System.out.println(">>>DEBUG <CCacheInputStream> start time: " + starttime.toDate().toString());
+            System.out.println(">>>DEBUG <CCacheInputStream> start time: " +
+                    ((starttime==null)?"null":starttime.toDate().toString()));
             System.out.println(">>>DEBUG <CCacheInputStream> end time: " + endtime.toDate().toString());
-            System.out.println(">>>DEBUG <CCacheInputStream> renew_till time: " + renewTill.toDate().toString());
+            System.out.println(">>>DEBUG <CCacheInputStream> renew_till time: " +
+                    ((renewTill==null)?"null":renewTill.toDate().toString()));
         }
         boolean skey = readskey();
         boolean flags[] = readFlags();
--- a/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java	Mon Apr 14 11:34:15 2008 -0700
@@ -34,168 +34,184 @@
 import sun.security.krb5.internal.*;
 
 public class Credentials {
-        PrincipalName cname;
-        Realm crealm;
+
+    PrincipalName cname;
+    Realm crealm;
     PrincipalName sname;
-        Realm srealm;
-        EncryptionKey key;
-        KerberosTime authtime;
-        KerberosTime starttime;//optional
-        KerberosTime endtime;
-        KerberosTime renewTill; //optional
-        HostAddresses caddr; //optional; for proxied tickets only
+    Realm srealm;
+    EncryptionKey key;
+    KerberosTime authtime;
+    KerberosTime starttime;//optional
+    KerberosTime endtime;
+    KerberosTime renewTill; //optional
+    HostAddresses caddr; //optional; for proxied tickets only
     AuthorizationData authorizationData; //optional, not being actually used
     public boolean isEncInSKey;  // true if ticket is encrypted in another ticket's skey
-        TicketFlags flags;
+    TicketFlags flags;
     Ticket ticket;
-        Ticket secondTicket; //optional
-        private boolean DEBUG = Krb5.DEBUG;
-
-        public Credentials(
-                PrincipalName new_cname,
-                PrincipalName new_sname,
-                EncryptionKey new_key,
-                KerberosTime new_authtime,
-                KerberosTime new_starttime,
-                KerberosTime new_endtime,
-                KerberosTime new_renewTill,
-                boolean new_isEncInSKey,
-                TicketFlags new_flags,
-                HostAddresses new_caddr,
-                AuthorizationData new_authData,
-                Ticket new_ticket,
-                Ticket new_secondTicket) {
-                cname = (PrincipalName)new_cname.clone();
-                if (new_cname.getRealm() != null)
-                        crealm = (Realm)new_cname.getRealm().clone();
+    Ticket secondTicket; //optional
+    private boolean DEBUG = Krb5.DEBUG;
 
-                sname = (PrincipalName)new_sname.clone();
-                if (new_sname.getRealm() != null)
-                        srealm = (Realm)new_sname.getRealm().clone();
-
-                key = (EncryptionKey)new_key.clone();
+    public Credentials(
+            PrincipalName new_cname,
+            PrincipalName new_sname,
+            EncryptionKey new_key,
+            KerberosTime new_authtime,
+            KerberosTime new_starttime,
+            KerberosTime new_endtime,
+            KerberosTime new_renewTill,
+            boolean new_isEncInSKey,
+            TicketFlags new_flags,
+            HostAddresses new_caddr,
+            AuthorizationData new_authData,
+            Ticket new_ticket,
+            Ticket new_secondTicket) {
+        cname = (PrincipalName) new_cname.clone();
+        if (new_cname.getRealm() != null) {
+            crealm = (Realm) new_cname.getRealm().clone();
+        }
 
-                authtime = (KerberosTime)new_authtime.clone();
-                starttime = (KerberosTime)new_starttime.clone();
-                endtime = (KerberosTime)new_endtime.clone();
-                renewTill = (KerberosTime)new_renewTill.clone();
-                if (new_caddr != null)
-                        caddr = (HostAddresses)new_caddr.clone();
-                if (new_authData != null) {
-                    authorizationData
-                        = (AuthorizationData)new_authData.clone();
-                }
+        sname = (PrincipalName) new_sname.clone();
+        if (new_sname.getRealm() != null) {
+            srealm = (Realm) new_sname.getRealm().clone();
+        }
+
+        key = (EncryptionKey) new_key.clone();
 
-                isEncInSKey = new_isEncInSKey;
-                flags = (TicketFlags)new_flags.clone();
-                ticket = (Ticket)(new_ticket.clone());
-                if (new_secondTicket != null)
-                         secondTicket = (Ticket)new_secondTicket.clone();
+        authtime = (KerberosTime) new_authtime.clone();
+        if (new_starttime != null) {
+            starttime = (KerberosTime) new_starttime.clone();
+        }
+        endtime = (KerberosTime) new_endtime.clone();
+        if (new_renewTill != null) {
+            renewTill = (KerberosTime) new_renewTill.clone();
+        }
+        if (new_caddr != null) {
+            caddr = (HostAddresses) new_caddr.clone();
+        }
+        if (new_authData != null) {
+            authorizationData = (AuthorizationData) new_authData.clone();
         }
 
-
+        isEncInSKey = new_isEncInSKey;
+        flags = (TicketFlags) new_flags.clone();
+        ticket = (Ticket) (new_ticket.clone());
+        if (new_secondTicket != null) {
+            secondTicket = (Ticket) new_secondTicket.clone();
+        }
+    }
 
-        public Credentials(
-                KDCRep kdcRep,
-                Ticket new_secondTicket,
-                AuthorizationData new_authorizationData,
-                boolean new_isEncInSKey
-        ) {
-                if (kdcRep.encKDCRepPart == null) //can't store while encrypted
-                        return;
-                crealm = (Realm)kdcRep.crealm.clone();
-                cname = (PrincipalName)kdcRep.cname.clone();
-                ticket = (Ticket)kdcRep.ticket.clone();
-                key = (EncryptionKey)kdcRep.encKDCRepPart.key.clone();
-                flags = (TicketFlags)kdcRep.encKDCRepPart.flags.clone();
-                authtime = (KerberosTime)kdcRep.encKDCRepPart.authtime.clone();
-                starttime = (KerberosTime)kdcRep.encKDCRepPart.starttime.clone();
-                endtime = (KerberosTime)kdcRep.encKDCRepPart.endtime.clone();
-                renewTill = (KerberosTime)kdcRep.encKDCRepPart.renewTill.clone();
-                srealm = (Realm)kdcRep.encKDCRepPart.srealm.clone();
-                sname = (PrincipalName)kdcRep.encKDCRepPart.sname.clone();
-                caddr = (HostAddresses)kdcRep.encKDCRepPart.caddr.clone();
-                secondTicket = (Ticket)new_secondTicket.clone();
-                authorizationData =
-                        (AuthorizationData)new_authorizationData.clone();
-                isEncInSKey = new_isEncInSKey;
+    public Credentials(
+            KDCRep kdcRep,
+            Ticket new_secondTicket,
+            AuthorizationData new_authorizationData,
+            boolean new_isEncInSKey) {
+        if (kdcRep.encKDCRepPart == null) //can't store while encrypted
+        {
+            return;
         }
+        crealm = (Realm) kdcRep.crealm.clone();
+        cname = (PrincipalName) kdcRep.cname.clone();
+        ticket = (Ticket) kdcRep.ticket.clone();
+        key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone();
+        flags = (TicketFlags) kdcRep.encKDCRepPart.flags.clone();
+        authtime = (KerberosTime) kdcRep.encKDCRepPart.authtime.clone();
+        if (kdcRep.encKDCRepPart.starttime != null) {
+            starttime = (KerberosTime) kdcRep.encKDCRepPart.starttime.clone();
+        }
+        endtime = (KerberosTime) kdcRep.encKDCRepPart.endtime.clone();
+        if (kdcRep.encKDCRepPart.renewTill != null) {
+            renewTill = (KerberosTime) kdcRep.encKDCRepPart.renewTill.clone();
+        }
+        srealm = (Realm) kdcRep.encKDCRepPart.srealm.clone();
+        sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone();
+        caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone();
+        secondTicket = (Ticket) new_secondTicket.clone();
+        authorizationData =
+                (AuthorizationData) new_authorizationData.clone();
+        isEncInSKey = new_isEncInSKey;
+    }
 
-        public Credentials(KDCRep kdcRep) {
-                this(kdcRep, null);
-        }
+    public Credentials(KDCRep kdcRep) {
+        this(kdcRep, null);
+    }
 
-        public Credentials(KDCRep kdcRep, Ticket new_ticket) {
-                sname = (PrincipalName)kdcRep.encKDCRepPart.sname.clone();
-                srealm = (Realm)kdcRep.encKDCRepPart.srealm.clone();
-                try {
-                        sname.setRealm(srealm);
-                }
-                catch (RealmException e) {
-                }
-                cname = (PrincipalName)kdcRep.cname.clone();
-                crealm = (Realm)kdcRep.crealm.clone();
-                try {
-                        cname.setRealm(crealm);
-                }
-                catch (RealmException e) {
-                }
-                key = (EncryptionKey)kdcRep.encKDCRepPart.key.clone();
-                authtime = (KerberosTime)kdcRep.encKDCRepPart.authtime.clone();
-                if (kdcRep.encKDCRepPart.starttime != null) {
-            starttime = (KerberosTime)kdcRep.encKDCRepPart.starttime.clone();
-                }
-                else starttime = null;
-                endtime = (KerberosTime)kdcRep.encKDCRepPart.endtime.clone();
-                if (kdcRep.encKDCRepPart.renewTill != null) {
-                        renewTill = (KerberosTime)kdcRep.encKDCRepPart.renewTill.clone();
-                }
-                else renewTill = null;
-           // if (kdcRep.msgType == Krb5.KRB_AS_REP) {
-          //    isEncInSKey = false;
-          //    secondTicket = null;
-          //  }
-                flags = kdcRep.encKDCRepPart.flags;
-                if (kdcRep.encKDCRepPart.caddr != null)
-                        caddr = (HostAddresses)kdcRep.encKDCRepPart.caddr.clone();
-                else caddr = null;
-                ticket = (Ticket)kdcRep.ticket.clone();
-                if (new_ticket != null) {
-                        secondTicket = (Ticket)new_ticket.clone();
-                        isEncInSKey = true;
-                } else {
-                        secondTicket = null;
-                        isEncInSKey = false;
-                }
+    public Credentials(KDCRep kdcRep, Ticket new_ticket) {
+        sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone();
+        srealm = (Realm) kdcRep.encKDCRepPart.srealm.clone();
+        try {
+            sname.setRealm(srealm);
+        } catch (RealmException e) {
+        }
+        cname = (PrincipalName) kdcRep.cname.clone();
+        crealm = (Realm) kdcRep.crealm.clone();
+        try {
+            cname.setRealm(crealm);
+        } catch (RealmException e) {
+        }
+        key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone();
+        authtime = (KerberosTime) kdcRep.encKDCRepPart.authtime.clone();
+        if (kdcRep.encKDCRepPart.starttime != null) {
+            starttime = (KerberosTime) kdcRep.encKDCRepPart.starttime.clone();
+        } else {
+            starttime = null;
+        }
+        endtime = (KerberosTime) kdcRep.encKDCRepPart.endtime.clone();
+        if (kdcRep.encKDCRepPart.renewTill != null) {
+            renewTill = (KerberosTime) kdcRep.encKDCRepPart.renewTill.clone();
+        } else {
+            renewTill = null;
+        }
+        // if (kdcRep.msgType == Krb5.KRB_AS_REP) {
+        //    isEncInSKey = false;
+        //    secondTicket = null;
+        //  }
+        flags = kdcRep.encKDCRepPart.flags;
+        if (kdcRep.encKDCRepPart.caddr != null) {
+            caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone();
+        } else {
+            caddr = null;
         }
+        ticket = (Ticket) kdcRep.ticket.clone();
+        if (new_ticket != null) {
+            secondTicket = (Ticket) new_ticket.clone();
+            isEncInSKey = true;
+        } else {
+            secondTicket = null;
+            isEncInSKey = false;
+        }
+    }
 
-        /**
-         * Checks if this credential is expired
-         */
-        public boolean isValid() {
-                boolean valid = true;
-                if (endtime.getTime() < System.currentTimeMillis()) {
-                        valid = false;
-                }
-                else if ((starttime.getTime() > System.currentTimeMillis())
-                        || ((starttime == null) && (authtime.getTime() > System.currentTimeMillis())))
-                 {
-                  valid = false;
-                }
-                return valid;
+    /**
+     * Checks if this credential is expired
+     */
+    public boolean isValid() {
+        boolean valid = true;
+        if (endtime.getTime() < System.currentTimeMillis()) {
+            valid = false;
+        } else if (starttime != null) {
+            if (starttime.getTime() > System.currentTimeMillis()) {
+                valid = false;
+            }
+        } else {
+            if (authtime.getTime() > System.currentTimeMillis()) {
+                valid = false;
+            }
         }
+        return valid;
+    }
 
-        public PrincipalName getServicePrincipal() throws RealmException{
-                if (sname.getRealm() == null) {
-                        sname.setRealm(srealm);
-                }
-                return sname;
+    public PrincipalName getServicePrincipal() throws RealmException {
+        if (sname.getRealm() == null) {
+            sname.setRealm(srealm);
         }
+        return sname;
+    }
 
-        public sun.security.krb5.Credentials setKrbCreds() {
-                return new sun.security.krb5.Credentials(ticket,
-          cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr);
-        }
+    public sun.security.krb5.Credentials setKrbCreds() {
+        return new sun.security.krb5.Credentials(ticket,
+                cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr);
+    }
 
     public KerberosTime getAuthTime() {
         return authtime;
--- a/src/share/classes/sun/security/krb5/internal/crypto/dk/AesDkCrypto.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/crypto/dk/AesDkCrypto.java	Mon Apr 14 11:34:15 2008 -0700
@@ -440,7 +440,9 @@
                 for (int i = 0; i < hashSize; i++) {
                     if (calculatedHmac[i] != ciphertext[hmacOffset+i]) {
                         cksumFailed = true;
-                        System.err.println("Checksum failed !");
+                        if (debug) {
+                            System.err.println("Checksum failed !");
+                        }
                         break;
                     }
                 }
--- a/src/share/classes/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java	Mon Apr 14 11:34:15 2008 -0700
@@ -397,7 +397,9 @@
             for (int i = 0; i < hashSize; i++) {
                 if (calculatedHmac[i] != ciphertext[i]) {
                     cksumFailed = true;
-                    System.err.println("Checksum failed !");
+                    if (debug) {
+                        System.err.println("Checksum failed !");
+                    }
                     break;
                 }
             }
--- a/src/share/classes/sun/security/ssl/CipherSuite.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/ssl/CipherSuite.java	Mon Apr 14 11:34:15 2008 -0700
@@ -191,7 +191,7 @@
         if (s == null) {
             throw new IllegalArgumentException("Name must not be null");
         }
-        CipherSuite c = (CipherSuite)nameMap.get(s);
+        CipherSuite c = nameMap.get(s);
         if ((c == null) || (c.allowed == false)) {
             throw new IllegalArgumentException("Unsupported ciphersuite " + s);
         }
@@ -395,7 +395,7 @@
         }
 
         private static synchronized boolean isAvailable(BulkCipher cipher) {
-            Boolean b = (Boolean)availableCache.get(cipher);
+            Boolean b = availableCache.get(cipher);
             if (b == null) {
                 try {
                     SecretKey key = new SecretKeySpec
--- a/src/share/classes/sun/security/ssl/DHCrypt.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/ssl/DHCrypt.java	Mon Apr 14 11:34:15 2008 -0700
@@ -132,8 +132,7 @@
         }
         try {
             KeyFactory factory = JsseJce.getKeyFactory("DH");
-            return (DHPublicKeySpec)factory.getKeySpec
-                                            (key, DHPublicKeySpec.class);
+            return factory.getKeySpec(key, DHPublicKeySpec.class);
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
--- a/src/share/classes/sun/security/ssl/Handshaker.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/ssl/Handshaker.java	Mon Apr 14 11:34:15 2008 -0700
@@ -617,7 +617,8 @@
         r.write(1);     // single byte of data
 
         if (conn != null) {
-            synchronized (conn.writeLock) {
+            conn.writeLock.lock();
+            try {
                 conn.writeRecord(r);
                 conn.changeWriteCiphers();
                 if (debug != null && Debug.isOn("handshake")) {
@@ -625,6 +626,8 @@
                 }
                 mesg.write(output);
                 output.flush();
+            } finally {
+                conn.writeLock.unlock();
             }
         } else {
             synchronized (engine.writeLock) {
--- a/src/share/classes/sun/security/ssl/InputRecord.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/ssl/InputRecord.java	Mon Apr 14 11:34:15 2008 -0700
@@ -426,11 +426,11 @@
             if (really < 0) {
                 throw new SSLException("SSL peer shut down incorrectly");
             }
+        }
 
-            // now we've got a complete record.
-            count = contentLen + headerSize;
-            exlen = 0;
-        }
+        // now we've got a complete record.
+        count = contentLen + headerSize;
+        exlen = 0;
 
         if (debug != null && Debug.isOn("record")) {
             if (count < 0 || count > (maxRecordSize - headerSize)) {
@@ -502,10 +502,11 @@
                 if (really < 0) {
                     throw new EOFException("SSL peer shut down incorrectly");
                 }
+            }
 
-                // now we've got a complete record.
-                exlen = 0;
-            }
+            // now we've got a complete record.
+            exlen = 0;
+
             hashInternal(buf, 2, 3);
             hashInternal(v2Buf, 0, len);
             V2toV3ClientHello(v2Buf);
--- a/src/share/classes/sun/security/ssl/JsseJce.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/ssl/JsseJce.java	Mon Apr 14 11:34:15 2008 -0700
@@ -343,8 +343,7 @@
         }
         try {
             KeyFactory factory = JsseJce.getKeyFactory("RSA");
-            return (RSAPublicKeySpec)factory.getKeySpec
-                                                (key, RSAPublicKeySpec.class);
+            return factory.getKeySpec(key, RSAPublicKeySpec.class);
         } catch (Exception e) {
             throw (RuntimeException)new RuntimeException().initCause(e);
         }
--- a/src/share/classes/sun/security/ssl/OutputRecord.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/ssl/OutputRecord.java	Mon Apr 14 11:34:15 2008 -0700
@@ -174,6 +174,18 @@
         return count == headerSize;
     }
 
+    /*
+     * Return true if the record is of a given alert.
+     */
+    boolean isAlert(byte description) {
+        // An alert is defined with a two bytes struct,
+        // {byte level, byte description}, following after the header bytes.
+        if (count > (headerSize + 1) && contentType == ct_alert) {
+            return buf[headerSize + 1] == description;
+        }
+
+        return false;
+    }
 
     /*
      * Compute the MAC and append it to this record.  In case we
--- a/src/share/classes/sun/security/ssl/ProtocolList.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/ssl/ProtocolList.java	Mon Apr 14 11:34:15 2008 -0700
@@ -98,7 +98,7 @@
                 protocolNames[i++] = version.name;
             }
         }
-        return (String[])protocolNames.clone();
+        return protocolNames.clone();
     }
 
     public String toString() {
--- a/src/share/classes/sun/security/ssl/SSLSessionImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/ssl/SSLSessionImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -458,7 +458,7 @@
                         + " for Kerberos cipher suites");
         }
         if (peerCerts != null) {
-            return (X509Certificate [])peerCerts.clone();
+            return peerCerts.clone();
         } else {
             throw new SSLPeerUnverifiedException("peer not authenticated");
         }
@@ -489,7 +489,7 @@
         if (peerCerts == null) {
             throw new SSLPeerUnverifiedException("peer not authenticated");
         }
-        return ((X500Principal)peerCerts[0].getSubjectX500Principal());
+        return peerCerts[0].getSubjectX500Principal();
     }
 
     /**
@@ -508,7 +508,7 @@
                         (KerberosPrincipal)localPrincipal);
         }
         return (localCerts == null ? null :
-            (X500Principal)localCerts[0].getSubjectX500Principal());
+                localCerts[0].getSubjectX500Principal());
     }
 
     /**
--- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,8 @@
 import java.security.AccessControlContext;
 import java.security.PrivilegedAction;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
 
 import javax.crypto.BadPaddingException;
 
@@ -274,7 +276,7 @@
      * from the peer are handled properly.
      */
     private Object              handshakeLock;
-    Object                      writeLock;
+    ReentrantLock               writeLock;
     private Object              readLock;
 
     private InputRecord         inrec;
@@ -314,7 +316,6 @@
     private HashMap<HandshakeCompletedListener, AccessControlContext>
                                                         handshakeListeners;
 
-
     /*
      * Reuse the same internal input/output streams.
      */
@@ -526,7 +527,7 @@
         enabledCipherSuites = CipherSuiteList.getDefault();
         enabledProtocols = ProtocolList.getDefault();
         handshakeLock = new Object();
-        writeLock = new Object();
+        writeLock = new ReentrantLock();
         readLock = new Object();
         inrec = null;
 
@@ -677,16 +678,81 @@
         // implementations are fragile and don't like to see empty
         // records, so this also increases robustness.
         //
-        synchronized (writeLock) {
-            if (!r.isEmpty()) {
-                // r.compress(c);
-                r.addMAC(writeMAC);
-                r.encrypt(writeCipher);
-                r.write(sockOutput);
+        if (!r.isEmpty()) {
+
+            // If the record is a close notify alert, we need to honor
+            // socket option SO_LINGER. Note that we will try to send
+            // the close notify even if the SO_LINGER set to zero.
+            if (r.isAlert(Alerts.alert_close_notify) && getSoLinger() >= 0) {
+
+                // keep and clear the current thread interruption status.
+                boolean interrupted = Thread.interrupted();
+                try {
+                    if (writeLock.tryLock(getSoLinger(), TimeUnit.SECONDS)) {
+                        try {
+                            writeRecordInternal(r);
+                        } finally {
+                            writeLock.unlock();
+                        }
+                    } else {
+                        SSLException ssle = new SSLException(
+                                "SO_LINGER timeout," +
+                                " close_notify message cannot be sent.");
+
+
+                        // For layered, non-autoclose sockets, we are not
+                        // able to bring them into a usable state, so we
+                        // treat it as fatal error.
+                        if (self != this && !autoClose) {
+                            // Note that the alert description is
+                            // specified as -1, so no message will be send
+                            // to peer anymore.
+                            fatal((byte)(-1), ssle);
+                        } else if ((debug != null) && Debug.isOn("ssl")) {
+                            System.out.println(threadName() +
+                                ", received Exception: " + ssle);
+                        }
+
+                        // RFC2246 requires that the session becomes
+                        // unresumable if any connection is terminated
+                        // without proper close_notify messages with
+                        // level equal to warning.
+                        //
+                        // RFC4346 no longer requires that a session not be
+                        // resumed if failure to properly close a connection.
+                        //
+                        // We choose to make the session unresumable if
+                        // failed to send the close_notify message.
+                        //
+                        sess.invalidate();
+                    }
+                } catch (InterruptedException ie) {
+                    // keep interrupted status
+                    interrupted = true;
+                }
+
+                // restore the interrupted status
+                if (interrupted) {
+                    Thread.currentThread().interrupt();
+                }
+            } else {
+                writeLock.lock();
+                try {
+                    writeRecordInternal(r);
+                } finally {
+                    writeLock.unlock();
+                }
             }
         }
     }
 
+    private void writeRecordInternal(OutputRecord r) throws IOException {
+        // r.compress(c);
+        r.addMAC(writeMAC);
+        r.encrypt(writeCipher);
+        r.write(sockOutput);
+    }
+
 
     /*
      * Read an application data record.  Alerts and handshake
@@ -1533,7 +1599,11 @@
             if (oldState == cs_HANDSHAKE) {
                 sockInput.skip(sockInput.available());
             }
-            sendAlert(Alerts.alert_fatal, description);
+
+            // If the description equals -1, the alert won't be sent to peer.
+            if (description != -1) {
+                sendAlert(Alerts.alert_fatal, description);
+            }
             if (cause instanceof SSLException) { // only true if != null
                 closeReason = (SSLException)cause;
             } else {
@@ -1614,7 +1684,7 @@
      * Emit alerts.  Caller must have synchronized with "this".
      */
     private void sendAlert(byte level, byte description) {
-        if (connectionState >= cs_CLOSED) {
+        if (connectionState >= cs_SENT_CLOSE) {
             return;
         }
 
--- a/src/share/classes/sun/security/ssl/SessionId.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/ssl/SessionId.java	Mon Apr 14 11:34:15 2008 -0700
@@ -64,7 +64,7 @@
     /** Returns the bytes in the ID.  May be an empty array.  */
     byte [] getId ()
     {
-        return (byte []) sessionId.clone ();
+        return sessionId.clone ();
     }
 
     /** Returns the ID as a string */
--- a/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -172,7 +172,7 @@
         if (cred == null) {
             return null;
         } else {
-            return (X509Certificate[])cred.certificates.clone();
+            return cred.certificates.clone();
         }
     }
 
@@ -255,7 +255,7 @@
         String[] aliases;
 
         if (issuers == null || issuers.length == 0) {
-            aliases = (String[])serverAliasCache.get(keyType);
+            aliases = serverAliasCache.get(keyType);
             if (aliases == null) {
                 aliases = getServerAliases(keyType, issuers);
                 // Cache the result (positive and negative lookups)
@@ -388,7 +388,7 @@
             }
         }
 
-        String[] aliasStrings = (String[])aliases.toArray(STRING0);
+        String[] aliasStrings = aliases.toArray(STRING0);
         return ((aliasStrings.length == 0) ? null : aliasStrings);
     }
 
--- a/src/share/classes/sun/security/x509/AVA.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/x509/AVA.java	Mon Apr 14 11:34:15 2008 -0700
@@ -780,7 +780,8 @@
              * Implementations MAY escape other characters.
              *
              * NOTE: this implementation also recognizes "=" and "#" as
-             * characters which need escaping.
+             * characters which need escaping, and null which is escaped as
+             * '\00' (see RFC 4514).
              *
              * If a character to be escaped is one of the list shown above, then
              * it is prefixed by a backslash ('\' ASCII 92).
@@ -805,6 +806,10 @@
                     // append printable/escaped char
                     sbuffer.append(c);
 
+                } else if (c == '\u0000') {
+                    // escape null character
+                    sbuffer.append("\\00");
+
                 } else if (debug != null && Debug.isOn("ava")) {
 
                     // embed non-printable/non-escaped char
--- a/src/share/classes/sun/security/x509/CertificatePolicySet.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/x509/CertificatePolicySet.java	Mon Apr 14 11:34:15 2008 -0700
@@ -87,7 +87,7 @@
         DerOutputStream tmp = new DerOutputStream();
 
         for (int i = 0; i < ids.size(); i++) {
-            ((CertificatePolicyId)ids.elementAt(i)).encode(tmp);
+            ids.elementAt(i).encode(tmp);
         }
         out.write(DerValue.tag_Sequence,tmp);
     }
--- a/src/share/classes/sun/security/x509/X509Cert.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/security/x509/X509Cert.java	Mon Apr 14 11:34:15 2008 -0700
@@ -516,7 +516,7 @@
      * Null is returned in the case of a partially constructed cert.
      */
     public byte []      getSignedCert ()
-        { return (byte[])signedCert.clone(); }
+        { return signedCert.clone(); }
 
 
     /**
--- a/src/share/classes/sun/tools/jar/JarVerifierStream.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jar/JarVerifierStream.java	Mon Apr 14 11:34:15 2008 -0700
@@ -32,7 +32,6 @@
 import java.security.cert.Certificate;
 import java.security.AccessController;
 import java.security.cert.X509Certificate;
-import java.security.Identity;
 import java.security.PublicKey;
 import java.security.Principal;
 import sun.security.provider.SystemIdentity;
@@ -49,7 +48,8 @@
 public class JarVerifierStream extends ZipInputStream {
 
     private JarEntry current;
-    private Hashtable verified = new Hashtable();
+    private Hashtable<String, Vector<SystemIdentity>> verified
+        = new Hashtable<String, Vector<SystemIdentity>>();
     private JarInputStream jis;
     private sun.tools.jar.Manifest man = null;
 
@@ -120,7 +120,7 @@
         if (current != null) {
             Certificate[] certs = current.getCertificates();
             if (certs != null) {
-                Vector ids = getIds(certs);
+                Vector<SystemIdentity> ids = getIds(certs);
                 if (ids != null) {
                     verified.put(current.getName(), ids);
                 }
@@ -189,7 +189,7 @@
 
     static class CertCache {
         Certificate [] certs;
-        Vector ids;
+        Vector<SystemIdentity> ids;
 
         boolean equals(Certificate[] certs) {
                 if (this.certs == null) {
@@ -229,21 +229,21 @@
         }
     }
 
-    private ArrayList certCache = null;
+    private ArrayList<CertCache> certCache = null;
 
 
     /**
      * Returns the Identity vector for the given array of Certificates
      */
-    protected Vector getIds(Certificate[] certs) {
+    protected Vector<SystemIdentity> getIds(Certificate[] certs) {
         if (certs == null)
             return null;
 
         if (certCache == null)
-            certCache = new ArrayList();
+            certCache = new ArrayList<CertCache>();
         CertCache cc;
         for (int i = 0; i < certCache.size(); i++) {
-            cc = (CertCache) certCache.get(i);
+            cc = certCache.get(i);
             if (cc.equals(certs)) {
                 return cc.ids;
             }
@@ -265,8 +265,8 @@
                         new sun.security.x509.X509Cert(encoded);
                     try {
                         AccessController.doPrivileged(
-                         new java.security.PrivilegedExceptionAction() {
-                            public Object run()
+                         new java.security.PrivilegedExceptionAction<Void>() {
+                            public Void run()
                                 throws java.security.KeyManagementException
                             {
                                 id.addCertificate(oldC);
@@ -278,7 +278,7 @@
                             pae.getException();
                     }
                     if (cc.ids == null)
-                        cc.ids = new Vector();
+                        cc.ids = new Vector<SystemIdentity>();
                     cc.ids.addElement(id);
                 } catch (java.security.KeyManagementException kme) {
                     // ignore if we can't create Identity
--- a/src/share/classes/sun/tools/jconsole/MBeansTab.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/MBeansTab.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2004-2007 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package sun.tools.jconsole;
 
 import java.awt.BorderLayout;
+import java.awt.EventQueue;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
@@ -42,7 +43,8 @@
 
 @SuppressWarnings("serial")
 public class MBeansTab extends Tab implements
-        NotificationListener, PropertyChangeListener, TreeSelectionListener {
+        NotificationListener, PropertyChangeListener,
+        TreeSelectionListener, TreeWillExpandListener {
 
     private XTree tree;
     private XSheet sheet;
@@ -70,6 +72,7 @@
         return sheet;
     }
 
+    @Override
     public void dispose() {
         super.dispose();
         sheet.dispose();
@@ -79,61 +82,79 @@
         return vmPanel.getUpdateInterval();
     }
 
-    void synchroniseMBeanServerView() {
-        // Register listener for MBean registration/unregistration
-        //
-        try {
-            getMBeanServerConnection().addNotificationListener(
-                    MBeanServerDelegate.DELEGATE_NAME,
-                    this,
-                    null,
-                    null);
-        } catch (InstanceNotFoundException e) {
-            // Should never happen because the MBeanServerDelegate
-            // is always present in any standard MBeanServer
-            //
-            if (JConsole.isDebug()) {
-                e.printStackTrace();
-            }
-        } catch (IOException e) {
-            if (JConsole.isDebug()) {
-                e.printStackTrace();
+    private void buildMBeanServerView() {
+        new SwingWorker<Set<ObjectName>, Void>() {
+            @Override
+            public Set<ObjectName> doInBackground() {
+                // Register listener for MBean registration/unregistration
+                //
+                try {
+                    getMBeanServerConnection().addNotificationListener(
+                            MBeanServerDelegate.DELEGATE_NAME,
+                            MBeansTab.this,
+                            null,
+                            null);
+                } catch (InstanceNotFoundException e) {
+                    // Should never happen because the MBeanServerDelegate
+                    // is always present in any standard MBeanServer
+                    //
+                    if (JConsole.isDebug()) {
+                        e.printStackTrace();
+                    }
+                } catch (IOException e) {
+                    if (JConsole.isDebug()) {
+                        e.printStackTrace();
+                    }
+                    vmPanel.getProxyClient().markAsDead();
+                    return null;
+                }
+                // Retrieve MBeans from MBeanServer
+                //
+                Set<ObjectName> mbeans = null;
+                try {
+                    mbeans = getMBeanServerConnection().queryNames(null, null);
+                } catch (IOException e) {
+                    if (JConsole.isDebug()) {
+                        e.printStackTrace();
+                    }
+                    vmPanel.getProxyClient().markAsDead();
+                    return null;
+                }
+                return mbeans;
             }
-            vmPanel.getProxyClient().markAsDead();
-            return;
-        }
-        // Retrieve MBeans from MBeanServer
-        //
-        Set<ObjectName> newSet = null;
-        try {
-            newSet = getMBeanServerConnection().queryNames(null,null);
-        } catch (IOException e) {
-            if (JConsole.isDebug()) {
-                e.printStackTrace();
+            @Override
+            protected void done() {
+                try {
+                    // Wait for mbsc.queryNames() result
+                    Set<ObjectName> mbeans = get();
+                    // Do not display anything until the new tree has been built
+                    //
+                    tree.setVisible(false);
+                    // Cleanup current tree
+                    //
+                    tree.removeAll();
+                    // Add MBeans to tree
+                    //
+                    tree.addMBeansToView(mbeans);
+                    // Display the new tree
+                    //
+                    tree.setVisible(true);
+                } catch (Exception e) {
+                    Throwable t = Utils.getActualException(e);
+                    if (JConsole.isDebug()) {
+                        System.err.println("Problem at MBean tree construction");
+                        t.printStackTrace();
+                    }
+                }
             }
-            vmPanel.getProxyClient().markAsDead();
-            return;
-        }
-        // Cleanup current tree
-        //
-        tree.removeAll();
-        // Do not display anything until the new tree has been built
-        //
-        tree.setVisible(false);
-        // Add MBeans to tree
-        //
-        for (ObjectName mbean : newSet) {
-            tree.addMBeanToView(mbean);
-        }
-        // Display the new tree
-        //
-        tree.setVisible(true);
+        }.execute();
     }
 
     public MBeanServerConnection getMBeanServerConnection() {
         return vmPanel.getProxyClient().getMBeanServerConnection();
     }
 
+    @Override
     public void update() {
         // Ping the connection to see if it is still alive. At
         // some point the ProxyClient class should centralize
@@ -160,6 +181,7 @@
         tree.getSelectionModel().setSelectionMode(
                 TreeSelectionModel.SINGLE_TREE_SELECTION);
         tree.addTreeSelectionListener(this);
+        tree.addTreeWillExpandListener(this);
         tree.addMouseListener(ml);
         JScrollPane theScrollPane = new JScrollPane(
                 tree,
@@ -177,55 +199,55 @@
         add(mainSplit);
     }
 
-    /* notification listener */
-    public void handleNotification(Notification notification, Object handback) {
-        if (notification instanceof MBeanServerNotification) {
-            ObjectName mbean =
-                    ((MBeanServerNotification) notification).getMBeanName();
-            if (notification.getType().equals(
-                    MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
-                tree.addMBeanToView(mbean);
-            } else if (notification.getType().equals(
-                    MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
-                tree.delMBeanFromView(mbean);
+    /* notification listener:  handleNotification */
+    public void handleNotification(
+            final Notification notification, Object handback) {
+        EventQueue.invokeLater(new Runnable() {
+            public void run() {
+                if (notification instanceof MBeanServerNotification) {
+                    ObjectName mbean =
+                            ((MBeanServerNotification) notification).getMBeanName();
+                    if (notification.getType().equals(
+                            MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
+                        tree.addMBeanToView(mbean);
+                    } else if (notification.getType().equals(
+                            MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
+                        tree.removeMBeanFromView(mbean);
+                    }
+                }
+            }
+        });
+    }
+
+    /* property change listener:  propertyChange */
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (JConsoleContext.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) {
+            boolean connected = (Boolean) evt.getNewValue();
+            if (connected) {
+                buildMBeanServerView();
+            } else {
+                sheet.dispose();
             }
         }
     }
 
-    /* property change listener */
-    public void propertyChange(PropertyChangeEvent evt) {
-        if (evt.getPropertyName() == JConsoleContext.CONNECTION_STATE_PROPERTY) {
-            boolean connected = (Boolean) evt.getNewValue();
-            if (connected) {
-                workerAdd(new Runnable() {
-                    public void run() {
-                        synchroniseMBeanServerView();
-                    }
-                });
-            } else {
-                sheet.dispose();
-            }
-        }
-
-    }
-
-    /* tree selection listener */
+    /* tree selection listener: valueChanged */
     public void valueChanged(TreeSelectionEvent e) {
         DefaultMutableTreeNode node =
                 (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
         sheet.displayNode(node);
     }
-
-    /* tree mouse listener */
+    /* tree mouse listener: mousePressed */
     private MouseListener ml = new MouseAdapter() {
+        @Override
         public void mousePressed(MouseEvent e) {
             if (e.getClickCount() == 1) {
                 int selRow = tree.getRowForLocation(e.getX(), e.getY());
                 if (selRow != -1) {
                     TreePath selPath =
                             tree.getPathForLocation(e.getX(), e.getY());
-                    DefaultMutableTreeNode node = (DefaultMutableTreeNode)
-                            selPath.getLastPathComponent();
+                    DefaultMutableTreeNode node =
+                            (DefaultMutableTreeNode) selPath.getLastPathComponent();
                     if (sheet.isMBeanNode(node)) {
                         tree.expandPath(selPath);
                     }
@@ -233,4 +255,22 @@
             }
         }
     };
+
+    /* tree will expand listener: treeWillExpand */
+    public void treeWillExpand(TreeExpansionEvent e)
+            throws ExpandVetoException {
+        TreePath path = e.getPath();
+        if (!tree.hasBeenExpanded(path)) {
+            DefaultMutableTreeNode node =
+                    (DefaultMutableTreeNode) path.getLastPathComponent();
+            if (sheet.isMBeanNode(node) && !tree.hasMetadataNodes(node)) {
+                tree.addMetadataNodes(node);
+            }
+        }
+    }
+
+    /* tree will expand listener: treeWillCollapse */
+    public void treeWillCollapse(TreeExpansionEvent e)
+            throws ExpandVetoException {
+    }
 }
--- a/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java	Mon Apr 14 11:34:15 2008 -0700
@@ -22,6 +22,7 @@
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
+
 package sun.tools.jconsole;
 
 import java.lang.management.MemoryUsage;
--- a/src/share/classes/sun/tools/jconsole/VMPanel.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/VMPanel.java	Mon Apr 14 11:34:15 2008 -0700
@@ -45,6 +45,7 @@
 
 @SuppressWarnings("serial")
 public class VMPanel extends JTabbedPane implements PropertyChangeListener {
+
     private ProxyClient proxyClient;
     private Timer timer;
     private int updateInterval;
@@ -55,12 +56,9 @@
     private String password;
     private String url;
     private VMInternalFrame vmIF = null;
-
     private static final String windowsLaF =
-        "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
-
+            "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
     private static ArrayList<TabInfo> tabInfos = new ArrayList<TabInfo>();
-
     private boolean wasConnected = false;
 
     // The everConnected flag keeps track of whether the window can be
@@ -76,7 +74,7 @@
 
     // Each VMPanel has its own instance of the JConsolePlugin
     // A map of JConsolePlugin to the previous SwingWorker
-    private Map<JConsolePlugin, SwingWorker<?,?>> plugins = null;
+    private Map<JConsolePlugin, SwingWorker<?, ?>> plugins = null;
     private boolean pluginTabsAdded = false;
 
     // Update these only on the EDT
@@ -86,11 +84,11 @@
 
     static {
         tabInfos.add(new TabInfo(OverviewTab.class, OverviewTab.getTabName(), true));
-        tabInfos.add(new TabInfo(MemoryTab.class,  MemoryTab.getTabName(),  true));
-        tabInfos.add(new TabInfo(ThreadTab.class,  ThreadTab.getTabName(),  true));
-        tabInfos.add(new TabInfo(ClassTab.class,   ClassTab.getTabName(),   true));
+        tabInfos.add(new TabInfo(MemoryTab.class, MemoryTab.getTabName(), true));
+        tabInfos.add(new TabInfo(ThreadTab.class, ThreadTab.getTabName(), true));
+        tabInfos.add(new TabInfo(ClassTab.class, ClassTab.getTabName(), true));
         tabInfos.add(new TabInfo(SummaryTab.class, SummaryTab.getTabName(), true));
-        tabInfos.add(new TabInfo(MBeansTab.class,  MBeansTab.getTabName(),  true));
+        tabInfos.add(new TabInfo(MBeansTab.class, MBeansTab.getTabName(), true));
     }
 
     public static TabInfo[] getTabInfos() {
@@ -101,8 +99,8 @@
         this.proxyClient = proxyClient;
         this.updateInterval = updateInterval;
         this.hostName = proxyClient.getHostName();
-        this.port     = proxyClient.getPort();
-        this.vmid     = proxyClient.getVmid();
+        this.port = proxyClient.getPort();
+        this.vmid = proxyClient.getVmid();
         this.userName = proxyClient.getUserName();
         this.password = proxyClient.getPassword();
         this.url = proxyClient.getUrl();
@@ -113,7 +111,7 @@
             }
         }
 
-        plugins = new LinkedHashMap<JConsolePlugin, SwingWorker<?,?>>();
+        plugins = new LinkedHashMap<JConsolePlugin, SwingWorker<?, ?>>();
         for (JConsolePlugin p : JConsole.getPlugins()) {
             p.setContext(proxyClient);
             plugins.put(p, null);
@@ -128,10 +126,9 @@
         proxyClient.addPropertyChangeListener(this);
 
         addMouseListener(new MouseAdapter() {
+
             public void mouseClicked(MouseEvent e) {
-                if (connectedIconBounds != null
-                    && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0
-                    && connectedIconBounds.contains(e.getPoint())) {
+                if (connectedIconBounds != null && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0 && connectedIconBounds.contains(e.getPoint())) {
 
                     if (isConnected()) {
                         disconnect();
@@ -145,23 +142,21 @@
         });
 
     }
-
     private static Icon connectedIcon16 =
-        new ImageIcon(VMPanel.class.getResource("resources/connected16.png"));
+            new ImageIcon(VMPanel.class.getResource("resources/connected16.png"));
     private static Icon connectedIcon24 =
-        new ImageIcon(VMPanel.class.getResource("resources/connected24.png"));
+            new ImageIcon(VMPanel.class.getResource("resources/connected24.png"));
     private static Icon disconnectedIcon16 =
-        new ImageIcon(VMPanel.class.getResource("resources/disconnected16.png"));
+            new ImageIcon(VMPanel.class.getResource("resources/disconnected16.png"));
     private static Icon disconnectedIcon24 =
-        new ImageIcon(VMPanel.class.getResource("resources/disconnected24.png"));
-
+            new ImageIcon(VMPanel.class.getResource("resources/disconnected24.png"));
     private Rectangle connectedIconBounds;
 
     // Override to increase right inset for tab area,
     // in order to reserve space for the connect toggle.
     public void setUI(TabbedPaneUI ui) {
-        Insets insets = (Insets)UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets");
-        insets = (Insets)insets.clone();
+        Insets insets = (Insets) UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets");
+        insets = (Insets) insets.clone();
         insets.right += connectedIcon24.getIconWidth() + 8;
         UIManager.put("TabbedPane.tabAreaInsets", insets);
         super.setUI(ui);
@@ -225,7 +220,7 @@
     private Tab instantiate(TabInfo tabInfo) {
         try {
             Constructor con = tabInfo.tabClass.getConstructor(VMPanel.class);
-            return (Tab)con.newInstance(this);
+            return (Tab) con.newInstance(this);
         } catch (Exception ex) {
             System.err.println(ex);
             return null;
@@ -247,10 +242,11 @@
      * IT IS USED TO MAKE SOME LOCAL MANIPULATIONS.
      */
     ProxyClient getProxyClient(boolean assertThread) {
-        if(assertThread)
+        if (assertThread) {
             return getProxyClient();
-        else
+        } else {
             return proxyClient;
+        }
     }
 
     public ProxyClient getProxyClient() {
@@ -294,6 +290,7 @@
             startUpdateTimer();
         } else {
             new Thread("VMPanel.connect") {
+
                 public void run() {
                     proxyClient.connect();
                 }
@@ -301,68 +298,63 @@
         }
     }
 
-
     // Call on EDT
     public void disconnect() {
         proxyClient.disconnect();
         updateFrameTitle();
     }
 
-
-
     // Called on EDT
     public void propertyChange(PropertyChangeEvent ev) {
         String prop = ev.getPropertyName();
 
         if (prop == CONNECTION_STATE_PROPERTY) {
-            ConnectionState oldState = (ConnectionState)ev.getOldValue();
-            ConnectionState newState = (ConnectionState)ev.getNewValue();
+            ConnectionState oldState = (ConnectionState) ev.getOldValue();
+            ConnectionState newState = (ConnectionState) ev.getNewValue();
             switch (newState) {
-              case CONNECTING:
-                onConnecting();
-                break;
+                case CONNECTING:
+                    onConnecting();
+                    break;
 
-              case CONNECTED:
-                if (progressBar != null) {
-                    progressBar.setIndeterminate(false);
-                    progressBar.setValue(100);
-                }
-                closeOptionPane();
-                updateFrameTitle();
-                // create tabs if not done
-                createPluginTabs();
-                repaint();
-                // Notify tabs
-                fireConnectedChange(true);
-                // Enable/disable tabs on initial update
-                initialUpdate = true;
-                // Start/Restart update timer on connect/reconnect
-                startUpdateTimer();
-                break;
+                case CONNECTED:
+                    if (progressBar != null) {
+                        progressBar.setIndeterminate(false);
+                        progressBar.setValue(100);
+                    }
+                    closeOptionPane();
+                    updateFrameTitle();
+                    // create tabs if not done
+                    createPluginTabs();
+                    repaint();
+                    // Notify tabs
+                    fireConnectedChange(true);
+                    // Enable/disable tabs on initial update
+                    initialUpdate = true;
+                    // Start/Restart update timer on connect/reconnect
+                    startUpdateTimer();
+                    break;
 
-              case DISCONNECTED:
-                if (progressBar != null) {
-                    progressBar.setIndeterminate(false);
-                    progressBar.setValue(0);
-                    closeOptionPane();
-                }
-                vmPanelDied();
-                if (oldState == ConnectionState.CONNECTED) {
-                    // Notify tabs
-                    fireConnectedChange(false);
-                }
-                break;
+                case DISCONNECTED:
+                    if (progressBar != null) {
+                        progressBar.setIndeterminate(false);
+                        progressBar.setValue(0);
+                        closeOptionPane();
+                    }
+                    vmPanelDied();
+                    if (oldState == ConnectionState.CONNECTED) {
+                        // Notify tabs
+                        fireConnectedChange(false);
+                    }
+                    break;
             }
         }
     }
 
-
-
     // Called on EDT
     private void onConnecting() {
         time0 = System.currentTimeMillis();
 
-        final JConsole jc = (JConsole)SwingUtilities.getWindowAncestor(this);
+        final JConsole jc = (JConsole) SwingUtilities.getWindowAncestor(this);
 
         String connectionName = getConnectionName();
         progressBar = new JProgressBar();
@@ -373,17 +365,16 @@
         Object[] message = {
             "<html><h3>" + getText("connectingTo1", connectionName) + "</h3></html>",
             progressPanel,
-            "<html><b>"  + getText("connectingTo2", connectionName) + "</b></html>"
+            "<html><b>" + getText("connectingTo2", connectionName) + "</b></html>"
         };
 
-
         optionPane =
-            SheetDialog.showOptionDialog(this,
-                                         message,
-                                         JOptionPane.DEFAULT_OPTION,
-                                         JOptionPane.INFORMATION_MESSAGE, null,
-                                         new String[] { getText("Cancel") },
-                                         0);
+                SheetDialog.showOptionDialog(this,
+                message,
+                JOptionPane.DEFAULT_OPTION,
+                JOptionPane.INFORMATION_MESSAGE, null,
+                new String[]{getText("Cancel")},
+                0);
 
 
     }
@@ -398,10 +389,11 @@
                         try {
                             sleep(2000 - elapsed);
                         } catch (InterruptedException ex) {
-                            // Ignore
+                        // Ignore
                         }
                     }
                     SwingUtilities.invokeLater(new Runnable() {
+
                         public void run() {
                             optionPane.setVisible(false);
                             progressBar = null;
@@ -425,8 +417,8 @@
 
     private VMInternalFrame getFrame() {
         if (vmIF == null) {
-            vmIF = (VMInternalFrame)SwingUtilities.getAncestorOfClass(VMInternalFrame.class,
-                                                                      this);
+            vmIF = (VMInternalFrame) SwingUtilities.getAncestorOfClass(VMInternalFrame.class,
+                    this);
         }
         return vmIF;
     }
@@ -452,27 +444,27 @@
             timer.cancel();
         }
         TimerTask timerTask = new TimerTask() {
+
             public void run() {
                 update();
             }
         };
-        String timerName = "Timer-"+getConnectionName();
+        String timerName = "Timer-" + getConnectionName();
         timer = new Timer(timerName, true);
         timer.schedule(timerTask, 0, updateInterval);
     }
 
-
     // Call on EDT
     private void vmPanelDied() {
         disconnect();
 
-        final JConsole jc = (JConsole)SwingUtilities.getWindowAncestor(this);
+        final JConsole jc = (JConsole) SwingUtilities.getWindowAncestor(this);
 
         JOptionPane optionPane;
 
-        final String connectStr   = getText("Connect");
+        final String connectStr = getText("Connect");
         final String reconnectStr = getText("Reconnect");
-        final String cancelStr    = getText("Cancel");
+        final String cancelStr = getText("Cancel");
 
         String msgTitle, msgExplanation, buttonStr;
 
@@ -488,15 +480,16 @@
         }
 
         optionPane =
-            SheetDialog.showOptionDialog(this,
-                                         "<html><h3>" + msgTitle + "</h3>" +
-                                         "<b>" + msgExplanation + "</b>",
-                                         JOptionPane.DEFAULT_OPTION,
-                                         JOptionPane.WARNING_MESSAGE, null,
-                                         new String[] { buttonStr, cancelStr },
-                                         0);
+                SheetDialog.showOptionDialog(this,
+                "<html><h3>" + msgTitle + "</h3>" +
+                "<b>" + msgExplanation + "</b>",
+                JOptionPane.DEFAULT_OPTION,
+                JOptionPane.WARNING_MESSAGE, null,
+                new String[]{buttonStr, cancelStr},
+                0);
 
         optionPane.addPropertyChangeListener(new PropertyChangeListener() {
+
             public void propertyChange(PropertyChangeEvent event) {
                 if (event.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) {
                     Object value = event.getNewValue();
@@ -507,7 +500,7 @@
                         try {
                             getFrame().setClosed(true);
                         } catch (PropertyVetoException ex) {
-                            // Should not happen, but can be ignored.
+                        // Should not happen, but can be ignored.
                         }
                     }
                 }
@@ -518,11 +511,13 @@
     // Note: This method is called on a TimerTask thread. Any GUI manipulation
     // must be performed with invokeLater() or invokeAndWait().
     private Object lockObject = new Object();
+
     private void update() {
-        synchronized(lockObject) {
+        synchronized (lockObject) {
             if (!isConnected()) {
                 if (wasConnected) {
                     EventQueue.invokeLater(new Runnable() {
+
                         public void run() {
                             vmPanelDied();
                         }
@@ -548,6 +543,7 @@
                         //
                         if (initialUpdate) {
                             EventQueue.invokeLater(new Runnable() {
+
                                 public void run() {
                                     setEnabledAt(index, true);
                                 }
@@ -569,8 +565,8 @@
 
             // plugin GUI update
             for (JConsolePlugin p : plugins.keySet()) {
-                SwingWorker<?,?> sw = p.newSwingWorker();
-                SwingWorker<?,?> prevSW = plugins.get(p);
+                SwingWorker<?, ?> sw = p.newSwingWorker();
+                SwingWorker<?, ?> prevSW = plugins.get(p);
                 // schedule SwingWorker to run only if the previous
                 // SwingWorker has finished its task and it hasn't started.
                 if (prevSW == null || prevSW.isDone()) {
@@ -583,7 +579,7 @@
                 }
             }
 
-            // Set the first enabled tab in the tab´s list
+            // Set the first enabled tab in the tab's list
             // as the selected tab on initial update
             //
             if (initialUpdate) {
@@ -622,7 +618,6 @@
         return url;
     }
 
-
     public String getPassword() {
         return password;
     }
@@ -636,6 +631,7 @@
     }
 
     static class TabInfo {
+
         Class<? extends Tab> tabClass;
         String name;
         boolean tabVisible;
--- a/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java	Mon Apr 14 11:34:15 2008 -0700
@@ -22,9 +22,9 @@
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
+
 package sun.tools.jconsole.inspector;
 
-
 // java import
 import java.awt.*;
 import java.awt.event.*;
--- a/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java	Mon Apr 14 11:34:15 2008 -0700
@@ -22,6 +22,7 @@
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
+
 package sun.tools.jconsole.inspector;
 
 import java.util.*;
--- a/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java	Mon Apr 14 11:34:15 2008 -0700
@@ -22,6 +22,7 @@
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
+
 package sun.tools.jconsole.inspector;
 
 // java import
--- a/src/share/classes/sun/tools/jconsole/inspector/Utils.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/Utils.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2004-2007 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,55 +29,51 @@
 import java.lang.reflect.*;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.util.*;
+import java.util.concurrent.ExecutionException;
 import javax.management.*;
 import javax.management.openmbean.*;
 import javax.swing.*;
 import javax.swing.text.*;
-import java.util.*;
 
 public class Utils {
 
     private Utils() {
     }
-
     private static Set<Integer> tableNavigationKeys =
-            new HashSet<Integer>(Arrays.asList(new Integer[] {
+            new HashSet<Integer>(Arrays.asList(new Integer[]{
         KeyEvent.VK_TAB, KeyEvent.VK_ENTER,
         KeyEvent.VK_HOME, KeyEvent.VK_END,
         KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT,
         KeyEvent.VK_UP, KeyEvent.VK_DOWN,
-        KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN}));
-
+        KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN
+    }));
     private static final Set<Class<?>> primitiveWrappers =
-            new HashSet<Class<?>>(Arrays.asList(new Class<?>[] {
+            new HashSet<Class<?>>(Arrays.asList(new Class<?>[]{
         Byte.class, Short.class, Integer.class, Long.class,
-        Float.class, Double.class, Character.class, Boolean.class}));
-
+        Float.class, Double.class, Character.class, Boolean.class
+    }));
     private static final Set<Class<?>> primitives = new HashSet<Class<?>>();
-
     private static final Map<String, Class<?>> primitiveMap =
             new HashMap<String, Class<?>>();
-
     private static final Map<String, Class<?>> primitiveToWrapper =
             new HashMap<String, Class<?>>();
-
     private static final Set<String> editableTypes = new HashSet<String>();
-
     private static final Set<Class<?>> extraEditableClasses =
-            new HashSet<Class<?>>(Arrays.asList(new Class<?>[] {
+            new HashSet<Class<?>>(Arrays.asList(new Class<?>[]{
         BigDecimal.class, BigInteger.class, Number.class,
-        String.class, ObjectName.class}));
-
+        String.class, ObjectName.class
+    }));
     private static final Set<String> numericalTypes = new HashSet<String>();
-
     private static final Set<String> extraNumericalTypes =
-            new HashSet<String>(Arrays.asList(new String[] {
+            new HashSet<String>(Arrays.asList(new String[]{
         BigDecimal.class.getName(), BigInteger.class.getName(),
-        Number.class.getName()}));
-
+        Number.class.getName()
+    }));
     private static final Set<String> booleanTypes =
-            new HashSet<String>(Arrays.asList(new String[] {
-        Boolean.TYPE.getName(), Boolean.class.getName()}));
+            new HashSet<String>(Arrays.asList(new String[]{
+        Boolean.TYPE.getName(), Boolean.class.getName()
+    }));
 
     static {
         // compute primitives/primitiveMap/primitiveToWrapper
@@ -122,10 +118,11 @@
      * It's used to cater for the primitive types.
      */
     public static Class<?> getClass(String className)
-    throws ClassNotFoundException {
+            throws ClassNotFoundException {
         Class<?> c;
-        if ((c = primitiveMap.get(className)) != null)
+        if ((c = primitiveMap.get(className)) != null) {
             return c;
+        }
         return Class.forName(className);
     }
 
@@ -155,7 +152,9 @@
      * structure, i.e. a data structure jconsole can render as an array.
      */
     public static boolean canBeRenderedAsArray(Object elem) {
-        if (isSupportedArray(elem)) return true;
+        if (isSupportedArray(elem)) {
+            return true;
+        }
         if (elem instanceof Collection) {
             Collection<?> c = (Collection<?>) elem;
             if (c.isEmpty()) {
@@ -168,7 +167,7 @@
                 // - Collections of other Java types are handled as arrays
                 //
                 return !isUniformCollection(c, CompositeData.class) &&
-                       !isUniformCollection(c, TabularData.class);
+                        !isUniformCollection(c, TabularData.class);
             }
         }
         if (elem instanceof Map) {
@@ -239,7 +238,9 @@
      */
     public static String getReadableClassName(String name) {
         String className = getArrayClassName(name);
-        if (className == null) return name;
+        if (className == null) {
+            return name;
+        }
         int index = name.lastIndexOf("[");
         StringBuilder brackets = new StringBuilder(className);
         for (int i = 0; i <= index; i++) {
@@ -282,7 +283,7 @@
      * Try to create a Java object using a one-string-param constructor.
      */
     public static Object newStringConstructor(String type, String param)
-    throws Exception {
+            throws Exception {
         Constructor c = Utils.getClass(type).getConstructor(String.class);
         try {
             return c.newInstance(param);
@@ -300,7 +301,7 @@
      * Try to convert a string value into a numerical value.
      */
     private static Number createNumberFromStringValue(String value)
-    throws NumberFormatException {
+            throws NumberFormatException {
         final String suffix = value.substring(value.length() - 1);
         if ("L".equalsIgnoreCase(suffix)) {
             return Long.valueOf(value.substring(0, value.length() - 1));
@@ -314,17 +315,17 @@
         try {
             return Integer.valueOf(value);
         } catch (NumberFormatException e) {
-            // OK: Ignore exception...
+        // OK: Ignore exception...
         }
         try {
             return Long.valueOf(value);
         } catch (NumberFormatException e1) {
-            // OK: Ignore exception...
+        // OK: Ignore exception...
         }
         try {
             return Double.valueOf(value);
         } catch (NumberFormatException e2) {
-            // OK: Ignore exception...
+        // OK: Ignore exception...
         }
         throw new NumberFormatException("Cannot convert string value '" +
                 value + "' into a numerical value");
@@ -337,7 +338,7 @@
      * will return an Integer object initialized to 10.
      */
     public static Object createObjectFromString(String type, String value)
-    throws Exception {
+            throws Exception {
         Object result;
         if (primitiveToWrapper.containsKey(type)) {
             if (type.equals(Character.TYPE.getName())) {
@@ -367,7 +368,7 @@
      * into a useful object array for passing into a parameter array.
      */
     public static Object[] getParameters(XTextField[] inputs, String[] params)
-    throws Exception {
+            throws Exception {
         Object result[] = new Object[inputs.length];
         Object userInput;
         for (int i = 0; i < inputs.length; i++) {
@@ -388,12 +389,17 @@
      * If the exception is wrapped, unwrap it.
      */
     public static Throwable getActualException(Throwable e) {
+        if (e instanceof ExecutionException) {
+            e = e.getCause();
+        }
         if (e instanceof MBeanException ||
                 e instanceof RuntimeMBeanException ||
                 e instanceof RuntimeOperationsException ||
                 e instanceof ReflectionException) {
             Throwable t = e.getCause();
-            if (t != null) return t;
+            if (t != null) {
+                return t;
+            }
         }
         return e;
     }
@@ -401,6 +407,7 @@
     @SuppressWarnings("serial")
     public static class ReadOnlyTableCellEditor
             extends DefaultCellEditor {
+
         public ReadOnlyTableCellEditor(JTextField tf) {
             super(tf);
             tf.addFocusListener(new Utils.EditFocusAdapter(this));
@@ -409,20 +416,25 @@
     }
 
     public static class EditFocusAdapter extends FocusAdapter {
+
         private CellEditor editor;
+
         public EditFocusAdapter(CellEditor editor) {
             this.editor = editor;
         }
+
+        @Override
         public void focusLost(FocusEvent e) {
             editor.stopCellEditing();
         }
-    };
+    }
 
     public static class CopyKeyAdapter extends KeyAdapter {
         private static final String defaultEditorKitCopyActionName =
                 DefaultEditorKit.copyAction;
         private static final String transferHandlerCopyActionName =
                 (String) TransferHandler.getCopyAction().getValue(Action.NAME);
+        @Override
         public void keyPressed(KeyEvent e) {
             // Accept "copy" key strokes
             KeyStroke ks = KeyStroke.getKeyStroke(
@@ -441,6 +453,8 @@
                 e.consume();
             }
         }
+
+        @Override
         public void keyTyped(KeyEvent e) {
             e.consume();
         }
--- a/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -22,6 +22,7 @@
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
+
 package sun.tools.jconsole.inspector;
 
 import javax.swing.JTable;
@@ -108,6 +109,7 @@
     public Component createOperationViewer(Object value,
                                            XMBean mbean) {
         if(value instanceof Number) return null;
+        if(value instanceof Component) return (Component) value;
         return createAttributeViewer(value, mbean, null, null);
     }
 
--- a/src/share/classes/sun/tools/jconsole/inspector/XMBean.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XMBean.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2004-2007 Sun Microsystems, Inc.  All Rights Reserved.
  * 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,47 +28,56 @@
 import java.io.IOException;
 import javax.management.*;
 import javax.swing.Icon;
+import sun.tools.jconsole.JConsole;
 import sun.tools.jconsole.MBeansTab;
 
-public class XMBean extends Object {
-    private ObjectName objectName;
+public class XMBean {
+
+    private final MBeansTab mbeansTab;
+    private final ObjectName objectName;
     private Icon icon;
     private String text;
-    private boolean broadcaster;
+    private Boolean broadcaster;
+    private final Object broadcasterLock = new Object();
     private MBeanInfo mbeanInfo;
-    private MBeansTab mbeansTab;
+    private final Object mbeanInfoLock = new Object();
 
-    public XMBean(ObjectName objectName, MBeansTab mbeansTab)
-        throws InstanceNotFoundException, IntrospectionException,
-            ReflectionException, IOException {
+    public XMBean(ObjectName objectName, MBeansTab mbeansTab) {
         this.mbeansTab = mbeansTab;
-        setObjectName(objectName);
+        this.objectName = objectName;
+        text = objectName.getKeyProperty("name");
+        if (text == null) {
+            text = objectName.getDomain();
+        }
         if (MBeanServerDelegate.DELEGATE_NAME.equals(objectName)) {
             icon = IconManager.MBEANSERVERDELEGATE;
         } else {
             icon = IconManager.MBEAN;
         }
-        this.broadcaster = isBroadcaster(objectName);
-        this.mbeanInfo = getMBeanInfo(objectName);
     }
 
     MBeanServerConnection getMBeanServerConnection() {
         return mbeansTab.getMBeanServerConnection();
     }
 
-    public boolean isBroadcaster() {
-        return broadcaster;
-    }
-
-    private boolean isBroadcaster(ObjectName name) {
-        try {
-            return getMBeanServerConnection().isInstanceOf(
-                    name, "javax.management.NotificationBroadcaster");
-        } catch (Exception e) {
-            System.out.println("Error calling isBroadcaster: " +
-                    e.getMessage());
+    public Boolean isBroadcaster() {
+        synchronized (broadcasterLock) {
+            if (broadcaster == null) {
+                try {
+                    broadcaster = getMBeanServerConnection().isInstanceOf(
+                            getObjectName(),
+                            "javax.management.NotificationBroadcaster");
+                } catch (Exception e) {
+                    if (JConsole.isDebug()) {
+                        System.err.println("Couldn't check if MBean [" +
+                                objectName + "] is a notification broadcaster");
+                        e.printStackTrace();
+                    }
+                    return false;
+                }
+            }
+            return broadcaster;
         }
-        return false;
     }
 
     public Object invoke(String operationName) throws Exception {
@@ -78,35 +87,35 @@
     }
 
     public Object invoke(String operationName, Object params[], String sig[])
-        throws Exception {
+            throws Exception {
         Object result = getMBeanServerConnection().invoke(
                 getObjectName(), operationName, params, sig);
         return result;
     }
 
     public void setAttribute(Attribute attribute)
-        throws AttributeNotFoundException, InstanceNotFoundException,
+            throws AttributeNotFoundException, InstanceNotFoundException,
             InvalidAttributeValueException, MBeanException,
             ReflectionException, IOException {
         getMBeanServerConnection().setAttribute(getObjectName(), attribute);
     }
 
     public Object getAttribute(String attributeName)
-        throws AttributeNotFoundException, InstanceNotFoundException,
+            throws AttributeNotFoundException, InstanceNotFoundException,
             MBeanException, ReflectionException, IOException {
         return getMBeanServerConnection().getAttribute(
                 getObjectName(), attributeName);
     }
 
     public AttributeList getAttributes(String attributeNames[])
-        throws AttributeNotFoundException, InstanceNotFoundException,
+            throws AttributeNotFoundException, InstanceNotFoundException,
             MBeanException, ReflectionException, IOException {
         return getMBeanServerConnection().getAttributes(
                 getObjectName(), attributeNames);
     }
 
     public AttributeList getAttributes(MBeanAttributeInfo attributeNames[])
-        throws AttributeNotFoundException, InstanceNotFoundException,
+            throws AttributeNotFoundException, InstanceNotFoundException,
             MBeanException, ReflectionException, IOException {
         String attributeString[] = new String[attributeNames.length];
         for (int i = 0; i < attributeNames.length; i++) {
@@ -119,32 +128,34 @@
         return objectName;
     }
 
-    private void setObjectName(ObjectName objectName) {
-        this.objectName = objectName;
-        // generate a readable name now
-        String name = getObjectName().getKeyProperty("name");
-        if (name == null)
-            setText(getObjectName().getDomain());
-        else
-            setText(name);
+    public MBeanInfo getMBeanInfo() throws InstanceNotFoundException,
+            IntrospectionException, ReflectionException, IOException {
+        synchronized (mbeanInfoLock) {
+            if (mbeanInfo == null) {
+                mbeanInfo = getMBeanServerConnection().getMBeanInfo(objectName);
+            }
+            return mbeanInfo;
+        }
     }
 
-    public MBeanInfo getMBeanInfo() {
-        return mbeanInfo;
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof XMBean)) {
+            return false;
+        }
+        XMBean that = (XMBean) obj;
+        return getObjectName().equals(that.getObjectName());
     }
 
-    private MBeanInfo getMBeanInfo(ObjectName name)
-        throws InstanceNotFoundException, IntrospectionException,
-            ReflectionException, IOException {
-        return getMBeanServerConnection().getMBeanInfo(name);
-    }
-
-    public boolean equals(Object o) {
-        if (o instanceof XMBean) {
-            XMBean mbean = (XMBean) o;
-            return getObjectName().equals((mbean).getObjectName());
-        }
-        return false;
+    @Override
+    public int hashCode() {
+        return (objectName == null ? 0 : objectName.hashCode());
     }
 
     public String getText() {
@@ -163,6 +174,7 @@
         this.icon = icon;
     }
 
+    @Override
     public String toString() {
         return getText();
     }
--- a/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2004-2007 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,10 +35,7 @@
 import javax.swing.border.TitledBorder;
 import javax.swing.event.*;
 import javax.swing.table.*;
-import javax.swing.tree.*;
-import sun.tools.jconsole.JConsole;
 import sun.tools.jconsole.Resources;
-import sun.tools.jconsole.inspector.XNodeInfo.Type;
 
 import static sun.tools.jconsole.Utilities.*;
 
@@ -46,21 +43,20 @@
 public class XMBeanInfo extends JPanel {
 
     private static final Color lightYellow = new Color(255, 255, 128);
-
     private final int NAME_COLUMN = 0;
     private final int VALUE_COLUMN = 1;
-
     private final String[] columnNames = {
         Resources.getText("Name"),
         Resources.getText("Value")
     };
-
     private JTable infoTable = new JTable();
     private JTable descTable = new JTable();
     private JPanel infoBorderPanel = new JPanel(new BorderLayout());
     private JPanel descBorderPanel = new JPanel(new BorderLayout());
 
     private static class ReadOnlyDefaultTableModel extends DefaultTableModel {
+
+        @Override
         public void setValueAt(Object value, int row, int col) {
         }
     }
@@ -73,17 +69,18 @@
             this.tableRowDividerText = tableRowDividerText;
         }
 
+        @Override
         public String toString() {
             return tableRowDividerText;
         }
     }
-
     private static MBeanInfoTableCellRenderer renderer =
             new MBeanInfoTableCellRenderer();
 
     private static class MBeanInfoTableCellRenderer
             extends DefaultTableCellRenderer {
 
+        @Override
         public Component getTableCellRendererComponent(
                 JTable table, Object value, boolean isSelected,
                 boolean hasFocus, int row, int column) {
@@ -92,22 +89,24 @@
             if (value instanceof TableRowDivider) {
                 JLabel label = new JLabel(value.toString());
                 label.setBackground(ensureContrast(lightYellow,
-                                                   label.getForeground()));
+                        label.getForeground()));
                 label.setOpaque(true);
                 return label;
             }
             return comp;
         }
     }
-
     private static TableCellEditor editor =
             new MBeanInfoTableCellEditor(new JTextField());
 
     private static class MBeanInfoTableCellEditor
             extends Utils.ReadOnlyTableCellEditor {
+
         public MBeanInfoTableCellEditor(JTextField tf) {
             super(tf);
         }
+
+        @Override
         public Component getTableCellEditorComponent(
                 JTable table, Object value, boolean isSelected,
                 int row, int column) {
@@ -116,7 +115,7 @@
             if (value instanceof TableRowDivider) {
                 JLabel label = new JLabel(value.toString());
                 label.setBackground(ensureContrast(lightYellow,
-                                                   label.getForeground()));
+                        label.getForeground()));
                 label.setOpaque(true);
                 return label;
             }
@@ -172,6 +171,7 @@
         add(descBorderPanel);
     }
 
+    // Call on EDT
     public void emptyInfoTable() {
         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
         while (tableModel.getRowCount() > 0) {
@@ -179,6 +179,7 @@
         }
     }
 
+    // Call on EDT
     public void emptyDescTable() {
         DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel();
         while (tableModel.getRowCount() > 0) {
@@ -186,6 +187,7 @@
         }
     }
 
+    // Call on EDT
     private void addDescriptor(Descriptor desc, String text) {
         if (desc != null && desc.getFieldNames().length > 0) {
             DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel();
@@ -223,6 +225,7 @@
         }
     }
 
+    // Call on EDT
     public void addMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) {
         emptyInfoTable();
         emptyDescTable();
@@ -263,6 +266,7 @@
         tableModel.newDataAvailable(new TableModelEvent(tableModel));
     }
 
+    // Call on EDT
     public void addMBeanAttributeInfo(MBeanAttributeInfo mbai) {
         emptyInfoTable();
         emptyDescTable();
@@ -296,6 +300,7 @@
         tableModel.newDataAvailable(new TableModelEvent(tableModel));
     }
 
+    // Call on EDT
     public void addMBeanOperationInfo(MBeanOperationInfo mboi) {
         emptyInfoTable();
         emptyDescTable();
@@ -343,6 +348,7 @@
         tableModel.newDataAvailable(new TableModelEvent(tableModel));
     }
 
+    // Call on EDT
     public void addMBeanNotificationInfo(MBeanNotificationInfo mbni) {
         emptyInfoTable();
         emptyDescTable();
@@ -367,6 +373,7 @@
         tableModel.newDataAvailable(new TableModelEvent(tableModel));
     }
 
+    // Call on EDT
     private void addMBeanConstructorInfo(MBeanConstructorInfo mbci, String text) {
         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
         Object rowData[] = new Object[2];
@@ -383,6 +390,7 @@
         tableModel.newDataAvailable(new TableModelEvent(tableModel));
     }
 
+    // Call on EDT
     private void addMBeanParameterInfo(MBeanParameterInfo mbpi, String text) {
         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
         Object rowData[] = new Object[2];
@@ -401,91 +409,4 @@
         addDescriptor(mbpi.getDescriptor(), text);
         tableModel.newDataAvailable(new TableModelEvent(tableModel));
     }
-
-    public static void loadInfo(DefaultMutableTreeNode root) {
-        // Retrieve XMBean from XNodeInfo
-        //
-        XMBean mbean = (XMBean) ((XNodeInfo) root.getUserObject()).getData();
-        // Initialize MBean*Info
-        //
-        final MBeanInfo mbeanInfo;
-        try {
-            mbeanInfo = mbean.getMBeanInfo();
-        } catch (Exception e) {
-            if (JConsole.isDebug()) {
-                e.printStackTrace();
-            }
-            return;
-        }
-        MBeanAttributeInfo[] ai = mbeanInfo.getAttributes();
-        MBeanOperationInfo[] oi = mbeanInfo.getOperations();
-        MBeanNotificationInfo[] ni = mbeanInfo.getNotifications();
-        // MBeanAttributeInfo node
-        //
-        if (ai != null && ai.length > 0) {
-            DefaultMutableTreeNode attributes = new DefaultMutableTreeNode();
-            XNodeInfo attributesUO = new XNodeInfo(Type.ATTRIBUTES, mbean,
-                    Resources.getText("Attributes"), null);
-            attributes.setUserObject(attributesUO);
-            root.add(attributes);
-            for (MBeanAttributeInfo mbai : ai) {
-                DefaultMutableTreeNode attribute = new DefaultMutableTreeNode();
-                XNodeInfo attributeUO = new XNodeInfo(Type.ATTRIBUTE,
-                        new Object[] {mbean, mbai}, mbai.getName(), null);
-                attribute.setUserObject(attributeUO);
-                attributes.add(attribute);
-            }
-        }
-        // MBeanOperationInfo node
-        //
-        if (oi != null && oi.length > 0) {
-            DefaultMutableTreeNode operations = new DefaultMutableTreeNode();
-            XNodeInfo operationsUO = new XNodeInfo(Type.OPERATIONS, mbean,
-                    Resources.getText("Operations"), null);
-            operations.setUserObject(operationsUO);
-            root.add(operations);
-            for (MBeanOperationInfo mboi : oi) {
-                // Compute the operation's tool tip text:
-                // "operationname(param1type,param2type,...)"
-                //
-                StringBuilder sb = new StringBuilder();
-                for (MBeanParameterInfo mbpi : mboi.getSignature()) {
-                    sb.append(mbpi.getType() + ",");
-                }
-                String signature = sb.toString();
-                if (signature.length() > 0) {
-                    // Remove the trailing ','
-                    //
-                    signature = signature.substring(0, signature.length() - 1);
-                }
-                String toolTipText = mboi.getName() + "(" + signature + ")";
-                // Create operation node
-                //
-                DefaultMutableTreeNode operation = new DefaultMutableTreeNode();
-                XNodeInfo operationUO = new XNodeInfo(Type.OPERATION,
-                        new Object[] {mbean, mboi}, mboi.getName(), toolTipText);
-                operation.setUserObject(operationUO);
-                operations.add(operation);
-            }
-        }
-        // MBeanNotificationInfo node
-        //
-        if (mbean.isBroadcaster()) {
-            DefaultMutableTreeNode notifications = new DefaultMutableTreeNode();
-            XNodeInfo notificationsUO = new XNodeInfo(Type.NOTIFICATIONS, mbean,
-                    Resources.getText("Notifications"), null);
-            notifications.setUserObject(notificationsUO);
-            root.add(notifications);
-            if (ni != null && ni.length > 0) {
-                for (MBeanNotificationInfo mbni : ni) {
-                    DefaultMutableTreeNode notification =
-                            new DefaultMutableTreeNode();
-                    XNodeInfo notificationUO = new XNodeInfo(Type.NOTIFICATION,
-                            mbni, mbni.getName(), null);
-                    notification.setUserObject(notificationUO);
-                    notifications.add(notification);
-                }
-            }
-        }
-    }
 }
--- a/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java	Mon Apr 14 11:34:15 2008 -0700
@@ -29,17 +29,13 @@
 import javax.swing.event.*;
 import javax.swing.table.*;
 import javax.swing.tree.*;
-import java.awt.BorderLayout;
-import java.awt.GridLayout;
 import java.awt.Font;
 
 import java.text.SimpleDateFormat;
 
-import java.awt.FlowLayout;
 import java.awt.Component;
 import java.awt.EventQueue;
 import java.awt.event.*;
-import java.awt.Insets;
 import java.awt.Dimension;
 import java.util.*;
 import java.io.*;
@@ -49,45 +45,44 @@
 import javax.management.openmbean.CompositeData;
 import javax.management.openmbean.TabularData;
 
+import sun.tools.jconsole.JConsole;
 import sun.tools.jconsole.Resources;
 
 @SuppressWarnings("serial")
 public class XMBeanNotifications extends JTable implements NotificationListener {
 
-    private final static String[] columnNames =  {
+    private final static String[] columnNames = {
         Resources.getText("TimeStamp"),
         Resources.getText("Type"),
         Resources.getText("UserData"),
         Resources.getText("SeqNum"),
         Resources.getText("Message"),
         Resources.getText("Event"),
-        Resources.getText("Source")};
-
+        Resources.getText("Source")
+    };
     private HashMap<ObjectName, XMBeanNotificationsListener> listeners =
-        new HashMap<ObjectName, XMBeanNotificationsListener>();
-    private boolean subscribed;
+            new HashMap<ObjectName, XMBeanNotificationsListener>();
+    private volatile boolean subscribed;
     private XMBeanNotificationsListener currentListener;
     public final static String NOTIFICATION_RECEIVED_EVENT =
-        "jconsole.xnotification.received";
-
+            "jconsole.xnotification.received";
     private List<NotificationListener> notificationListenersList;
-    private boolean enabled;
-    private Font normalFont, boldFont;
+    private volatile boolean enabled;
+    private Font normalFont,  boldFont;
     private int rowMinHeight = -1;
     private TableCellEditor userDataEditor = new UserDataCellEditor();
     private NotifMouseListener mouseListener = new NotifMouseListener();
     private SimpleDateFormat timeFormater = new SimpleDateFormat("HH:mm:ss:SSS");
-
     private static TableCellEditor editor =
             new Utils.ReadOnlyTableCellEditor(new JTextField());
 
     public XMBeanNotifications() {
-        super(new TableSorter(columnNames,0));
+        super(new TableSorter(columnNames, 0));
         setColumnSelectionAllowed(false);
         setRowSelectionAllowed(false);
         getTableHeader().setReorderingAllowed(false);
         ArrayList<NotificationListener> l =
-            new ArrayList<NotificationListener>(1);
+                new ArrayList<NotificationListener>(1);
         notificationListenersList = Collections.synchronizedList(l);
 
         addMouseListener(mouseListener);
@@ -103,20 +98,24 @@
         addKeyListener(new Utils.CopyKeyAdapter());
     }
 
+    // Call on EDT
     public void cancelCellEditing() {
-        TableCellEditor editor = getCellEditor();
-        if (editor != null) {
-            editor.cancelCellEditing();
+        TableCellEditor tce = getCellEditor();
+        if (tce != null) {
+            tce.cancelCellEditing();
         }
     }
 
+    // Call on EDT
     public void stopCellEditing() {
-        TableCellEditor editor = getCellEditor();
-        if (editor != null) {
-            editor.stopCellEditing();
+        TableCellEditor tce = getCellEditor();
+        if (tce != null) {
+            tce.stopCellEditing();
         }
     }
 
+    // Call on EDT
+    @Override
     public boolean isCellEditable(int row, int col) {
         UserDataCell cell = getUserDataCell(row, col);
         if (cell != null) {
@@ -125,16 +124,21 @@
         return true;
     }
 
+    // Call on EDT
+    @Override
     public void setValueAt(Object value, int row, int column) {
     }
 
-    public synchronized Component prepareRenderer(TableCellRenderer renderer,
-                                                  int row, int column) {
+    // Call on EDT
+    @Override
+    public synchronized Component prepareRenderer(
+            TableCellRenderer renderer, int row, int column) {
         //In case we have a repaint thread that is in the process of
         //repainting an obsolete table, just ignore the call.
         //It can happen when MBean selection is switched at a very quick rate
-        if(row >= getRowCount())
+        if (row >= getRowCount()) {
             return null;
+        }
 
         Component comp = super.prepareRenderer(renderer, row, column);
 
@@ -146,9 +150,10 @@
         if (column == 2 && cell != null) {
             comp.setFont(boldFont);
             int size = cell.getHeight();
-            if(size > 0) {
-                if(getRowHeight(row) != size)
+            if (size > 0) {
+                if (getRowHeight(row) != size) {
                     setRowHeight(row, size);
+                }
             }
         } else {
             comp.setFont(normalFont);
@@ -157,34 +162,35 @@
         return comp;
     }
 
-    public synchronized TableCellRenderer getCellRenderer(int row,
-                                                          int column) {
+    // Call on EDT
+    @Override
+    public synchronized TableCellRenderer getCellRenderer(int row, int column) {
         //In case we have a repaint thread that is in the process of
         //repainting an obsolete table, just ignore the call.
         //It can happen when MBean selection is switched at a very quick rate
-        if(row >= getRowCount())
+        if (row >= getRowCount()) {
             return null;
+        }
 
         DefaultTableCellRenderer renderer;
         String toolTip = null;
         UserDataCell cell = getUserDataCell(row, column);
-        if(cell != null && cell.isInited()) {
+        if (cell != null && cell.isInited()) {
             renderer = (DefaultTableCellRenderer) cell.getRenderer();
-        }
-        else {
-            renderer = (DefaultTableCellRenderer)
-                super.getCellRenderer(row,
-                                      column);
+        } else {
+            renderer =
+                    (DefaultTableCellRenderer) super.getCellRenderer(row, column);
         }
 
-        if(cell != null)
-            toolTip = Resources.getText("Double click to expand/collapse")+". "
-                + cell.toString();
-        else {
+        if (cell != null) {
+            toolTip = Resources.getText("Double click to expand/collapse") +
+                    ". " + cell.toString();
+        } else {
             Object val =
-                ((DefaultTableModel) getModel()).getValueAt(row,column);
-            if(val != null)
+                    ((DefaultTableModel) getModel()).getValueAt(row, column);
+            if (val != null) {
                 toolTip = val.toString();
+            }
         }
 
         renderer.setToolTipText(toolTip);
@@ -192,9 +198,12 @@
         return renderer;
     }
 
+    // Call on EDT
     private UserDataCell getUserDataCell(int row, int column) {
-        Object obj = ((DefaultTableModel) getModel()).getValueAt(row,column);
-        if(obj instanceof UserDataCell) return (UserDataCell) obj;
+        Object obj = ((DefaultTableModel) getModel()).getValueAt(row, column);
+        if (obj instanceof UserDataCell) {
+            return (UserDataCell) obj;
+        }
         return null;
     }
 
@@ -204,19 +213,22 @@
 
     public long getReceivedNotifications(XMBean mbean) {
         XMBeanNotificationsListener listener =
-            listeners.get(mbean.getObjectName());
-        if(listener == null) return 0;
-        else
+                listeners.get(mbean.getObjectName());
+        if (listener == null) {
+            return 0;
+        } else {
             return listener.getReceivedNotifications();
+        }
     }
 
     public synchronized boolean clearCurrentNotifications() {
         emptyTable();
-        if(currentListener != null) {
+        if (currentListener != null) {
             currentListener.clear();
             return true;
-        } else
+        } else {
             return false;
+        }
     }
 
     public synchronized boolean unregisterListener(DefaultMutableTreeNode node) {
@@ -225,29 +237,25 @@
     }
 
     public synchronized void registerListener(DefaultMutableTreeNode node)
-        throws InstanceNotFoundException, IOException {
+            throws InstanceNotFoundException, IOException {
         XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();
-        if(!subscribed) {
+        if (!subscribed) {
             try {
-                mbean.getMBeanServerConnection().
-                    addNotificationListener(new ObjectName("JMImplementation:type=MBeanServerDelegate"),
-                                            this,
-                                            null,
-                                            null);
+                mbean.getMBeanServerConnection().addNotificationListener(
+                        MBeanServerDelegate.DELEGATE_NAME, this, null, null);
                 subscribed = true;
-            }catch(Exception e) {
-                System.out.println("Error adding listener for delegate :"+
-                                   e.getMessage());
+            } catch (Exception e) {
+                if (JConsole.isDebug()) {
+                    System.err.println("Error adding listener for delegate:");
+                    e.printStackTrace();
+                }
             }
         }
-
         XMBeanNotificationsListener listener =
-            listeners.get(mbean.getObjectName());
+                listeners.get(mbean.getObjectName());
         if (listener == null) {
-            listener = new XMBeanNotificationsListener(this,
-                                                       mbean,
-                                                       node,
-                                                       columnNames);
+            listener = new XMBeanNotificationsListener(
+                    this, mbean, node, columnNames);
             listeners.put(mbean.getObjectName(), listener);
         } else {
             if (!listener.isRegistered()) {
@@ -259,19 +267,21 @@
         currentListener = listener;
     }
 
-    public synchronized void handleNotification(Notification notif,
-                                                Object handback) {
+    public synchronized void handleNotification(
+            Notification notif, Object handback) {
         try {
             if (notif instanceof MBeanServerNotification) {
                 ObjectName mbean =
-                    ((MBeanServerNotification)notif).getMBeanName();
-                if (notif.getType().indexOf("JMX.mbean.unregistered")>=0){
+                        ((MBeanServerNotification) notif).getMBeanName();
+                if (notif.getType().indexOf("JMX.mbean.unregistered") >= 0) {
                     unregister(mbean);
                 }
             }
-        } catch(Exception e) {
-             System.out.println("Error unregistering notification:"+
-                               e.getMessage());
+        } catch (Exception e) {
+            if (JConsole.isDebug()) {
+                System.err.println("Error unregistering notification:");
+                e.printStackTrace();
+            }
         }
     }
 
@@ -283,75 +293,77 @@
 
     private synchronized boolean unregister(ObjectName mbean) {
         XMBeanNotificationsListener listener = listeners.get(mbean);
-        if(listener != null && listener.isRegistered()) {
+        if (listener != null && listener.isRegistered()) {
             listener.unregister();
             return true;
-        } else
+        } else {
             return false;
+        }
     }
 
     public void addNotificationsListener(NotificationListener nl) {
-            notificationListenersList.add(nl);
+        notificationListenersList.add(nl);
     }
 
     public void removeNotificationsListener(NotificationListener nl) {
         notificationListenersList.remove(nl);
     }
 
-    void fireNotificationReceived(XMBeanNotificationsListener listener,
-                                  XMBean mbean,
-                                  DefaultMutableTreeNode node,
-                                  Object[] rowData,
-                                  long received) {
-        if(enabled) {
+    // Call on EDT
+    void fireNotificationReceived(
+            XMBeanNotificationsListener listener, XMBean mbean,
+            DefaultMutableTreeNode node, Object[] rowData, long received) {
+        if (enabled) {
             DefaultTableModel tableModel = (DefaultTableModel) getModel();
-            if(listener == currentListener) {
-
-                //tableModel.addRow(rowData);
+            if (listener == currentListener) {
                 tableModel.insertRow(0, rowData);
-
-                //tableModel.newDataAvailable(new TableModelEvent(tableModel));
                 repaint();
             }
         }
-
-        Notification notif = new Notification(NOTIFICATION_RECEIVED_EVENT,
-                                              this,
-                                              0);
-        notif.setUserData(new Long(received));
-        for(NotificationListener nl : notificationListenersList)
-            nl.handleNotification(notif,node);
+        Notification notif =
+                new Notification(NOTIFICATION_RECEIVED_EVENT, this, 0);
+        notif.setUserData(received);
+        for (NotificationListener nl : notificationListenersList) {
+            nl.handleNotification(notif, node);
+        }
     }
 
+    // Call on EDT
     private void updateModel(List<Object[]> data) {
         emptyTable();
         DefaultTableModel tableModel = (DefaultTableModel) getModel();
-        for(Object[] rowData : data)
+        for (Object[] rowData : data) {
             tableModel.addRow(rowData);
+        }
     }
 
     public synchronized boolean isListenerRegistered(XMBean mbean) {
         XMBeanNotificationsListener listener =
-            listeners.get(mbean.getObjectName());
-        if(listener == null) return false;
+                listeners.get(mbean.getObjectName());
+        if (listener == null) {
+            return false;
+        }
         return listener.isRegistered();
     }
 
+    // Call on EDT
     public synchronized void loadNotifications(XMBean mbean) {
         XMBeanNotificationsListener listener =
-            listeners.get(mbean.getObjectName());
+                listeners.get(mbean.getObjectName());
         emptyTable();
-        if(listener != null ) {
+        if (listener != null) {
             enabled = true;
             List<Object[]> data = listener.getData();
             updateModel(data);
             currentListener = listener;
             validate();
             repaint();
-        } else
+        } else {
             enabled = false;
+        }
     }
 
+    // Call on EDT
     private void setColumnEditors() {
         TableColumnModel tcm = getColumnModel();
         for (int i = 0; i < columnNames.length; i++) {
@@ -364,40 +376,40 @@
         }
     }
 
+    // Call on EDT
     public boolean isTableEditable() {
         return true;
     }
 
+    // Call on EDT
     public synchronized void emptyTable() {
-        DefaultTableModel model = (DefaultTableModel)getModel();
+        DefaultTableModel model = (DefaultTableModel) getModel();
         //invalidate();
-        while (model.getRowCount()>0)
+        while (model.getRowCount() > 0) {
             model.removeRow(0);
+        }
         validate();
     }
 
-    synchronized void updateUserDataCell(int row,
-                                         int col) {
+    // Call on EDT
+    synchronized void updateUserDataCell(int row, int col) {
         Object obj = getModel().getValueAt(row, 2);
-        if(obj instanceof UserDataCell) {
+        if (obj instanceof UserDataCell) {
             UserDataCell cell = (UserDataCell) obj;
-            if(!cell.isInited()) {
-                if(rowMinHeight == -1)
+            if (!cell.isInited()) {
+                if (rowMinHeight == -1) {
                     rowMinHeight = getRowHeight(row);
-
-                cell.init(super.getCellRenderer(row, col),
-                          rowMinHeight);
+                }
+                cell.init(super.getCellRenderer(row, col), rowMinHeight);
             }
 
             cell.switchState();
-            setRowHeight(row,
-                         cell.getHeight());
+            setRowHeight(row, cell.getHeight());
 
-            if(!cell.isMaximized()) {
+            if (!cell.isMaximized()) {
                 cancelCellEditing();
                 //Back to simple editor.
-                editCellAt(row,
-                           2);
+                editCellAt(row, 2);
             }
 
             invalidate();
@@ -406,7 +418,9 @@
     }
 
     class UserDataCellRenderer extends DefaultTableCellRenderer {
+
         Component comp;
+
         UserDataCellRenderer(Component comp) {
             this.comp = comp;
             Dimension d = comp.getPreferredSize();
@@ -415,56 +429,62 @@
             }
         }
 
-        public Component getTableCellRendererComponent(JTable table,
-                                                       Object value,
-                                                       boolean isSelected,
-                                                       boolean hasFocus,
-                                                       int row,
-                                                       int column) {
+        @Override
+        public Component getTableCellRendererComponent(
+                JTable table,
+                Object value,
+                boolean isSelected,
+                boolean hasFocus,
+                int row,
+                int column) {
             return comp;
         }
 
         public Component getComponent() {
             return comp;
         }
-
     }
 
     class UserDataCell {
+
         TableCellRenderer minRenderer;
         UserDataCellRenderer maxRenderer;
         int minHeight;
         boolean minimized = true;
         boolean init = false;
         Object userData;
-       UserDataCell(Object userData, Component max) {
-           this.userData = userData;
-           this.maxRenderer = new UserDataCellRenderer(max);
 
-       }
+        UserDataCell(Object userData, Component max) {
+            this.userData = userData;
+            this.maxRenderer = new UserDataCellRenderer(max);
+
+        }
 
-       public String toString() {
-           if(userData == null) return null;
-           if(userData.getClass().isArray()) {
-               String name =
-                   Utils.getArrayClassName(userData.getClass().getName());
-               int length = Array.getLength(userData);
-               return name + "[" + length +"]";
-           }
+        @Override
+        public String toString() {
+            if (userData == null) {
+                return null;
+            }
+            if (userData.getClass().isArray()) {
+                String name =
+                        Utils.getArrayClassName(userData.getClass().getName());
+                int length = Array.getLength(userData);
+                return name + "[" + length + "]";
+            }
 
-            if(userData instanceof CompositeData ||
-               userData instanceof TabularData)
+            if (userData instanceof CompositeData ||
+                    userData instanceof TabularData) {
                 return userData.getClass().getName();
+            }
 
             return userData.toString();
-       }
+        }
 
         boolean isInited() {
             return init;
         }
 
-        void init(TableCellRenderer minRenderer,
-                  int minHeight) {
+        void init(TableCellRenderer minRenderer, int minHeight) {
             this.minRenderer = minRenderer;
             this.minHeight = minHeight;
             init = true;
@@ -473,9 +493,11 @@
         void switchState() {
             minimized = !minimized;
         }
+
         boolean isMaximized() {
             return !minimized;
         }
+
         void minimize() {
             minimized = true;
         }
@@ -485,30 +507,39 @@
         }
 
         int getHeight() {
-            if(minimized) return minHeight;
-            else
+            if (minimized) {
+                return minHeight;
+            } else {
                 return (int) maxRenderer.getComponent().
-                    getPreferredSize().getHeight() ;
+                        getPreferredSize().getHeight();
+            }
         }
 
         TableCellRenderer getRenderer() {
-            if(minimized) return minRenderer;
-            else return maxRenderer;
+            if (minimized) {
+                return minRenderer;
+            } else {
+                return maxRenderer;
+            }
         }
     }
 
     class NotifMouseListener extends MouseAdapter {
 
+        @Override
         public void mousePressed(MouseEvent e) {
-            if(e.getButton() == MouseEvent.BUTTON1) {
-                if(e.getClickCount() >= 2) {
+            if (e.getButton() == MouseEvent.BUTTON1) {
+                if (e.getClickCount() >= 2) {
                     int row = XMBeanNotifications.this.getSelectedRow();
                     int col = XMBeanNotifications.this.getSelectedColumn();
-                    if(col != 2) return;
-                    if(col == -1 || row == -1) return;
+                    if (col != 2) {
+                        return;
+                    }
+                    if (col == -1 || row == -1) {
+                        return;
+                    }
 
-                    XMBeanNotifications.this.updateUserDataCell(row,
-                                                                col);
+                    XMBeanNotifications.this.updateUserDataCell(row, col);
                 }
             }
         }
@@ -516,20 +547,21 @@
 
     class UserDataCellEditor extends XTextFieldEditor {
         // implements javax.swing.table.TableCellEditor
-        public Component getTableCellEditorComponent(JTable table,
-                                                     Object value,
-                                                     boolean isSelected,
-                                                     int row,
-                                                     int column) {
+        @Override
+        public Component getTableCellEditorComponent(
+                JTable table,
+                Object value,
+                boolean isSelected,
+                int row,
+                int column) {
             Object val = value;
-            if(column == 2) {
-                Object obj = getModel().getValueAt(row,
-                                                   column);
-                if(obj instanceof UserDataCell) {
+            if (column == 2) {
+                Object obj = getModel().getValueAt(row, column);
+                if (obj instanceof UserDataCell) {
                     UserDataCell cell = (UserDataCell) obj;
-                    if(cell.getRenderer() instanceof UserDataCellRenderer) {
+                    if (cell.getRenderer() instanceof UserDataCellRenderer) {
                         UserDataCellRenderer zr =
-                            (UserDataCellRenderer) cell.getRenderer();
+                                (UserDataCellRenderer) cell.getRenderer();
                         return zr.getComponent();
                     }
                 } else {
@@ -539,12 +571,14 @@
                     return comp;
                 }
             }
-            return super.getTableCellEditorComponent(table,
-                                                     val,
-                                                     isSelected,
-                                                     row,
-                                                     column);
+            return super.getTableCellEditorComponent(
+                    table,
+                    val,
+                    isSelected,
+                    row,
+                    column);
         }
+
         @Override
         public boolean stopCellEditing() {
             int editingRow = getEditingRow();
@@ -554,7 +588,7 @@
                 if (obj instanceof UserDataCell) {
                     UserDataCell cell = (UserDataCell) obj;
                     if (cell.isMaximized()) {
-                        this.cancelCellEditing();
+                        cancelCellEditing();
                         return true;
                     }
                 }
@@ -564,17 +598,20 @@
     }
 
     class XMBeanNotificationsListener implements NotificationListener {
+
         private String[] columnNames;
         private XMBean xmbean;
         private DefaultMutableTreeNode node;
-        private long received;
+        private volatile long received;
         private XMBeanNotifications notifications;
-        private boolean unregistered;
+        private volatile boolean unregistered;
         private ArrayList<Object[]> data = new ArrayList<Object[]>();
-        public XMBeanNotificationsListener(XMBeanNotifications notifications,
-                                           XMBean xmbean,
-                                           DefaultMutableTreeNode node,
-                                           String[] columnNames) {
+
+        public XMBeanNotificationsListener(
+                XMBeanNotifications notifications,
+                XMBean xmbean,
+                DefaultMutableTreeNode node,
+                String[] columnNames) {
             this.notifications = notifications;
             this.xmbean = xmbean;
             this.node = node;
@@ -591,22 +628,24 @@
             received = 0;
         }
 
-        public boolean isRegistered() {
+        public synchronized boolean isRegistered() {
             return !unregistered;
         }
 
         public synchronized void unregister() {
             try {
-                xmbean.getMBeanServerConnection().
-                    removeNotificationListener(xmbean.getObjectName(),this,null,null);
-            }catch(Exception e) {
-                System.out.println("Error removing listener :"+
-                                   e.getMessage());
+                xmbean.getMBeanServerConnection().removeNotificationListener(
+                        xmbean.getObjectName(), this, null, null);
+            } catch (Exception e) {
+                if (JConsole.isDebug()) {
+                    System.err.println("Error removing listener:");
+                    e.printStackTrace();
+                }
             }
             unregistered = true;
         }
 
-        public long getReceivedNotifications() {
+        public synchronized long getReceivedNotifications() {
             return received;
         }
 
@@ -614,52 +653,62 @@
             clear();
             this.node = node;
             try {
-                xmbean.getMBeanServerConnection().
-                    addNotificationListener(xmbean.getObjectName(),this,null,null);
+                xmbean.getMBeanServerConnection().addNotificationListener(
+                        xmbean.getObjectName(), this, null, null);
                 unregistered = false;
-            }catch(Exception e) {
-                System.out.println("Error adding listener :"+
-                                   e.getMessage());
+            } catch (Exception e) {
+                if (JConsole.isDebug()) {
+                    System.err.println("Error adding listener:");
+                    e.printStackTrace();
+                }
             }
         }
 
-        public synchronized void handleNotification(Notification e,
-                                                    Object handback) {
-            try {
-                if(unregistered) return;
-                Date receivedDate = new Date(e.getTimeStamp());
-                String time = timeFormater.format(receivedDate);
+        public synchronized void handleNotification(
+                final Notification n, Object hb) {
+            EventQueue.invokeLater(new Runnable() {
 
-                Object userData = e.getUserData();
-                Component comp = null;
-                UserDataCell cell = null;
-                if((comp = XDataViewer.createNotificationViewer(userData))
-                   != null) {
-                    XDataViewer.registerForMouseEvent(comp, mouseListener);
-                    cell = new UserDataCell(userData, comp);
-                }
+                public void run() {
+                    synchronized (XMBeanNotificationsListener.this) {
+                        try {
+                            if (unregistered) {
+                                return;
+                            }
+                            Date receivedDate = new Date(n.getTimeStamp());
+                            String time = timeFormater.format(receivedDate);
+
+                            Object userData = n.getUserData();
+                            Component comp = null;
+                            UserDataCell cell = null;
+                            if ((comp = XDataViewer.createNotificationViewer(userData)) != null) {
+                                XDataViewer.registerForMouseEvent(comp, mouseListener);
+                                cell = new UserDataCell(userData, comp);
+                            }
 
-                Object[] rowData = {time,
-                                    e.getType(),
-                                    (cell == null ? userData : cell),
-                                    new Long(e.getSequenceNumber()),
-                                    e.getMessage(),
-                                    e,
-                                    e.getSource()};
-                received++;
-                data.add(0, rowData);
+                            Object[] rowData = {
+                                time,
+                                n.getType(),
+                                (cell == null ? userData : cell),
+                                n.getSequenceNumber(),
+                                n.getMessage(),
+                                n,
+                                n.getSource()
+                            };
+                            received++;
+                            data.add(0, rowData);
 
-                notifications.fireNotificationReceived(this,
-                                                       xmbean,
-                                                       node,
-                                                       rowData,
-                                                       received);
-            }
-            catch (Exception ex) {
-                ex.printStackTrace();
-                System.out.println("Error when handling notification :"+
-                                   ex.toString());
-            }
+                            notifications.fireNotificationReceived(
+                                    XMBeanNotificationsListener.this,
+                                    xmbean, node, rowData, received);
+                        } catch (Exception e) {
+                            if (JConsole.isDebug()) {
+                                System.err.println("Error handling notification:");
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                }
+            });
         }
     }
 }
--- a/src/share/classes/sun/tools/jconsole/inspector/XMBeanOperations.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XMBeanOperations.java	Mon Apr 14 11:34:15 2008 -0700
@@ -22,6 +22,7 @@
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
+
 package sun.tools.jconsole.inspector;
 
 import javax.management.*;
--- a/src/share/classes/sun/tools/jconsole/inspector/XObject.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XObject.java	Mon Apr 14 11:34:15 2008 -0700
@@ -22,6 +22,7 @@
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
+
 package sun.tools.jconsole.inspector;
 
 // java import
--- a/src/share/classes/sun/tools/jconsole/inspector/XOperations.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XOperations.java	Mon Apr 14 11:34:15 2008 -0700
@@ -33,10 +33,7 @@
 import java.awt.GridLayout;
 import java.awt.FlowLayout;
 import java.awt.Component;
-import java.awt.EventQueue;
 import java.awt.event.*;
-import java.awt.Insets;
-import java.awt.Dimension;
 import java.util.*;
 import java.io.*;
 
@@ -49,29 +46,30 @@
 public abstract class XOperations extends JPanel implements ActionListener {
 
     public final static String OPERATION_INVOCATION_EVENT =
-        "jam.xoperations.invoke.result";
+            "jam.xoperations.invoke.result";
     private java.util.List<NotificationListener> notificationListenersList;
-
     private Hashtable<JButton, OperationEntry> operationEntryTable;
-
     private XMBean mbean;
     private MBeanInfo mbeanInfo;
     private MBeansTab mbeansTab;
+
     public XOperations(MBeansTab mbeansTab) {
-        super(new GridLayout(1,1));
+        super(new GridLayout(1, 1));
         this.mbeansTab = mbeansTab;
         operationEntryTable = new Hashtable<JButton, OperationEntry>();
         ArrayList<NotificationListener> l =
-            new ArrayList<NotificationListener>(1);
+                new ArrayList<NotificationListener>(1);
         notificationListenersList =
-            Collections.synchronizedList(l);
+                Collections.synchronizedList(l);
     }
 
+    // Call on EDT
     public void removeOperations() {
         removeAll();
     }
 
-    public void loadOperations(XMBean mbean,MBeanInfo mbeanInfo) {
+    // Call on EDT
+    public void loadOperations(XMBean mbean, MBeanInfo mbeanInfo) {
         this.mbean = mbean;
         this.mbeanInfo = mbeanInfo;
         // add operations information
@@ -80,131 +78,149 @@
 
         // remove listeners, if any
         Component listeners[] = getComponents();
-        for (int i = 0; i < listeners.length; i++)
-            if (listeners[i] instanceof JButton)
-                ((JButton)listeners[i]).removeActionListener(this);
+        for (int i = 0; i < listeners.length; i++) {
+            if (listeners[i] instanceof JButton) {
+                ((JButton) listeners[i]).removeActionListener(this);
+            }
+        }
 
         removeAll();
         setLayout(new BorderLayout());
 
         JButton methodButton;
         JLabel methodLabel;
-        JPanel innerPanelLeft,innerPanelRight;
-        JPanel outerPanelLeft,outerPanelRight;
-        outerPanelLeft  = new JPanel(new GridLayout(operations.length,1));
-        outerPanelRight = new JPanel(new GridLayout(operations.length,1));
+        JPanel innerPanelLeft, innerPanelRight;
+        JPanel outerPanelLeft, outerPanelRight;
+        outerPanelLeft = new JPanel(new GridLayout(operations.length, 1));
+        outerPanelRight = new JPanel(new GridLayout(operations.length, 1));
 
-        for (int i=0;i<operations.length;i++) {
-            innerPanelLeft  = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+        for (int i = 0; i < operations.length; i++) {
+            innerPanelLeft = new JPanel(new FlowLayout(FlowLayout.RIGHT));
             innerPanelRight = new JPanel(new FlowLayout(FlowLayout.LEFT));
-            innerPanelLeft.add(methodLabel =
-                               new JLabel(Utils.
-                                          getReadableClassName(operations[i].
-                                                             getReturnType()),
-                                          JLabel.RIGHT));
-            if (methodLabel.getText().length()>20) {
+            String returnType = operations[i].getReturnType();
+            if (returnType == null) {
+                methodLabel = new JLabel("null", JLabel.RIGHT);
+                if (JConsole.isDebug()) {
+                    System.err.println(
+                            "WARNING: The operation's return type " +
+                            "shouldn't be \"null\". Check how the " +
+                            "MBeanOperationInfo for the \"" +
+                            operations[i].getName() + "\" operation has " +
+                            "been defined in the MBean's implementation code.");
+                }
+            } else {
+                methodLabel = new JLabel(
+                        Utils.getReadableClassName(returnType), JLabel.RIGHT);
+            }
+            innerPanelLeft.add(methodLabel);
+            if (methodLabel.getText().length() > 20) {
                 methodLabel.setText(methodLabel.getText().
-                                    substring(methodLabel.getText().
-                                              lastIndexOf(".")+1,
-                                             methodLabel.getText().length()));
+                        substring(methodLabel.getText().
+                        lastIndexOf(".") + 1,
+                        methodLabel.getText().length()));
             }
 
             methodButton = new JButton(operations[i].getName());
             methodButton.setToolTipText(operations[i].getDescription());
             boolean callable = isCallable(operations[i].getSignature());
-            if(callable)
+            if (callable) {
                 methodButton.addActionListener(this);
-            else
+            } else {
                 methodButton.setEnabled(false);
+            }
 
             MBeanParameterInfo[] signature = operations[i].getSignature();
             OperationEntry paramEntry = new OperationEntry(operations[i],
-                                                           callable,
-                                                           methodButton,
-                                                           this);
+                    callable,
+                    methodButton,
+                    this);
             operationEntryTable.put(methodButton, paramEntry);
             innerPanelRight.add(methodButton);
-                if(signature.length==0)
-                    innerPanelRight.add(new JLabel("( )",JLabel.CENTER));
-                else
-                    innerPanelRight.add(paramEntry);
+            if (signature.length == 0) {
+                innerPanelRight.add(new JLabel("( )", JLabel.CENTER));
+            } else {
+                innerPanelRight.add(paramEntry);
+            }
 
-            outerPanelLeft.add(innerPanelLeft,BorderLayout.WEST);
-            outerPanelRight.add(innerPanelRight,BorderLayout.CENTER);
+            outerPanelLeft.add(innerPanelLeft, BorderLayout.WEST);
+            outerPanelRight.add(innerPanelRight, BorderLayout.CENTER);
         }
-        add(outerPanelLeft,BorderLayout.WEST);
-        add(outerPanelRight,BorderLayout.CENTER);
+        add(outerPanelLeft, BorderLayout.WEST);
+        add(outerPanelRight, BorderLayout.CENTER);
         validate();
     }
 
     private boolean isCallable(MBeanParameterInfo[] signature) {
-        for(int i = 0; i < signature.length; i++) {
-            if(!Utils.isEditableType(signature[i].getType()))
+        for (int i = 0; i < signature.length; i++) {
+            if (!Utils.isEditableType(signature[i].getType())) {
                 return false;
+            }
         }
         return true;
     }
 
+    // Call on EDT
     public void actionPerformed(final ActionEvent e) {
-        performInvokeRequest((JButton)e.getSource());
+        performInvokeRequest((JButton) e.getSource());
     }
 
     void performInvokeRequest(final JButton button) {
-        mbeansTab.workerAdd(new Runnable() {
-            public void run() {
+        final OperationEntry entryIf = operationEntryTable.get(button);
+        new SwingWorker<Object, Void>() {
+            @Override
+            public Object doInBackground() throws Exception {
+                return mbean.invoke(button.getText(),
+                        entryIf.getParameters(), entryIf.getSignature());
+            }
+            @Override
+            protected void done() {
                 try {
-                    OperationEntry entryIf = operationEntryTable.get(button);
-                    Object result = null;
-                    result = mbean.invoke(button.getText(),
-                                          entryIf.getParameters(),
-                                          entryIf.getSignature());
+                    Object result = get();
                     // sends result notification to upper level if
                     // there is a return value
                     if (entryIf.getReturnType() != null &&
-                        !entryIf.getReturnType().equals(Void.TYPE.getName()) &&
-                        !entryIf.getReturnType().equals(Void.class.getName()))
-                        fireChangedNotification(OPERATION_INVOCATION_EVENT,
-                                                button,
-                                                result);
-                    else
-                        EventQueue.invokeLater(new ThreadDialog(
+                            !entryIf.getReturnType().equals(Void.TYPE.getName()) &&
+                            !entryIf.getReturnType().equals(Void.class.getName())) {
+                        fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result);
+                    } else {
+                        new ThreadDialog(
+                                button,
+                                Resources.getText("Method successfully invoked"),
+                                Resources.getText("Info"),
+                                JOptionPane.INFORMATION_MESSAGE).run();
+                    }
+                } catch (Throwable t) {
+                    t = Utils.getActualException(t);
+                    if (JConsole.isDebug()) {
+                        t.printStackTrace();
+                    }
+                    new ThreadDialog(
                             button,
-                            Resources.getText("Method successfully invoked"),
-                            Resources.getText("Info"),
-                            JOptionPane.INFORMATION_MESSAGE));
-                } catch (Throwable ex) {
-                    if (JConsole.isDebug()) {
-                        ex.printStackTrace();
-                    }
-                    ex = Utils.getActualException(ex);
-                    String message = ex.toString();
-                    EventQueue.invokeLater(new ThreadDialog(
-                        button,
-                        Resources.getText("Problem invoking") + " " +
-                        button.getText() + " : " + message,
-                        Resources.getText("Error"),
-                        JOptionPane.ERROR_MESSAGE));
+                            Resources.getText("Problem invoking") + " " +
+                            button.getText() + " : " + t.toString(),
+                            Resources.getText("Error"),
+                            JOptionPane.ERROR_MESSAGE).run();
                 }
             }
-        });
+        }.execute();
     }
 
     public void addOperationsListener(NotificationListener nl) {
-            notificationListenersList.add(nl);
-        }
+        notificationListenersList.add(nl);
+    }
 
     public void removeOperationsListener(NotificationListener nl) {
         notificationListenersList.remove(nl);
     }
 
-    private void fireChangedNotification(String type,
-                                         Object source,
-                                         Object handback) {
-        Notification e = new Notification(type,source,0);
-        for(NotificationListener nl : notificationListenersList)
-            nl.handleNotification(e,handback);
+    // Call on EDT
+    private void fireChangedNotification(
+            String type, Object source, Object handback) {
+        Notification n = new Notification(type, source, 0);
+        for (NotificationListener nl : notificationListenersList) {
+            nl.handleNotification(n, handback);
+        }
     }
 
-    protected abstract MBeanOperationInfo[]
-        updateOperations(MBeanOperationInfo[] operations);
+    protected abstract MBeanOperationInfo[] updateOperations(MBeanOperationInfo[] operations);
 }
--- a/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java	Mon Apr 14 11:34:15 2008 -0700
@@ -22,7 +22,9 @@
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
+
 package sun.tools.jconsole.inspector;
+
 import sun.tools.jconsole.Plotter;
 import javax.swing.JTable;
 import java.awt.Graphics;
--- a/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -22,6 +22,7 @@
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
+
 package sun.tools.jconsole.inspector;
 
 import java.awt.*;
--- a/src/share/classes/sun/tools/jconsole/inspector/XSheet.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XSheet.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2004-2007 Sun Microsystems, Inc.  All Rights Reserved.
  * 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,7 +28,6 @@
 import java.awt.*;
 import java.awt.event.*;
 import java.io.*;
-import java.util.Enumeration;
 import javax.management.*;
 import javax.swing.*;
 import javax.swing.border.*;
@@ -45,31 +44,22 @@
 
     private JPanel mainPanel;
     private JPanel southPanel;
-
     // Node being currently displayed
-    private DefaultMutableTreeNode node;
-
+    private volatile DefaultMutableTreeNode currentNode;
     // MBean being currently displayed
-    private XMBean mbean;
-
+    private volatile XMBean mbean;
     // XMBeanAttributes container
     private XMBeanAttributes mbeanAttributes;
-
     // XMBeanOperations container
     private XMBeanOperations mbeanOperations;
-
     // XMBeanNotifications container
     private XMBeanNotifications mbeanNotifications;
-
     // XMBeanInfo container
     private XMBeanInfo mbeanInfo;
-
     // Refresh JButton (mbean attributes case)
     private JButton refreshButton;
-
     // Subscribe/Unsubscribe/Clear JButton (mbean notifications case)
-    private JButton clearButton, subscribeButton, unsubscribeButton;
-
+    private JButton clearButton,  subscribeButton,  unsubscribeButton;
     // Reference to MBeans tab
     private MBeansTab mbeansTab;
 
@@ -86,6 +76,7 @@
 
     private void setupScreen() {
         setLayout(new BorderLayout());
+        setBorder(BorderFactory.createLineBorder(Color.GRAY));
         // add main panel to XSheet
         mainPanel = new JPanel();
         mainPanel.setLayout(new BorderLayout());
@@ -129,17 +120,32 @@
         mbeanInfo = new XMBeanInfo();
     }
 
-    public boolean isMBeanNode(DefaultMutableTreeNode node) {
-        XNodeInfo uo = (XNodeInfo) node.getUserObject();
-        return uo.getType().equals(Type.MBEAN);
+    private boolean isSelectedNode(DefaultMutableTreeNode n, DefaultMutableTreeNode cn) {
+        return (cn == n);
+    }
+
+    // Call on EDT
+    private void showErrorDialog(Object message, String title) {
+        new ThreadDialog(this, message, title, JOptionPane.ERROR_MESSAGE).run();
     }
 
-    public void displayNode(DefaultMutableTreeNode node) {
+    public boolean isMBeanNode(DefaultMutableTreeNode node) {
+        Object userObject = node.getUserObject();
+        if (userObject instanceof XNodeInfo) {
+            XNodeInfo uo = (XNodeInfo) userObject;
+            return uo.getType().equals(Type.MBEAN);
+        }
+        return false;
+    }
+
+    // Call on EDT
+    public synchronized void displayNode(DefaultMutableTreeNode node) {
         clear();
+        displayEmptyNode();
         if (node == null) {
-            displayEmptyNode();
             return;
         }
+        currentNode = node;
         Object userObject = node.getUserObject();
         if (userObject instanceof XNodeInfo) {
             XNodeInfo uo = (XNodeInfo) userObject;
@@ -173,27 +179,28 @@
         }
     }
 
+    // Call on EDT
     private void displayMBeanNode(final DefaultMutableTreeNode node) {
         final XNodeInfo uo = (XNodeInfo) node.getUserObject();
         if (!uo.getType().equals(Type.MBEAN)) {
             return;
         }
-        mbeansTab.workerAdd(new Runnable() {
-            public void run() {
+        mbean = (XMBean) uo.getData();
+        SwingWorker<MBeanInfo, Void> sw = new SwingWorker<MBeanInfo, Void>() {
+            @Override
+            public MBeanInfo doInBackground() throws InstanceNotFoundException,
+                    IntrospectionException, ReflectionException, IOException {
+                return mbean.getMBeanInfo();
+            }
+            @Override
+            protected void done() {
                 try {
-                    XSheet.this.node = node;
-                    XSheet.this.mbean = (XMBean) uo.getData();
-                    mbeanInfo.addMBeanInfo(mbean, mbean.getMBeanInfo());
-                } catch (Throwable ex) {
-                    EventQueue.invokeLater(new ThreadDialog(
-                            XSheet.this,
-                            ex.getMessage(),
-                            Resources.getText("Problem displaying MBean"),
-                            JOptionPane.ERROR_MESSAGE));
-                    return;
-                }
-                EventQueue.invokeLater(new Runnable() {
-                    public void run() {
+                    MBeanInfo mbi = get();
+                    if (mbi != null) {
+                        if (!isSelectedNode(node, currentNode)) {
+                            return;
+                        }
+                        mbeanInfo.addMBeanInfo(mbean, mbi);
                         invalidate();
                         mainPanel.removeAll();
                         mainPanel.add(mbeanInfo, BorderLayout.CENTER);
@@ -202,9 +209,19 @@
                         validate();
                         repaint();
                     }
-                });
+                } catch (Exception e) {
+                    Throwable t = Utils.getActualException(e);
+                    if (JConsole.isDebug()) {
+                        System.err.println("Couldn't get MBeanInfo for MBean [" +
+                                mbean.getObjectName() + "]");
+                        t.printStackTrace();
+                    }
+                    showErrorDialog(t.toString(),
+                            Resources.getText("Problem displaying MBean"));
+                }
             }
-        });
+        };
+        sw.execute();
     }
 
     // Call on EDT
@@ -213,90 +230,90 @@
         final XMBeanInfo mbi = mbeanInfo;
         switch (uo.getType()) {
             case ATTRIBUTE:
-                mbeansTab.workerAdd(new Runnable() {
-                    public void run() {
-                        Object attrData = uo.getData();
-                        XSheet.this.mbean = (XMBean) ((Object[]) attrData)[0];
-                        final MBeanAttributeInfo mbai =
-                                (MBeanAttributeInfo) ((Object[]) attrData)[1];
-                        final XMBeanAttributes mba = mbeanAttributes;
-                        try {
-                            mba.loadAttributes(mbean, new MBeanInfo(
-                                    null, null, new MBeanAttributeInfo[] {mbai},
-                                    null, null, null));
-                        } catch (Exception e) {
-                            EventQueue.invokeLater(new ThreadDialog(
-                                    XSheet.this,
-                                    e.getMessage(),
-                                    Resources.getText("Problem displaying MBean"),
-                                    JOptionPane.ERROR_MESSAGE));
-                            return;
-                        }
-                        EventQueue.invokeLater(new Runnable() {
-                            public void run() {
-                                invalidate();
-                                mainPanel.removeAll();
-                                JPanel attributePanel =
-                                        new JPanel(new BorderLayout());
-                                JPanel attributeBorderPanel =
-                                        new JPanel(new BorderLayout());
-                                attributeBorderPanel.setBorder(
-                                        BorderFactory.createTitledBorder(
-                                        Resources.getText("Attribute value")));
-                                JPanel attributeValuePanel =
-                                        new JPanel(new BorderLayout());
-                                attributeValuePanel.setBorder(
-                                        LineBorder.createGrayLineBorder());
-                                attributeValuePanel.add(mba.getTableHeader(),
-                                        BorderLayout.PAGE_START);
-                                attributeValuePanel.add(mba,
-                                        BorderLayout.CENTER);
-                                attributeBorderPanel.add(attributeValuePanel,
-                                        BorderLayout.CENTER);
-                                JPanel refreshButtonPanel = new JPanel();
-                                refreshButtonPanel.add(refreshButton);
-                                attributeBorderPanel.add(refreshButtonPanel,
-                                        BorderLayout.SOUTH);
-                                refreshButton.setEnabled(true);
-                                attributePanel.add(attributeBorderPanel,
-                                        BorderLayout.NORTH);
-                                mbi.addMBeanAttributeInfo(mbai);
-                                attributePanel.add(mbi, BorderLayout.CENTER);
-                                mainPanel.add(attributePanel,
-                                        BorderLayout.CENTER);
-                                southPanel.setVisible(false);
-                                southPanel.removeAll();
-                                validate();
-                                repaint();
+                SwingWorker<MBeanAttributeInfo, Void> sw =
+                        new SwingWorker<MBeanAttributeInfo, Void>() {
+                            @Override
+                            public MBeanAttributeInfo doInBackground() {
+                                Object attrData = uo.getData();
+                                mbean = (XMBean) ((Object[]) attrData)[0];
+                                MBeanAttributeInfo mbai =
+                                        (MBeanAttributeInfo) ((Object[]) attrData)[1];
+                                mbeanAttributes.loadAttributes(mbean, new MBeanInfo(
+                                        null, null, new MBeanAttributeInfo[]{mbai},
+                                        null, null, null));
+                                return mbai;
                             }
-                        });
-                    }
-                });
+                            @Override
+                            protected void done() {
+                                try {
+                                    MBeanAttributeInfo mbai = get();
+                                    if (!isSelectedNode(node, currentNode)) {
+                                        return;
+                                    }
+                                    invalidate();
+                                    mainPanel.removeAll();
+                                    JPanel attributePanel =
+                                            new JPanel(new BorderLayout());
+                                    JPanel attributeBorderPanel =
+                                            new JPanel(new BorderLayout());
+                                    attributeBorderPanel.setBorder(
+                                            BorderFactory.createTitledBorder(
+                                            Resources.getText("Attribute value")));
+                                    JPanel attributeValuePanel =
+                                            new JPanel(new BorderLayout());
+                                    attributeValuePanel.setBorder(
+                                            LineBorder.createGrayLineBorder());
+                                    attributeValuePanel.add(mbeanAttributes.getTableHeader(),
+                                            BorderLayout.PAGE_START);
+                                    attributeValuePanel.add(mbeanAttributes,
+                                            BorderLayout.CENTER);
+                                    attributeBorderPanel.add(attributeValuePanel,
+                                            BorderLayout.CENTER);
+                                    JPanel refreshButtonPanel = new JPanel();
+                                    refreshButtonPanel.add(refreshButton);
+                                    attributeBorderPanel.add(refreshButtonPanel,
+                                            BorderLayout.SOUTH);
+                                    refreshButton.setEnabled(true);
+                                    attributePanel.add(attributeBorderPanel,
+                                            BorderLayout.NORTH);
+                                    mbi.addMBeanAttributeInfo(mbai);
+                                    attributePanel.add(mbi, BorderLayout.CENTER);
+                                    mainPanel.add(attributePanel,
+                                            BorderLayout.CENTER);
+                                    southPanel.setVisible(false);
+                                    southPanel.removeAll();
+                                    validate();
+                                    repaint();
+                                } catch (Exception e) {
+                                    Throwable t = Utils.getActualException(e);
+                                    if (JConsole.isDebug()) {
+                                        System.err.println("Problem displaying MBean " +
+                                                "attribute for MBean [" +
+                                                mbean.getObjectName() + "]");
+                                        t.printStackTrace();
+                                    }
+                                    showErrorDialog(t.toString(),
+                                            Resources.getText("Problem displaying MBean"));
+                                }
+                            }
+                        };
+                sw.execute();
                 break;
             case OPERATION:
                 Object operData = uo.getData();
-                XSheet.this.mbean = (XMBean) ((Object[]) operData)[0];
+                mbean = (XMBean) ((Object[]) operData)[0];
                 MBeanOperationInfo mboi =
                         (MBeanOperationInfo) ((Object[]) operData)[1];
-                XMBeanOperations mbo = mbeanOperations;
-                try {
-                    mbo.loadOperations(mbean, new MBeanInfo(null, null, null,
-                            null, new MBeanOperationInfo[] {mboi}, null));
-                } catch (Exception e) {
-                    EventQueue.invokeLater(new ThreadDialog(
-                            XSheet.this,
-                            e.getMessage(),
-                            Resources.getText("Problem displaying MBean"),
-                            JOptionPane.ERROR_MESSAGE));
-                    return;
-                }
+                mbeanOperations.loadOperations(mbean,
+                        new MBeanInfo(null, null, null, null,
+                        new MBeanOperationInfo[]{mboi}, null));
                 invalidate();
                 mainPanel.removeAll();
                 JPanel operationPanel = new JPanel(new BorderLayout());
                 JPanel operationBorderPanel = new JPanel(new BorderLayout());
                 operationBorderPanel.setBorder(BorderFactory.createTitledBorder(
                         Resources.getText("Operation invocation")));
-                operationBorderPanel.add(new JScrollPane(mbo));
+                operationBorderPanel.add(new JScrollPane(mbeanOperations));
                 operationPanel.add(operationBorderPanel, BorderLayout.NORTH);
                 mbi.addMBeanOperationInfo(mboi);
                 operationPanel.add(mbi, BorderLayout.CENTER);
@@ -320,134 +337,134 @@
         }
     }
 
+    // Call on EDT
     private void displayMBeanAttributesNode(final DefaultMutableTreeNode node) {
         final XNodeInfo uo = (XNodeInfo) node.getUserObject();
         if (!uo.getType().equals(Type.ATTRIBUTES)) {
             return;
         }
-        final XMBeanAttributes mba = mbeanAttributes;
-        mbeansTab.workerAdd(new Runnable() {
-            public void run() {
+        mbean = (XMBean) uo.getData();
+        SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>() {
+            @Override
+            public Void doInBackground() throws InstanceNotFoundException,
+                    IntrospectionException, ReflectionException, IOException {
+                mbeanAttributes.loadAttributes(mbean, mbean.getMBeanInfo());
+                return null;
+            }
+            @Override
+            protected void done() {
                 try {
-                    XSheet.this.node = node;
-                    XSheet.this.mbean = (XMBean) uo.getData();
-                    mba.loadAttributes(mbean, mbean.getMBeanInfo());
-                } catch (Throwable ex) {
-                    EventQueue.invokeLater(new ThreadDialog(
-                            XSheet.this,
-                            ex.getMessage(),
-                            Resources.getText("Problem displaying MBean"),
-                            JOptionPane.ERROR_MESSAGE));
-                    return;
+                    get();
+                    if (!isSelectedNode(node, currentNode)) {
+                        return;
+                    }
+                    invalidate();
+                    mainPanel.removeAll();
+                    JPanel borderPanel = new JPanel(new BorderLayout());
+                    borderPanel.setBorder(BorderFactory.createTitledBorder(
+                            Resources.getText("Attribute values")));
+                    borderPanel.add(new JScrollPane(mbeanAttributes));
+                    mainPanel.add(borderPanel, BorderLayout.CENTER);
+                    // add the refresh button to the south panel
+                    southPanel.removeAll();
+                    southPanel.add(refreshButton, BorderLayout.SOUTH);
+                    southPanel.setVisible(true);
+                    refreshButton.setEnabled(true);
+                    validate();
+                    repaint();
+                } catch (Exception e) {
+                    Throwable t = Utils.getActualException(e);
+                    if (JConsole.isDebug()) {
+                        System.err.println("Problem displaying MBean " +
+                                "attributes for MBean [" +
+                                mbean.getObjectName() + "]");
+                        t.printStackTrace();
+                    }
+                    showErrorDialog(t.toString(),
+                            Resources.getText("Problem displaying MBean"));
                 }
-                EventQueue.invokeLater(new Runnable() {
-                    public void run() {
-                        invalidate();
-                        mainPanel.removeAll();
-                        JPanel borderPanel = new JPanel(new BorderLayout());
-                        borderPanel.setBorder(BorderFactory.createTitledBorder(
-                                Resources.getText("Attribute values")));
-                        borderPanel.add(new JScrollPane(mba));
-                        mainPanel.add(borderPanel, BorderLayout.CENTER);
-                        // add the refresh button to the south panel
-                        southPanel.removeAll();
-                        southPanel.add(refreshButton, BorderLayout.SOUTH);
-                        southPanel.setVisible(true);
-                        refreshButton.setEnabled(true);
-                        validate();
-                        repaint();
-                    }
-                });
             }
-        });
+        };
+        sw.execute();
     }
 
+    // Call on EDT
     private void displayMBeanOperationsNode(final DefaultMutableTreeNode node) {
         final XNodeInfo uo = (XNodeInfo) node.getUserObject();
         if (!uo.getType().equals(Type.OPERATIONS)) {
             return;
         }
-        final XMBeanOperations mbo = mbeanOperations;
-        mbeansTab.workerAdd(new Runnable() {
-            public void run() {
+        mbean = (XMBean) uo.getData();
+        SwingWorker<MBeanInfo, Void> sw = new SwingWorker<MBeanInfo, Void>() {
+            @Override
+            public MBeanInfo doInBackground() throws InstanceNotFoundException,
+                    IntrospectionException, ReflectionException, IOException {
+                return mbean.getMBeanInfo();
+            }
+            @Override
+            protected void done() {
                 try {
-                    XSheet.this.node = node;
-                    XSheet.this.mbean = (XMBean) uo.getData();
-                    mbo.loadOperations(mbean, mbean.getMBeanInfo());
-                } catch (Throwable ex) {
-                    EventQueue.invokeLater(new ThreadDialog(
-                            XSheet.this,
-                            ex.getMessage(),
-                            Resources.getText("Problem displaying MBean"),
-                            JOptionPane.ERROR_MESSAGE));
-                    return;
-                }
-                EventQueue.invokeLater(new Runnable() {
-                    public void run() {
+                    MBeanInfo mbi = get();
+                    if (mbi != null) {
+                        if (!isSelectedNode(node, currentNode)) {
+                            return;
+                        }
+                        mbeanOperations.loadOperations(mbean, mbi);
                         invalidate();
                         mainPanel.removeAll();
                         JPanel borderPanel = new JPanel(new BorderLayout());
                         borderPanel.setBorder(BorderFactory.createTitledBorder(
                                 Resources.getText("Operation invocation")));
-                        borderPanel.add(new JScrollPane(mbo));
+                        borderPanel.add(new JScrollPane(mbeanOperations));
                         mainPanel.add(borderPanel, BorderLayout.CENTER);
                         southPanel.setVisible(false);
                         southPanel.removeAll();
                         validate();
                         repaint();
                     }
-                });
+                } catch (Exception e) {
+                    Throwable t = Utils.getActualException(e);
+                    if (JConsole.isDebug()) {
+                        System.err.println("Problem displaying MBean " +
+                                "operations for MBean [" +
+                                mbean.getObjectName() + "]");
+                        t.printStackTrace();
+                    }
+                    showErrorDialog(t.toString(),
+                            Resources.getText("Problem displaying MBean"));
+                }
             }
-        });
+        };
+        sw.execute();
     }
 
-    private void displayMBeanNotificationsNode(
-            final DefaultMutableTreeNode node) {
+    // Call on EDT
+    private void displayMBeanNotificationsNode(DefaultMutableTreeNode node) {
         final XNodeInfo uo = (XNodeInfo) node.getUserObject();
         if (!uo.getType().equals(Type.NOTIFICATIONS)) {
             return;
         }
-        final XMBeanNotifications mbn = mbeanNotifications;
-        mbeansTab.workerAdd(new Runnable() {
-            public void run() {
-                try {
-                    XSheet.this.node = node;
-                    XSheet.this.mbean = (XMBean) uo.getData();
-                    mbn.loadNotifications(mbean);
-                    updateNotifications();
-                } catch (Throwable ex) {
-                    EventQueue.invokeLater(new ThreadDialog(
-                            XSheet.this,
-                            ex.getMessage(),
-                            Resources.getText("Problem displaying MBean"),
-                            JOptionPane.ERROR_MESSAGE));
-                    return;
-                }
-                EventQueue.invokeLater(new Runnable() {
-                    public void run() {
-                        invalidate();
-                        mainPanel.removeAll();
-                        JPanel borderPanel = new JPanel(new BorderLayout());
-                        borderPanel.setBorder(BorderFactory.createTitledBorder(
-                                Resources.getText("Notification buffer")));
-                        borderPanel.add(new JScrollPane(mbn));
-                        mainPanel.add(borderPanel, BorderLayout.CENTER);
-                        // add the subscribe/unsubscribe/clear buttons to
-                        // the south panel
-                        southPanel.removeAll();
-                        southPanel.add(subscribeButton, BorderLayout.WEST);
-                        southPanel.add(unsubscribeButton, BorderLayout.CENTER);
-                        southPanel.add(clearButton, BorderLayout.EAST);
-                        southPanel.setVisible(true);
-                        subscribeButton.setEnabled(true);
-                        unsubscribeButton.setEnabled(true);
-                        clearButton.setEnabled(true);
-                        validate();
-                        repaint();
-                    }
-                });
-            }
-        });
+        mbean = (XMBean) uo.getData();
+        mbeanNotifications.loadNotifications(mbean);
+        updateNotifications();
+        invalidate();
+        mainPanel.removeAll();
+        JPanel borderPanel = new JPanel(new BorderLayout());
+        borderPanel.setBorder(BorderFactory.createTitledBorder(
+                Resources.getText("Notification buffer")));
+        borderPanel.add(new JScrollPane(mbeanNotifications));
+        mainPanel.add(borderPanel, BorderLayout.CENTER);
+        // add the subscribe/unsubscribe/clear buttons to the south panel
+        southPanel.removeAll();
+        southPanel.add(subscribeButton, BorderLayout.WEST);
+        southPanel.add(unsubscribeButton, BorderLayout.CENTER);
+        southPanel.add(clearButton, BorderLayout.EAST);
+        southPanel.setVisible(true);
+        subscribeButton.setEnabled(true);
+        unsubscribeButton.setEnabled(true);
+        clearButton.setEnabled(true);
+        validate();
+        repaint();
     }
 
     // Call on EDT
@@ -462,21 +479,60 @@
     /**
      * Subscribe button action.
      */
-    private void registerListener() throws InstanceNotFoundException,
-            IOException {
-        mbeanNotifications.registerListener(node);
-        updateNotifications();
-        validate();
+    private void registerListener() {
+        new SwingWorker<Void, Void>() {
+            @Override
+            public Void doInBackground()
+                    throws InstanceNotFoundException, IOException {
+                mbeanNotifications.registerListener(currentNode);
+                return null;
+            }
+            @Override
+            protected void done() {
+                try {
+                    get();
+                    updateNotifications();
+                    validate();
+                } catch (Exception e) {
+                    Throwable t = Utils.getActualException(e);
+                    if (JConsole.isDebug()) {
+                        System.err.println("Problem adding listener");
+                        t.printStackTrace();
+                    }
+                    showErrorDialog(t.getMessage(),
+                            Resources.getText("Problem adding listener"));
+                }
+            }
+        }.execute();
     }
 
     /**
      * Unsubscribe button action.
      */
     private void unregisterListener() {
-        if (mbeanNotifications.unregisterListener(node)) {
-            clearNotifications();
-            validate();
-        }
+        new SwingWorker<Boolean, Void>() {
+            @Override
+            public Boolean doInBackground() {
+                return mbeanNotifications.unregisterListener(currentNode);
+            }
+            @Override
+            protected void done() {
+                try {
+                    if (get()) {
+                        updateNotifications();
+                        validate();
+                    }
+                } catch (Exception e) {
+                    Throwable t = Utils.getActualException(e);
+                    if (JConsole.isDebug()) {
+                        System.err.println("Problem removing listener");
+                        t.printStackTrace();
+                    }
+                    showErrorDialog(t.getMessage(),
+                            Resources.getText("Problem removing listener"));
+                }
+            }
+        }.execute();
     }
 
     /**
@@ -486,15 +542,11 @@
         mbeanAttributes.refreshAttributes();
     }
 
+    // Call on EDT
     private void updateNotifications() {
-        if (mbean.isBroadcaster()) {
-            if (mbeanNotifications.isListenerRegistered(mbean)) {
-                long received =
-                        mbeanNotifications.getReceivedNotifications(mbean);
-                updateReceivedNotifications(node, received, false);
-            } else {
-                clearNotifications();
-            }
+        if (mbeanNotifications.isListenerRegistered(mbean)) {
+            long received = mbeanNotifications.getReceivedNotifications(mbean);
+            updateReceivedNotifications(currentNode, received, false);
         } else {
             clearNotifications();
         }
@@ -503,11 +555,11 @@
     /**
      * Update notification node label in MBean tree: "Notifications[received]".
      */
+    // Call on EDT
     private void updateReceivedNotifications(
             DefaultMutableTreeNode emitter, long received, boolean bold) {
         String text = Resources.getText("Notifications") + "[" + received + "]";
-        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)
-        mbeansTab.getTree().getLastSelectedPathComponent();
+        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) mbeansTab.getTree().getLastSelectedPathComponent();
         if (bold && emitter != selectedNode) {
             text = "<html><b>" + text + "</b></html>";
         }
@@ -517,41 +569,40 @@
     /**
      * Update notification node label in MBean tree: "Notifications".
      */
+    // Call on EDT
     private void clearNotifications() {
-        updateNotificationsNodeLabel(node,
+        updateNotificationsNodeLabel(currentNode,
                 Resources.getText("Notifications"));
     }
 
     /**
      * Update notification node label in MBean tree: "Notifications[0]".
      */
+    // Call on EDT
     private void clearNotifications0() {
-        updateNotificationsNodeLabel(node,
+        updateNotificationsNodeLabel(currentNode,
                 Resources.getText("Notifications") + "[0]");
     }
 
     /**
      * Update the label of the supplied MBean tree node.
      */
+    // Call on EDT
     private void updateNotificationsNodeLabel(
-            final DefaultMutableTreeNode node, final String label) {
-        EventQueue.invokeLater(new Runnable() {
-            public void run() {
-                synchronized (mbeansTab.getTree()) {
-                    invalidate();
-                    XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject();
-                    XNodeInfo newUserObject = new XNodeInfo(
-                            oldUserObject.getType(), oldUserObject.getData(),
-                            label, oldUserObject.getToolTipText());
-                    node.setUserObject(newUserObject);
-                    DefaultTreeModel model =
-                            (DefaultTreeModel) mbeansTab.getTree().getModel();
-                    model.nodeChanged(node);
-                    validate();
-                    repaint();
-                }
-            }
-        });
+            DefaultMutableTreeNode node, String label) {
+        synchronized (mbeansTab.getTree()) {
+            invalidate();
+            XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject();
+            XNodeInfo newUserObject = new XNodeInfo(
+                    oldUserObject.getType(), oldUserObject.getData(),
+                    label, oldUserObject.getToolTipText());
+            node.setUserObject(newUserObject);
+            DefaultTreeModel model =
+                    (DefaultTreeModel) mbeansTab.getTree().getModel();
+            model.nodeChanged(node);
+            validate();
+            repaint();
+        }
     }
 
     /**
@@ -577,6 +628,7 @@
         }
     }
 
+    // Call on EDT
     private void clear() {
         mbeanAttributes.stopCellEditing();
         mbeanAttributes.emptyTable();
@@ -586,13 +638,14 @@
         mbeanNotifications.emptyTable();
         mbeanNotifications.disableNotifications();
         mbean = null;
-        node = null;
+        currentNode = null;
     }
 
     /**
      * Notification listener: handles asynchronous reception
      * of MBean operation results and MBean notifications.
      */
+    // Call on EDT
     public void handleNotification(Notification e, Object handback) {
         // Operation result
         if (e.getType().equals(XOperations.OPERATION_INVOCATION_EVENT)) {
@@ -628,13 +681,12 @@
                     message = comp;
                 }
             }
-            EventQueue.invokeLater(new ThreadDialog(
+            new ThreadDialog(
                     (Component) e.getSource(),
                     message,
                     Resources.getText("Operation return value"),
-                    JOptionPane.INFORMATION_MESSAGE));
-        }
-        // Got notification
+                    JOptionPane.INFORMATION_MESSAGE).run();
+        } // Got notification
         else if (e.getType().equals(
                 XMBeanNotifications.NOTIFICATION_RECEIVED_EVENT)) {
             DefaultMutableTreeNode emitter = (DefaultMutableTreeNode) handback;
@@ -646,16 +698,19 @@
     /**
      * Action listener: handles actions in panel buttons
      */
+    // Call on EDT
     public void actionPerformed(ActionEvent e) {
         if (e.getSource() instanceof JButton) {
             JButton button = (JButton) e.getSource();
             // Refresh button
             if (button == refreshButton) {
-                mbeansTab.workerAdd(new Runnable() {
-                    public void run() {
+                new SwingWorker<Void, Void>() {
+                    @Override
+                    public Void doInBackground() {
                         refreshAttributes();
+                        return null;
                     }
-                });
+                }.execute();
                 return;
             }
             // Clear button
@@ -665,38 +720,12 @@
             }
             // Subscribe button
             if (button == subscribeButton) {
-                mbeansTab.workerAdd(new Runnable() {
-                    public void run() {
-                        try {
-                            registerListener();
-                        } catch (Throwable ex) {
-                            ex = Utils.getActualException(ex);
-                            EventQueue.invokeLater(new ThreadDialog(
-                                    XSheet.this,
-                                    ex.getMessage(),
-                                    Resources.getText("Problem adding listener"),
-                                    JOptionPane.ERROR_MESSAGE));
-                        }
-                    }
-                });
+                registerListener();
                 return;
             }
             // Unsubscribe button
             if (button == unsubscribeButton) {
-                mbeansTab.workerAdd(new Runnable() {
-                    public void run() {
-                        try {
-                            unregisterListener();
-                        } catch (Throwable ex) {
-                            ex = Utils.getActualException(ex);
-                            EventQueue.invokeLater(new ThreadDialog(
-                                    XSheet.this,
-                                    ex.getMessage(),
-                                    Resources.getText("Problem removing listener"),
-                                    JOptionPane.ERROR_MESSAGE));
-                        }
-                    }
-                });
+                unregisterListener();
                 return;
             }
         }
--- a/src/share/classes/sun/tools/jconsole/inspector/XTable.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XTable.java	Mon Apr 14 11:34:15 2008 -0700
@@ -22,6 +22,7 @@
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
+
 package sun.tools.jconsole.inspector;
 
 import javax.swing.*;
--- a/src/share/classes/sun/tools/jconsole/inspector/XTextField.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XTextField.java	Mon Apr 14 11:34:15 2008 -0700
@@ -22,6 +22,7 @@
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
+
 package sun.tools.jconsole.inspector;
 
 import java.awt.*;
--- a/src/share/classes/sun/tools/jconsole/inspector/XTextFieldEditor.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XTextFieldEditor.java	Mon Apr 14 11:34:15 2008 -0700
@@ -22,6 +22,7 @@
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
+
 package sun.tools.jconsole.inspector;
 
 import java.awt.Component;
--- a/src/share/classes/sun/tools/jconsole/inspector/XTree.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/jconsole/inspector/XTree.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2004-2007 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
 
 package sun.tools.jconsole.inspector;
 
-import java.awt.EventQueue;
+import java.io.IOException;
 import java.util.*;
 import javax.management.*;
 import javax.swing.*;
@@ -34,13 +34,14 @@
 import sun.tools.jconsole.MBeansTab;
 import sun.tools.jconsole.Resources;
 import sun.tools.jconsole.inspector.XNodeInfo;
-import sun.tools.jconsole.inspector.XNodeInfo.Type;
+import static sun.tools.jconsole.inspector.XNodeInfo.Type;
 
 @SuppressWarnings("serial")
 public class XTree extends JTree {
 
     private static final List<String> orderedKeyPropertyList =
             new ArrayList<String>();
+
     static {
         String keyPropertyList =
                 System.getProperty("com.sun.tools.jconsole.mbeans.keyPropertyList");
@@ -54,9 +55,7 @@
             }
         }
     }
-
     private MBeansTab mbeansTab;
-
     private Map<String, DefaultMutableTreeNode> nodes =
             new HashMap<String, DefaultMutableTreeNode>();
 
@@ -65,7 +64,7 @@
     }
 
     public XTree(TreeNode root, MBeansTab mbeansTab) {
-        super(root);
+        super(root, true);
         this.mbeansTab = mbeansTab;
         setRootVisible(false);
         setShowsRootHandles(true);
@@ -90,15 +89,8 @@
             DefaultMutableTreeNode parent,
             DefaultMutableTreeNode child,
             int index) {
-        // Tree does not show up when there is only the root node
-        //
         DefaultTreeModel model = (DefaultTreeModel) getModel();
-        DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
-        boolean rootLeaf = root.isLeaf();
         model.insertNodeInto(child, parent, index);
-        if (rootLeaf) {
-            model.nodeStructureChanged(root);
-        }
     }
 
     /**
@@ -114,32 +106,29 @@
         int childCount = parent.getChildCount();
         if (childCount == 0) {
             addChildNode(parent, child, 0);
-        } else if (child instanceof ComparableDefaultMutableTreeNode) {
+            return;
+        }
+        if (child instanceof ComparableDefaultMutableTreeNode) {
             ComparableDefaultMutableTreeNode comparableChild =
-                (ComparableDefaultMutableTreeNode)child;
-            int i = 0;
-            for (; i < childCount; i++) {
+                    (ComparableDefaultMutableTreeNode) child;
+            for (int i = childCount - 1; i >= 0; i--) {
                 DefaultMutableTreeNode brother =
                         (DefaultMutableTreeNode) parent.getChildAt(i);
-                //child < brother
-                if (comparableChild.compareTo(brother) < 0) {
-                    addChildNode(parent, child, i);
-                    break;
-                }
-                //child = brother
-                else if (comparableChild.compareTo(brother) == 0) {
-                    addChildNode(parent, child, i);
-                    break;
+                // expr1: child node must be inserted after metadata nodes
+                // - OR -
+                // expr2: "child >= brother"
+                if ((i <= 2 && isMetadataNode(brother)) ||
+                        comparableChild.compareTo(brother) >= 0) {
+                    addChildNode(parent, child, i + 1);
+                    return;
                 }
             }
-            //child < all brothers
-            if (i == childCount) {
-                addChildNode(parent, child, childCount);
-            }
-        } else {
-            //not comparable, add at the end
-            addChildNode(parent, child, childCount);
+            // "child < all brothers", add at the beginning
+            addChildNode(parent, child, 0);
+            return;
         }
+        // "child not comparable", add at the end
+        addChildNode(parent, child, childCount);
     }
 
     /**
@@ -147,6 +136,7 @@
      * but does not affect actual MBeanServer contents.
      */
     // Call on EDT
+    @Override
     public synchronized void removeAll() {
         DefaultTreeModel model = (DefaultTreeModel) getModel();
         DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
@@ -155,51 +145,56 @@
         nodes.clear();
     }
 
-    public void delMBeanFromView(final ObjectName mbean) {
-        EventQueue.invokeLater(new Runnable() {
-            public void run() {
-                // We assume here that MBeans are removed one by one (on MBean
-                // unregistered notification). Deletes the tree node associated
-                // with the given MBean and recursively all the node parents
-                // which are leaves and non XMBean.
-                //
-                synchronized (XTree.this) {
-                    DefaultMutableTreeNode node = null;
-                    Dn dn = buildDn(mbean);
-                    if (dn.size() > 0) {
-                        DefaultTreeModel model = (DefaultTreeModel) getModel();
-                        Token token = dn.getToken(0);
-                        String hashKey = dn.getHashKey(token);
-                        node = nodes.get(hashKey);
-                        if ((node != null) && (!node.isRoot())) {
-                            if (hasMBeanChildren(node)) {
-                                removeNonMBeanChildren(node);
-                                String label = token.getValue().toString();
-                                XNodeInfo userObject = new XNodeInfo(
-                                        Type.NONMBEAN, label,
-                                        label, token.toString());
-                                changeNodeValue(node, userObject);
-                            } else {
-                                DefaultMutableTreeNode parent =
-                                        (DefaultMutableTreeNode) node.getParent();
-                                model.removeNodeFromParent(node);
-                                nodes.remove(hashKey);
-                                delParentFromView(dn, 1, parent);
-                            }
-                        }
-                    }
+    // Call on EDT
+    public synchronized void removeMBeanFromView(ObjectName mbean) {
+        // We assume here that MBeans are removed one by one (on MBean
+        // unregistered notification). Deletes the tree node associated
+        // with the given MBean and recursively all the node parents
+        // which are leaves and non XMBean.
+        //
+        DefaultMutableTreeNode node = null;
+        Dn dn = new Dn(mbean);
+        if (dn.getTokenCount() > 0) {
+            DefaultTreeModel model = (DefaultTreeModel) getModel();
+            Token token = dn.getToken(0);
+            String hashKey = dn.getHashKey(token);
+            node = nodes.get(hashKey);
+            if ((node != null) && (!node.isRoot())) {
+                if (hasNonMetadataNodes(node)) {
+                    removeMetadataNodes(node);
+                    String label = token.getValue();
+                    XNodeInfo userObject = new XNodeInfo(
+                            Type.NONMBEAN, label,
+                            label, token.getTokenValue());
+                    changeNodeValue(node, userObject);
+                } else {
+                    DefaultMutableTreeNode parent =
+                            (DefaultMutableTreeNode) node.getParent();
+                    model.removeNodeFromParent(node);
+                    nodes.remove(hashKey);
+                    removeParentFromView(dn, 1, parent);
                 }
             }
-        });
+        }
     }
 
     /**
-     * Returns true if any of the children nodes is an MBean.
+     * Returns true if any of the children nodes is a non MBean metadata node.
      */
-    private boolean hasMBeanChildren(DefaultMutableTreeNode node) {
-        for (Enumeration e = node.children(); e.hasMoreElements(); ) {
+    private boolean hasNonMetadataNodes(DefaultMutableTreeNode node) {
+        for (Enumeration e = node.children(); e.hasMoreElements();) {
             DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
-            if (((XNodeInfo) n.getUserObject()).getType().equals(Type.MBEAN)) {
+            Object uo = n.getUserObject();
+            if (uo instanceof XNodeInfo) {
+                switch (((XNodeInfo) uo).getType()) {
+                    case ATTRIBUTES:
+                    case NOTIFICATIONS:
+                    case OPERATIONS:
+                        break;
+                    default:
+                        return true;
+                }
+            } else {
                 return true;
             }
         }
@@ -207,16 +202,68 @@
     }
 
     /**
-     * Remove all the children nodes which are not MBean.
+     * Returns true if any of the children nodes is an MBean metadata node.
      */
-    private void removeNonMBeanChildren(DefaultMutableTreeNode node) {
+    public boolean hasMetadataNodes(DefaultMutableTreeNode node) {
+        for (Enumeration e = node.children(); e.hasMoreElements();) {
+            DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
+            Object uo = n.getUserObject();
+            if (uo instanceof XNodeInfo) {
+                switch (((XNodeInfo) uo).getType()) {
+                    case ATTRIBUTES:
+                    case NOTIFICATIONS:
+                    case OPERATIONS:
+                        return true;
+                    default:
+                        break;
+                }
+            } else {
+                return false;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if the given node is an MBean metadata node.
+     */
+    public boolean isMetadataNode(DefaultMutableTreeNode node) {
+        Object uo = node.getUserObject();
+        if (uo instanceof XNodeInfo) {
+            switch (((XNodeInfo) uo).getType()) {
+                case ATTRIBUTES:
+                case NOTIFICATIONS:
+                case OPERATIONS:
+                    return true;
+                default:
+                    return false;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Remove the metadata nodes associated with a given MBean node.
+     */
+    // Call on EDT
+    private void removeMetadataNodes(DefaultMutableTreeNode node) {
         Set<DefaultMutableTreeNode> metadataNodes =
                 new HashSet<DefaultMutableTreeNode>();
         DefaultTreeModel model = (DefaultTreeModel) getModel();
-        for (Enumeration e = node.children(); e.hasMoreElements(); ) {
+        for (Enumeration e = node.children(); e.hasMoreElements();) {
             DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
-            if (!((XNodeInfo) n.getUserObject()).getType().equals(Type.MBEAN)) {
-                metadataNodes.add(n);
+            Object uo = n.getUserObject();
+            if (uo instanceof XNodeInfo) {
+                switch (((XNodeInfo) uo).getType()) {
+                    case ATTRIBUTES:
+                    case NOTIFICATIONS:
+                    case OPERATIONS:
+                        metadataNodes.add(n);
+                        break;
+                    default:
+                        break;
+                }
             }
         }
         for (DefaultMutableTreeNode n : metadataNodes) {
@@ -228,7 +275,8 @@
      * Removes only the parent nodes which are non MBean and leaf.
      * This method assumes the child nodes have been removed before.
      */
-    private DefaultMutableTreeNode delParentFromView(
+    // Call on EDT
+    private DefaultMutableTreeNode removeParentFromView(
             Dn dn, int index, DefaultMutableTreeNode node) {
         if ((!node.isRoot()) && node.isLeaf() &&
                 (!(((XNodeInfo) node.getUserObject()).getType().equals(Type.MBEAN)))) {
@@ -237,115 +285,100 @@
             removeChildNode(node);
             String hashKey = dn.getHashKey(dn.getToken(index));
             nodes.remove(hashKey);
-            delParentFromView(dn, index + 1, parent);
+            removeParentFromView(dn, index + 1, parent);
         }
         return node;
     }
 
-    public synchronized void addMBeanToView(final ObjectName mbean) {
-        final XMBean xmbean;
-        try {
-            xmbean = new XMBean(mbean, mbeansTab);
-            if (xmbean == null) {
-                return;
-            }
-        } catch (Exception e) {
-            // Got exception while trying to retrieve the
-            // given MBean from the underlying MBeanServer
+    // Call on EDT
+    public synchronized void addMBeansToView(Set<ObjectName> mbeans) {
+        Set<Dn> dns = new TreeSet<Dn>();
+        for (ObjectName mbean : mbeans) {
+            Dn dn = new Dn(mbean);
+            dns.add(dn);
+        }
+        for (Dn dn : dns) {
+            ObjectName mbean = dn.getObjectName();
+            XMBean xmbean = new XMBean(mbean, mbeansTab);
+            addMBeanToView(mbean, xmbean, dn);
+        }
+    }
+
+    // Call on EDT
+    public synchronized void addMBeanToView(ObjectName mbean) {
+        // Build XMBean for the given MBean
+        //
+        XMBean xmbean = new XMBean(mbean, mbeansTab);
+        // Build Dn for the given MBean
+        //
+        Dn dn = new Dn(mbean);
+        // Add the new nodes to the MBean tree from leaf to root
+        //
+        addMBeanToView(mbean, xmbean, dn);
+    }
+
+    // Call on EDT
+    private synchronized void addMBeanToView(
+            ObjectName mbean, XMBean xmbean, Dn dn) {
+
+        DefaultMutableTreeNode childNode = null;
+        DefaultMutableTreeNode parentNode = null;
+
+        // Add the node or replace its user object if already added
+        //
+        Token token = dn.getToken(0);
+        String hashKey = dn.getHashKey(token);
+        if (nodes.containsKey(hashKey)) {
+            // Found existing node previously created when adding another node
             //
-            if (JConsole.isDebug()) {
-                e.printStackTrace();
-            }
+            childNode = nodes.get(hashKey);
+            // Replace user object to reflect that this node is an MBean
+            //
+            Object data = createNodeValue(xmbean, token);
+            String label = data.toString();
+            XNodeInfo userObject =
+                    new XNodeInfo(Type.MBEAN, data, label, mbean.toString());
+            changeNodeValue(childNode, userObject);
             return;
         }
-        EventQueue.invokeLater(new Runnable() {
-            public void run() {
-                synchronized (XTree.this) {
-                    // Add the new nodes to the MBean tree from leaf to root
 
-                    Dn dn = buildDn(mbean);
-                    if (dn.size() == 0) return;
-                    Token token = dn.getToken(0);
-                    DefaultMutableTreeNode node = null;
-                    boolean nodeCreated = true;
-
-                    //
-                    // Add the node or replace its user object if already added
-                    //
-
-                    String hashKey = dn.getHashKey(token);
-                    if (nodes.containsKey(hashKey)) {
-                        //already in the tree, means it has been created previously
-                        //when adding another node
-                        node = nodes.get(hashKey);
-                        //sets the user object
-                        final Object data = createNodeValue(xmbean, token);
-                        final String label = data.toString();
-                        final XNodeInfo userObject =
-                                new XNodeInfo(Type.MBEAN, data, label, mbean.toString());
-                        changeNodeValue(node, userObject);
-                        nodeCreated = false;
-                    } else {
-                        //create a new node
-                        node = createDnNode(dn, token, xmbean);
-                        if (node != null) {
-                            nodes.put(hashKey, node);
-                            nodeCreated = true;
-                        } else {
-                            return;
-                        }
-                    }
-
-                    //
-                    // Add (virtual) nodes without user object if necessary
-                    //
+        // Create new leaf node
+        //
+        childNode = createDnNode(dn, token, xmbean);
+        nodes.put(hashKey, childNode);
 
-                    for (int i = 1; i < dn.size(); i++) {
-                        DefaultMutableTreeNode currentNode = null;
-                        token = dn.getToken(i);
-                        hashKey = dn.getHashKey(token);
-                        if (nodes.containsKey(hashKey)) {
-                            //node already present
-                            if (nodeCreated) {
-                                //previous node created, link to do
-                                currentNode = nodes.get(hashKey);
-                                addChildNode(currentNode, node);
-                                return;
-                            } else {
-                                //both nodes already present
-                                return;
-                            }
-                        } else {
-                            //creates the node that can be a virtual one
-                            if (token.getKeyDn().equals("domain")) {
-                                //better match on keyDn that on Dn
-                                currentNode = createDomainNode(dn, token);
-                                if (currentNode != null) {
-                                    final DefaultMutableTreeNode root =
-                                            (DefaultMutableTreeNode) getModel().getRoot();
-                                    addChildNode(root, currentNode);
-                                }
-                            } else {
-                                currentNode = createSubDnNode(dn, token);
-                                if (currentNode == null) {
-                                    //skip
-                                    continue;
-                                }
-                            }
-                            nodes.put(hashKey, currentNode);
-                            addChildNode(currentNode, node);
-                            nodeCreated = true;
-                        }
-                        node = currentNode;
-                    }
+        // Add intermediate non MBean nodes
+        //
+        for (int i = 1; i < dn.getTokenCount(); i++) {
+            token = dn.getToken(i);
+            hashKey = dn.getHashKey(token);
+            if (nodes.containsKey(hashKey)) {
+                // Intermediate node already present, add new node as child
+                //
+                parentNode = nodes.get(hashKey);
+                addChildNode(parentNode, childNode);
+                return;
+            } else {
+                // Create new intermediate node
+                //
+                if ("domain".equals(token.getTokenType())) {
+                    parentNode = createDomainNode(dn, token);
+                    DefaultMutableTreeNode root =
+                            (DefaultMutableTreeNode) getModel().getRoot();
+                    addChildNode(root, parentNode);
+                } else {
+                    parentNode = createSubDnNode(dn, token);
                 }
+                nodes.put(hashKey, parentNode);
+                addChildNode(parentNode, childNode);
             }
-        });
+            childNode = parentNode;
+        }
     }
 
     // Call on EDT
     private synchronized void changeNodeValue(
-            final DefaultMutableTreeNode node, XNodeInfo nodeValue) {
+            DefaultMutableTreeNode node, XNodeInfo nodeValue) {
         if (node instanceof ComparableDefaultMutableTreeNode) {
             // should it stay at the same place?
             DefaultMutableTreeNode clone =
@@ -373,9 +406,12 @@
         }
         // Load the MBean metadata if type is MBEAN
         if (nodeValue.getType().equals(Type.MBEAN)) {
-            XMBeanInfo.loadInfo(node);
-            DefaultTreeModel model = (DefaultTreeModel) getModel();
-            model.nodeStructureChanged(node);
+            removeMetadataNodes(node);
+            TreeNode[] treeNodes = node.getPath();
+            TreePath path = new TreePath(treeNodes);
+            if (isExpanded(path)) {
+                addMetadataNodes(node);
+            }
         }
         // Clear the current selection and set it
         // again so valueChanged() gets called
@@ -386,7 +422,9 @@
         }
     }
 
-    //creates the domain node, called on a domain token
+    /**
+     * Creates the domain node.
+     */
     private DefaultMutableTreeNode createDomainNode(Dn dn, Token token) {
         DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();
         String label = dn.getDomain();
@@ -396,7 +434,9 @@
         return node;
     }
 
-    //creates the node corresponding to the whole Dn
+    /**
+     * Creates the node corresponding to the whole Dn, i.e. an MBean.
+     */
     private DefaultMutableTreeNode createDnNode(
             Dn dn, Token token, XMBean xmbean) {
         DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();
@@ -405,38 +445,36 @@
         XNodeInfo userObject = new XNodeInfo(Type.MBEAN, data, label,
                 xmbean.getObjectName().toString());
         node.setUserObject(userObject);
-        XMBeanInfo.loadInfo(node);
         return node;
     }
 
-    //creates a node with the token value, call for each non domain sub
-    //dn token
+    /**
+     * Creates the node corresponding to a subDn, i.e. a non-MBean
+     * intermediate node.
+     */
     private DefaultMutableTreeNode createSubDnNode(Dn dn, Token token) {
         DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();
-        String label = isKeyValueView() ? token.toString() :
-            token.getValue().toString();
+        String label = isKeyValueView() ? token.getTokenValue() : token.getValue();
         XNodeInfo userObject =
-                new XNodeInfo(Type.NONMBEAN, label, label, token.toString());
+                new XNodeInfo(Type.NONMBEAN, label, label, token.getTokenValue());
         node.setUserObject(userObject);
         return node;
     }
 
     private Object createNodeValue(XMBean xmbean, Token token) {
-        String label = isKeyValueView() ? token.toString() :
-            token.getValue().toString();
+        String label = isKeyValueView() ? token.getTokenValue() : token.getValue();
         xmbean.setText(label);
         return xmbean;
     }
 
     /**
-     * Parses MBean ObjectName comma-separated properties string and put the
-     * individual key/value pairs into the map. Key order in the properties
+     * Parses the MBean ObjectName comma-separated properties string and puts
+     * the individual key/value pairs into the map. Key order in the properties
      * string is preserved by the map.
      */
-    private Map<String,String> extractKeyValuePairs(
-            String properties, ObjectName mbean) {
-        String props = properties;
-        Map<String,String> map = new LinkedHashMap<String,String>();
+    private static Map<String, String> extractKeyValuePairs(
+            String props, ObjectName mbean) {
+        Map<String, String> map = new LinkedHashMap<String, String>();
         int eq = props.indexOf("=");
         while (eq != -1) {
             String key = props.substring(0, eq);
@@ -461,9 +499,9 @@
      * in the comma-separated key property list does not apply to the given
      * MBean then it will be discarded.
      */
-    private String getKeyPropertyListString(ObjectName mbean) {
+    private static String getKeyPropertyListString(ObjectName mbean) {
         String props = mbean.getKeyPropertyListString();
-        Map<String,String> map = extractKeyValuePairs(props, mbean);
+        Map<String, String> map = extractKeyValuePairs(props, mbean);
         StringBuilder sb = new StringBuilder();
         // Add the key/value pairs to the buffer following the
         // key order defined by the "orderedKeyPropertyList"
@@ -474,7 +512,7 @@
             }
         }
         // Add the remaining key/value pairs to the buffer
-        for (Map.Entry<String,String> entry : map.entrySet()) {
+        for (Map.Entry<String, String> entry : map.entrySet()) {
             sb.append(entry.getKey() + "=" + entry.getValue() + ",");
         }
         String orderedKeyPropertyListString = sb.toString();
@@ -483,67 +521,158 @@
         return orderedKeyPropertyListString;
     }
 
-    /**
-     * Builds the Dn for the given MBean.
-     */
-    private Dn buildDn(ObjectName mbean) {
-
-        String domain = mbean.getDomain();
-        String globalDn = getKeyPropertyListString(mbean);
-
-        Dn dn = buildDn(domain, globalDn, mbean);
-
-        //update the Dn tokens to add the domain
-        dn.updateDn();
-
-        //reverse the Dn (from leaf to root)
-        dn.reverseOrder();
-
-        //compute the hashDn
-        dn.computeHashDn();
-
-        return dn;
-    }
-
-    /**
-     * Builds the Dn for the given MBean.
-     */
-    private Dn buildDn(String domain, String globalDn, ObjectName mbean) {
-        Dn dn = new Dn(domain, globalDn);
-        String keyDn = "no_key";
-        if (isTreeView()) {
-            String props = globalDn;
-            Map<String,String> map = extractKeyValuePairs(props, mbean);
-            for (Map.Entry<String,String> entry : map.entrySet()) {
-                dn.addToken(new Token(keyDn,
-                        entry.getKey() + "=" + entry.getValue()));
-            }
-        } else {
-            //flat view
-            dn.addToken(new Token(keyDn, "properties=" + globalDn));
-        }
-        return dn;
-    }
-
-    //
-    //utility objects
-    //
-
-    public static class ComparableDefaultMutableTreeNode
-            extends DefaultMutableTreeNode
-            implements Comparable<DefaultMutableTreeNode> {
-        public int compareTo(DefaultMutableTreeNode node) {
-            return (this.toString().compareTo(node.toString()));
+    // Call on EDT
+    public void addMetadataNodes(DefaultMutableTreeNode node) {
+        XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();
+        DefaultTreeModel model = (DefaultTreeModel) getModel();
+        MBeanInfoNodesSwingWorker sw =
+                new MBeanInfoNodesSwingWorker(model, node, mbean);
+        if (sw != null) {
+            sw.execute();
         }
     }
 
-    //
-    //tree preferences
-    //
+    private static class MBeanInfoNodesSwingWorker
+            extends SwingWorker<Object[], Void> {
+
+        private final DefaultTreeModel model;
+        private final DefaultMutableTreeNode node;
+        private final XMBean mbean;
+
+        public MBeanInfoNodesSwingWorker(
+                DefaultTreeModel model,
+                DefaultMutableTreeNode node,
+                XMBean mbean) {
+            this.model = model;
+            this.node = node;
+            this.mbean = mbean;
+        }
+
+        @Override
+        public Object[] doInBackground() throws InstanceNotFoundException,
+                IntrospectionException, ReflectionException, IOException {
+            Object result[] = new Object[2];
+            // Retrieve MBeanInfo for this MBean
+            result[0] = mbean.getMBeanInfo();
+            // Check if this MBean is a notification emitter
+            result[1] = mbean.isBroadcaster();
+            return result;
+        }
+
+        @Override
+        protected void done() {
+            try {
+                Object result[] = get();
+                MBeanInfo mbeanInfo = (MBeanInfo) result[0];
+                Boolean isBroadcaster = (Boolean) result[1];
+                if (mbeanInfo != null) {
+                    addMBeanInfoNodes(model, node, mbean, mbeanInfo, isBroadcaster);
+                }
+            } catch (Exception e) {
+                Throwable t = Utils.getActualException(e);
+                if (JConsole.isDebug()) {
+                    t.printStackTrace();
+                }
+            }
+        }
+
+        // Call on EDT
+        private void addMBeanInfoNodes(
+                DefaultTreeModel tree, DefaultMutableTreeNode node,
+                XMBean mbean, MBeanInfo mbeanInfo, Boolean isBroadcaster) {
+            MBeanAttributeInfo[] ai = mbeanInfo.getAttributes();
+            MBeanOperationInfo[] oi = mbeanInfo.getOperations();
+            MBeanNotificationInfo[] ni = mbeanInfo.getNotifications();
+
+            // Insert the Attributes/Operations/Notifications metadata nodes as
+            // the three first children of this MBean node. This is only useful
+            // when this MBean node denotes an MBean but it's not a leaf in the
+            // MBean tree
+            //
+            int childIndex = 0;
 
-    private boolean treeView;
-    private boolean treeViewInit = false;
-    public boolean isTreeView() {
+            // MBeanAttributeInfo node
+            //
+            if (ai != null && ai.length > 0) {
+                DefaultMutableTreeNode attributes = new DefaultMutableTreeNode();
+                XNodeInfo attributesUO = new XNodeInfo(Type.ATTRIBUTES, mbean,
+                        Resources.getText("Attributes"), null);
+                attributes.setUserObject(attributesUO);
+                node.insert(attributes, childIndex++);
+                for (MBeanAttributeInfo mbai : ai) {
+                    DefaultMutableTreeNode attribute = new DefaultMutableTreeNode();
+                    XNodeInfo attributeUO = new XNodeInfo(Type.ATTRIBUTE,
+                            new Object[]{mbean, mbai}, mbai.getName(), null);
+                    attribute.setUserObject(attributeUO);
+                    attribute.setAllowsChildren(false);
+                    attributes.add(attribute);
+                }
+            }
+            // MBeanOperationInfo node
+            //
+            if (oi != null && oi.length > 0) {
+                DefaultMutableTreeNode operations = new DefaultMutableTreeNode();
+                XNodeInfo operationsUO = new XNodeInfo(Type.OPERATIONS, mbean,
+                        Resources.getText("Operations"), null);
+                operations.setUserObject(operationsUO);
+                node.insert(operations, childIndex++);
+                for (MBeanOperationInfo mboi : oi) {
+                    // Compute the operation's tool tip text:
+                    // "operationname(param1type,param2type,...)"
+                    //
+                    StringBuilder sb = new StringBuilder();
+                    for (MBeanParameterInfo mbpi : mboi.getSignature()) {
+                        sb.append(mbpi.getType() + ",");
+                    }
+                    String signature = sb.toString();
+                    if (signature.length() > 0) {
+                        // Remove the trailing ','
+                        //
+                        signature = signature.substring(0, signature.length() - 1);
+                    }
+                    String toolTipText = mboi.getName() + "(" + signature + ")";
+                    // Create operation node
+                    //
+                    DefaultMutableTreeNode operation = new DefaultMutableTreeNode();
+                    XNodeInfo operationUO = new XNodeInfo(Type.OPERATION,
+                            new Object[]{mbean, mboi}, mboi.getName(), toolTipText);
+                    operation.setUserObject(operationUO);
+                    operation.setAllowsChildren(false);
+                    operations.add(operation);
+                }
+            }
+            // MBeanNotificationInfo node
+            //
+            if (isBroadcaster != null && isBroadcaster.booleanValue()) {
+                DefaultMutableTreeNode notifications = new DefaultMutableTreeNode();
+                XNodeInfo notificationsUO = new XNodeInfo(Type.NOTIFICATIONS, mbean,
+                        Resources.getText("Notifications"), null);
+                notifications.setUserObject(notificationsUO);
+                node.insert(notifications, childIndex++);
+                if (ni != null && ni.length > 0) {
+                    for (MBeanNotificationInfo mbni : ni) {
+                        DefaultMutableTreeNode notification =
+                                new DefaultMutableTreeNode();
+                        XNodeInfo notificationUO = new XNodeInfo(Type.NOTIFICATION,
+                                mbni, mbni.getName(), null);
+                        notification.setUserObject(notificationUO);
+                        notification.setAllowsChildren(false);
+                        notifications.add(notification);
+                    }
+                }
+            }
+            // Update tree model
+            //
+            model.reload(node);
+        }
+    }
+    //
+    // Tree preferences
+    //
+    private static boolean treeView;
+    private static boolean treeViewInit = false;
+
+    private static boolean isTreeView() {
         if (!treeViewInit) {
             treeView = getTreeViewValue();
             treeViewInit = true;
@@ -551,170 +680,136 @@
         return treeView;
     }
 
-    private boolean getTreeViewValue() {
-        String treeView = System.getProperty("treeView");
-        return ((treeView == null) ? true : !(treeView.equals("false")));
+    private static boolean getTreeViewValue() {
+        String tv = System.getProperty("treeView");
+        return ((tv == null) ? true : !(tv.equals("false")));
     }
-
     //
-    //MBean key-value preferences
+    // MBean key-value preferences
     //
+    private boolean keyValueView = Boolean.getBoolean("keyValueView");
 
-    private boolean keyValueView = Boolean.getBoolean("keyValueView");
-    public boolean isKeyValueView() {
+    private boolean isKeyValueView() {
         return keyValueView;
     }
 
     //
-    //utility classes
+    // Utility classes
     //
+    private static class ComparableDefaultMutableTreeNode
+            extends DefaultMutableTreeNode
+            implements Comparable<DefaultMutableTreeNode> {
 
-    public static class Dn {
+        public int compareTo(DefaultMutableTreeNode node) {
+            return (this.toString().compareTo(node.toString()));
+        }
+    }
 
+    private static class Dn implements Comparable<Dn> {
+
+        private ObjectName mbean;
         private String domain;
-        private String dn;
+        private String keyPropertyList;
         private String hashDn;
-        private ArrayList<Token> tokens = new ArrayList<Token>();
+        private List<Token> tokens = new ArrayList<Token>();
+
+        public Dn(ObjectName mbean) {
+            this.mbean = mbean;
+            this.domain = mbean.getDomain();
+            this.keyPropertyList = getKeyPropertyListString(mbean);
 
-        public Dn(String domain, String dn) {
-            this.domain = domain;
-            this.dn = dn;
+            if (isTreeView()) {
+                // Tree view
+                Map<String, String> map =
+                        extractKeyValuePairs(keyPropertyList, mbean);
+                for (Map.Entry<String, String> entry : map.entrySet()) {
+                    tokens.add(new Token("key", entry.getKey() + "=" + entry.getValue()));
+                }
+            } else {
+                // Flat view
+                tokens.add(new Token("key", "properties=" + keyPropertyList));
+            }
+
+            // Add the domain as the first token in the Dn
+            tokens.add(0, new Token("domain", "domain=" + domain));
+
+            // Reverse the Dn (from leaf to root)
+            Collections.reverse(tokens);
+
+            // Compute hash for Dn
+            computeHashDn();
         }
 
-        public void clearTokens() {
-            tokens.clear();
-        }
-
-        public void addToken(Token token) {
-            tokens.add(token);
+        public ObjectName getObjectName() {
+            return mbean;
         }
 
-        public void addToken(int index, Token token) {
-            tokens.add(index, token);
+        public String getDomain() {
+            return domain;
         }
 
-        public void setToken(int index, Token token) {
-            tokens.set(index, token);
-        }
-
-        public void removeToken(int index) {
-            tokens.remove(index);
+        public String getKeyPropertyList() {
+            return keyPropertyList;
         }
 
         public Token getToken(int index) {
             return tokens.get(index);
         }
 
-        public void reverseOrder() {
-            ArrayList<Token> newOrder = new ArrayList<Token>(tokens.size());
-            for (int i = tokens.size() - 1; i >= 0; i--) {
-                newOrder.add(tokens.get(i));
-            }
-            tokens = newOrder;
-        }
-
-        public int size() {
+        public int getTokenCount() {
             return tokens.size();
         }
 
-        public String getDomain() {
-            return domain;
-        }
-
-        public String getDn() {
-            return dn;
-        }
-
         public String getHashDn() {
             return hashDn;
         }
 
         public String getHashKey(Token token) {
-            final int begin = getHashDn().indexOf(token.getHashToken());
-            return  getHashDn().substring(begin, getHashDn().length());
+            final int begin = hashDn.indexOf(token.getTokenValue());
+            return hashDn.substring(begin, hashDn.length());
         }
 
-        public void computeHashDn() {
-            final StringBuilder hashDn = new StringBuilder();
-            final int tokensSize = tokens.size();
-            for (int i = 0; i < tokensSize; i++) {
-                Token token = tokens.get(i);
-                String hashToken = token.getHashToken();
-                if (hashToken == null) {
-                    hashToken = token.getToken() + (tokensSize - i);
-                    token.setHashToken(hashToken);
-                }
-                hashDn.append(hashToken);
-                hashDn.append(",");
+        private void computeHashDn() {
+            if (tokens.isEmpty()) {
+                return;
             }
-            if (tokensSize > 0) {
-                this.hashDn = hashDn.substring(0, hashDn.length() - 1);
-            } else {
-                this.hashDn = "";
+            final StringBuilder hdn = new StringBuilder();
+            for (int i = 0; i < tokens.size(); i++) {
+                hdn.append(tokens.get(i).getTokenValue());
+                hdn.append(",");
             }
+            hashDn = hdn.substring(0, hdn.length() - 1);
         }
 
-        /**
-         * Adds the domain as the first token in the Dn.
-         */
-        public void updateDn() {
-            addToken(0, new Token("domain", "domain=" + getDomain()));
+        @Override
+        public String toString() {
+            return domain + ":" + keyPropertyList;
         }
 
-        public String toString() {
-            return tokens.toString();
+        public int compareTo(Dn dn) {
+            return this.toString().compareTo(dn.toString());
         }
     }
 
-    public static class Token {
+    private static class Token {
 
-        private String keyDn;
-        private String token;
-        private String hashToken;
+        private String tokenType;
+        private String tokenValue;
         private String key;
         private String value;
 
-        public Token(String keyDn, String token) {
-            this.keyDn = keyDn;
-            this.token = token;
-            buildKeyValue();
-        }
-
-        public Token(String keyDn, String token, String hashToken) {
-            this.keyDn = keyDn;
-            this.token = token;
-            this.hashToken = hashToken;
+        public Token(String tokenType, String tokenValue) {
+            this.tokenType = tokenType;
+            this.tokenValue = tokenValue;
             buildKeyValue();
         }
 
-        public String getKeyDn() {
-            return keyDn;
-        }
-
-        public String getToken() {
-            return token;
-        }
-
-        public void setValue(String value) {
-            this.value = value;
-            this.token = key + "=" + value;
+        public String getTokenType() {
+            return tokenType;
         }
 
-        public void setKey(String key) {
-            this.key = key;
-            this.token = key + "=" + value;
-        }
-
-        public void setKeyDn(String keyDn) {
-            this.keyDn = keyDn;
-        }
-
-        public  void setHashToken(String hashToken) {
-            this.hashToken = hashToken;
-        }
-
-        public String getHashToken() {
-            return hashToken;
+        public String getTokenValue() {
+            return tokenValue;
         }
 
         public String getKey() {
@@ -725,26 +820,14 @@
             return value;
         }
 
-        public String toString(){
-            return getToken();
-        }
-
-        public boolean equals(Object object) {
-            if (object instanceof Token) {
-                return token.equals(((Token) object));
+        private void buildKeyValue() {
+            int index = tokenValue.indexOf("=");
+            if (index < 0) {
+                key = tokenValue;
+                value = tokenValue;
             } else {
-                return false;
-            }
-        }
-
-        private void buildKeyValue() {
-            int index = token.indexOf("=");
-            if (index < 0) {
-                key = token;
-                value = token;
-            } else {
-                key = token.substring(0, index);
-                value = token.substring(index + 1, token.length());
+                key = tokenValue.substring(0, index);
+                value = tokenValue.substring(index + 1, tokenValue.length());
             }
         }
     }
--- a/src/share/classes/sun/tools/native2ascii/N2AFilter.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/classes/sun/tools/native2ascii/N2AFilter.java	Mon Apr 14 11:34:15 2008 -0700
@@ -42,7 +42,7 @@
 
     public void write(char b) throws IOException {
         char[] buf = new char[1];
-        buf[0] = (char)b;
+        buf[0] = b;
         write(buf, 0, 1);
     }
 
--- a/src/share/demo/jfc/Notepad/resources/Notepad.properties	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/demo/jfc/Notepad/resources/Notepad.properties	Mon Apr 14 11:34:15 2008 -0700
@@ -1,76 +1,76 @@
-#
-# Resource strings for Notepad example
-
-Title=Notepad
-ElementTreeFrameTitle=Elements
-ViewportBackingStore=false
-
-# menubar definition
-#
-# Each of the strings that follow form a key to be 
-# used to the actual menu definition.
-menubar=file edit debug
-
-# file Menu definition
-#
-# Each of the strings that follow form a key to be
-# used as the basis of a menu item definition.
-#
-# open ->  Notepad.openAction
-# new  ->  Notepad.newAction
-# save ->  Notepad.saveAction
-# exit ->  Notepad.exitAction
-file=new open save - exit
-fileLabel=File
-openLabel=Open
-openImage=resources/open.gif
-newLabel=New
-newImage=resources/new.gif
-saveLabel=Save
-saveImage=resources/save.gif
-exitLabel=Exit
-
-#
-# edit Menu definition
-#
-# cut   -> JTextComponent.cutAction
-# copy  -> JTextComponent.copyAction
-# paste -> JTextComponent.pasteAction
-edit=cut copy paste - undo redo
-editLabel=Edit
-cutLabel=Cut
-cutAction=cut-to-clipboard
-cutImage=resources/cut.gif
-copyLabel=Copy
-copyAction=copy-to-clipboard
-copyImage=resources/copy.gif
-pasteLabel=Paste
-pasteAction=paste-from-clipboard
-pasteImage=resources/paste.gif
-undoLabel=Undo
-undoAction=Undo
-redoLabel=Redo
-redoAction=Redo
-
-#
-# debug Menu definition
-#
-debug=dump showElementTree
-debugLabel=Debug
-dumpLabel=Dump model to System.err
-dumpAction=dump-model
-showElementTreeLabel=Show Elements
-
-# toolbar definition
-#
-# Each of the strings that follow form a key to be
-# used as the basis of the tool definition.  Actions
-# are of course sharable, and in this case are shared
-# with the menu items.
-toolbar=new open save - cut copy paste
-newTooltip=Create a new file
-openTooltip=Open a file
-saveTooltip=Save to a file
-cutTooltip=Move selection to clipboard
-copyTooltip=Copy selection to clipboard
-pasteTooltip=Paste clipboard to selection
+#
+# Resource strings for Notepad example
+
+Title=Notepad
+ElementTreeFrameTitle=Elements
+ViewportBackingStore=false
+
+# menubar definition
+#
+# Each of the strings that follow form a key to be 
+# used to the actual menu definition.
+menubar=file edit debug
+
+# file Menu definition
+#
+# Each of the strings that follow form a key to be
+# used as the basis of a menu item definition.
+#
+# open ->  Notepad.openAction
+# new  ->  Notepad.newAction
+# save ->  Notepad.saveAction
+# exit ->  Notepad.exitAction
+file=new open save - exit
+fileLabel=File
+openLabel=Open
+openImage=resources/open.gif
+newLabel=New
+newImage=resources/new.gif
+saveLabel=Save
+saveImage=resources/save.gif
+exitLabel=Exit
+
+#
+# edit Menu definition
+#
+# cut   -> JTextComponent.cutAction
+# copy  -> JTextComponent.copyAction
+# paste -> JTextComponent.pasteAction
+edit=cut copy paste - undo redo
+editLabel=Edit
+cutLabel=Cut
+cutAction=cut-to-clipboard
+cutImage=resources/cut.gif
+copyLabel=Copy
+copyAction=copy-to-clipboard
+copyImage=resources/copy.gif
+pasteLabel=Paste
+pasteAction=paste-from-clipboard
+pasteImage=resources/paste.gif
+undoLabel=Undo
+undoAction=Undo
+redoLabel=Redo
+redoAction=Redo
+
+#
+# debug Menu definition
+#
+debug=dump showElementTree
+debugLabel=Debug
+dumpLabel=Dump model to System.err
+dumpAction=dump-model
+showElementTreeLabel=Show Elements
+
+# toolbar definition
+#
+# Each of the strings that follow form a key to be
+# used as the basis of the tool definition.  Actions
+# are of course sharable, and in this case are shared
+# with the menu items.
+toolbar=new open save - cut copy paste
+newTooltip=Create a new file
+openTooltip=Open a file
+saveTooltip=Save to a file
+cutTooltip=Move selection to clipboard
+copyTooltip=Copy selection to clipboard
+pasteTooltip=Paste clipboard to selection
--- a/src/share/native/java/io/io_util.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/native/java/io/io_util.c	Mon Apr 14 11:34:15 2008 -0700
@@ -40,7 +40,7 @@
     char ret;
     FD fd = GET_FD(this, fid);
     if (fd == -1) {
-        JNU_ThrowIOException (env, "Stream Closed");
+        JNU_ThrowIOException(env, "Stream Closed");
         return -1;
     }
     nread = IO_Read(fd, &ret, 1);
@@ -94,8 +94,8 @@
 
     fd = GET_FD(this, fid);
     if (fd == -1) {
-        JNU_ThrowIOException (env, "Stream Closed");
-        return  -1;
+        JNU_ThrowIOException(env, "Stream Closed");
+        return -1;
     }
 
     nread = IO_Read(fd, buf, len);
@@ -121,7 +121,7 @@
     int n;
     FD fd = GET_FD(this, fid);
     if (fd == -1) {
-        JNU_ThrowIOException (env, "Stream Closed");
+        JNU_ThrowIOException(env, "Stream Closed");
         return;
     }
     n = IO_Write(fd, &c, 1);
@@ -172,8 +172,8 @@
         while (len > 0) {
             fd = GET_FD(this, fid);
             if (fd == -1) {
-                JNU_ThrowIOException (env, "Stream Closed");
-                return;
+                JNU_ThrowIOException(env, "Stream Closed");
+                break;
             }
             n = IO_Write(fd, buf+off, len);
             if (n == JVM_IO_ERR) {
--- a/src/share/sample/vm/clr-jvm/Makefile	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/sample/vm/clr-jvm/Makefile	Mon Apr 14 11:34:15 2008 -0700
@@ -29,16 +29,16 @@
 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
 
-all: jinvoker.dll invoked.class invoker.exe
-
-jinvoker.dll: jinvoker.obj Makefile
-	cl /LD /o jinvoker.dll jinvoker.obj
-
-jinvoker.obj: jinvoker.cpp jinvokerExp.h Makefile
-	cl /Fojinvoker.obj /DJINVOKEREEXPORT /c jinvoker.cpp
-
-invoked.class: invoked.java Makefile
-	javac invoked.java
-
-invoker.exe: invoker.cs Makefile
-	csc /unsafe invoker.cs
+all: jinvoker.dll invoked.class invoker.exe
+
+jinvoker.dll: jinvoker.obj Makefile
+	cl /LD /o jinvoker.dll jinvoker.obj
+
+jinvoker.obj: jinvoker.cpp jinvokerExp.h Makefile
+	cl /Fojinvoker.obj /DJINVOKEREEXPORT /c jinvoker.cpp
+
+invoked.class: invoked.java Makefile
+	javac invoked.java
+
+invoker.exe: invoker.cs Makefile
+	csc /unsafe invoker.cs
--- a/src/share/sample/vm/clr-jvm/README.txt	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/sample/vm/clr-jvm/README.txt	Mon Apr 14 11:34:15 2008 -0700
@@ -1,54 +1,54 @@
-This sample provides Java "Hello World" program that is invoked
-from C# application in the same process.
-
-The problem of direct call of the JVM API from CLR applications
-by PInvoke interface is the JVM API functions do not have static
-adresses, they need to be got by JNI_CreateJavaVM() call.
-The sample contains C++ libraty that wraps JVM API calls by the
-static functions that are called from the C# application by
-PInvoke interface.
-
-The sample contains the following files:
-
-Makefile      - make file
-README.txt    - this readme
-invoked.java  - the invoked HelloWorld Java program
-invoker.cs    - C# invoker application
-jinvoker.cpp  - C++ wrapper
-jinvokerExp.h - wrapper library exports
-
-After the success making the following files are produced:
-
-invoked.class - the compiled HelloWorld class
-invoker.exe   - the executable .NET program that invokes Java
-jinvoker.dll  - the wrapper library
-
-The following environment needs to be set for the correct sample
-build and execution:
-
-INCLUDE must contain the paths to:
-  1. MS Visual C++ standard include
-  2. .NET SDK include
-  3. Java includes
-  Example: %MSDEV%/VC98/Include;%DOTNET%/Include;%JAVA_HOME%/include;%JAVA_HOME%/include/win32
-
-LIB must contain the paths to:
-  1. MS Visual C++ standard libraries
-  2. .NET SDK libraries
-  3. jvm.dll
-  Example: %MSDEV%/VC98/Lib;%DOTNET%/Lib;%JAVA_HOME%/jre/bin/client
-
-PATH must contain the paths to:
-  1. MS Visual C++ standard bin
-  2. MS Dev common bin
-  3. .NET SDK libraries
-  4. Java bin
-  5. jvm.dll
-  Example: %MSDEV%/VC98/Bin;%MSDEV%/Common/MSDev98/Bin;%DOTNET%/Lib;%JAVA_HOME%/bin;%JAVA_HOME%/jre/bin/client;%PATH%
-
-To run the sample please do:
-
-  invoker.exe invoked
-
-
---Dmitry Ryashchentsev
+This sample provides Java "Hello World" program that is invoked
+from C# application in the same process.
+
+The problem of direct call of the JVM API from CLR applications
+by PInvoke interface is the JVM API functions do not have static
+adresses, they need to be got by JNI_CreateJavaVM() call.
+The sample contains C++ libraty that wraps JVM API calls by the
+static functions that are called from the C# application by
+PInvoke interface.
+
+The sample contains the following files:
+
+Makefile      - make file
+README.txt    - this readme
+invoked.java  - the invoked HelloWorld Java program
+invoker.cs    - C# invoker application
+jinvoker.cpp  - C++ wrapper
+jinvokerExp.h - wrapper library exports
+
+After the success making the following files are produced:
+
+invoked.class - the compiled HelloWorld class
+invoker.exe   - the executable .NET program that invokes Java
+jinvoker.dll  - the wrapper library
+
+The following environment needs to be set for the correct sample
+build and execution:
+
+INCLUDE must contain the paths to:
+  1. MS Visual C++ standard include
+  2. .NET SDK include
+  3. Java includes
+  Example: %MSDEV%/VC98/Include;%DOTNET%/Include;%JAVA_HOME%/include;%JAVA_HOME%/include/win32
+
+LIB must contain the paths to:
+  1. MS Visual C++ standard libraries
+  2. .NET SDK libraries
+  3. jvm.dll
+  Example: %MSDEV%/VC98/Lib;%DOTNET%/Lib;%JAVA_HOME%/jre/bin/client
+
+PATH must contain the paths to:
+  1. MS Visual C++ standard bin
+  2. MS Dev common bin
+  3. .NET SDK libraries
+  4. Java bin
+  5. jvm.dll
+  Example: %MSDEV%/VC98/Bin;%MSDEV%/Common/MSDev98/Bin;%DOTNET%/Lib;%JAVA_HOME%/bin;%JAVA_HOME%/jre/bin/client;%PATH%
+
+To run the sample please do:
+
+  invoker.exe invoked
+
+
+--Dmitry Ryashchentsev
--- a/src/share/sample/vm/clr-jvm/invoker.cs	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/sample/vm/clr-jvm/invoker.cs	Mon Apr 14 11:34:15 2008 -0700
@@ -29,30 +29,30 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/*
-*/
-
+/*
+*/
+
 using System;
 using System.Runtime.InteropServices;
 
 class jinvoker{
 
     public static int Main(string[] aArgs){
-        
-        // Print Hello to show we are in CLR
-        Console.WriteLine("Hello from C#");
-        if(aArgs.Length > 0)
-            // invoke JVM
-            return InvokeMain(aArgs[0]);
-        else
-            return -1;
+        
+        // Print Hello to show we are in CLR
+        Console.WriteLine("Hello from C#");
+        if(aArgs.Length > 0)
+            // invoke JVM
+            return InvokeMain(aArgs[0]);
+        else
+            return -1;
     }
 
     // Link the JVM API functions and the wrappers
 
     [DllImport("jvm.dll")]      public unsafe static extern int  JNI_CreateJavaVM(void** ppVm, void** ppEnv, void* pArgs);
     [DllImport("jinvoker.dll")] public unsafe static extern int  MakeJavaVMInitArgs( void** ppArgs );
-    [DllImport("jinvoker.dll")] public unsafe static extern void FreeJavaVMInitArgs( void* pArgs );
+    [DllImport("jinvoker.dll")] public unsafe static extern void FreeJavaVMInitArgs( void* pArgs );
     [DllImport("jinvoker.dll")] public unsafe static extern int  FindClass( void* pEnv, String sClass, void** ppClass );
     [DllImport("jinvoker.dll")] public unsafe static extern int  GetStaticMethodID( void*  pEnv,
                                                                                     void*  pClass, 
@@ -73,7 +73,7 @@
     [DllImport("jinvoker.dll")] public unsafe static extern int DestroyJavaVM( void* pJVM );
 
 	public unsafe static int InvokeMain( String sClass ){
-	    
+	    
         void*  pJVM;    // JVM struct
         void*  pEnv;    // JVM environment
         void*  pVMArgs; // VM args
@@ -81,23 +81,23 @@
         void*  pMethod; // The executed method struct
         void*  pArgs;   // The executed method arguments struct
 
-        // Fill the pVMArgs structs
+        // Fill the pVMArgs structs
         MakeJavaVMInitArgs( &pVMArgs );
 
-        // Create JVM
+        // Create JVM
         int nRes = JNI_CreateJavaVM( &pJVM, &pEnv, pVMArgs );
         if( nRes == 0 ){
-			
-            // Find the executed method class 
+			
+            // Find the executed method class 
             if(FindClass( pEnv, sClass, &pClass) == 0 )
-				
-                // Find the executed method
+				
+                // Find the executed method
                 if( GetStaticMethodID( pEnv, pClass, "main", "([Ljava/lang/String;)V", &pMethod ) == 0 )
-					
-                    // Create empty String[] array to pass to the main()
+					
+                    // Create empty String[] array to pass to the main()
                     if( NewObjectArray( pEnv, 0, "java/lang/String", &pArgs ) == 0 ){
-
-                        // Call main()
+
+                        // Call main()
                         nRes = CallStaticVoidMethod( pEnv, pClass, pMethod, pArgs );
                         if( nRes != -1 )
                             Console.WriteLine("Result:"+nRes);
@@ -116,16 +116,16 @@
                 Console.WriteLine("can not find class:"+sClass);
                 nRes = -102;
             }
-			
-            // Destroy the JVM
+			
+            // Destroy the JVM
             DestroyJavaVM( pJVM );
 
         }else
-            Console.WriteLine("Can not create Java VM");
-
-        // Free the JVM args structs
+            Console.WriteLine("Can not create Java VM");
+
+        // Free the JVM args structs
         FreeJavaVMInitArgs(pVMArgs);
-		
+		
         return nRes;
     }
 }
--- a/src/share/sample/vm/jvm-clr/README.txt	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/sample/vm/jvm-clr/README.txt	Mon Apr 14 11:34:15 2008 -0700
@@ -42,10 +42,10 @@
   3. .NET SDK libraries
   4. Java bin
   Example: %MSDEV%/VC98/Bin;%MSDEV%/Common/MSDev98/Bin;%DOTNET%/Lib;%JAVA_HOME%/bin;%PATH%
-
-To run the sample please do:
-
-java invoker invoked.exe
-
-
---Dmitry Ryashchentsev
+
+To run the sample please do:
+
+java invoker invoked.exe
+
+
+--Dmitry Ryashchentsev
--- a/src/share/sample/vm/jvm-clr/invoked.cs	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/share/sample/vm/jvm-clr/invoked.cs	Mon Apr 14 11:34:15 2008 -0700
@@ -29,17 +29,17 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/*
-*/
-
-
+/*
+*/
+
+
 using System;
 
 class App{
 
     public static int Main(){
-
-        // Print Hello to show we are in CLR
+
+        // Print Hello to show we are in CLR
         Console.WriteLine("Hello from C#!!!");
         return 0;
     }
--- a/src/solaris/bin/java_md.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/bin/java_md.c	Mon Apr 14 11:34:15 2008 -0700
@@ -1299,12 +1299,6 @@
     AddOption(pid_prop_str, NULL);
 #endif
 }
-void
-SetJavaw()
-{
-    /* noop on UNIX */
-    return;
-}
 
 jboolean
 IsJavaw()
@@ -1312,3 +1306,9 @@
     /* noop on UNIX */
     return JNI_FALSE;
 }
+
+void
+InitLauncher(jboolean javaw)
+{
+    JLI_SetTraceLauncher();
+}
--- a/src/solaris/classes/java/io/FileDescriptor.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/java/io/FileDescriptor.java	Mon Apr 14 11:34:15 2008 -0700
@@ -152,11 +152,19 @@
                 public int get(FileDescriptor obj) {
                     return obj.fd;
                 }
+
+                public void setHandle(FileDescriptor obj, long handle) {
+                    throw new UnsupportedOperationException();
+                }
+
+                public long getHandle(FileDescriptor obj) {
+                    throw new UnsupportedOperationException();
+                }
             }
         );
     }
 
-    // pacakge private methods used by FIS,FOS and RAF
+    // package private methods used by FIS, FOS and RAF
 
     int incrementAndGetUseCount() {
         return useCount.incrementAndGet();
--- a/src/solaris/classes/java/lang/ProcessImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/java/lang/ProcessImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -26,7 +26,10 @@
 package java.lang;
 
 import java.io.IOException;
-import java.lang.Process;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.lang.ProcessBuilder.Redirect;
+import java.lang.ProcessBuilder.Redirect;
 
 /**
  * This class is for the exclusive use of ProcessBuilder.start() to
@@ -36,6 +39,9 @@
  * @since   1.5
  */
 final class ProcessImpl {
+    private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
+        = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
+
     private ProcessImpl() {}    // Not instantiable
 
     private static byte[] toCString(String s) {
@@ -54,6 +60,7 @@
     static Process start(String[] cmdarray,
                          java.util.Map<String,String> environment,
                          String dir,
+                         ProcessBuilder.Redirect[] redirects,
                          boolean redirectErrorStream)
         throws IOException
     {
@@ -78,11 +85,61 @@
         int[] envc = new int[1];
         byte[] envBlock = ProcessEnvironment.toEnvironmentBlock(environment, envc);
 
+        int[] std_fds;
+
+        FileInputStream  f0 = null;
+        FileOutputStream f1 = null;
+        FileOutputStream f2 = null;
+
+        try {
+            if (redirects == null) {
+                std_fds = new int[] { -1, -1, -1 };
+            } else {
+                std_fds = new int[3];
+
+                if (redirects[0] == Redirect.PIPE)
+                    std_fds[0] = -1;
+                else if (redirects[0] == Redirect.INHERIT)
+                    std_fds[0] = 0;
+                else {
+                    f0 = new FileInputStream(redirects[0].file());
+                    std_fds[0] = fdAccess.get(f0.getFD());
+                }
+
+                if (redirects[1] == Redirect.PIPE)
+                    std_fds[1] = -1;
+                else if (redirects[1] == Redirect.INHERIT)
+                    std_fds[1] = 1;
+                else {
+                    f1 = redirects[1].toFileOutputStream();
+                    std_fds[1] = fdAccess.get(f1.getFD());
+                }
+
+                if (redirects[2] == Redirect.PIPE)
+                    std_fds[2] = -1;
+                else if (redirects[2] == Redirect.INHERIT)
+                    std_fds[2] = 2;
+                else {
+                    f2 = redirects[2].toFileOutputStream();
+                    std_fds[2] = fdAccess.get(f2.getFD());
+                }
+            }
+
         return new UNIXProcess
             (toCString(cmdarray[0]),
              argBlock, args.length,
              envBlock, envc[0],
              toCString(dir),
+                 std_fds,
              redirectErrorStream);
+        } finally {
+            // In theory, close() can throw IOException
+            // (although it is rather unlikely to happen here)
+            try { if (f0 != null) f0.close(); }
+            finally {
+                try { if (f1 != null) f1.close(); }
+                finally { if (f2 != null) f2.close(); }
+            }
+        }
     }
 }
--- a/src/solaris/classes/java/lang/UNIXProcess.java.linux	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/java/lang/UNIXProcess.java.linux	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
-/* 
- * Copyright 1995-2006 Sun Microsystems, Inc.  All Rights Reserved.
+/*
+ * Copyright 1995-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,9 +34,9 @@
  */
 
 final class UNIXProcess extends Process {
-    private FileDescriptor stdin_fd;
-    private FileDescriptor stdout_fd;
-    private FileDescriptor stderr_fd;
+    private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
+        = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
+
     private int pid;
     private int exitcode;
     private boolean hasExited;
@@ -48,15 +48,26 @@
     /* this is for the reaping thread */
     private native int waitForProcessExit(int pid);
 
+    /**
+     * Create a process using fork(2) and exec(2).
+     *
+     * @param std_fds array of file descriptors.  Indexes 0, 1, and
+     *        2 correspond to standard input, standard output and
+     *        standard error, respectively.  On input, a value of -1
+     *        means to create a pipe to connect child and parent
+     *        processes.  On output, a value which is not -1 is the
+     *        parent pipe fd corresponding to the pipe which has
+     *        been created.  An element of this array is -1 on input
+     *        if and only if it is <em>not</em> -1 on output.
+     * @return the pid of the subprocess
+     */
     private native int forkAndExec(byte[] prog,
-				   byte[] argBlock, int argc,
-				   byte[] envBlock, int envc,
-				   byte[] dir,
-				   boolean redirectErrorStream,
-				   FileDescriptor stdin_fd,
-				   FileDescriptor stdout_fd,
-				   FileDescriptor stderr_fd)
-	throws IOException;
+                                   byte[] argBlock, int argc,
+                                   byte[] envBlock, int envc,
+                                   byte[] dir,
+                                   int[] std_fds,
+                                   boolean redirectErrorStream)
+        throws IOException;
 
     /* In the process constructor we wait on this gate until the process    */
     /* has been created. Then we return from the constructor.               */
@@ -97,67 +108,82 @@
     }
 
     UNIXProcess(final byte[] prog,
-		final byte[] argBlock, final int argc,
-		final byte[] envBlock, final int envc,
-		final byte[] dir,
-		final boolean redirectErrorStream)
+                final byte[] argBlock, final int argc,
+                final byte[] envBlock, final int envc,
+                final byte[] dir,
+                final int[] std_fds,
+                final boolean redirectErrorStream)
     throws IOException {
-	stdin_fd  = new FileDescriptor();
-	stdout_fd = new FileDescriptor();
-	stderr_fd = new FileDescriptor();
 
         final Gate gate = new Gate();
-	/*
-	 * For each subprocess forked a corresponding reaper thread
-	 * is started.  That thread is the only thread which waits
-	 * for the subprocess to terminate and it doesn't hold any
-	 * locks while doing so.  This design allows waitFor() and
-	 * exitStatus() to be safely executed in parallel (and they
-	 * need no native code).
-	 */
+        /*
+         * For each subprocess forked a corresponding reaper thread
+         * is started.  That thread is the only thread which waits
+         * for the subprocess to terminate and it doesn't hold any
+         * locks while doing so.  This design allows waitFor() and
+         * exitStatus() to be safely executed in parallel (and they
+         * need no native code).
+         */
 
-	java.security.AccessController.doPrivileged(
-			    new java.security.PrivilegedAction() {
-	    public Object run() {
-		Thread t = new Thread("process reaper") {
-		    public void run() {
+        java.security.AccessController.doPrivileged(
+        new java.security.PrivilegedAction<Void>() {
+        public Void run() {
+            Thread t = new Thread("process reaper") {
+                    public void run() {
                         try {
                             pid = forkAndExec(prog,
-					      argBlock, argc,
-					      envBlock, envc,
-					      dir,
-					      redirectErrorStream,
-					      stdin_fd, stdout_fd, stderr_fd);
+                                              argBlock, argc,
+                                              envBlock, envc,
+                                              dir,
+                                              std_fds,
+                                              redirectErrorStream);
                         } catch (IOException e) {
                             gate.setException(e); /*remember to rethrow later*/
                             gate.exit();
                             return;
                         }
                         java.security.AccessController.doPrivileged(
-                        new java.security.PrivilegedAction() {
-                            public Object run() {
-                            stdin_stream = new BufferedOutputStream(new
-                                                    FileOutputStream(stdin_fd));
-                            stdout_stream = new BufferedInputStream(new
-                                                    FileInputStream(stdout_fd));
-                            stderr_stream = new FileInputStream(stderr_fd);
-                            return null;
+                    new java.security.PrivilegedAction<Void>() {
+                    public Void run() {
+                        if (std_fds[0] == -1)
+                            stdin_stream = new ProcessBuilder.NullOutputStream();
+                        else {
+                            FileDescriptor stdin_fd = new FileDescriptor();
+                            fdAccess.set(stdin_fd, std_fds[0]);
+                            stdin_stream = new BufferedOutputStream(
+                                new FileOutputStream(stdin_fd));
+                        }
+
+                        if (std_fds[1] == -1)
+                            stdout_stream = new ProcessBuilder.NullInputStream();
+                        else {
+                            FileDescriptor stdout_fd = new FileDescriptor();
+                            fdAccess.set(stdout_fd, std_fds[1]);
+                            stdout_stream = new BufferedInputStream(
+                                new FileInputStream(stdout_fd));
                         }
-                        });
+
+                        if (std_fds[2] == -1)
+                            stderr_stream = new ProcessBuilder.NullInputStream();
+                        else {
+                            FileDescriptor stderr_fd = new FileDescriptor();
+                            fdAccess.set(stderr_fd, std_fds[2]);
+                            stderr_stream = new FileInputStream(stderr_fd);
+                        }
+
+                        return null; }});
                         gate.exit(); /* exit from constructor */
-			int res = waitForProcessExit(pid);
-			synchronized (UNIXProcess.this) {
-			    hasExited = true;
-			    exitcode = res;
-			    UNIXProcess.this.notifyAll();
-			}
-		    }
-		};
+                        int res = waitForProcessExit(pid);
+                        synchronized (UNIXProcess.this) {
+                            hasExited = true;
+                            exitcode = res;
+                            UNIXProcess.this.notifyAll();
+                        }
+                    }
+                };
                 t.setDaemon(true);
                 t.start();
-		return null;
-	    }
-	});
+                return null; }});
         gate.waitForExit();
         IOException e = gate.getException();
         if (e != null)
@@ -165,43 +191,43 @@
     }
 
     public OutputStream getOutputStream() {
-	return stdin_stream;
+        return stdin_stream;
     }
 
     public InputStream getInputStream() {
-	return stdout_stream;
+        return stdout_stream;
     }
 
     public InputStream getErrorStream() {
-	return stderr_stream;
+        return stderr_stream;
     }
 
     public synchronized int waitFor() throws InterruptedException {
         while (!hasExited) {
-	    wait();
-	}
-	return exitcode;
+            wait();
+        }
+        return exitcode;
     }
 
     public synchronized int exitValue() {
-	if (!hasExited) {
-	    throw new IllegalThreadStateException("process hasn't exited");
-	}
-	return exitcode;
+        if (!hasExited) {
+            throw new IllegalThreadStateException("process hasn't exited");
+        }
+        return exitcode;
     }
 
     private static native void destroyProcess(int pid);
     public void destroy() {
-	// There is a risk that pid will be recycled, causing us to
-	// kill the wrong process!  So we only terminate processes
-	// that appear to still be running.  Even with this check,
-	// there is an unavoidable race condition here, but the window
-	// is very small, and OSes try hard to not recycle pids too
-	// soon, so this is quite safe.
-	synchronized (this) {
-	    if (!hasExited)
-		destroyProcess(pid);
-	}
+        // There is a risk that pid will be recycled, causing us to
+        // kill the wrong process!  So we only terminate processes
+        // that appear to still be running.  Even with this check,
+        // there is an unavoidable race condition here, but the window
+        // is very small, and OSes try hard to not recycle pids too
+        // soon, so this is quite safe.
+        synchronized (this) {
+            if (!hasExited)
+                destroyProcess(pid);
+        }
         try {
             stdin_stream.close();
             stdout_stream.close();
@@ -215,6 +241,6 @@
     private static native void initIDs();
 
     static {
-	initIDs();
+        initIDs();
     }
 }
--- a/src/solaris/classes/java/lang/UNIXProcess.java.solaris	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/java/lang/UNIXProcess.java.solaris	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
-/* 
- * Copyright 1995-2006 Sun Microsystems, Inc.  All Rights Reserved.
+/*
+ * Copyright 1995-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,129 +33,155 @@
  */
 
 final class UNIXProcess extends Process {
-    private FileDescriptor stdin_fd;
-    private FileDescriptor stdout_fd;
-    private FileDescriptor stderr_fd;
-    private int pid;
+    private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
+        = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
+
+    private final int pid;
     private int exitcode;
     private boolean hasExited;
 
     private OutputStream stdin_stream;
-    private BufferedInputStream stdout_stream;
+    private InputStream stdout_stream;
     private DeferredCloseInputStream stdout_inner_stream;
-    private DeferredCloseInputStream stderr_stream;
+    private InputStream stderr_stream;
 
     /* this is for the reaping thread */
     private native int waitForProcessExit(int pid);
 
+    /**
+     * Create a process using fork(2) and exec(2).
+     *
+     * @param std_fds array of file descriptors.  Indexes 0, 1, and
+     *        2 correspond to standard input, standard output and
+     *        standard error, respectively.  On input, a value of -1
+     *        means to create a pipe to connect child and parent
+     *        processes.  On output, a value which is not -1 is the
+     *        parent pipe fd corresponding to the pipe which has
+     *        been created.  An element of this array is -1 on input
+     *        if and only if it is <em>not</em> -1 on output.
+     * @return the pid of the subprocess
+     */
     private native int forkAndExec(byte[] prog,
-				   byte[] argBlock, int argc,
-				   byte[] envBlock, int envc,
-				   byte[] dir,
-				   boolean redirectErrorStream,
-				   FileDescriptor stdin_fd,
-				   FileDescriptor stdout_fd,
-				   FileDescriptor stderr_fd)
-	throws IOException;
+                                   byte[] argBlock, int argc,
+                                   byte[] envBlock, int envc,
+                                   byte[] dir,
+                                   int[] std_fds,
+                                   boolean redirectErrorStream)
+        throws IOException;
 
     UNIXProcess(final byte[] prog,
-		final byte[] argBlock, int argc,
-		final byte[] envBlock, int envc,
-		final byte[] dir,
-		final boolean redirectErrorStream)
+                final byte[] argBlock, int argc,
+                final byte[] envBlock, int envc,
+                final byte[] dir,
+                final int[] std_fds,
+                final boolean redirectErrorStream)
     throws IOException {
-	stdin_fd  = new FileDescriptor();
-	stdout_fd = new FileDescriptor();
-	stderr_fd = new FileDescriptor();
+        pid = forkAndExec(prog,
+                          argBlock, argc,
+                          envBlock, envc,
+                          dir,
+                          std_fds,
+                          redirectErrorStream);
 
-	pid = forkAndExec(prog,
-			  argBlock, argc,
-			  envBlock, envc,
-			  dir,
-			  redirectErrorStream,
-			  stdin_fd, stdout_fd, stderr_fd);
+        java.security.AccessController.doPrivileged(
+        new java.security.PrivilegedAction<Void>() { public Void run() {
+            if (std_fds[0] == -1)
+                stdin_stream = new ProcessBuilder.NullOutputStream();
+            else {
+                FileDescriptor stdin_fd = new FileDescriptor();
+                fdAccess.set(stdin_fd, std_fds[0]);
+                stdin_stream = new BufferedOutputStream(
+                    new FileOutputStream(stdin_fd));
+            }
 
-	java.security.AccessController.doPrivileged(
-				    new java.security.PrivilegedAction() {
-	    public Object run() {
-	        stdin_stream
-		    = new BufferedOutputStream(new FileOutputStream(stdin_fd));
-		stdout_inner_stream = new DeferredCloseInputStream(stdout_fd);
-	        stdout_stream = new BufferedInputStream(stdout_inner_stream);
-	        stderr_stream = new DeferredCloseInputStream(stderr_fd);
-		return null;
-	    }
-	});
+            if (std_fds[1] == -1)
+                stdout_stream = new ProcessBuilder.NullInputStream();
+            else {
+                FileDescriptor stdout_fd = new FileDescriptor();
+                fdAccess.set(stdout_fd, std_fds[1]);
+                stdout_inner_stream = new DeferredCloseInputStream(stdout_fd);
+                stdout_stream = new BufferedInputStream(stdout_inner_stream);
+            }
 
-	/*
-	 * For each subprocess forked a corresponding reaper thread
-	 * is started.  That thread is the only thread which waits
-	 * for the subprocess to terminate and it doesn't hold any
-	 * locks while doing so.  This design allows waitFor() and
-	 * exitStatus() to be safely executed in parallel (and they
-	 * need no native code).
-	 */
+            if (std_fds[2] == -1)
+                stderr_stream = new ProcessBuilder.NullInputStream();
+            else {
+                FileDescriptor stderr_fd = new FileDescriptor();
+                fdAccess.set(stderr_fd, std_fds[2]);
+                stderr_stream = new DeferredCloseInputStream(stderr_fd);
+            }
+
+            return null; }});
 
-	java.security.AccessController.doPrivileged(
-			    new java.security.PrivilegedAction() {
-	    public Object run() {
-		Thread t = new Thread("process reaper") {
-		    public void run() {
-			int res = waitForProcessExit(pid);
-			synchronized (UNIXProcess.this) {
-			    hasExited = true;
-			    exitcode = res;
-			    UNIXProcess.this.notifyAll();
-			}
-		    }
-		};
-		t.setDaemon(true);
-		t.start();
-		return null;
-	    }
-	});
+        /*
+         * For each subprocess forked a corresponding reaper thread
+         * is started.  That thread is the only thread which waits
+         * for the subprocess to terminate and it doesn't hold any
+         * locks while doing so.  This design allows waitFor() and
+         * exitStatus() to be safely executed in parallel (and they
+         * need no native code).
+         */
+
+        java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Void>() { public Void run() {
+                Thread t = new Thread("process reaper") {
+                    public void run() {
+                        int res = waitForProcessExit(pid);
+                        synchronized (UNIXProcess.this) {
+                            hasExited = true;
+                            exitcode = res;
+                            UNIXProcess.this.notifyAll();
+                        }
+                    }
+                };
+                t.setDaemon(true);
+                t.start();
+                return null; }});
     }
 
     public OutputStream getOutputStream() {
-	return stdin_stream;
+        return stdin_stream;
     }
 
     public InputStream getInputStream() {
-	return stdout_stream;
+        return stdout_stream;
     }
 
     public InputStream getErrorStream() {
-	return stderr_stream;
+        return stderr_stream;
     }
 
     public synchronized int waitFor() throws InterruptedException {
         while (!hasExited) {
-	    wait();
-	}
-	return exitcode;
+            wait();
+        }
+        return exitcode;
     }
 
     public synchronized int exitValue() {
-	if (!hasExited) {
-	    throw new IllegalThreadStateException("process hasn't exited");
-	}
-	return exitcode;
+        if (!hasExited) {
+            throw new IllegalThreadStateException("process hasn't exited");
+        }
+        return exitcode;
     }
 
     private static native void destroyProcess(int pid);
     public synchronized void destroy() {
-	// There is a risk that pid will be recycled, causing us to
-	// kill the wrong process!  So we only terminate processes
-	// that appear to still be running.  Even with this check,
-	// there is an unavoidable race condition here, but the window
-	// is very small, and OSes try hard to not recycle pids too
-	// soon, so this is quite safe.
-	if (!hasExited)
-	    destroyProcess(pid);
-	try {
+        // There is a risk that pid will be recycled, causing us to
+        // kill the wrong process!  So we only terminate processes
+        // that appear to still be running.  Even with this check,
+        // there is an unavoidable race condition here, but the window
+        // is very small, and OSes try hard to not recycle pids too
+        // soon, so this is quite safe.
+        if (!hasExited)
+            destroyProcess(pid);
+        try {
             stdin_stream.close();
-	    stdout_inner_stream.closeDeferred(stdout_stream);
-	    stderr_stream.closeDeferred(stderr_stream);
+            if (stdout_inner_stream != null)
+                stdout_inner_stream.closeDeferred(stdout_stream);
+            if (stderr_stream instanceof DeferredCloseInputStream)
+                ((DeferredCloseInputStream) stderr_stream)
+                    .closeDeferred(stderr_stream);
         } catch (IOException e) {
             // ignore
         }
@@ -172,99 +198,99 @@
     // (EOF) as they did before.
     //
     private static class DeferredCloseInputStream
-	extends FileInputStream
+        extends FileInputStream
     {
 
-	private DeferredCloseInputStream(FileDescriptor fd) {
-	    super(fd);
-	}
+        private DeferredCloseInputStream(FileDescriptor fd) {
+            super(fd);
+        }
 
-	private Object lock = new Object();	// For the following fields
-	private boolean closePending = false;
-	private int useCount = 0;
-	private InputStream streamToClose;
+        private Object lock = new Object();     // For the following fields
+        private boolean closePending = false;
+        private int useCount = 0;
+        private InputStream streamToClose;
 
-	private void raise() {
-	    synchronized (lock) {
-		useCount++;
-	    }
-	}
+        private void raise() {
+            synchronized (lock) {
+                useCount++;
+            }
+        }
 
-	private void lower() throws IOException {
-	    synchronized (lock) {
-		useCount--;
-		if (useCount == 0 && closePending) {
-		    streamToClose.close();
-		}
-	    }
-	}
+        private void lower() throws IOException {
+            synchronized (lock) {
+                useCount--;
+                if (useCount == 0 && closePending) {
+                    streamToClose.close();
+                }
+            }
+        }
 
-	// stc is the actual stream to be closed; it might be this object, or
-	// it might be an upstream object for which this object is downstream.
-	//
-	private void closeDeferred(InputStream stc) throws IOException {
-	    synchronized (lock) {
-		if (useCount == 0) {
-		    stc.close();
-		} else {
-		    closePending = true;
-		    streamToClose = stc;
-		}
-	    }
-	}
+        // stc is the actual stream to be closed; it might be this object, or
+        // it might be an upstream object for which this object is downstream.
+        //
+        private void closeDeferred(InputStream stc) throws IOException {
+            synchronized (lock) {
+                if (useCount == 0) {
+                    stc.close();
+                } else {
+                    closePending = true;
+                    streamToClose = stc;
+                }
+            }
+        }
 
-	public void close() throws IOException {
-	    synchronized (lock) {
-		useCount = 0;
-		closePending = false;
-	    }
-	    super.close();
-	}
+        public void close() throws IOException {
+            synchronized (lock) {
+                useCount = 0;
+                closePending = false;
+            }
+            super.close();
+        }
 
-	public int read() throws IOException {
-	    raise();
-	    try {
-		return super.read();
-	    } finally {
-		lower();
-	    }
-	}
+        public int read() throws IOException {
+            raise();
+            try {
+                return super.read();
+            } finally {
+                lower();
+            }
+        }
 
-	public int read(byte[] b) throws IOException {
-	    raise();
-	    try {
-		return super.read(b);
-	    } finally {
-		lower();
-	    }
-	}
+        public int read(byte[] b) throws IOException {
+            raise();
+            try {
+                return super.read(b);
+            } finally {
+                lower();
+            }
+        }
 
-	public int read(byte[] b, int off, int len) throws IOException {
-	    raise();
-	    try {
-		return super.read(b, off, len);
-	    } finally {
-		lower();
-	    }
-	}
+        public int read(byte[] b, int off, int len) throws IOException {
+            raise();
+            try {
+                return super.read(b, off, len);
+            } finally {
+                lower();
+            }
+        }
 
-	public long skip(long n) throws IOException {
-	    raise();
-	    try {
-		return super.skip(n);
-	    } finally {
-		lower();
-	    }
-	}
+        public long skip(long n) throws IOException {
+            raise();
+            try {
+                return super.skip(n);
+            } finally {
+                lower();
+            }
+        }
 
-	public int available() throws IOException {
-	    raise();
-	    try {
-		return super.available();
-	    } finally {
-		lower();
-	    }
-	}
+        public int available() throws IOException {
+            raise();
+            try {
+                return super.available();
+            } finally {
+                lower();
+            }
+        }
 
     }
 
@@ -272,6 +298,6 @@
     private static native void initIDs();
 
     static {
-	initIDs();
+        initIDs();
     }
 }
--- a/src/solaris/classes/java/net/PlainSocketImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/java/net/PlainSocketImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -76,9 +76,6 @@
 
     native int socketGetOption(int opt, Object iaContainerObj) throws SocketException;
 
-    native int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd)
-        throws SocketException;
-
     native void socketSendUrgentData(int data) throws IOException;
 
 }
--- a/src/solaris/classes/java/util/prefs/FileSystemPreferences.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/java/util/prefs/FileSystemPreferences.java	Mon Apr 14 11:34:15 2008 -0700
@@ -52,14 +52,10 @@
      * Sync interval in seconds.
      */
     private static final int SYNC_INTERVAL = Math.max(1,
-        Integer.parseInt((String)
-            AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
-                    return System.getProperty("java.util.prefs.syncInterval",
-                                              "30");
-                }
-        })));
-
+        Integer.parseInt(
+            AccessController.doPrivileged(
+                new sun.security.action.GetPropertyAction(
+                    "java.util.prefs.syncInterval", "30"))));
 
     /**
      * Returns logger for error messages. Backing store exceptions are logged at
@@ -103,8 +99,8 @@
     }
 
     private static void setupUserRoot() {
-        AccessController.doPrivileged(new PrivilegedAction() {
-            public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
                 userRootDir =
                       new File(System.getProperty("java.util.prefs.userRoot",
                       System.getProperty("user.home")), ".java/.userPrefs");
@@ -164,9 +160,9 @@
     }
 
     private static void setupSystemRoot() {
-        AccessController.doPrivileged( new PrivilegedAction() {
-            public Object run() {
-                String systemPrefsDirName = (String)
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                String systemPrefsDirName =
                   System.getProperty("java.util.prefs.systemRoot","/etc/.java");
                 systemRootDir =
                      new File(systemPrefsDirName, ".systemPrefs");
@@ -322,7 +318,7 @@
      * corresponding disk file (prefsFile) by the sync operation.  The initial
      * value is read *without* acquiring the file-lock.
      */
-    private Map prefsCache = null;
+    private Map<String, String> prefsCache = null;
 
     /**
      * The last modification time of the file backing this node at the time
@@ -358,7 +354,7 @@
      * log against that map.  The resulting map is then written back
      * to the disk.
      */
-    final List changeLog = new ArrayList();
+    final List<Change> changeLog = new ArrayList<Change>();
 
     /**
      * Represents a change to a preference.
@@ -424,7 +420,7 @@
      */
     private void replayChanges() {
         for (int i = 0, n = changeLog.size(); i<n; i++)
-            ((Change)changeLog.get(i)).replay();
+            changeLog.get(i).replay();
     }
 
     private static Timer syncTimer = new Timer(true); // Daemon Thread
@@ -438,8 +434,8 @@
         }, SYNC_INTERVAL*1000, SYNC_INTERVAL*1000);
 
         // Add shutdown hook to flush cached prefs on normal termination
-        AccessController.doPrivileged(new PrivilegedAction() {
-            public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
                 Runtime.getRuntime().addShutdownHook(new Thread() {
                     public void run() {
                         syncTimer.cancel();
@@ -503,15 +499,15 @@
         dir  = new File(parent.dir, dirName(name));
         prefsFile = new File(dir, "prefs.xml");
         tmpFile  = new File(dir, "prefs.tmp");
-        AccessController.doPrivileged( new PrivilegedAction() {
-            public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
                 newNode = !dir.exists();
                 return null;
             }
         });
         if (newNode) {
             // These 2 things guarantee node will get wrtten at next flush/sync
-            prefsCache = new TreeMap();
+            prefsCache = new TreeMap<String, String>();
             nodeCreate = new NodeCreate();
             changeLog.add(nodeCreate);
         }
@@ -529,7 +525,7 @@
 
     protected String getSpi(String key) {
         initCacheIfNecessary();
-        return (String) prefsCache.get(key);
+        return prefsCache.get(key);
     }
 
     protected void removeSpi(String key) {
@@ -554,7 +550,7 @@
             loadCache();
         } catch(Exception e) {
             // assert lastSyncTime == 0;
-            prefsCache = new TreeMap();
+            prefsCache = new TreeMap<String, String>();
         }
     }
 
@@ -568,9 +564,10 @@
      */
     private void loadCache() throws BackingStoreException {
         try {
-            AccessController.doPrivileged( new PrivilegedExceptionAction() {
-                public Object run() throws BackingStoreException {
-                    Map m = new TreeMap();
+            AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Void>() {
+                public Void run() throws BackingStoreException {
+                    Map<String, String> m = new TreeMap<String, String>();
                     long newLastSyncTime = 0;
                     try {
                         newLastSyncTime = prefsFile.lastModified();
@@ -584,7 +581,7 @@
                             prefsFile.renameTo( new File(
                                                     prefsFile.getParentFile(),
                                                   "IncorrectFormatPrefs.xml"));
-                            m = new TreeMap();
+                            m = new TreeMap<String, String>();
                         } else if (e instanceof FileNotFoundException) {
                         getLogger().warning("Prefs file removed in background "
                                            + prefsFile.getPath());
@@ -614,8 +611,9 @@
      */
     private void writeBackCache() throws BackingStoreException {
         try {
-            AccessController.doPrivileged( new PrivilegedExceptionAction() {
-                public Object run() throws BackingStoreException {
+            AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Void>() {
+                public Void run() throws BackingStoreException {
                     try {
                         if (!dir.exists() && !dir.mkdirs())
                             throw new BackingStoreException(dir +
@@ -641,15 +639,14 @@
 
     protected String[] keysSpi() {
         initCacheIfNecessary();
-        return (String[])
-            prefsCache.keySet().toArray(new String[prefsCache.size()]);
+        return prefsCache.keySet().toArray(new String[prefsCache.size()]);
     }
 
     protected String[] childrenNamesSpi() {
-        return (String[])
-            AccessController.doPrivileged( new PrivilegedAction() {
-                public Object run() {
-                    List result = new ArrayList();
+        return AccessController.doPrivileged(
+            new PrivilegedAction<String[]>() {
+                public String[] run() {
+                    List<String> result = new ArrayList<String>();
                     File[] dirContents = dir.listFiles();
                     if (dirContents != null) {
                         for (int i = 0; i < dirContents.length; i++)
@@ -685,8 +682,9 @@
      */
     protected void removeNodeSpi() throws BackingStoreException {
         try {
-            AccessController.doPrivileged( new PrivilegedExceptionAction() {
-                public Object run() throws BackingStoreException {
+            AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Void>() {
+                public Void run() throws BackingStoreException {
                     if (changeLog.contains(nodeCreate)) {
                         changeLog.remove(nodeCreate);
                         nodeCreate = null;
@@ -731,8 +729,9 @@
            if (!lockFile(shared))
                throw(new BackingStoreException("Couldn't get file lock."));
            final Long newModTime =
-                (Long) AccessController.doPrivileged( new PrivilegedAction() {
-               public Object run() {
+                AccessController.doPrivileged(
+                    new PrivilegedAction<Long>() {
+               public Long run() {
                    long nmt;
                    if (isUserNode()) {
                        nmt = userRootModFile.lastModified();
@@ -746,8 +745,8 @@
            });
            try {
                super.sync();
-               AccessController.doPrivileged( new PrivilegedAction() {
-                   public Object run() {
+               AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                   public Void run() {
                    if (isUserNode()) {
                        userRootModTime = newModTime.longValue() + 1000;
                        userRootModFile.setLastModified(userRootModTime);
@@ -766,8 +765,9 @@
 
     protected void syncSpi() throws BackingStoreException {
         try {
-            AccessController.doPrivileged( new PrivilegedExceptionAction() {
-                public Object run() throws BackingStoreException {
+            AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Void>() {
+                public Void run() throws BackingStoreException {
                     syncSpiPrivileged();
                     return null;
                 }
@@ -794,7 +794,7 @@
         } else if (lastSyncTime != 0 && !dir.exists()) {
             // This node was removed in the background.  Playback any changes
             // against a virgin (empty) Map.
-            prefsCache = new TreeMap();
+            prefsCache = new TreeMap<String, String>();
             replayChanges();
         }
         if (!changeLog.isEmpty()) {
--- a/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,8 @@
  * @since 1.5
  */
 class MotifDnDConstants {
+    // utility class can not be instantiated
+    private MotifDnDConstants() {}
     // Note that offsets in all native structures below do not depend on the
     // architecture.
     private static final Unsafe unsafe = XlibWrapper.unsafe;
@@ -55,8 +57,7 @@
         XAtom.get("XmTRANSFER_SUCCESS");
     static final XAtom XA_XmTRANSFER_FAILURE =
         XAtom.get("XmTRANSFER_FAILURE");
-    static final XSelection MotifDnDSelection =
-        new XSelection(XA_MOTIF_ATOM_0, null);
+    static final XSelection MotifDnDSelection = new XSelection(XA_MOTIF_ATOM_0);
 
     public static final byte MOTIF_DND_PROTOCOL_VERSION = 0;
 
@@ -231,6 +232,9 @@
     }
 
     public static final class Swapper {
+        // utility class can not be instantiated
+        private Swapper() {}
+
         public static short swap(short s) {
             return (short)(((s & 0xFF00) >>> 8) | ((s & 0xFF) << 8));
         }
--- a/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -933,7 +933,7 @@
 
         XSelection selection = XSelection.getSelection(selectionAtom);
         if (selection == null) {
-            selection = new XSelection(selectionAtom, null);
+            selection = new XSelection(selectionAtom);
         }
 
         return selection.getData(format, time_stamp);
@@ -1056,7 +1056,7 @@
         // the original structure can be freed before this
         // SunDropTargetEvent is dispatched.
         if (xclient != null) {
-            int size = new XClientMessageEvent(nativeCtxt).getSize();
+            int size = XClientMessageEvent.getSize();
 
             nativeCtxt = unsafe.allocateMemory(size + 4 * Native.getLongSize());
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/solaris/classes/sun/awt/X11/OwnershipListener.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.awt.X11;
+
+interface OwnershipListener {
+    public void ownershipChanged(final boolean isOwner);
+}
--- a/src/solaris/classes/sun/awt/X11/XAtom.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XAtom.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,7 @@
 import sun.misc.Unsafe;
 import java.util.HashMap;
 
-public class XAtom {
+public final class XAtom {
 
     // Order of lock:  XAWTLock -> XAtom.class
 
@@ -175,7 +175,7 @@
     public static XAtom get(String name) {
         XAtom xatom = lookup(name);
         if (xatom == null) {
-            xatom = new XAtom(name);
+            xatom = new XAtom(XToolkit.getDisplay(), name);
         }
         return xatom;
     }
@@ -232,10 +232,6 @@
         this(display, name, true);
     }
 
-    private XAtom(String name) {
-        this(XToolkit.getDisplay(), name, true);
-    }
-
     public XAtom(String name, boolean autoIntern) {
         this(XToolkit.getDisplay(), name, autoIntern);
     }
@@ -262,7 +258,7 @@
      * @since 1.5
      */
 
-    public XAtom(long display, String name, boolean autoIntern) {
+    private XAtom(long display, String name, boolean autoIntern) {
         this.name = name;
         this.display = display;
         if (autoIntern) {
@@ -651,28 +647,6 @@
         }
     }
 
-    /**
-     * Initializes atom with name and display values
-     */
-    public void setValues(long display, String name, boolean autoIntern) {
-        this.display = display;
-        this.name = name;
-        if (autoIntern) {
-            XToolkit.awtLock();
-            try {
-                atom = XlibWrapper.InternAtom(display,name,0);
-            } finally {
-                XToolkit.awtUnlock();
-            }
-        }
-        register();
-    }
-
-    public void setValues(long display, long atom) {
-        this.display = display;
-        this.atom = atom;
-        register();
-    }
     public void setValues(long display, String name, long atom) {
         this.display = display;
         this.atom = atom;
--- a/src/solaris/classes/sun/awt/X11/XClipboard.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XClipboard.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,30 +26,32 @@
 package sun.awt.X11;
 
 import java.awt.datatransfer.Transferable;
-
 import java.util.SortedMap;
-import java.util.Set;
-import java.util.Iterator;
-import java.util.HashSet;
-
 import java.io.IOException;
-
 import java.security.AccessController;
-
+import java.util.HashMap;
+import java.util.Map;
+import sun.awt.UNIXToolkit;
 import sun.awt.datatransfer.DataTransferer;
 import sun.awt.datatransfer.SunClipboard;
 import sun.awt.datatransfer.ClipboardTransferable;
-
 import sun.security.action.GetIntegerAction;
 
-
-
 /**
  * A class which interfaces with the X11 selection service in order to support
  * data transfer via Clipboard operations.
  */
-public class XClipboard extends SunClipboard implements Runnable {
+public final class XClipboard extends SunClipboard implements OwnershipListener
+{
     private final XSelection selection;
+    // Time of calling XConvertSelection().
+    private long convertSelectionTime;
+    // The flag used not to call XConvertSelection() if the previous SelectionNotify
+    // has not been processed by checkChange().
+    private volatile boolean isSelectionNotifyProcessed;
+    // The property in which the owner should place requested targets
+    // when tracking changes of available data flavors (practically targets).
+    private volatile XAtom targetsPropertyAtom;
 
     private static final Object classLock = new Object();
 
@@ -57,31 +59,33 @@
 
     private static int pollInterval;
 
-    private static Set listenedClipboards;
-
+    private static Map<Long, XClipboard> targetsAtom2Clipboard;
 
     /**
      * Creates a system clipboard object.
      */
     public XClipboard(String name, String selectionName) {
         super(name);
-        selection = new XSelection(XAtom.get(selectionName), this);
+        selection = new XSelection(XAtom.get(selectionName));
+        selection.registerOwershipListener(this);
     }
 
-    /**
-     * The action to be run when we lose ownership
+    /*
      * NOTE: This method may be called by privileged threads.
      *       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
      */
-    public void run() {
-        lostOwnershipImpl();
+    public void ownershipChanged(final boolean isOwner) {
+        if (isOwner) {
+            checkChangeHere(contents);
+        } else {
+            lostOwnershipImpl();
+        }
     }
 
     protected synchronized void setContentsNative(Transferable contents) {
         SortedMap formatMap = DataTransferer.getInstance().getFormatsForTransferable
                 (contents, DataTransferer.adaptFlavorMap(flavorMap));
-        long[] formats =
-            DataTransferer.getInstance().keysToLongArray(formatMap);
+        long[] formats = DataTransferer.keysToLongArray(formatMap);
 
         if (!selection.setOwner(contents, formatMap, formats,
                                 XToolkit.getCurrentServerTime())) {
@@ -94,6 +98,7 @@
         return selection.getSelectionAtom().getAtom();
     }
 
+    @Override
     public synchronized Transferable getContents(Object requestor) {
         if (contents != null) {
             return contents;
@@ -115,62 +120,163 @@
         return selection.getData(format, XToolkit.getCurrentServerTime());
     }
 
-    // Called on the toolkit thread under awtLock.
-    public void checkChange(long[] formats) {
-        if (!selection.isOwner()) {
-            super.checkChange(formats);
-        }
-    }
-
-    void checkChangeHere(Transferable contents) {
+    private void checkChangeHere(Transferable contents) {
         if (areFlavorListenersRegistered()) {
-            super.checkChange(DataTransferer.getInstance().
+            checkChange(DataTransferer.getInstance().
                         getFormatsForTransferableAsArray(contents, flavorMap));
         }
     }
 
+    private static int getPollInterval() {
+        synchronized (XClipboard.classLock) {
+            if (pollInterval <= 0) {
+                pollInterval = AccessController.doPrivileged(
+                        new GetIntegerAction("awt.datatransfer.clipboard.poll.interval",
+                                             defaultPollInterval));
+                if (pollInterval <= 0) {
+                    pollInterval = defaultPollInterval;
+                }
+            }
+            return pollInterval;
+        }
+    }
+
+    private XAtom getTargetsPropertyAtom() {
+        if (null == targetsPropertyAtom) {
+            targetsPropertyAtom =
+                    XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selection.getSelectionAtom().getName());
+        }
+        return targetsPropertyAtom;
+    }
+
     protected void registerClipboardViewerChecked() {
-        if (pollInterval <= 0) {
-            pollInterval = ((Integer)AccessController.doPrivileged(
-                    new GetIntegerAction("awt.datatransfer.clipboard.poll.interval",
-                                         defaultPollInterval))).intValue();
-            if (pollInterval <= 0) {
-                pollInterval = defaultPollInterval;
+        // for XConvertSelection() to be called for the first time in getTargetsDelayed()
+        isSelectionNotifyProcessed = true;
+
+        boolean mustSchedule = false;
+        synchronized (XClipboard.classLock) {
+            if (targetsAtom2Clipboard == null) {
+                targetsAtom2Clipboard = new HashMap<Long, XClipboard>(2);
+            }
+            mustSchedule = targetsAtom2Clipboard.isEmpty();
+            targetsAtom2Clipboard.put(getTargetsPropertyAtom().getAtom(), this);
+            if (mustSchedule) {
+                XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(),
+                                            new SelectionNotifyHandler());
             }
         }
-        selection.initializeSelectionForTrackingChanges();
-        boolean mustSchedule = false;
-        synchronized (XClipboard.classLock) {
-            if (listenedClipboards == null) {
-                listenedClipboards = new HashSet(2);
-            }
-            mustSchedule = listenedClipboards.isEmpty();
-            listenedClipboards.add(this);
-        }
         if (mustSchedule) {
-            XToolkit.schedule(new CheckChangeTimerTask(), pollInterval);
+            XToolkit.schedule(new CheckChangeTimerTask(), XClipboard.getPollInterval());
         }
     }
 
     private static class CheckChangeTimerTask implements Runnable {
         public void run() {
-            for (Iterator iter = listenedClipboards.iterator(); iter.hasNext();) {
-                XClipboard clpbrd = (XClipboard)iter.next();
-                clpbrd.selection.getTargetsDelayed();
+            for (XClipboard clpbrd : targetsAtom2Clipboard.values()) {
+                clpbrd.getTargetsDelayed();
             }
             synchronized (XClipboard.classLock) {
-                if (listenedClipboards != null && !listenedClipboards.isEmpty()) {
-                    XToolkit.schedule(this, pollInterval);
+                if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
+                    XToolkit.schedule(this, XClipboard.getPollInterval());
+                }
+            }
+        }
+    }
+
+    private static class SelectionNotifyHandler implements XEventDispatcher {
+        public void dispatchEvent(XEvent ev) {
+            if (ev.get_type() == XlibWrapper.SelectionNotify) {
+                final XSelectionEvent xse = ev.get_xselection();
+                XClipboard clipboard = null;
+                synchronized (XClipboard.classLock) {
+                    if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
+                        XToolkit.removeEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), this);
+                        return;
+                    }
+                    final long propertyAtom = xse.get_property();
+                    clipboard = targetsAtom2Clipboard.get(propertyAtom);
+                }
+                if (null != clipboard) {
+                    clipboard.checkChange(xse);
                 }
             }
         }
     }
 
     protected void unregisterClipboardViewerChecked() {
-        selection.deinitializeSelectionForTrackingChanges();
+        isSelectionNotifyProcessed = false;
         synchronized (XClipboard.classLock) {
-            listenedClipboards.remove(this);
+            targetsAtom2Clipboard.remove(getTargetsPropertyAtom().getAtom());
+        }
+    }
+
+    // checkChange() will be called on SelectionNotify
+    private void getTargetsDelayed() {
+        XToolkit.awtLock();
+        try {
+            long curTime = System.currentTimeMillis();
+            if (isSelectionNotifyProcessed || curTime >= (convertSelectionTime + UNIXToolkit.getDatatransferTimeout()))
+            {
+                convertSelectionTime = curTime;
+                XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
+                                              selection.getSelectionAtom().getAtom(),
+                                              XDataTransferer.TARGETS_ATOM.getAtom(),
+                                              getTargetsPropertyAtom().getAtom(),
+                                              XWindow.getXAWTRootWindow().getWindow(),
+                                              XlibWrapper.CurrentTime);
+                isSelectionNotifyProcessed = false;
+            }
+        } finally {
+            XToolkit.awtUnlock();
         }
     }
 
+    /*
+     * Tracks changes of available formats.
+     * NOTE: This method may be called by privileged threads.
+     *       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
+     */
+    private void checkChange(XSelectionEvent xse) {
+        final long propertyAtom = xse.get_property();
+        if (propertyAtom != getTargetsPropertyAtom().getAtom()) {
+            // wrong atom
+            return;
+        }
+
+        final XAtom selectionAtom = XAtom.get(xse.get_selection());
+        final XSelection changedSelection = XSelection.getSelection(selectionAtom);
+
+        if (null == changedSelection || changedSelection != selection) {
+            // unknown selection - do nothing
+            return;
+        }
+
+        isSelectionNotifyProcessed = true;
+
+        if (selection.isOwner()) {
+            // selection is owner - do not need formats
+            return;
+        }
+
+        long[] formats = null;
+
+        if (propertyAtom == XlibWrapper.None) {
+            // We treat None property atom as "empty selection".
+            formats = new long[0];
+        } else {
+            WindowPropertyGetter targetsGetter =
+                new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
+                                         XAtom.get(propertyAtom), 0,
+                                         XSelection.MAX_LENGTH, true,
+                                         XlibWrapper.AnyPropertyType);
+            try {
+                targetsGetter.execute();
+                formats = XSelection.getFormats(targetsGetter);
+            } finally {
+                targetsGetter.dispose();
+            }
+        }
+
+        checkChange(formats);
+    }
 }
--- a/src/solaris/classes/sun/awt/X11/XComponentPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XComponentPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,17 +31,13 @@
 import java.awt.Component;
 import java.awt.Container;
 import java.awt.Cursor;
-import java.awt.DefaultKeyboardFocusManager;
 import java.awt.Dimension;
-import java.awt.Event;
 import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.Graphics;
 import java.awt.Image;
 import java.awt.Insets;
 import java.awt.KeyboardFocusManager;
-import java.awt.MenuBar;
-import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.SystemColor;
 import java.awt.Toolkit;
@@ -60,12 +56,9 @@
 import java.awt.image.ImageObserver;
 import java.awt.image.ImageProducer;
 import java.awt.image.VolatileImage;
-import java.awt.peer.CanvasPeer;
 import java.awt.peer.ComponentPeer;
 import java.awt.peer.ContainerPeer;
 import java.awt.peer.LightweightPeer;
-import java.awt.peer.PanelPeer;
-import java.awt.peer.WindowPeer;
 import java.lang.reflect.*;
 import java.security.*;
 import java.util.Collection;
@@ -821,7 +814,7 @@
     public void setFont(Font f) {
         synchronized (getStateLock()) {
             if (f == null) {
-                f = defaultFont;
+                f = XWindow.getDefaultFont();
             }
             font = f;
         }
--- a/src/solaris/classes/sun/awt/X11/XContentWindow.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XContentWindow.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,16 +39,37 @@
  * This class implements window which serves as content window for decorated frames.
  * Its purpose to provide correct events dispatching for the complex
  * constructs such as decorated frames.
+ *
+ * It should always be located at (- left inset, - top inset) in the associated
+ * decorated window.  So coordinates in it would be the same as java coordinates.
  */
-public class XContentWindow extends XWindow implements XConstants {
+public final class XContentWindow extends XWindow implements XConstants {
     private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XContentWindow");
 
-    XDecoratedPeer parentFrame;
+    static XContentWindow createContent(XDecoratedPeer parentFrame) {
+        final WindowDimensions dims = parentFrame.getDimensions();
+        Rectangle rec = dims.getBounds();
+        // Fix for  - set the location of the content window to the (-left inset, -top inset)
+        Insets ins = dims.getInsets();
+        if (ins != null) {
+            rec.x = -ins.left;
+            rec.y = -ins.top;
+        } else {
+            rec.x = 0;
+            rec.y = 0;
+        }
+        final XContentWindow cw = new XContentWindow(parentFrame, rec);
+        cw.xSetVisible(true);
+        return cw;
+    }
+
+    private final XDecoratedPeer parentFrame;
 
     // A list of expose events that come when the parentFrame is iconified
-    private java.util.List<SavedExposeEvent> iconifiedExposeEvents = new java.util.ArrayList<SavedExposeEvent>();
+    private final java.util.List<SavedExposeEvent> iconifiedExposeEvents =
+            new java.util.ArrayList<SavedExposeEvent>();
 
-    XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
+    private XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
         super((Component)parentFrame.getTarget(), parentFrame.getShell(), bounds);
         this.parentFrame = parentFrame;
     }
@@ -63,9 +84,6 @@
         }
     }
 
-    void initialize() {
-        xSetVisible(true);
-    }
     protected String getWMName() {
         return "Content window";
     }
--- a/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -36,7 +36,7 @@
 import sun.awt.ComponentAccessor;
 import sun.awt.SunToolkit;
 
-class XDecoratedPeer extends XWindowPeer {
+abstract class XDecoratedPeer extends XWindowPeer {
     private static final Logger log = Logger.getLogger("sun.awt.X11.XDecoratedPeer");
     private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XDecoratedPeer");
     private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XDecoratedPeer");
@@ -98,8 +98,7 @@
         // happen after the X window is created.
         initResizability();
         updateSizeHints(dimensions);
-        content = createContent(dimensions);
-        content.initialize();
+        content = XContentWindow.createContent(this);
         if (warningWindow != null) {
             warningWindow.toFront();
         }
@@ -160,20 +159,6 @@
         }
     }
 
-    XContentWindow createContent(WindowDimensions dims) {
-        Rectangle rec = dims.getBounds();
-        // Fix for  - set the location of the content window to the (-left inset, -top inset)
-        Insets ins = dims.getInsets();
-        if (ins != null) {
-            rec.x = -ins.left;
-            rec.y = -ins.top;
-        } else {
-            rec.x = 0;
-            rec.y = 0;
-        }
-        return new XContentWindow(this, rec);
-    }
-
     XFocusProxyWindow createFocusProxy() {
         return new XFocusProxyWindow(this);
     }
@@ -286,7 +271,7 @@
                 return;
             }
             Component t = (Component)target;
-            if (getDecorations() == winAttr.AWT_DECOR_NONE) {
+            if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) {
                 setReparented(true);
                 insets_corrected = true;
                 reshape(dimensions, SET_SIZE, false);
@@ -471,6 +456,15 @@
         if (insLog.isLoggable(Level.FINE)) {
             insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape);
         }
+        if (userReshape) {
+            // We handle only userReshape == true cases. It means that
+            // if the window manager or any other part of the windowing
+            // system sets inappropriate size for this window, we can
+            // do nothing but accept it.
+            Rectangle reqBounds = newDimensions.getBounds();
+            Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height);
+            newDimensions = new WindowDimensions(newBounds, newDimensions.getInsets(), newDimensions.isClientSizeSet());
+        }
         XToolkit.awtLock();
         try {
             if (!isReparented() || !isVisible()) {
@@ -586,6 +580,49 @@
         reshape(dims, operation, userReshape);
     }
 
+    // This method gets overriden in XFramePeer & XDialogPeer.
+    abstract boolean isTargetUndecorated();
+
+    @Override
+    Rectangle constrainBounds(int x, int y, int width, int height) {
+        // We don't restrict the setBounds() operation if the code is trusted.
+        if (!hasWarningWindow()) {
+            return new Rectangle(x, y, width, height);
+        }
+
+        // If it's undecorated or is not currently visible,
+        // apply the same constraints as for the Window.
+        if (!isVisible() || isTargetUndecorated()) {
+            return super.constrainBounds(x, y, width, height);
+        }
+
+        // If it's visible & decorated, constraint the size only
+        int newX = x;
+        int newY = y;
+        int newW = width;
+        int newH = height;
+
+        GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
+        Rectangle sB = gc.getBounds();
+        Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
+
+        Rectangle curBounds = getBounds();
+
+        int maxW = Math.max(sB.width - sIn.left - sIn.right, curBounds.width);
+        int maxH = Math.max(sB.height - sIn.top - sIn.bottom, curBounds.height);
+
+        // First make sure the size is withing the visible part of the screen
+        if (newW > maxW) {
+            newW = maxW;
+        }
+
+        if (newH > maxH) {
+            newH = maxH;
+        }
+
+        return new Rectangle(newX, newY, newW, newH);
+    }
+
     /**
      * @see java.awt.peer.ComponentPeer#setBounds
      */
@@ -651,12 +688,12 @@
         }
         if (!isReparented() && isVisible() && runningWM != XWM.NO_WM
                 &&  !XWM.isNonReparentingWM()
-                && getDecorations() != winAttr.AWT_DECOR_NONE) {
+                && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
             insLog.fine("- visible but not reparented, skipping");
             return;
         }
         //Last chance to correct insets
-        if (!insets_corrected && getDecorations() != winAttr.AWT_DECOR_NONE) {
+        if (!insets_corrected && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
             long parent = XlibUtil.getParentWindow(window);
             Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null;
             if (insLog.isLoggable(Level.FINER)) {
@@ -824,7 +861,7 @@
                 fs &= ~(MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE);
             }
             winAttr.functions = fs;
-            XWM.setShellNotResizable(this, dimensions, dimensions.getScreenBounds(), false);
+            XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false);
         }
     }
 
@@ -870,7 +907,7 @@
         return getSize().height;
     }
 
-    public WindowDimensions getDimensions() {
+    final public WindowDimensions getDimensions() {
         return dimensions;
     }
 
--- a/src/solaris/classes/sun/awt/X11/XDialogPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XDialogPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -88,7 +88,8 @@
         }
     }
 
-    private boolean isTargetUndecorated() {
+    @Override
+    boolean isTargetUndecorated() {
         if (undecorated != null) {
             return undecorated.booleanValue();
         } else {
--- a/src/solaris/classes/sun/awt/X11/XDnDConstants.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XDnDConstants.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,8 +48,7 @@
     static final XAtom XA_XdndStatus     = XAtom.get("XdndStatus");
     static final XAtom XA_XdndFinished   = XAtom.get("XdndFinished");
 
-    static final XSelection XDnDSelection =
-        new XSelection(XA_XdndSelection, null);
+    static final XSelection XDnDSelection = new XSelection(XA_XdndSelection);
 
     public static final int XDND_MIN_PROTOCOL_VERSION = 3;
     public static final int XDND_PROTOCOL_VERSION     = 5;
--- a/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -647,12 +647,6 @@
         }
         if (isXEmbedActive()) {
             switch ((int)msg.get_data(1)) {
-              case _SUN_XEMBED_START:
-                  // Child has finished initialization and waits for notify
-                  xembed.processXEmbedInfo();
-
-                  notifyChildEmbedded();
-                  break;
               case XEMBED_REQUEST_FOCUS:
                   requestXEmbedFocus();
                   break;
--- a/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java	Mon Apr 14 11:34:15 2008 -0700
@@ -74,7 +74,6 @@
                 XToolkit.awtUnlock();
             }
         }
-        notifyReady();
     }
 
     void handleClientMessage(XEvent xev) {
@@ -84,7 +83,6 @@
             if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Embedded message: " + msgidToString((int)msg.get_data(1)));
             switch ((int)msg.get_data(1)) {
               case XEMBED_EMBEDDED_NOTIFY: // Notification about embedding protocol start
-                  // NOTE: May be called two times because we send _SUN_XEMBED_START
                   active = true;
                   server = getEmbedder(embedded, msg);
                   // Check if window is reparented. If not - it was created with
@@ -223,13 +221,4 @@
     long getX11Mods(AWTKeyStroke stroke) {
         return XWindow.getXModifiers(stroke);
     }
-
-    void notifyReady() {
-        long wnd = server;
-        if (wnd == 0) {
-            // Server is still 0, get the parent
-            wnd = embedded.getParentWindowHandle();
-        }
-        sendMessage(wnd, _SUN_XEMBED_START);
-    }
 }
--- a/src/solaris/classes/sun/awt/X11/XEmbedHelper.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XEmbedHelper.java	Mon Apr 14 11:34:15 2008 -0700
@@ -58,7 +58,6 @@
     final static int XEMBED_REGISTER_ACCELERATOR =    12;
     final static int XEMBED_UNREGISTER_ACCELERATOR=   13;
     final static int XEMBED_ACTIVATE_ACCELERATOR  =   14;
-    final static int _SUN_XEMBED_START = 1119;
 
     final static int NON_STANDARD_XEMBED_GTK_GRAB_KEY = 108;
     final static int NON_STANDARD_XEMBED_GTK_UNGRAB_KEY = 109;
@@ -151,8 +150,6 @@
               return "NON_STANDARD_XEMBED_GTK_UNGRAB_KEY";
           case NON_STANDARD_XEMBED_GTK_GRAB_KEY:
               return "NON_STANDARD_XEMBED_GTK_GRAB_KEY";
-          case _SUN_XEMBED_START:
-              return "XEMBED_START";
           case XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK:
               return "KeyPress";
           case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK:
--- a/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java	Mon Apr 14 11:34:15 2008 -0700
@@ -177,13 +177,6 @@
         embedCompletely();
     }
 
-    public void test3_2() {
-        embedCompletely();
-        int res = getEventPos();
-        sendMessage(XEmbedHelper._SUN_XEMBED_START);
-        waitEmbeddedNotify(res);
-    }
-
     public void test3_3() {
         reparent = true;
         embedCompletely();
--- a/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -184,6 +184,12 @@
         }
     }
 
+    @Override
+    Rectangle constrainBounds(int x, int y, int width, int height) {
+        // We don't constrain the bounds of the EmbeddedFrames
+        return new Rectangle(x, y, width, height);
+    }
+
     // don't use getBounds() inherited from XDecoratedPeer
     public Rectangle getBounds() {
         return new Rectangle(x, y, width, height);
--- a/src/solaris/classes/sun/awt/X11/XFramePeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XFramePeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,15 +24,18 @@
  */
 package sun.awt.X11;
 
-import java.util.Vector;
-import java.awt.*;
-import java.awt.peer.*;
-import java.awt.event.*;
-import sun.awt.im.*;
-import sun.awt.*;
-import java.util.logging.*;
-import java.lang.reflect.Field;
-import java.util.*;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.MenuBar;
+import java.awt.Rectangle;
+import java.awt.peer.FramePeer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants {
     private static Logger log = Logger.getLogger("sun.awt.X11.XFramePeer");
@@ -92,7 +95,8 @@
         }
     }
 
-    private boolean isTargetUndecorated() {
+    @Override
+    boolean isTargetUndecorated() {
         if (undecorated != null) {
             return undecorated.booleanValue();
         } else {
@@ -285,19 +289,20 @@
          * Let's see if this is a window state protocol message, and
          * if it is - decode a new state in terms of java constants.
          */
-        Integer newState = XWM.getWM().isStateChange(this, ev);
-        if (newState == null) {
+        if (!XWM.getWM().isStateChange(this, ev)) {
+            stateLog.finer("either not a state atom or state has not been changed");
             return;
         }
 
-        int changed = state ^ newState.intValue();
+        final int newState = XWM.getWM().getState(this);
+        int changed = state ^ newState;
         if (changed == 0) {
             stateLog.finer("State is the same: " + state);
             return;
         }
 
         int old_state = state;
-        state = newState.intValue();
+        state = newState;
 
         if ((changed & Frame.ICONIFIED) != 0) {
             if ((state & Frame.ICONIFIED) != 0) {
--- a/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -218,7 +218,7 @@
 
     Font getTargetFont() {
         if (target == null) {
-            return XWindow.defaultFont;
+            return XWindow.getDefaultFont();
         }
         try {
             return (Font)m_getFont.invoke(target, new Object[0]);
@@ -227,7 +227,7 @@
         } catch (InvocationTargetException e) {
             e.printStackTrace();
         }
-        return XWindow.defaultFont;
+        return XWindow.getDefaultFont();
     }
 
     String getTargetLabel() {
--- a/src/solaris/classes/sun/awt/X11/XNETProtocol.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XNETProtocol.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,17 +26,15 @@
 
 package sun.awt.X11;
 
-import java.awt.*;
+import java.awt.Frame;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import java.util.logging.LogManager;
-import java.awt.*;
-import java.awt.image.*;
-import java.util.*;
 
-class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol {
-    final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol");
+final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol
+{
+    private final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol");
     private final static Logger iconLog = Logger.getLogger("sun.awt.X11.icon.XNETProtocol");
+    private static Logger stateLog = Logger.getLogger("sun.awt.X11.states.XNETProtocol");
 
     /**
      * XStateProtocol
@@ -276,6 +274,7 @@
 
     boolean doStateProtocol() {
         boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE);
+        stateLog.finer("doStateProtocol() returns " + res);
         return res;
     }
 
--- a/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -187,7 +187,7 @@
     //Fix for 6267144: PIT: Popup menu label is not shown, XToolkit
     Font getTargetFont() {
         if (popupMenuTarget == null) {
-            return XWindow.defaultFont;
+            return XWindow.getDefaultFont();
         }
         try {
             return (Font)m_getFont.invoke(popupMenuTarget, new Object[0]);
@@ -196,7 +196,7 @@
         } catch (InvocationTargetException e) {
             e.printStackTrace();
         }
-        return XWindow.defaultFont;
+        return XWindow.getDefaultFont();
     }
 
     String getTargetLabel() {
--- a/src/solaris/classes/sun/awt/X11/XSelection.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XSelection.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,9 +32,6 @@
 
 import java.util.Hashtable;
 import java.util.Map;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Collections;
 
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
@@ -45,7 +42,7 @@
 /**
  * A class which interfaces with the X11 selection service.
  */
-public class XSelection {
+public final class XSelection {
 
     /* Maps atoms to XSelection instances. */
     private static final Hashtable<XAtom, XSelection> table = new Hashtable<XAtom, XSelection>();
@@ -69,8 +66,6 @@
             XToolkit.awtUnlock();
         }
     }
-    /* The selection timeout. */
-    private static long SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
 
     /* The PropertyNotify event handler for incremental data transfer. */
     private static final XEventDispatcher incrementalTransferHandler =
@@ -84,11 +79,6 @@
 
     /* The X atom for the underlying selection. */
     private final XAtom selectionAtom;
-    /*
-     * XClipboard.run() is to be called when we lose ownership.
-     * XClipbioard.checkChange() is to be called when tracking changes of flavors.
-     */
-    private final XClipboard clipboard;
 
     /*
      * Owner-related variables - protected with synchronized (this).
@@ -109,17 +99,8 @@
     private long ownershipTime = 0;
     // True if we are the owner of this selection.
     private boolean isOwner;
-    // The property in which the owner should place requested targets
-    // when tracking changes of available data flavors (practically targets).
-    private volatile XAtom targetsPropertyAtom;
-    // A set of these property atoms.
-    private static volatile Set targetsPropertyAtoms;
-    // The flag used not to call XConvertSelection() if the previous SelectionNotify
-    // has not been processed by checkChange().
-    private volatile boolean isSelectionNotifyProcessed;
-    // Time of calling XConvertSelection().
-    private long convertSelectionTime;
-
+    private OwnershipListener ownershipListener = null;
+    private final Object stateLock = new Object();
 
     static {
         XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(),
@@ -141,12 +122,11 @@
      * @param clpbrd the corresponding clipoboard
      * @exception NullPointerException if atom is <code>null</code>.
      */
-    public XSelection(XAtom atom, XClipboard clpbrd) {
+    public XSelection(XAtom atom) {
         if (atom == null) {
             throw new NullPointerException("Null atom");
         }
         selectionAtom = atom;
-        clipboard = clpbrd;
         table.put(selectionAtom, this);
     }
 
@@ -154,25 +134,9 @@
         return selectionAtom;
     }
 
-    void initializeSelectionForTrackingChanges() {
-        targetsPropertyAtom = XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selectionAtom.getName());
-        if (targetsPropertyAtoms == null) {
-            targetsPropertyAtoms = Collections.synchronizedSet(new HashSet(2));
-        }
-        targetsPropertyAtoms.add(Long.valueOf(targetsPropertyAtom.getAtom()));
-        // for XConvertSelection() to be called for the first time in getTargetsDelayed()
-        isSelectionNotifyProcessed = true;
-    }
-
-    void deinitializeSelectionForTrackingChanges() {
-        if (targetsPropertyAtoms != null && targetsPropertyAtom != null) {
-            targetsPropertyAtoms.remove(Long.valueOf(targetsPropertyAtom.getAtom()));
-        }
-        isSelectionNotifyProcessed = false;
-    }
-
     public synchronized boolean setOwner(Transferable contents, Map formatMap,
-                                         long[] formats, long time) {
+                                         long[] formats, long time)
+    {
         long owner = XWindow.getXAWTRootWindow().getWindow();
         long selection = selectionAtom.getAtom();
 
@@ -192,15 +156,12 @@
             XlibWrapper.XSetSelectionOwner(XToolkit.getDisplay(),
                                            selection, owner, time);
             if (XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(),
-                                               selection) != owner) {
-
+                                               selection) != owner)
+            {
                 reset();
                 return false;
             }
-            isOwner = true;
-            if (clipboard != null) {
-                clipboard.checkChangeHere(contents);
-            }
+            setOwnerProp(true);
             return true;
         } finally {
             XToolkit.awtUnlock();
@@ -217,7 +178,7 @@
             do {
                 DataTransferer.getInstance().processDataConversionRequests();
                 XToolkit.awtLockWait(250);
-            } while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + SELECTION_TIMEOUT);
+            } while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + UNIXToolkit.getDatatransferTimeout());
         } finally {
             XToolkit.awtUnlock();
         }
@@ -232,11 +193,9 @@
             throw new Error("UNIMPLEMENTED");
         }
 
-        long[] formats = null;
+        long[] targets = null;
 
         synchronized (lock) {
-            SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
-
             WindowPropertyGetter targetsGetter =
                 new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
                                          selectionPropertyAtom, 0, MAX_LENGTH,
@@ -267,23 +226,25 @@
                 } finally {
                     XToolkit.awtUnlock();
                 }
-                formats = getFormats(targetsGetter);
+                targets = getFormats(targetsGetter);
             } finally {
                 targetsGetter.dispose();
             }
         }
-        return formats;
+        return targets;
     }
 
-    private static long[] getFormats(WindowPropertyGetter targetsGetter) {
+    static long[] getFormats(WindowPropertyGetter targetsGetter) {
         long[] formats = null;
 
         if (targetsGetter.isExecuted() && !targetsGetter.isDisposed() &&
                 (targetsGetter.getActualType() == XAtom.XA_ATOM ||
                  targetsGetter.getActualType() == XDataTransferer.TARGETS_ATOM.getAtom()) &&
-                targetsGetter.getActualFormat() == 32) {
-
-            int count = (int)targetsGetter.getNumberOfItems();
+                targetsGetter.getActualFormat() == 32)
+        {
+            // we accept property with TARGETS type to be compatible with old jdks
+            // see 6607163
+            int count = targetsGetter.getNumberOfItems();
             if (count > 0) {
                 long atoms = targetsGetter.getData();
                 formats = new long[count];
@@ -297,26 +258,6 @@
         return formats != null ? formats : new long[0];
     }
 
-    // checkChange() will be called on SelectionNotify
-    void getTargetsDelayed() {
-        XToolkit.awtLock();
-        try {
-            long curTime = System.currentTimeMillis();
-            if (isSelectionNotifyProcessed || curTime >= convertSelectionTime + SELECTION_TIMEOUT) {
-                convertSelectionTime = curTime;
-                XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
-                                              getSelectionAtom().getAtom(),
-                                              XDataTransferer.TARGETS_ATOM.getAtom(),
-                                              targetsPropertyAtom.getAtom(),
-                                              XWindow.getXAWTRootWindow().getWindow(),
-                                              XlibWrapper.CurrentTime);
-                isSelectionNotifyProcessed = false;
-            }
-        } finally {
-            XToolkit.awtUnlock();
-        }
-    }
-
     /*
      * Requests the selection data in the specified format and returns
      * the data provided by the owner.
@@ -329,8 +270,6 @@
         byte[] data = null;
 
         synchronized (lock) {
-            SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
-
             WindowPropertyGetter dataGetter =
                 new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
                                          selectionPropertyAtom, 0, MAX_LENGTH,
@@ -379,7 +318,7 @@
                                               dataGetter.getActualFormat());
                     }
 
-                    int count = (int)dataGetter.getNumberOfItems();
+                    int count = dataGetter.getNumberOfItems();
 
                     if (count <= 0) {
                         throw new IOException("INCR data is missed.");
@@ -455,7 +394,7 @@
                                                       incrDataGetter.getActualFormat());
                             }
 
-                            count = (int)incrDataGetter.getNumberOfItems();
+                            count = incrDataGetter.getNumberOfItems();
 
                             if (count == 0) {
                                 break;
@@ -489,7 +428,7 @@
                                               dataGetter.getActualFormat());
                     }
 
-                    int count = (int)dataGetter.getNumberOfItems();
+                    int count = dataGetter.getNumberOfItems();
                     if (count > 0) {
                         data = new byte[count];
                         long ptr = dataGetter.getData();
@@ -511,11 +450,14 @@
         return isOwner;
     }
 
-    public void lostOwnership() {
-        isOwner = false;
-        if (clipboard != null) {
-            clipboard.run();
-        }
+    // To be MT-safe this method should be called under awtLock.
+    private void setOwnerProp(boolean f) {
+        isOwner = f;
+        fireOwnershipChanges(isOwner);
+    }
+
+    private void lostOwnership() {
+        setOwnerProp(false);
     }
 
     public synchronized void reset() {
@@ -595,125 +537,39 @@
 
     private void handleSelectionRequest(XSelectionRequestEvent xsre) {
         long property = xsre.get_property();
-        long requestor = xsre.get_requestor();
-        long requestTime = xsre.get_time();
-        long format = xsre.get_target();
-        int dataFormat = 0;
+        final long requestor = xsre.get_requestor();
+        final long requestTime = xsre.get_time();
+        final long format = xsre.get_target();
         boolean conversionSucceeded = false;
 
         if (ownershipTime != 0 &&
-            (requestTime == XlibWrapper.CurrentTime ||
-             requestTime >= ownershipTime)) {
-
-            property = xsre.get_property();
-
+            (requestTime == XlibWrapper.CurrentTime || requestTime >= ownershipTime))
+        {
             // Handle MULTIPLE requests as per ICCCM.
             if (format == XDataTransferer.MULTIPLE_ATOM.getAtom()) {
-                // The property cannot be 0 for a MULTIPLE request.
-                if (property != 0) {
-                    // First retrieve the list of requested targets.
-                    WindowPropertyGetter wpg =
-                        new WindowPropertyGetter(requestor, XAtom.get(property), 0,
-                                                 MAX_LENGTH, false,
-                                                 XlibWrapper.AnyPropertyType);
-                    try {
-                        wpg.execute();
-
-                        if (wpg.getActualFormat() == 32 &&
-                            (wpg.getNumberOfItems() % 2) == 0) {
-                            long count = wpg.getNumberOfItems() / 2;
-                            long pairsPtr = wpg.getData();
-                            boolean writeBack = false;
-                            for (int i = 0; i < count; i++) {
-                                long target = Native.getLong(pairsPtr, 2*i);
-                                long prop = Native.getLong(pairsPtr, 2*i + 1);
-
-                                if (!convertAndStore(requestor, target, prop)) {
-                                    // To report failure, we should replace the
-                                    // target atom with 0 in the MULTIPLE property.
-                                    Native.putLong(pairsPtr, 2*i, 0);
-                                    writeBack = true;
-                                }
-                            }
-                            if (writeBack) {
-                                XToolkit.awtLock();
-                                try {
-                                    XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
-                                                                property,
-                                                                wpg.getActualType(),
-                                                                wpg.getActualFormat(),
-                                                                XlibWrapper.PropModeReplace,
-                                                                wpg.getData(),
-                                                                wpg.getNumberOfItems());
-                                } finally {
-                                    XToolkit.awtUnlock();
-                                }
-                            }
-                            conversionSucceeded = true;
-                        }
-                    } finally {
-                        wpg.dispose();
-                    }
-                }
+                conversionSucceeded = handleMultipleRequest(requestor, property);
             } else {
-
                 // Support for obsolete clients as per ICCCM.
-                if (property == 0) {
+                if (property == XlibWrapper.None) {
                     property = format;
                 }
 
                 if (format == XDataTransferer.TARGETS_ATOM.getAtom()) {
-                    long nativeDataPtr = 0;
-                    int count = 0;
-                    dataFormat = 32;
-
-                    // Use a local copy to avoid synchronization.
-                    long[] formatsLocal = formats;
-
-                    if (formatsLocal == null) {
-                        throw new IllegalStateException("Not an owner.");
-                    }
-
-                    count = formatsLocal.length;
-
-                    try {
-                        if (count > 0) {
-                            nativeDataPtr = Native.allocateLongArray(count);
-                            Native.put(nativeDataPtr, formatsLocal);
-                        }
-
-                        conversionSucceeded = true;
-
-                        XToolkit.awtLock();
-                        try {
-                            XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
-                                                        property, format, dataFormat,
-                                                        XlibWrapper.PropModeReplace,
-                                                        nativeDataPtr, count);
-                        } finally {
-                            XToolkit.awtUnlock();
-                        }
-                    } finally {
-                        if (nativeDataPtr != 0) {
-                            XlibWrapper.unsafe.freeMemory(nativeDataPtr);
-                            nativeDataPtr = 0;
-                        }
-                    }
+                    conversionSucceeded = handleTargetsRequest(property, requestor);
                 } else {
-                    conversionSucceeded = convertAndStore(requestor, format,
-                                                          property);
+                    conversionSucceeded = convertAndStore(requestor, format, property);
                 }
             }
         }
 
         if (!conversionSucceeded) {
-            // Zero property indicates conversion failure.
-            property = 0;
+            // None property indicates conversion failure.
+            property = XlibWrapper.None;
         }
 
         XSelectionEvent xse = new XSelectionEvent();
         try {
-            xse.set_type((int)XlibWrapper.SelectionNotify);
+            xse.set_type(XlibWrapper.SelectionNotify);
             xse.set_send_event(true);
             xse.set_requestor(requestor);
             xse.set_selection(selectionAtom.getAtom());
@@ -733,40 +589,123 @@
         }
     }
 
-    private static void checkChange(XSelectionEvent xse) {
-        if (targetsPropertyAtoms == null || targetsPropertyAtoms.isEmpty()) {
-            // We are not tracking changes.
-            return;
+    private boolean handleMultipleRequest(final long requestor, long property) {
+        if (XlibWrapper.None == property) {
+            // The property cannot be None for a MULTIPLE request.
+            return false;
+        }
+
+        boolean conversionSucceeded = false;
+
+        // First retrieve the list of requested targets.
+        WindowPropertyGetter wpg =
+                new WindowPropertyGetter(requestor, XAtom.get(property),
+                                         0, MAX_LENGTH, false,
+                                         XlibWrapper.AnyPropertyType);
+        try {
+            wpg.execute();
+
+            if (wpg.getActualFormat() == 32 && (wpg.getNumberOfItems() % 2) == 0) {
+                final long count = wpg.getNumberOfItems() / 2;
+                final long pairsPtr = wpg.getData();
+                boolean writeBack = false;
+
+                for (int i = 0; i < count; i++) {
+                    long target = Native.getLong(pairsPtr, 2 * i);
+                    long prop = Native.getLong(pairsPtr, 2 * i + 1);
+
+                    if (!convertAndStore(requestor, target, prop)) {
+                        // To report failure, we should replace the
+                        // target atom with 0 in the MULTIPLE property.
+                        Native.putLong(pairsPtr, 2 * i, 0);
+                        writeBack = true;
+                    }
+                }
+                if (writeBack) {
+                    XToolkit.awtLock();
+                    try {
+                        XlibWrapper.XChangeProperty(XToolkit.getDisplay(),
+                                                    requestor,
+                                                    property,
+                                                    wpg.getActualType(),
+                                                    wpg.getActualFormat(),
+                                                    XlibWrapper.PropModeReplace,
+                                                    wpg.getData(),
+                                                    wpg.getNumberOfItems());
+                    } finally {
+                        XToolkit.awtUnlock();
+                    }
+                }
+                conversionSucceeded = true;
+            }
+        } finally {
+            wpg.dispose();
         }
 
-        long propertyAtom = xse.get_property();
-        long[] formats = null;
+        return conversionSucceeded;
+    }
+
+    private boolean handleTargetsRequest(long property, long requestor)
+            throws IllegalStateException
+    {
+        boolean conversionSucceeded = false;
+        // Use a local copy to avoid synchronization.
+        long[] formatsLocal = formats;
+
+        if (formatsLocal == null) {
+            throw new IllegalStateException("Not an owner.");
+        }
+
+        long nativeDataPtr = 0;
+
+        try {
+            final int count = formatsLocal.length;
+            final int dataFormat = 32;
 
-        if (propertyAtom == XlibWrapper.None) {
-            // We threat None property atom as "empty selection".
-            formats = new long[0];
-        } else if (!targetsPropertyAtoms.contains(Long.valueOf(propertyAtom))) {
-            return;
-        } else {
-            WindowPropertyGetter targetsGetter =
-                new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
-                                         XAtom.get(propertyAtom), 0, MAX_LENGTH,
-                                         true, XlibWrapper.AnyPropertyType);
+            if (count > 0) {
+                nativeDataPtr = Native.allocateLongArray(count);
+                Native.put(nativeDataPtr, formatsLocal);
+            }
+
+            conversionSucceeded = true;
+
+            XToolkit.awtLock();
             try {
-                targetsGetter.execute();
-                formats = getFormats(targetsGetter);
+                XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
+                                            property, XAtom.XA_ATOM, dataFormat,
+                                            XlibWrapper.PropModeReplace,
+                                            nativeDataPtr, count);
             } finally {
-                targetsGetter.dispose();
+                XToolkit.awtUnlock();
+            }
+        } finally {
+            if (nativeDataPtr != 0) {
+                XlibWrapper.unsafe.freeMemory(nativeDataPtr);
+                nativeDataPtr = 0;
             }
         }
+        return conversionSucceeded;
+    }
 
-        XAtom selectionAtom = XAtom.get(xse.get_selection());
-        XSelection selection = getSelection(selectionAtom);
-        if (selection != null) {
-            selection.isSelectionNotifyProcessed = true;
-            if (selection.clipboard != null) {
-                selection.clipboard.checkChange(formats);
-            }
+    private void fireOwnershipChanges(final boolean isOwner) {
+        OwnershipListener l = null;
+        synchronized (stateLock) {
+            l = ownershipListener;
+        }
+        if (null != l) {
+            l.ownershipChanged(isOwner);
+        }
+    }
+
+    void registerOwershipListener(OwnershipListener l) {
+        synchronized (stateLock) {
+            ownershipListener = l;
+        }
+    }
+
+    void unregisterOwnershipListener() {
+        synchronized (stateLock) {
+            ownershipListener = null;
         }
     }
 
@@ -774,10 +713,9 @@
         public void dispatchEvent(XEvent ev) {
             switch (ev.get_type()) {
             case XlibWrapper.SelectionNotify: {
-                XSelectionEvent xse = ev.get_xselection();
-                checkChange(xse);
                 XToolkit.awtLock();
                 try {
+                    XSelectionEvent xse = ev.get_xselection();
                     // Ignore the SelectionNotify event if it is not the response to our last request.
                     if (propertyGetter != null && xse.get_time() == lastRequestServerTime) {
                         // The property will be None in case of convertion failure.
--- a/src/solaris/classes/sun/awt/X11/XToolkit.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XToolkit.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,9 @@
 package sun.awt.X11;
 
 import java.awt.*;
-import java.awt.event.*;
-import java.awt.peer.*;
-import java.beans.PropertyChangeListener;
-import sun.awt.*;
-import java.util.*;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.awt.datatransfer.Clipboard;
 import java.awt.dnd.DragSource;
 import java.awt.dnd.DragGestureListener;
 import java.awt.dnd.DragGestureEvent;
@@ -37,20 +35,27 @@
 import java.awt.dnd.MouseDragGestureRecognizer;
 import java.awt.dnd.InvalidDnDOperationException;
 import java.awt.dnd.peer.DragSourceContextPeer;
-import java.awt.image.*;
-import java.security.*;
 import java.awt.im.InputMethodHighlight;
 import java.awt.im.spi.InputMethodDescriptor;
-import java.awt.datatransfer.Clipboard;
+import java.awt.image.ColorModel;
+import java.awt.peer.*;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import javax.swing.LookAndFeel;
 import javax.swing.UIDefaults;
-import java.util.logging.*;
+import sun.awt.*;
 import sun.font.FontManager;
 import sun.misc.PerformanceLogger;
 import sun.print.PrintJob2D;
-import java.lang.reflect.*;
 
-public class XToolkit extends UNIXToolkit implements Runnable, XConstants {
+public final class XToolkit extends UNIXToolkit implements Runnable, XConstants
+{
     private static Logger log = Logger.getLogger("sun.awt.X11.XToolkit");
     private static Logger eventLog = Logger.getLogger("sun.awt.X11.event.XToolkit");
     private static final Logger timeoutTaskLog = Logger.getLogger("sun.awt.X11.timeoutTask.XToolkit");
@@ -1871,9 +1876,7 @@
     }
 
     public boolean isAlwaysOnTopSupported() {
-        Iterator iter = XWM.getWM().getProtocols(XLayerProtocol.class).iterator();
-        while (iter.hasNext()) {
-            XLayerProtocol proto = (XLayerProtocol)iter.next();
+        for (XLayerProtocol proto : XWM.getWM().getProtocols(XLayerProtocol.class)) {
             if (proto.supportsLayer(XLayerProtocol.LAYER_ALWAYS_ON_TOP)) {
                 return true;
             }
--- a/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,11 +31,8 @@
 import sun.awt.*;
 import java.awt.image.*;
 import java.text.BreakIterator;
-import java.util.Vector;
-import java.lang.reflect.Field;
 import java.util.logging.Logger;
 import java.util.logging.Level;
-import java.util.AbstractQueue;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -629,7 +626,7 @@
         final static int TOOLTIP_MAX_LENGTH = 64;
         final static int TOOLTIP_MOUSE_CURSOR_INDENT = 5;
         final static Color TOOLTIP_BACKGROUND_COLOR = new Color(255, 255, 220);
-        final static Font TOOLTIP_TEXT_FONT = XWindow.defaultFont;
+        final static Font TOOLTIP_TEXT_FONT = XWindow.getDefaultFont();
 
         Tooltip(XTrayIconPeer xtiPeer, Frame parent) {
             super(parent, Color.black);
--- a/src/solaris/classes/sun/awt/X11/XWM.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XWM.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,20 +31,23 @@
 package sun.awt.X11;
 
 import sun.misc.Unsafe;
-import java.util.regex.*;
+import java.awt.Insets;
 import java.awt.Frame;
 import java.awt.Rectangle;
-import java.util.*;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.logging.Level;
-import java.util.logging.LogManager;
 import java.util.logging.Logger;
-import java.awt.Insets;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Class incapsulating knowledge about window managers in general
  * Descendants should provide some information about specific window manager.
  */
-class XWM implements MWMConstants, XUtilConstants {
+final class XWM implements MWMConstants, XUtilConstants
+{
 
     private final static Logger log = Logger.getLogger("sun.awt.X11.XWM");
     private final static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XWM");
@@ -1026,21 +1029,21 @@
 /*****************************************************************************\
  * Protocols support
  */
-    HashMap<Class<?>, Collection<XProtocol>> protocolsMap = new HashMap<Class<?>, Collection<XProtocol>>();
+    private HashMap<Class<?>, Collection<?>> protocolsMap = new HashMap<Class<?>, Collection<?>>();
     /**
      * Returns all protocols supporting given protocol interface
      */
-    Collection<XProtocol> getProtocols(Class protocolInterface) {
-        Collection<XProtocol> res = protocolsMap.get(protocolInterface);
+    <T> Collection<T> getProtocols(Class<T> protocolInterface) {
+        Collection<T> res = (Collection<T>) protocolsMap.get(protocolInterface);
         if (res != null) {
-            return (Collection<XProtocol>)res;
+            return res;
         } else {
-            return new LinkedList<XProtocol>();
+            return new LinkedList<T>();
         }
     }
 
-    void addProtocol(Class protocolInterface, XProtocol protocol) {
-        Collection<XProtocol> protocols = getProtocols(protocolInterface);
+    private <T> void addProtocol(Class<T> protocolInterface, T protocol) {
+        Collection<T> protocols = getProtocols(protocolInterface);
         protocols.add(protocol);
         protocolsMap.put(protocolInterface, protocols);
     }
@@ -1085,9 +1088,7 @@
               }
               /* FALLTROUGH */
           case Frame.MAXIMIZED_BOTH:
-              Iterator iter = getProtocols(XStateProtocol.class).iterator();
-              while (iter.hasNext()) {
-                  XStateProtocol proto = (XStateProtocol)iter.next();
+              for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
                   if (proto.supportsState(state)) {
                       return true;
                   }
@@ -1105,10 +1106,8 @@
 
 
     int getExtendedState(XWindowPeer window) {
-        Iterator iter = getProtocols(XStateProtocol.class).iterator();
         int state = 0;
-        while (iter.hasNext()) {
-            XStateProtocol proto = (XStateProtocol)iter.next();
+        for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
             state |= proto.getState(window);
         }
         if (state != 0) {
@@ -1127,18 +1126,17 @@
 
     /*
      * Check if property change is a window state protocol message.
-     * If it is - return the new state as Integer, otherwise return null
      */
-    Integer isStateChange(XDecoratedPeer window, XPropertyEvent e) {
+    boolean isStateChange(XDecoratedPeer window, XPropertyEvent e) {
         if (!window.isShowing()) {
             stateLog.finer("Window is not showing");
-            return null;
+            return false;
         }
 
         int wm_state = window.getWMState();
         if (wm_state == XlibWrapper.WithdrawnState) {
             stateLog.finer("WithdrawnState");
-            return null;
+            return false;
         } else {
             stateLog.finer("Window WM_STATE is " + wm_state);
         }
@@ -1147,26 +1145,26 @@
             is_state_change = true;
         }
 
-        Iterator iter = getProtocols(XStateProtocol.class).iterator();
-        while (iter.hasNext()) {
-            XStateProtocol proto = (XStateProtocol)iter.next();
+        for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
             is_state_change |= proto.isStateChange(e);
+            stateLog.finest(proto + ": is state changed = " + is_state_change);
         }
-        int res = 0;
+        return is_state_change;
+    }
 
-        if (is_state_change) {
-            if (wm_state == XlibWrapper.IconicState) {
-                res = Frame.ICONIFIED;
-            } else {
-                res = Frame.NORMAL;
-            }
-            res |= getExtendedState(window);
+    /*
+     * Returns current state (including extended) of a given window.
+     */
+    int getState(XDecoratedPeer window) {
+        int res = 0;
+        final int wm_state = window.getWMState();
+        if (wm_state == XlibWrapper.IconicState) {
+            res = Frame.ICONIFIED;
+        } else {
+            res = Frame.NORMAL;
         }
-        if (is_state_change) {
-            return Integer.valueOf(res);
-        } else {
-            return null;
-        }
+        res |= getExtendedState(window);
+        return res;
     }
 
 /*****************************************************************************\
@@ -1180,9 +1178,7 @@
      * in XLayerProtocol
      */
     void setLayer(XWindowPeer window, int layer) {
-        Iterator iter = getProtocols(XLayerProtocol.class).iterator();
-        while (iter.hasNext()) {
-            XLayerProtocol proto = (XLayerProtocol)iter.next();
+        for (XLayerProtocol proto : getProtocols(XLayerProtocol.class)) {
             if (proto.supportsLayer(layer)) {
                 proto.setLayer(window, layer);
             }
@@ -1191,9 +1187,7 @@
     }
 
     void setExtendedState(XWindowPeer window, int state) {
-        Iterator iter = getProtocols(XStateProtocol.class).iterator();
-        while (iter.hasNext()) {
-            XStateProtocol proto = (XStateProtocol)iter.next();
+        for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
             if (proto.supportsState(state)) {
                 proto.setState(window, state);
                 break;
@@ -1239,9 +1233,7 @@
     void unshadeKludge(XDecoratedPeer window) {
         assert(window.isShowing());
 
-        Iterator iter = getProtocols(XStateProtocol.class).iterator();
-        while (iter.hasNext()) {
-            XStateProtocol proto = (XStateProtocol)iter.next();
+        for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
             proto.unshadeKludge(window);
         }
         XToolkit.XSync();
--- a/src/solaris/classes/sun/awt/X11/XWindow.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XWindow.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -92,8 +92,16 @@
     SurfaceData surfaceData;
 
     XRepaintArea paintArea;
+
     // fallback default font object
-    final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
+    private static Font defaultFont;
+
+    static synchronized Font getDefaultFont() {
+        if (null == defaultFont) {
+            defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
+        }
+        return defaultFont;
+    }
 
     /*
      * Keeps all buttons which were pressed at the time of the last mouse
@@ -333,7 +341,7 @@
         }
         Font font = afont;
         if (font == null) {
-            font = defaultFont;
+            font = XWindow.getDefaultFont();
         }
         return new SunGraphics2D(surfData, fgColor, bgColor, font);
     }
@@ -902,13 +910,11 @@
 
         super.handleConfigureNotifyEvent(xev);
         insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}",
-                   new Object[] {xev, isEventDisabled(xev)});
+                   new Object[] {xev.get_xconfigure(), isEventDisabled(xev)});
         if (isEventDisabled(xev)) {
             return;
         }
 
-        long eventWindow = xev.get_xany().get_window();
-
 //  if ( Check if it's a resize, a move, or a stacking order change )
 //  {
         Rectangle bounds = getBounds();
@@ -982,7 +988,6 @@
     // called directly from this package, unlike handleKeyRelease.
     // un-final it if you need to override it in a subclass.
     final void handleKeyPress(XKeyEvent ev) {
-        int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
         long keysym[] = new long[2];
         char unicodeKey = 0;
         keysym[0] = NoSymbol;
@@ -1066,7 +1071,6 @@
     }
     // un-private it if you need to call it from elsewhere
     private void handleKeyRelease(XKeyEvent ev) {
-        int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
         long keysym[] = new long[2];
         char unicodeKey = 0;
         keysym[0] = NoSymbol;
--- a/src/solaris/classes/sun/awt/X11/XWindowPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/X11/XWindowPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -112,9 +112,6 @@
             PARENT_WINDOW, Long.valueOf(0)}));
     }
 
-    // fallback default font object
-    static Font defaultFont;
-
     /*
      * This constant defines icon size recommended for using.
      * Apparently, we should use XGetIconSizes which should
@@ -162,10 +159,7 @@
 
         Font f = target.getFont();
         if (f == null) {
-            if (defaultFont == null) {
-                defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
-            }
-            f = defaultFont;
+            f = XWindow.getDefaultFont();
             target.setFont(f);
             // we should not call setFont because it will call a repaint
             // which the peer may not be ready to do yet.
@@ -188,6 +182,9 @@
 
         GraphicsConfiguration gc = getGraphicsConfiguration();
         ((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
+
+        Rectangle bounds = (Rectangle)(params.get(BOUNDS));
+        params.put(BOUNDS, constrainBounds(bounds.x, bounds.y, bounds.width, bounds.height));
     }
 
     private void initWMProtocols() {
@@ -437,6 +434,56 @@
         return ownerPeer;
     }
 
+    // This method is overriden at the XDecoratedPeer to handle
+    // decorated windows a bit differently.
+    Rectangle constrainBounds(int x, int y, int width, int height) {
+        // We don't restrict the setBounds() operation if the code is trusted.
+        if (!hasWarningWindow()) {
+            return new Rectangle(x, y, width, height);
+        }
+
+        // The window bounds should be within the visible part of the screen
+        int newX = x;
+        int newY = y;
+        int newW = width;
+        int newH = height;
+
+        // Now check each point is within the visible part of the screen
+        GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
+        Rectangle sB = gc.getBounds();
+        Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
+
+        int screenX = sB.x + sIn.left;
+        int screenY = sB.y + sIn.top;
+        int screenW = sB.width - sIn.left - sIn.right;
+        int screenH = sB.height - sIn.top - sIn.bottom;
+
+
+        // First make sure the size is withing the visible part of the screen
+        if (newW > screenW) {
+            newW = screenW;
+        }
+
+        if (newH > screenH) {
+            newH = screenH;
+        }
+
+        // Tweak the location if needed
+        if (newX < screenX) {
+            newX = screenX;
+        } else if (newX + newW > screenX + screenW) {
+            newX = screenX + screenW - newW;
+        }
+
+        if (newY < screenY) {
+            newY = screenY;
+        } else if (newY + newH > screenY + screenH) {
+            newY = screenY + screenH - newH;
+        }
+
+        return new Rectangle(newX, newY, newW, newH);
+    }
+
     //Fix for 6318144: PIT:Setting Min Size bigger than current size enlarges
     //the window but fails to revalidate, Sol-CDE
     //This bug is regression for
@@ -445,10 +492,14 @@
     //Note that this function is overriden in XDecoratedPeer so event
     //posting is not changing for decorated peers
     public void setBounds(int x, int y, int width, int height, int op) {
+        Rectangle newBounds = constrainBounds(x, y, width, height);
+
         XToolkit.awtLock();
         try {
             Rectangle oldBounds = getBounds();
-            super.setBounds(x, y, width, height, op);
+
+            super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
+
             Rectangle bounds = getBounds();
 
             XSizeHints hints = getHints();
@@ -1035,7 +1086,7 @@
         return !(target instanceof Frame || target instanceof Dialog);
     }
     boolean hasWarningWindow() {
-        return warningWindow != null;
+        return ((Window)target).getWarningString() != null;
     }
 
     // The height of menu bar window
--- a/src/solaris/classes/sun/awt/motif/MDialogPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/motif/MDialogPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -102,4 +102,9 @@
     public void blockWindows(java.util.List<Window> toBlock) {
         // do nothing
     }
+
+    @Override
+    final boolean isTargetUndecorated() {
+        return ((Dialog)target).isUndecorated();
+    }
 }
--- a/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -204,4 +204,10 @@
     }
 
     public native Rectangle getBoundsPrivate();
+
+    @Override
+    Rectangle constrainBounds(int x, int y, int width, int height) {
+        // We don't constrain the bounds of the EmbeddedFrames
+        return new Rectangle(x, y, width, height);
+    }
 }
--- a/src/solaris/classes/sun/awt/motif/MFramePeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/motif/MFramePeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -503,4 +503,9 @@
     public Rectangle getBoundsPrivate() {
         return getBounds();
     }
+
+    @Override
+    final boolean isTargetUndecorated() {
+        return ((Frame)target).isUndecorated();
+    }
 }
--- a/src/solaris/classes/sun/awt/motif/MWindowPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/awt/motif/MWindowPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -113,6 +113,12 @@
             insets.right = getInset("awt.frame.rightInset", -1);
         }
 
+        Rectangle bounds = target.getBounds();
+        sysX = bounds.x;
+        sysY = bounds.y;
+        sysW = bounds.width;
+        sysH = bounds.height;
+
         super.init(target);
         InputMethodManager imm = InputMethodManager.getInstance();
         String menuString = imm.getTriggerMenuString();
@@ -150,6 +156,7 @@
 
         GraphicsConfiguration gc = getGraphicsConfiguration();
         ((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
+
     }
 
     /* Support for multiple icons is not implemented in MAWT */
@@ -246,6 +253,8 @@
     // NOTE: This method may be called by privileged threads.
     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
     public void handleResize(int width, int height) {
+        sysW = width;
+        sysH = height;
 
         // REMIND: Is this secure? Can client code subclass input method?
         if (!tcList.isEmpty() &&
@@ -268,6 +277,8 @@
     }
 
     public void handleMoved(int x, int y) {
+        sysX = x;
+        sysY = y;
         postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));
     }
 
@@ -505,4 +516,87 @@
         }
         return false;
     }
+
+    private final boolean hasWarningWindow() {
+        return ((Window)target).getWarningString() != null;
+    }
+
+    // This method is overriden at Dialog and Frame peers.
+    boolean isTargetUndecorated() {
+        return true;
+    }
+
+    private volatile int sysX = 0;
+    private volatile int sysY = 0;
+    private volatile int sysW = 0;
+    private volatile int sysH = 0;
+
+    Rectangle constrainBounds(int x, int y, int width, int height) {
+        // We don't restrict the setBounds() operation if the code is trusted.
+        if (!hasWarningWindow()) {
+            return new Rectangle(x, y, width, height);
+        }
+
+        int newX = x;
+        int newY = y;
+        int newW = width;
+        int newH = height;
+
+        GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
+        Rectangle sB = gc.getBounds();
+        Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
+
+        int screenW = sB.width - sIn.left - sIn.right;
+        int screenH = sB.height - sIn.top - sIn.bottom;
+
+        // If it's undecorated or is not currently visible,
+        // then check each point is within the visible part of the screen
+        if (!target.isVisible() || isTargetUndecorated()) {
+            int screenX = sB.x + sIn.left;
+            int screenY = sB.y + sIn.top;
+
+            // First make sure the size is withing the visible part of the screen
+            if (newW > screenW) {
+                newW = screenW;
+            }
+
+            if (newH > screenH) {
+                newH = screenH;
+            }
+
+            // Tweak the location if needed
+            if (newX < screenX) {
+                newX = screenX;
+            } else if (newX + newW > screenX + screenW) {
+                newX = screenX + screenW - newW;
+            }
+
+            if (newY < screenY) {
+                newY = screenY;
+            } else if (newY + newH > screenY + screenH) {
+                newY = screenY + screenH - newH;
+            }
+        } else {
+            int maxW = Math.max(screenW, sysW);
+            int maxH = Math.max(screenH, sysH);
+
+            // Make sure the size is withing the visible part of the screen
+            // OR is less that the current size of the window.
+            if (newW > maxW) {
+                newW = maxW;
+            }
+
+            if (newH > maxH) {
+                newH = maxH;
+            }
+        }
+
+        return new Rectangle(newX, newY, newW, newH);
+    }
+
+    public void setBounds(int x, int y, int width, int height, int op) {
+        Rectangle newBounds = constrainBounds(x, y, width, height);
+        super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
+    }
+
 }
--- a/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java	Mon Apr 14 11:34:15 2008 -0700
@@ -217,8 +217,7 @@
                         Updator u = null;
                         while ((u = updateList.poll()) != null) {
                             // First add pollfd struct to clear out this fd
-                            putPollFD(updatePollArray, index, u.fd,
-                                      (short)POLLREMOVE);
+                            putPollFD(updatePollArray, index, u.fd, POLLREMOVE);
                             index++;
                             // Now add pollfd to update this fd, if necessary
                             if (u.mask != POLLREMOVE) {
--- a/src/solaris/classes/sun/security/provider/NativePRNG.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/classes/sun/security/provider/NativePRNG.java	Mon Apr 14 11:34:15 2008 -0700
@@ -71,8 +71,9 @@
     private static final RandomIO INSTANCE = initIO();
 
     private static RandomIO initIO() {
-        Object o = AccessController.doPrivileged(new PrivilegedAction() {
-            public Object run() {
+        return AccessController.doPrivileged(
+            new PrivilegedAction<RandomIO>() {
+                public RandomIO run() {
                 File randomFile = new File(NAME_RANDOM);
                 if (randomFile.exists() == false) {
                     return null;
@@ -88,7 +89,6 @@
                 }
             }
         });
-        return (RandomIO)o;
     }
 
     // return whether the NativePRNG is available
--- a/src/solaris/hpi/native_threads/src/sys_api_td.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/hpi/native_threads/src/sys_api_td.c	Mon Apr 14 11:34:15 2008 -0700
@@ -63,15 +63,8 @@
 #define CLOSEIO
 #endif /* NO_INTERRUPTIBLE_IO */
 
-/*
- * Linux <sys/resource.h> does not define rlim_t (solaris
- * does). THIS IS PROBABLY NOT THE RIGHT THING TO DO, so
- * somebody please fix this.
- */
-#ifdef __linux__
-typedef int rlim_t ;
-#endif
-
+/* Get typedef for rlim_t */
+#include <sys/resource.h>
 
 #ifdef CLOSEIO
 
--- a/src/solaris/native/java/io/FileOutputStream_md.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/native/java/io/FileOutputStream_md.c	Mon Apr 14 11:34:15 2008 -0700
@@ -53,13 +53,10 @@
  */
 
 JNIEXPORT void JNICALL
-Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this, jstring path) {
-    fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | O_TRUNC);
-}
-
-JNIEXPORT void JNICALL
-Java_java_io_FileOutputStream_openAppend(JNIEnv *env, jobject this, jstring path) {
-    fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | O_APPEND);
+Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this,
+                                   jstring path, jboolean append) {
+    fileOpen(env, this, path, fos_fd,
+             O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC));
 }
 
 JNIEXPORT void JNICALL
--- a/src/solaris/native/java/lang/UNIXProcess_md.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/native/java/lang/UNIXProcess_md.c	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1995-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -479,6 +479,37 @@
         close(fd);
 }
 
+/*
+ * Reads nbyte bytes from file descriptor fd into buf,
+ * The read operation is retried in case of EINTR or partial reads.
+ *
+ * Returns number of bytes read (normally nbyte, but may be less in
+ * case of EOF).  In case of read errors, returns -1 and sets errno.
+ */
+static ssize_t
+readFully(int fd, void *buf, size_t nbyte)
+{
+    ssize_t remaining = nbyte;
+    for (;;) {
+        ssize_t n = read(fd, buf, remaining);
+        if (n == 0) {
+            return nbyte - remaining;
+        } else if (n > 0) {
+            remaining -= n;
+            if (remaining <= 0)
+                return nbyte;
+            /* We were interrupted in the middle of reading the bytes.
+             * Unlikely, but possible. */
+            buf = (void *) (((char *)buf) + n);
+        } else if (errno == EINTR) {
+            /* Strange signals like SIGJVM1 are possible at any time.
+             * See http://www.dreamsongs.com/WorseIsBetter.html */
+        } else {
+            return -1;
+        }
+    }
+}
+
 #ifndef __solaris__
 #undef fork1
 #define fork1() fork()
@@ -491,10 +522,8 @@
                                        jbyteArray argBlock, jint argc,
                                        jbyteArray envBlock, jint envc,
                                        jbyteArray dir,
-                                       jboolean redirectErrorStream,
-                                       jobject stdin_fd,
-                                       jobject stdout_fd,
-                                       jobject stderr_fd)
+                                       jintArray std_fds,
+                                       jboolean redirectErrorStream)
 {
     int errnum;
     int resultPid = -1;
@@ -505,6 +534,7 @@
     const char *pargBlock = getBytes(env, argBlock);
     const char *penvBlock = getBytes(env, envBlock);
     const char *pdir      = getBytes(env, dir);
+    jint *fds = NULL;
 
     in[0] = in[1] = out[0] = out[1] = err[0] = err[1] = fail[0] = fail[1] = -1;
 
@@ -527,9 +557,13 @@
         initVectorFromBlock(envv, penvBlock, envc);
     }
 
-    if ((pipe(in)   < 0) ||
-        (pipe(out)  < 0) ||
-        (pipe(err)  < 0) ||
+    assert(std_fds != NULL);
+    fds = (*env)->GetIntArrayElements(env, std_fds, NULL);
+    if (fds == NULL) goto Catch;
+
+    if ((fds[0] == -1 && pipe(in)  < 0) ||
+        (fds[1] == -1 && pipe(out) < 0) ||
+        (fds[2] == -1 && pipe(err) < 0) ||
         (pipe(fail) < 0)) {
         throwIOException(env, errno, "Bad file descriptor");
         goto Catch;
@@ -544,23 +578,26 @@
     if (resultPid == 0) {
         /* Child process */
 
-        /* Close the parent sides of the pipe.
-           Give the child sides of the pipes the right fileno's.
+        /* Close the parent sides of the pipes.
            Closing pipe fds here is redundant, since closeDescriptors()
            would do it anyways, but a little paranoia is a good thing. */
+        closeSafely(in[1]);
+        closeSafely(out[0]);
+        closeSafely(err[0]);
+        closeSafely(fail[0]);
+
+        /* Give the child sides of the pipes the right fileno's. */
         /* Note: it is possible for in[0] == 0 */
-        close(in[1]);
-        moveDescriptor(in[0], STDIN_FILENO);
-        close(out[0]);
-        moveDescriptor(out[1], STDOUT_FILENO);
-        close(err[0]);
+        moveDescriptor(in[0] != -1 ?  in[0] : fds[0], STDIN_FILENO);
+        moveDescriptor(out[1]!= -1 ? out[1] : fds[1], STDOUT_FILENO);
+
         if (redirectErrorStream) {
-            close(err[1]);
+            closeSafely(err[1]);
             dup2(STDOUT_FILENO, STDERR_FILENO);
         } else {
-            moveDescriptor(err[1], STDERR_FILENO);
+            moveDescriptor(err[1] != -1 ? err[1] : fds[2], STDERR_FILENO);
         }
-        close(fail[0]);
+
         moveDescriptor(fail[1], FAIL_FILENO);
 
         /* close everything */
@@ -600,15 +637,21 @@
     /* parent process */
 
     close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */
-    if (read(fail[0], &errnum, sizeof(errnum)) != 0) {
+
+    switch (readFully(fail[0], &errnum, sizeof(errnum))) {
+    case 0: break; /* Exec succeeded */
+    case sizeof(errnum):
         waitpid(resultPid, NULL, 0);
         throwIOException(env, errnum, "Exec failed");
         goto Catch;
+    default:
+        throwIOException(env, errno, "Read failed");
+        goto Catch;
     }
 
-    (*env)->SetIntField(env, stdin_fd,  IO_fd_fdID, in [1]);
-    (*env)->SetIntField(env, stdout_fd, IO_fd_fdID, out[0]);
-    (*env)->SetIntField(env, stderr_fd, IO_fd_fdID, err[0]);
+    fds[0] = (in [1] != -1) ? in [1] : -1;
+    fds[1] = (out[0] != -1) ? out[0] : -1;
+    fds[2] = (err[0] != -1) ? err[0] : -1;
 
  Finally:
     /* Always clean up the child's side of the pipes */
@@ -628,6 +671,9 @@
     releaseBytes(env, envBlock, penvBlock);
     releaseBytes(env, dir,      pdir);
 
+    if (fds != NULL)
+        (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0);
+
     return resultPid;
 
  Catch:
--- a/src/solaris/native/sun/nio/ch/FileChannelImpl.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/solaris/native/sun/nio/ch/FileChannelImpl.c	Mon Apr 14 11:34:15 2008 -0700
@@ -31,6 +31,7 @@
 #include <sys/stat.h>
 #include "sun_nio_ch_FileChannelImpl.h"
 #include "java_lang_Integer.h"
+#include "java_lang_Long.h"
 #include "nio.h"
 #include "nio_util.h"
 #include <dlfcn.h>
@@ -291,7 +292,11 @@
     struct flock64 fl;
 
     fl.l_whence = SEEK_SET;
-    fl.l_len = (off64_t)size;
+    if (size == (jlong)java_lang_Long_MAX_VALUE) {
+        fl.l_len = (off64_t)0;
+    } else {
+        fl.l_len = (off64_t)size;
+    }
     fl.l_start = (off64_t)pos;
     if (shared == JNI_TRUE) {
         fl.l_type = F_RDLCK;
@@ -325,7 +330,11 @@
     int cmd = F_SETLK64;
 
     fl.l_whence = SEEK_SET;
-    fl.l_len = (off64_t)size;
+    if (size == (jlong)java_lang_Long_MAX_VALUE) {
+        fl.l_len = (off64_t)0;
+    } else {
+        fl.l_len = (off64_t)size;
+    }
     fl.l_start = (off64_t)pos;
     fl.l_type = F_UNLCK;
     lockResult = fcntl(fd, cmd, &fl);
--- a/src/windows/bin/java_md.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/bin/java_md.c	Mon Apr 14 11:34:15 2008 -0700
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <wtypes.h>
+#include <commctrl.h>
 
 #include <jni.h>
 #include "java.h"
@@ -52,11 +53,6 @@
 
 static jboolean _isjavaw = JNI_FALSE;
 
-void
-SetJavaw()
-{
-    _isjavaw = JNI_TRUE;
-}
 
 jboolean
 IsJavaw()
@@ -999,3 +995,20 @@
 
 /* Linux only, empty on windows. */
 void SetJavaLauncherPlatformProps() {}
+
+void
+InitLauncher(boolean javaw)
+{
+    INITCOMMONCONTROLSEX icx;
+
+    /*
+     * Required for javaw mode MessageBox output as well as for
+     * HotSpot -XX:+ShowMessageBoxOnError in java mode, an empty
+     * flag field is sufficient to perform the basic UI initialization.
+     */
+    memset(&icx, 0, sizeof(INITCOMMONCONTROLSEX));
+    icx.dwSize = sizeof(INITCOMMONCONTROLSEX);
+    InitCommonControlsEx(&icx);
+    _isjavaw = javaw;
+    JLI_SetTraceLauncher();
+}
--- a/src/windows/classes/java/io/FileDescriptor.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/classes/java/io/FileDescriptor.java	Mon Apr 14 11:34:15 2008 -0700
@@ -29,17 +29,14 @@
 
 /**
  * Instances of the file descriptor class serve as an opaque handle
- * to the underlying machine-specific structure representing an open
- * file, an open socket, or another source or sink of bytes. The
- * main practical use for a file descriptor is to create a
- * <code>FileInputStream</code> or <code>FileOutputStream</code> to
- * contain it.
- * <p>
- * Applications should not create their own file descriptors.
+ * to the underlying machine-specific structure representing an
+ * open file, an open socket, or another source or sink of bytes.
+ * The main practical use for a file descriptor is to create a
+ * {@link FileInputStream} or {@link FileOutputStream} to contain it.
+ *
+ * <p>Applications should not create their own file descriptors.
  *
  * @author  Pavani Diwanji
- * @see     java.io.FileInputStream
- * @see     java.io.FileOutputStream
  * @since   JDK1.0
  */
 public final class FileDescriptor {
@@ -81,6 +78,14 @@
                 public int get(FileDescriptor obj) {
                     return obj.fd;
                 }
+
+                public void setHandle(FileDescriptor obj, long handle) {
+                    obj.handle = handle;
+                }
+
+                public long getHandle(FileDescriptor obj) {
+                    return obj.handle;
+                }
             }
         );
     }
@@ -88,7 +93,7 @@
     /**
      * A handle to the standard input stream. Usually, this file
      * descriptor is not used directly, but rather via the input stream
-     * known as <code>System.in</code>.
+     * known as {@code System.in}.
      *
      * @see     java.lang.System#in
      */
@@ -97,7 +102,7 @@
     /**
      * A handle to the standard output stream. Usually, this file
      * descriptor is not used directly, but rather via the output stream
-     * known as <code>System.out</code>.
+     * known as {@code System.out}.
      * @see     java.lang.System#out
      */
     public static final FileDescriptor out = standardStream(1);
@@ -105,7 +110,7 @@
     /**
      * A handle to the standard error stream. Usually, this file
      * descriptor is not used directly, but rather via the output stream
-     * known as <code>System.err</code>.
+     * known as {@code System.err}.
      *
      * @see     java.lang.System#err
      */
@@ -114,9 +119,9 @@
     /**
      * Tests if this file descriptor object is valid.
      *
-     * @return  <code>true</code> if the file descriptor object represents a
+     * @return  {@code true} if the file descriptor object represents a
      *          valid, open file, socket, or other active I/O connection;
-     *          <code>false</code> otherwise.
+     *          {@code false} otherwise.
      */
     public boolean valid() {
         return ((handle != -1) || (fd != -1));
--- a/src/windows/classes/java/lang/ProcessImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/classes/java/lang/ProcessImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -25,7 +25,16 @@
 
 package java.lang;
 
-import java.io.*;
+import java.io.IOException;
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileDescriptor;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.lang.ProcessBuilder.Redirect;
 
 /* This class is for the exclusive use of ProcessBuilder.start() to
  * create new processes.
@@ -35,30 +44,82 @@
  */
 
 final class ProcessImpl extends Process {
+    private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
+        = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
 
     // System-dependent portion of ProcessBuilder.start()
     static Process start(String cmdarray[],
                          java.util.Map<String,String> environment,
                          String dir,
+                         ProcessBuilder.Redirect[] redirects,
                          boolean redirectErrorStream)
         throws IOException
     {
         String envblock = ProcessEnvironment.toEnvironmentBlock(environment);
-        return new ProcessImpl(cmdarray, envblock, dir, redirectErrorStream);
+
+        FileInputStream  f0 = null;
+        FileOutputStream f1 = null;
+        FileOutputStream f2 = null;
+
+        try {
+            long[] stdHandles;
+            if (redirects == null) {
+                stdHandles = new long[] { -1L, -1L, -1L };
+            } else {
+                stdHandles = new long[3];
+
+                if (redirects[0] == Redirect.PIPE)
+                    stdHandles[0] = -1L;
+                else if (redirects[0] == Redirect.INHERIT)
+                    stdHandles[0] = fdAccess.getHandle(FileDescriptor.in);
+                else {
+                    f0 = new FileInputStream(redirects[0].file());
+                    stdHandles[0] = fdAccess.getHandle(f0.getFD());
+                }
+
+                if (redirects[1] == Redirect.PIPE)
+                    stdHandles[1] = -1L;
+                else if (redirects[1] == Redirect.INHERIT)
+                    stdHandles[1] = fdAccess.getHandle(FileDescriptor.out);
+                else {
+                    f1 = redirects[1].toFileOutputStream();
+                    stdHandles[1] = fdAccess.getHandle(f1.getFD());
+                }
+
+                if (redirects[2] == Redirect.PIPE)
+                    stdHandles[2] = -1L;
+                else if (redirects[2] == Redirect.INHERIT)
+                    stdHandles[2] = fdAccess.getHandle(FileDescriptor.err);
+                else {
+                    f2 = redirects[2].toFileOutputStream();
+                    stdHandles[2] = fdAccess.getHandle(f2.getFD());
+                }
+            }
+
+            return new ProcessImpl(cmdarray, envblock, dir,
+                                   stdHandles, redirectErrorStream);
+        } finally {
+            // In theory, close() can throw IOException
+            // (although it is rather unlikely to happen here)
+            try { if (f0 != null) f0.close(); }
+            finally {
+                try { if (f1 != null) f1.close(); }
+                finally { if (f2 != null) f2.close(); }
+            }
+        }
+
     }
 
     private long handle = 0;
-    private FileDescriptor stdin_fd;
-    private FileDescriptor stdout_fd;
-    private FileDescriptor stderr_fd;
     private OutputStream stdin_stream;
     private InputStream stdout_stream;
     private InputStream stderr_stream;
 
-    private ProcessImpl(String cmd[],
-                        String envblock,
-                        String path,
-                        boolean redirectErrorStream)
+    private ProcessImpl(final String cmd[],
+                        final String envblock,
+                        final String path,
+                        final long[] stdHandles,
+                        final boolean redirectErrorStream)
         throws IOException
     {
         // Win32 CreateProcess requires cmd[0] to be normalized
@@ -91,25 +152,39 @@
         }
         String cmdstr = cmdbuf.toString();
 
-        stdin_fd  = new FileDescriptor();
-        stdout_fd = new FileDescriptor();
-        stderr_fd = new FileDescriptor();
-
-        handle = create(cmdstr, envblock, path, redirectErrorStream,
-                        stdin_fd, stdout_fd, stderr_fd);
+        handle = create(cmdstr, envblock, path,
+                        stdHandles, redirectErrorStream);
 
         java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction() {
-            public Object run() {
-                stdin_stream =
-                    new BufferedOutputStream(new FileOutputStream(stdin_fd));
-                stdout_stream =
-                    new BufferedInputStream(new FileInputStream(stdout_fd));
-                stderr_stream =
-                    new FileInputStream(stderr_fd);
-                return null;
+        new java.security.PrivilegedAction<Void>() {
+        public Void run() {
+            if (stdHandles[0] == -1L)
+                stdin_stream = new ProcessBuilder.NullOutputStream();
+            else {
+                FileDescriptor stdin_fd = new FileDescriptor();
+                fdAccess.setHandle(stdin_fd, stdHandles[0]);
+                stdin_stream = new BufferedOutputStream(
+                    new FileOutputStream(stdin_fd));
             }
-        });
+
+            if (stdHandles[1] == -1L)
+                stdout_stream = new ProcessBuilder.NullInputStream();
+            else {
+                FileDescriptor stdout_fd = new FileDescriptor();
+                fdAccess.setHandle(stdout_fd, stdHandles[1]);
+                stdout_stream = new BufferedInputStream(
+                    new FileInputStream(stdout_fd));
+            }
+
+            if (stdHandles[2] == -1L)
+                stderr_stream = new ProcessBuilder.NullInputStream();
+            else {
+                FileDescriptor stderr_fd = new FileDescriptor();
+                fdAccess.setHandle(stderr_fd, stdHandles[2]);
+                stderr_stream = new FileInputStream(stderr_fd);
+            }
+
+            return null; }});
     }
 
     public OutputStream getOutputStream() {
@@ -150,13 +225,30 @@
     public void destroy() { terminateProcess(handle); }
     private static native void terminateProcess(long handle);
 
+    /**
+     * Create a process using the win32 function CreateProcess.
+     *
+     * @param cmdstr the Windows commandline
+     * @param envblock NUL-separated, double-NUL-terminated list of
+     *        environment strings in VAR=VALUE form
+     * @param dir the working directory of the process, or null if
+     *        inheriting the current directory from the parent process
+     * @param stdHandles array of windows HANDLEs.  Indexes 0, 1, and
+     *        2 correspond to standard input, standard output and
+     *        standard error, respectively.  On input, a value of -1
+     *        means to create a pipe to connect child and parent
+     *        processes.  On output, a value which is not -1 is the
+     *        parent pipe handle corresponding to the pipe which has
+     *        been created.  An element of this array is -1 on input
+     *        if and only if it is <em>not</em> -1 on output.
+     * @param redirectErrorStream redirectErrorStream attribute
+     * @return the native subprocess HANDLE returned by CreateProcess
+     */
     private static native long create(String cmdstr,
                                       String envblock,
                                       String dir,
-                                      boolean redirectErrorStream,
-                                      FileDescriptor in_fd,
-                                      FileDescriptor out_fd,
-                                      FileDescriptor err_fd)
+                                      long[] stdHandles,
+                                      boolean redirectErrorStream)
         throws IOException;
 
     private static native boolean closeHandle(long handle);
--- a/src/windows/classes/java/net/DualStackPlainSocketImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/classes/java/net/DualStackPlainSocketImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -218,9 +218,6 @@
         return value;
     }
 
-    int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd)
-        throws SocketException {return 0;}   // un-implemented REMOVE
-
     void socketSendUrgentData(int data) throws IOException {
         int nativefd = checkAndReturnNativeFD();
         sendOOB(nativefd, data);
--- a/src/windows/classes/java/net/PlainSocketImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/classes/java/net/PlainSocketImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -304,11 +304,6 @@
         return impl.socketGetOption(opt, iaContainerObj);
     }
 
-    int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd)
-        throws SocketException {
-        return impl.socketGetOption1(opt, iaContainerObj, fd);
-    }
-
     void socketSendUrgentData(int data) throws IOException {
         impl.socketSendUrgentData(data);
     }
--- a/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java	Mon Apr 14 11:34:15 2008 -0700
@@ -199,8 +199,5 @@
 
     native int socketGetOption(int opt, Object iaContainerObj) throws SocketException;
 
-    native int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd)
-        throws SocketException;
-
     native void socketSendUrgentData(int data) throws IOException;
 }
--- a/src/windows/classes/sun/awt/windows/WDialogPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/classes/sun/awt/windows/WDialogPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -108,11 +108,18 @@
         }
     }
 
+    @Override
+    boolean isTargetUndecorated() {
+        return ((Dialog)target).isUndecorated();
+    }
+
     public void reshape(int x, int y, int width, int height) {
+        Rectangle newBounds = constrainBounds(x, y, width, height);
+
         if (((Dialog)target).isUndecorated()) {
-            super.reshape(x,y,width,height);
+            super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
         } else {
-            reshapeFrame(x,y,width,height);
+            reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
         }
     }
 
--- a/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -65,4 +65,10 @@
     public native Rectangle getBoundsPrivate();
 
     public native void synthesizeWmActivate(boolean doActivate);
+
+    @Override
+    Rectangle constrainBounds(int x, int y, int width, int height) {
+        // We don't constrain the bounds of the EmbeddedFrames
+        return new Rectangle(x, y, width, height);
+    }
 }
--- a/src/windows/classes/sun/awt/windows/WFramePeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/classes/sun/awt/windows/WFramePeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -64,11 +64,18 @@
         }
     }
 
+    @Override
+    boolean isTargetUndecorated() {
+        return ((Frame)target).isUndecorated();
+    }
+
     public void reshape(int x, int y, int width, int height) {
+        Rectangle newBounds = constrainBounds(x, y, width, height);
+
         if (((Frame)target).isUndecorated()) {
-            super.reshape(x,y,width,height);
+            super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
         } else {
-            reshapeFrame(x,y,width,height);
+            reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
         }
     }
 
--- a/src/windows/classes/sun/awt/windows/WObjectPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/classes/sun/awt/windows/WObjectPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,12 @@
         initIDs();
     }
 
-    long      pData;    // The Windows handle for the native widget.
-    Object    target;   // The associated AWT object.
+    // The Windows handle for the native widget.
+    long pData;
+    // if the native peer has been destroyed
+    boolean destroyed = false;
+    // The associated AWT object.
+    Object target;
 
     private volatile boolean disposed;
 
--- a/src/windows/classes/sun/awt/windows/WWindowPeer.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/classes/sun/awt/windows/WWindowPeer.java	Mon Apr 14 11:34:15 2008 -0700
@@ -434,6 +434,97 @@
      private native void nativeGrab();
      private native void nativeUngrab();
 
+     private final boolean hasWarningWindow() {
+         return ((Window)target).getWarningString() != null;
+     }
+
+     boolean isTargetUndecorated() {
+         return true;
+     }
+
+     // These are the peer bounds. They get updated at:
+     //    1. the WWindowPeer.setBounds() method.
+     //    2. the native code (on WM_SIZE/WM_MOVE)
+     private volatile int sysX = 0;
+     private volatile int sysY = 0;
+     private volatile int sysW = 0;
+     private volatile int sysH = 0;
+
+     Rectangle constrainBounds(int x, int y, int width, int height) {
+         // We don't restrict the setBounds() operation if the code is trusted.
+         if (!hasWarningWindow()) {
+             return new Rectangle(x, y, width, height);
+         }
+
+         int newX = x;
+         int newY = y;
+         int newW = width;
+         int newH = height;
+
+         GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
+         Rectangle sB = gc.getBounds();
+         Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
+
+         int screenW = sB.width - sIn.left - sIn.right;
+         int screenH = sB.height - sIn.top - sIn.bottom;
+
+         // If it's undecorated or is not currently visible
+         if (!((Window)target).isVisible() || isTargetUndecorated()) {
+             // Now check each point is within the visible part of the screen
+             int screenX = sB.x + sIn.left;
+             int screenY = sB.y + sIn.top;
+
+             // First make sure the size is withing the visible part of the screen
+             if (newW > screenW) {
+                 newW = screenW;
+             }
+
+             if (newH > screenH) {
+                 newH = screenH;
+             }
+
+             // Tweak the location if needed
+             if (newX < screenX) {
+                 newX = screenX;
+             } else if (newX + newW > screenX + screenW) {
+                 newX = screenX + screenW - newW;
+             }
+
+             if (newY < screenY) {
+                 newY = screenY;
+             } else if (newY + newH > screenY + screenH) {
+                 newY = screenY + screenH - newH;
+             }
+         } else {
+             int maxW = Math.max(screenW, sysW);
+             int maxH = Math.max(screenH, sysH);
+
+             // Make sure the size is withing the visible part of the screen
+             // OR less that the current size of the window.
+             if (newW > maxW) {
+                 newW = maxW;
+             }
+
+             if (newH > maxH) {
+                 newH = maxH;
+             }
+         }
+
+         return new Rectangle(newX, newY, newW, newH);
+     }
+
+     @Override
+     public void setBounds(int x, int y, int width, int height, int op) {
+         Rectangle newBounds = constrainBounds(x, y, width, height);
+
+         sysX = newBounds.x;
+         sysY = newBounds.y;
+         sysW = newBounds.width;
+         sysH = newBounds.height;
+
+         super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
+     }
+
     /*
      * The method maps the list of the active windows to the window's AppContext,
      * then the method registers ActiveWindowListener, GuiDisposedListener listeners;
--- a/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	Mon Apr 14 11:34:15 2008 -0700
@@ -48,8 +48,8 @@
     private static final String INFO = "Sun's Microsoft Crypto API provider";
 
     static {
-        AccessController.doPrivileged(new PrivilegedAction() {
-            public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
                 System.loadLibrary("sunmscapi");
                 return null;
             }
--- a/src/windows/native/java/io/FileOutputStream_md.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/java/io/FileOutputStream_md.c	Mon Apr 14 11:34:15 2008 -0700
@@ -39,8 +39,6 @@
 
 jfieldID fos_fd; /* id for jobject 'fd' in java.io.FileOutputStream */
 
-jfieldID fos_append;
-
 /**************************************************************
  * static methods to store field ID's in initializers
  */
@@ -49,7 +47,6 @@
 Java_java_io_FileOutputStream_initIDs(JNIEnv *env, jclass fosClass) {
     fos_fd =
         (*env)->GetFieldID(env, fosClass, "fd", "Ljava/io/FileDescriptor;");
-    fos_append = (*env)->GetFieldID(env, fosClass, "append", "Z");
 }
 
 /**************************************************************
@@ -57,45 +54,20 @@
  */
 
 JNIEXPORT void JNICALL
-Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this, jstring path) {
-    fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | O_TRUNC);
-}
-
-JNIEXPORT void JNICALL
-Java_java_io_FileOutputStream_openAppend(JNIEnv *env, jobject this, jstring path) {
-    fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | O_APPEND);
+Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this,
+                                   jstring path, jboolean append) {
+    fileOpen(env, this, path, fos_fd,
+             O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC));
 }
 
 JNIEXPORT void JNICALL
 Java_java_io_FileOutputStream_write(JNIEnv *env, jobject this, jint byte) {
-    jboolean append = (*env)->GetBooleanField(env, this, fos_append);
-    FD fd = GET_FD(this, fos_fd);
-    if (fd == -1) {
-        JNU_ThrowIOException(env, "Stream Closed");
-        return;
-    }
-    if (append == JNI_TRUE) {
-        if (IO_Lseek(fd, 0L, SEEK_END) == -1) {
-            JNU_ThrowIOExceptionWithLastError(env, "Append failed");
-        }
-    }
     writeSingle(env, this, byte, fos_fd);
 }
 
 JNIEXPORT void JNICALL
 Java_java_io_FileOutputStream_writeBytes(JNIEnv *env,
     jobject this, jbyteArray bytes, jint off, jint len) {
-    jboolean append = (*env)->GetBooleanField(env, this, fos_append);
-    FD fd = GET_FD(this, fos_fd);
-    if (fd == -1) {
-        JNU_ThrowIOException(env, "Stream Closed");
-        return;
-    }
-    if (append == JNI_TRUE) {
-        if (IO_Lseek(fd, 0L, SEEK_END) == -1) {
-            JNU_ThrowIOExceptionWithLastError(env, "Append failed");
-        }
-    }
     writeBytes(env, this, bytes, off, len, fos_fd);
 }
 
--- a/src/windows/native/java/io/io_util_md.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/java/io/io_util_md.c	Mon Apr 14 11:34:15 2008 -0700
@@ -42,7 +42,7 @@
 
 extern jboolean onNT = JNI_FALSE;
 
-static int MAX_INPUT_EVENTS = 2000;
+static DWORD MAX_INPUT_EVENTS = 2000;
 
 void
 initializeWindowsVersion() {
@@ -190,9 +190,16 @@
 jlong
 winFileHandleOpen(JNIEnv *env, jstring path, int flags)
 {
+    /* To implement O_APPEND, we use the strategy from
+       http://msdn2.microsoft.com/en-us/library/aa363858.aspx
+       "You can get atomic append by opening a file with
+       FILE_APPEND_DATA access and _without_ FILE_WRITE_DATA access.
+       If you do this then all writes will ignore the current file
+       pointer and be done at the end-of file." */
     const DWORD access =
-        (flags & O_RDWR)   ? (GENERIC_WRITE | GENERIC_READ) :
+        (flags & O_APPEND) ? (FILE_GENERIC_WRITE & ~FILE_WRITE_DATA) :
         (flags & O_WRONLY) ?  GENERIC_WRITE :
+        (flags & O_RDWR)   ? (GENERIC_READ | GENERIC_WRITE) :
         GENERIC_READ;
     const DWORD sharing =
         FILE_SHARE_READ | FILE_SHARE_WRITE;
@@ -444,24 +451,6 @@
     return 0;
 }
 
-int
-handleFileSizeFD(jlong fd, jlong *size)
-{
-    DWORD sizeLow = 0;
-    DWORD sizeHigh = 0;
-    HANDLE h = (HANDLE)fd;
-    if (h == INVALID_HANDLE_VALUE) {
-        return -1;
-    }
-    sizeLow = GetFileSize(h, &sizeHigh);
-    if (sizeLow == ((DWORD)-1)) {
-        if (GetLastError() != ERROR_SUCCESS) {
-            return -1;
-        }
-    }
-    return (((jlong)sizeHigh) << 32) | sizeLow;
-}
-
 JNIEXPORT
 size_t
 handleRead(jlong fd, void *buf, jint len)
@@ -513,7 +502,7 @@
     FD fd = GET_FD(this, fid);
     HANDLE h = (HANDLE)fd;
 
-    if (fd == INVALID_HANDLE_VALUE) {
+    if (h == INVALID_HANDLE_VALUE) {
         return 0;
     }
 
--- a/src/windows/native/java/io/io_util_md.h	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/java/io/io_util_md.h	Mon Apr 14 11:34:15 2008 -0700
@@ -38,7 +38,6 @@
 int handleAvailable(jlong fd, jlong *pbytes);
 JNIEXPORT int handleSync(jlong fd);
 int handleSetLength(jlong fd, jlong length);
-int handleFileSizeFD(jlong fd, jlong *size);
 JNIEXPORT size_t handleRead(jlong fd, void *buf, jint len);
 JNIEXPORT size_t handleWrite(jlong fd, const void *buf, jint len);
 jint handleClose(JNIEnv *env, jobject this, jfieldID fid);
--- a/src/windows/native/java/lang/ProcessImpl_md.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/java/lang/ProcessImpl_md.c	Mon Apr 14 11:34:15 2008 -0700
@@ -33,7 +33,12 @@
 #include <windows.h>
 #include <io.h>
 
-#define PIPE_SIZE 4096
+/* We try to make sure that we can read and write 4095 bytes (the
+ * fixed limit on Linux) to the pipe on all operating systems without
+ * deadlock.  Windows 2000 inexplicably appears to need an extra 24
+ * bytes of slop to avoid deadlock.
+ */
+#define PIPE_SIZE (4096+24)
 
 char *
 extractExecutablePath(JNIEnv *env, char *source)
@@ -120,7 +125,7 @@
 static void
 closeSafely(HANDLE handle)
 {
-    if (handle)
+    if (handle != INVALID_HANDLE_VALUE)
         CloseHandle(handle);
 }
 
@@ -129,23 +134,22 @@
                                   jstring cmd,
                                   jstring envBlock,
                                   jstring dir,
-                                  jboolean redirectErrorStream,
-                                  jobject in_fd,
-                                  jobject out_fd,
-                                  jobject err_fd)
+                                  jlongArray stdHandles,
+                                  jboolean redirectErrorStream)
 {
-    HANDLE inRead   = 0;
-    HANDLE inWrite  = 0;
-    HANDLE outRead  = 0;
-    HANDLE outWrite = 0;
-    HANDLE errRead  = 0;
-    HANDLE errWrite = 0;
+    HANDLE inRead   = INVALID_HANDLE_VALUE;
+    HANDLE inWrite  = INVALID_HANDLE_VALUE;
+    HANDLE outRead  = INVALID_HANDLE_VALUE;
+    HANDLE outWrite = INVALID_HANDLE_VALUE;
+    HANDLE errRead  = INVALID_HANDLE_VALUE;
+    HANDLE errWrite = INVALID_HANDLE_VALUE;
     SECURITY_ATTRIBUTES sa;
     PROCESS_INFORMATION pi;
     STARTUPINFO si;
     LPTSTR  pcmd      = NULL;
     LPCTSTR pdir      = NULL;
     LPVOID  penvBlock = NULL;
+    jlong  *handles   = NULL;
     jlong ret = 0;
     OSVERSIONINFO ver;
     jboolean onNT = JNI_FALSE;
@@ -156,17 +160,6 @@
     if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT)
         onNT = JNI_TRUE;
 
-    sa.nLength = sizeof(sa);
-    sa.lpSecurityDescriptor = 0;
-    sa.bInheritHandle = TRUE;
-
-    if (!(CreatePipe(&inRead,  &inWrite,  &sa, PIPE_SIZE) &&
-          CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE) &&
-          CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE))) {
-        win32Error(env, "CreatePipe");
-        goto Catch;
-    }
-
     assert(cmd != NULL);
     pcmd = (LPTSTR) JNU_GetStringPlatformChars(env, cmd, NULL);
     if (pcmd == NULL) goto Catch;
@@ -184,19 +177,62 @@
         if (penvBlock == NULL) goto Catch;
     }
 
+    assert(stdHandles != NULL);
+    handles = (*env)->GetLongArrayElements(env, stdHandles, NULL);
+    if (handles == NULL) goto Catch;
+
     memset(&si, 0, sizeof(si));
     si.cb = sizeof(si);
     si.dwFlags = STARTF_USESTDHANDLES;
-    si.hStdInput  = inRead;
-    si.hStdOutput = outWrite;
-    si.hStdError  = redirectErrorStream ? outWrite : errWrite;
+
+    sa.nLength = sizeof(sa);
+    sa.lpSecurityDescriptor = 0;
+    sa.bInheritHandle = TRUE;
+
+    if (handles[0] != (jlong) -1) {
+        si.hStdInput = (HANDLE) handles[0];
+        handles[0] = (jlong) -1;
+    } else {
+        if (! CreatePipe(&inRead,  &inWrite,  &sa, PIPE_SIZE)) {
+            win32Error(env, "CreatePipe");
+            goto Catch;
+        }
+        si.hStdInput = inRead;
+        SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, FALSE);
+        handles[0] = (jlong) inWrite;
+    }
+    SetHandleInformation(si.hStdInput, HANDLE_FLAG_INHERIT, TRUE);
 
-    SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, FALSE);
-    SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, FALSE);
-    SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, FALSE);
+    if (handles[1] != (jlong) -1) {
+        si.hStdOutput = (HANDLE) handles[1];
+        handles[1] = (jlong) -1;
+    } else {
+        if (! CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE)) {
+            win32Error(env, "CreatePipe");
+            goto Catch;
+        }
+        si.hStdOutput = outWrite;
+        SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, FALSE);
+        handles[1] = (jlong) outRead;
+    }
+    SetHandleInformation(si.hStdOutput, HANDLE_FLAG_INHERIT, TRUE);
 
-    if (redirectErrorStream)
-        SetHandleInformation(errWrite, HANDLE_FLAG_INHERIT, FALSE);
+    if (redirectErrorStream) {
+        si.hStdError = si.hStdOutput;
+        handles[2] = (jlong) -1;
+    } else if (handles[2] != (jlong) -1) {
+        si.hStdError = (HANDLE) handles[2];
+        handles[2] = (jlong) -1;
+    } else {
+        if (! CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE)) {
+            win32Error(env, "CreatePipe");
+            goto Catch;
+        }
+        si.hStdError = errWrite;
+        SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, FALSE);
+        handles[2] = (jlong) errRead;
+    }
+    SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, TRUE);
 
     if (onNT)
         processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;
@@ -232,9 +268,6 @@
 
     CloseHandle(pi.hThread);
     ret = (jlong)pi.hProcess;
-    (*env)->SetLongField(env, in_fd,  IO_handle_fdID, (jlong)inWrite);
-    (*env)->SetLongField(env, out_fd, IO_handle_fdID, (jlong)outRead);
-    (*env)->SetLongField(env, err_fd, IO_handle_fdID, (jlong)errRead);
 
  Finally:
     /* Always clean up the child's side of the pipes */
@@ -252,6 +285,9 @@
         else
             JNU_ReleaseStringPlatformChars(env, dir, (char *) penvBlock);
     }
+    if (handles != NULL)
+        (*env)->ReleaseLongArrayElements(env, stdHandles, handles, 0);
+
     return ret;
 
  Catch:
--- a/src/windows/native/java/lang/java_props_md.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/java/lang/java_props_md.c	Mon Apr 14 11:34:15 2008 -0700
@@ -673,13 +673,13 @@
     /* OS properties */
     {
         char buf[100];
-        OSVERSIONINFO ver;
+        OSVERSIONINFOEX ver;
         ver.dwOSVersionInfoSize = sizeof(ver);
-        GetVersionEx(&ver);
+        GetVersionEx((OSVERSIONINFO *) &ver);
 
         /*
          * From msdn page on OSVERSIONINFOEX, current as of this
-         * writing decoding of dwMajorVersion and dwMinorVersion.
+         * writing, decoding of dwMajorVersion and dwMinorVersion.
          *
          *  Operating system            dwMajorVersion  dwMinorVersion
          * ==================           ==============  ==============
@@ -692,7 +692,7 @@
          * Windows 2000                 5               0
          * Windows XP                   5               1
          * Windows Server 2003 family   5               2
-         * Windows Vista                6               0
+         * Windows Vista family         6               0
          *
          * This mapping will presumably be augmented as new Windows
          * versions are released.
@@ -724,7 +724,20 @@
                 default: sprops.os_name = "Windows NT (unknown)"; break;
                 }
             } else if (ver.dwMajorVersion == 6) {
-                sprops.os_name = "Windows Vista";
+                /*
+                 * From MSDN OSVERSIONINFOEX documentation:
+                 *
+                 * "Because the version numbers for Windows Server 2008
+                 * and Windows Vista are identical, you must also test
+                 * whether the wProductType member is VER_NT_WORKSTATION.
+                 * If wProductType is VER_NT_WORKSTATION, the operating
+                 * system is Windows Vista; otherwise, it is Windows
+                 * Server 2008."
+                 */
+                if (ver.wProductType == VER_NT_WORKSTATION)
+                    sprops.os_name = "Windows Vista";
+                else
+                    sprops.os_name = "Windows Server 2008";
             } else {
                 sprops.os_name = "Windows NT (unknown)";
             }
--- a/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c	Mon Apr 14 11:34:15 2008 -0700
@@ -36,6 +36,8 @@
 #include <tchar.h>
 #include <fcntl.h>
 
+#include "jni_util.h"
+
 #define SECURITY_WIN32
 #include "sspi.h"
 #include "issperr.h"
@@ -52,7 +54,7 @@
 static COMPLETE_AUTH_TOKEN_FN pCompleteAuthToken;
 static DELETE_SECURITY_CONTEXT_FN pDeleteSecurityContext;
 
-static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle, SecBufferDesc OutBuffDesc);
+static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle);
 
 static jfieldID ntlm_ctxHandleID;
 static jfieldID ntlm_crdHandleID;
@@ -117,22 +119,36 @@
 {
     SEC_WINNT_AUTH_IDENTITY   AuthId;
     SEC_WINNT_AUTH_IDENTITY * pAuthId;
-    CHAR        *pUser = 0;
-    CHAR        *pDomain = 0;
-    CHAR        *pPassword = 0;
+    const CHAR        *pUser = 0;
+    const CHAR        *pDomain = 0;
+    const CHAR        *pPassword = 0;
     CredHandle      *pCred;
     TimeStamp            ltime;
     jboolean         isCopy;
     SECURITY_STATUS      ss;
 
     if (user != 0) {
-        pUser = (CHAR *)(*env)->GetStringUTFChars(env, user, &isCopy);
+        pUser = JNU_GetStringPlatformChars(env, user, &isCopy);
+        if (pUser == NULL)
+            return 0;  // pending Exception
     }
     if (domain != 0) {
-        pDomain = (CHAR *)(*env)->GetStringUTFChars(env, domain, &isCopy);
+        pDomain = JNU_GetStringPlatformChars(env, domain, &isCopy);
+        if (pDomain == NULL) {
+            if (pUser != NULL)
+                JNU_ReleaseStringPlatformChars(env, user, pUser);
+            return 0;  // pending Exception
+        }
     }
     if (password != 0) {
-        pPassword = (CHAR *)(*env)->GetStringUTFChars(env, password, &isCopy);
+        pPassword = JNU_GetStringPlatformChars(env, password, &isCopy);
+        if (pPassword == NULL) {
+            if(pUser != NULL)
+                JNU_ReleaseStringPlatformChars(env, user, pUser);
+            if(pDomain != NULL)
+                JNU_ReleaseStringPlatformChars(env, domain, pDomain);
+            return 0;  // pending Exception
+        }
     }
     pCred = (CredHandle *)malloc(sizeof (CredHandle));
 
@@ -167,6 +183,14 @@
         pCred, &ltime
         );
 
+    /* Release resources held by JNU_GetStringPlatformChars */
+    if (pUser != NULL)
+        JNU_ReleaseStringPlatformChars(env, user, pUser);
+    if (pPassword != NULL)
+        JNU_ReleaseStringPlatformChars(env, password, pPassword);
+    if (pDomain != NULL)
+        JNU_ReleaseStringPlatformChars(env, domain, pDomain);
+
     if (ss == 0) {
         return (jlong) pCred;
     } else {
@@ -181,7 +205,6 @@
     VOID        *pInput = 0;
     DWORD            inputLen;
     CHAR         buffOut[512];
-    DWORD        pcbBuffOut;
     jboolean         isCopy;
     SECURITY_STATUS      ss;
     SecBufferDesc        OutBuffDesc;
@@ -247,7 +270,7 @@
     }
 
     if (ss < 0) {
-        endSequence (pCred, pCtx, OutBuffDesc);
+        endSequence (pCred, pCtx);
         return 0;
     }
 
@@ -255,7 +278,7 @@
         ss = pCompleteAuthToken( pCtx, &OutBuffDesc );
 
         if (ss < 0) {
-            endSequence (pCred, pCtx, OutBuffDesc);
+            endSequence (pCred, pCtx);
             return 0;
         }
     }
@@ -265,25 +288,23 @@
         (*env)->SetByteArrayRegion(env, ret, 0, OutSecBuff.cbBuffer,
                 OutSecBuff.pvBuffer);
         if (lastToken != 0) // 2nd stage
-            endSequence (pCred, pCtx, OutBuffDesc);
+            endSequence (pCred, pCtx);
         result = ret;
     }
 
     if ((ss != SEC_I_CONTINUE_NEEDED) && (ss == SEC_I_COMPLETE_AND_CONTINUE)) {
-        endSequence (pCred, pCtx, OutBuffDesc);
+        endSequence (pCred, pCtx);
     }
 
     return result;
 }
 
-static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle, SecBufferDesc OutBuffDesc) {
+static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle) {
     if (credHand != 0) {
         pFreeCredentialsHandle (credHand);
         free (credHand);
     }
 
-    pFreeContextBuffer (&OutBuffDesc);
-
     if (ctxHandle != 0) {
         pDeleteSecurityContext(ctxHandle);
         free (ctxHandle);
--- a/src/windows/native/sun/security/krb5/NativeCreds.c	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/security/krb5/NativeCreds.c	Mon Apr 14 11:34:15 2008 -0700
@@ -88,9 +88,9 @@
 
 VOID
 InitUnicodeString(
-        PUNICODE_STRING DestinationString,
+    PUNICODE_STRING DestinationString,
     PCWSTR SourceString OPTIONAL
-    );
+);
 
 jobject BuildTicket(JNIEnv *env, PUCHAR encodedTicket, ULONG encodedTicketSize);
 
@@ -108,215 +108,215 @@
  */
 
 JNIEXPORT jint JNICALL JNI_OnLoad(
-                JavaVM  *jvm,
-                void    *reserved) {
+        JavaVM  *jvm,
+        void    *reserved) {
 
-        jclass cls;
-        JNIEnv *env;
+    jclass cls;
+    JNIEnv *env;
 
-        if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) {
-                return JNI_EVERSION; /* JNI version not supported */
-        }
+    if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) {
+        return JNI_EVERSION; /* JNI version not supported */
+    }
 
-        cls = (*env)->FindClass(env,"sun/security/krb5/internal/Ticket");
+    cls = (*env)->FindClass(env,"sun/security/krb5/internal/Ticket");
 
-        if (cls == NULL) {
-                printf("Couldn't find Ticket\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found Ticket\n");
-        #endif /* DEBUG */
+    if (cls == NULL) {
+        printf("Couldn't find Ticket\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found Ticket\n");
+    #endif /* DEBUG */
 
-        ticketClass = (*env)->NewWeakGlobalRef(env,cls);
-        if (ticketClass == NULL) {
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Made NewWeakGlobalRef\n");
-        #endif /* DEBUG */
+    ticketClass = (*env)->NewWeakGlobalRef(env,cls);
+    if (ticketClass == NULL) {
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Made NewWeakGlobalRef\n");
+    #endif /* DEBUG */
 
-        cls = (*env)->FindClass(env, "sun/security/krb5/PrincipalName");
+    cls = (*env)->FindClass(env, "sun/security/krb5/PrincipalName");
 
-        if (cls == NULL) {
-                printf("Couldn't find PrincipalName\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found PrincipalName\n");
-        #endif /* DEBUG */
+    if (cls == NULL) {
+        printf("Couldn't find PrincipalName\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found PrincipalName\n");
+    #endif /* DEBUG */
 
-        principalNameClass = (*env)->NewWeakGlobalRef(env,cls);
-        if (principalNameClass == NULL) {
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Made NewWeakGlobalRef\n");
-        #endif /* DEBUG */
+    principalNameClass = (*env)->NewWeakGlobalRef(env,cls);
+    if (principalNameClass == NULL) {
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Made NewWeakGlobalRef\n");
+    #endif /* DEBUG */
 
-        cls = (*env)->FindClass(env,"sun/security/util/DerValue");
+    cls = (*env)->FindClass(env,"sun/security/util/DerValue");
 
-        if (cls == NULL) {
-                printf("Couldn't find DerValue\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found DerValue\n");
-        #endif /* DEBUG */
+    if (cls == NULL) {
+        printf("Couldn't find DerValue\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found DerValue\n");
+    #endif /* DEBUG */
 
-        derValueClass = (*env)->NewWeakGlobalRef(env,cls);
-        if (derValueClass == NULL) {
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Made NewWeakGlobalRef\n");
-        #endif /* DEBUG */
+    derValueClass = (*env)->NewWeakGlobalRef(env,cls);
+    if (derValueClass == NULL) {
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Made NewWeakGlobalRef\n");
+    #endif /* DEBUG */
 
-        cls = (*env)->FindClass(env,"sun/security/krb5/EncryptionKey");
+    cls = (*env)->FindClass(env,"sun/security/krb5/EncryptionKey");
 
-        if (cls == NULL) {
-                printf("Couldn't find EncryptionKey\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found EncryptionKey\n");
-        #endif /* DEBUG */
+    if (cls == NULL) {
+        printf("Couldn't find EncryptionKey\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found EncryptionKey\n");
+    #endif /* DEBUG */
 
-        encryptionKeyClass = (*env)->NewWeakGlobalRef(env,cls);
-        if (encryptionKeyClass == NULL) {
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Made NewWeakGlobalRef\n");
-        #endif /* DEBUG */
+    encryptionKeyClass = (*env)->NewWeakGlobalRef(env,cls);
+    if (encryptionKeyClass == NULL) {
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Made NewWeakGlobalRef\n");
+    #endif /* DEBUG */
 
-        cls = (*env)->FindClass(env,"sun/security/krb5/internal/TicketFlags");
+    cls = (*env)->FindClass(env,"sun/security/krb5/internal/TicketFlags");
 
-        if (cls == NULL) {
-                printf("Couldn't find TicketFlags\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found TicketFlags\n");
-        #endif /* DEBUG */
+    if (cls == NULL) {
+        printf("Couldn't find TicketFlags\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found TicketFlags\n");
+    #endif /* DEBUG */
 
-        ticketFlagsClass = (*env)->NewWeakGlobalRef(env,cls);
-        if (ticketFlagsClass == NULL) {
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Made NewWeakGlobalRef\n");
-        #endif /* DEBUG */
+    ticketFlagsClass = (*env)->NewWeakGlobalRef(env,cls);
+    if (ticketFlagsClass == NULL) {
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Made NewWeakGlobalRef\n");
+    #endif /* DEBUG */
 
-        cls = (*env)->FindClass(env,"sun/security/krb5/internal/KerberosTime");
+    cls = (*env)->FindClass(env,"sun/security/krb5/internal/KerberosTime");
 
-        if (cls == NULL) {
-                printf("Couldn't find KerberosTime\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found KerberosTime\n");
-        #endif /* DEBUG */
+    if (cls == NULL) {
+        printf("Couldn't find KerberosTime\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found KerberosTime\n");
+    #endif /* DEBUG */
 
-        kerberosTimeClass = (*env)->NewWeakGlobalRef(env,cls);
-        if (kerberosTimeClass == NULL) {
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Made NewWeakGlobalRef\n");
-        #endif /* DEBUG */
+    kerberosTimeClass = (*env)->NewWeakGlobalRef(env,cls);
+    if (kerberosTimeClass == NULL) {
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Made NewWeakGlobalRef\n");
+    #endif /* DEBUG */
 
-        cls = (*env)->FindClass(env,"java/lang/String");
+    cls = (*env)->FindClass(env,"java/lang/String");
 
-        if (cls == NULL) {
-                printf("Couldn't find String\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found String\n");
-        #endif /* DEBUG */
+    if (cls == NULL) {
+        printf("Couldn't find String\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found String\n");
+    #endif /* DEBUG */
 
-        javaLangStringClass = (*env)->NewWeakGlobalRef(env,cls);
-        if (javaLangStringClass == NULL) {
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Made NewWeakGlobalRef\n");
-        #endif /* DEBUG */
+    javaLangStringClass = (*env)->NewWeakGlobalRef(env,cls);
+    if (javaLangStringClass == NULL) {
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Made NewWeakGlobalRef\n");
+    #endif /* DEBUG */
 
-        derValueConstructor = (*env)->GetMethodID(env, derValueClass,
-                                                "<init>", "([B)V");
-        if (derValueConstructor == 0) {
-                printf("Couldn't find DerValue constructor\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found DerValue constructor\n");
-        #endif /* DEBUG */
+    derValueConstructor = (*env)->GetMethodID(env, derValueClass,
+                                            "<init>", "([B)V");
+    if (derValueConstructor == 0) {
+        printf("Couldn't find DerValue constructor\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found DerValue constructor\n");
+    #endif /* DEBUG */
 
-        ticketConstructor = (*env)->GetMethodID(env, ticketClass,
-                                "<init>", "(Lsun/security/util/DerValue;)V");
-        if (ticketConstructor == 0) {
-                printf("Couldn't find Ticket constructor\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found Ticket constructor\n");
-        #endif /* DEBUG */
+    ticketConstructor = (*env)->GetMethodID(env, ticketClass,
+                            "<init>", "(Lsun/security/util/DerValue;)V");
+    if (ticketConstructor == 0) {
+        printf("Couldn't find Ticket constructor\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found Ticket constructor\n");
+    #endif /* DEBUG */
 
-        principalNameConstructor = (*env)->GetMethodID(env, principalNameClass,
-                                        "<init>", "([Ljava/lang/String;)V");
-        if (principalNameConstructor == 0) {
-                printf("Couldn't find PrincipalName constructor\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found PrincipalName constructor\n");
-        #endif /* DEBUG */
+    principalNameConstructor = (*env)->GetMethodID(env, principalNameClass,
+                                    "<init>", "([Ljava/lang/String;)V");
+    if (principalNameConstructor == 0) {
+        printf("Couldn't find PrincipalName constructor\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found PrincipalName constructor\n");
+    #endif /* DEBUG */
 
-        encryptionKeyConstructor = (*env)->GetMethodID(env, encryptionKeyClass,
-                                                "<init>", "(I[B)V");
-        if (encryptionKeyConstructor == 0) {
-                printf("Couldn't find EncryptionKey constructor\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found EncryptionKey constructor\n");
-        #endif /* DEBUG */
+    encryptionKeyConstructor = (*env)->GetMethodID(env, encryptionKeyClass,
+                                            "<init>", "(I[B)V");
+    if (encryptionKeyConstructor == 0) {
+        printf("Couldn't find EncryptionKey constructor\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found EncryptionKey constructor\n");
+    #endif /* DEBUG */
 
-        ticketFlagsConstructor = (*env)->GetMethodID(env, ticketFlagsClass,
-                                                "<init>", "(I[B)V");
-        if (ticketFlagsConstructor == 0) {
-                printf("Couldn't find TicketFlags constructor\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found TicketFlags constructor\n");
-        #endif /* DEBUG */
+    ticketFlagsConstructor = (*env)->GetMethodID(env, ticketFlagsClass,
+                                            "<init>", "(I[B)V");
+    if (ticketFlagsConstructor == 0) {
+        printf("Couldn't find TicketFlags constructor\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found TicketFlags constructor\n");
+    #endif /* DEBUG */
 
-        kerberosTimeConstructor = (*env)->GetMethodID(env, kerberosTimeClass,
-                                        "<init>", "(Ljava/lang/String;)V");
-        if (kerberosTimeConstructor == 0) {
-                printf("Couldn't find KerberosTime constructor\n");
-                return JNI_ERR;
-        }
-        #ifdef DEBUG
-        printf("Found KerberosTime constructor\n");
-        #endif /* DEBUG */
+    kerberosTimeConstructor = (*env)->GetMethodID(env, kerberosTimeClass,
+                                    "<init>", "(Ljava/lang/String;)V");
+    if (kerberosTimeConstructor == 0) {
+        printf("Couldn't find KerberosTime constructor\n");
+        return JNI_ERR;
+    }
+    #ifdef DEBUG
+    printf("Found KerberosTime constructor\n");
+    #endif /* DEBUG */
 
-        // load the setRealm method in PrincipalName
-        setRealmMethod = (*env)->GetMethodID(env, principalNameClass,
-                                        "setRealm", "(Ljava/lang/String;)V");
-        if (setRealmMethod == 0) {
-                printf("Couldn't find setRealm in PrincipalName\n");
-                return JNI_ERR;
-        }
+    // load the setRealm method in PrincipalName
+    setRealmMethod = (*env)->GetMethodID(env, principalNameClass,
+                                    "setRealm", "(Ljava/lang/String;)V");
+    if (setRealmMethod == 0) {
+        printf("Couldn't find setRealm in PrincipalName\n");
+        return JNI_ERR;
+    }
 
-        #ifdef DEBUG
-        printf("Finished OnLoad processing\n");
-        #endif /* DEBUG */
+    #ifdef DEBUG
+    printf("Finished OnLoad processing\n");
+    #endif /* DEBUG */
 
-        return JNI_VERSION_1_2;
+    return JNI_VERSION_1_2;
 }
 
 /*
@@ -325,38 +325,38 @@
  */
 
 JNIEXPORT void JNICALL JNI_OnUnload(
-                JavaVM  *jvm,
-                void    *reserved) {
+        JavaVM  *jvm,
+        void    *reserved) {
 
-        JNIEnv *env;
+    JNIEnv *env;
 
-        if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) {
-                return; /* Nothing else we can do */
-        }
+    if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) {
+        return; /* Nothing else we can do */
+    }
 
-        if (ticketClass != NULL) {
-                (*env)->DeleteWeakGlobalRef(env,ticketClass);
-        }
-        if (derValueClass != NULL) {
-                (*env)->DeleteWeakGlobalRef(env,derValueClass);
-        }
-        if (principalNameClass != NULL) {
-                (*env)->DeleteWeakGlobalRef(env,principalNameClass);
-        }
-        if (encryptionKeyClass != NULL) {
-                (*env)->DeleteWeakGlobalRef(env,encryptionKeyClass);
-        }
-        if (ticketFlagsClass != NULL) {
-                (*env)->DeleteWeakGlobalRef(env,ticketFlagsClass);
-        }
-        if (kerberosTimeClass != NULL) {
-                (*env)->DeleteWeakGlobalRef(env,kerberosTimeClass);
-        }
-        if (javaLangStringClass != NULL) {
-                (*env)->DeleteWeakGlobalRef(env,javaLangStringClass);
-        }
+    if (ticketClass != NULL) {
+        (*env)->DeleteWeakGlobalRef(env,ticketClass);
+    }
+    if (derValueClass != NULL) {
+        (*env)->DeleteWeakGlobalRef(env,derValueClass);
+    }
+    if (principalNameClass != NULL) {
+        (*env)->DeleteWeakGlobalRef(env,principalNameClass);
+    }
+    if (encryptionKeyClass != NULL) {
+        (*env)->DeleteWeakGlobalRef(env,encryptionKeyClass);
+    }
+    if (ticketFlagsClass != NULL) {
+        (*env)->DeleteWeakGlobalRef(env,ticketFlagsClass);
+    }
+    if (kerberosTimeClass != NULL) {
+        (*env)->DeleteWeakGlobalRef(env,kerberosTimeClass);
+    }
+    if (javaLangStringClass != NULL) {
+        (*env)->DeleteWeakGlobalRef(env,javaLangStringClass);
+    }
 
-        return;
+    return;
 }
 
 /*
@@ -365,31 +365,31 @@
  * Signature: ()Lsun/security/krb5/Credentials;
  */
 JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds(
-                JNIEnv *env,
-                jclass krbcredsClass) {
+        JNIEnv *env,
+        jclass krbcredsClass) {
 
-        KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
-        PKERB_RETRIEVE_TKT_RESPONSE TktCacheResponse = NULL;
-        PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL;
-        PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL;
-        NTSTATUS Status, SubStatus;
-        ULONG requestSize = 0;
-        ULONG responseSize = 0;
-        ULONG rspSize = 0;
-        HANDLE LogonHandle = NULL;
-        ULONG PackageId;
-        jobject ticket, clientPrincipal, targetPrincipal, encryptionKey;
-        jobject ticketFlags, startTime, endTime, krbCreds = NULL;
-        jobject authTime, renewTillTime, hostAddresses = NULL;
-        KERB_EXTERNAL_TICKET *msticket;
-        int ignore_cache = 0;
-        FILETIME Now, EndTime, LocalEndTime;
+    KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
+    PKERB_RETRIEVE_TKT_RESPONSE TktCacheResponse = NULL;
+    PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL;
+    PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL;
+    NTSTATUS Status, SubStatus;
+    ULONG requestSize = 0;
+    ULONG responseSize = 0;
+    ULONG rspSize = 0;
+    HANDLE LogonHandle = NULL;
+    ULONG PackageId;
+    jobject ticket, clientPrincipal, targetPrincipal, encryptionKey;
+    jobject ticketFlags, startTime, endTime, krbCreds = NULL;
+    jobject authTime, renewTillTime, hostAddresses = NULL;
+    KERB_EXTERNAL_TICKET *msticket;
+    int ignore_cache = 0;
+    FILETIME Now, EndTime, LocalEndTime;
 
-        while (TRUE) {
+    while (TRUE) {
 
         if (krbcredsConstructor == 0) {
-                krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "<init>",
-        "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V");
+            krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "<init>",
+                    "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V");
             if (krbcredsConstructor == 0) {
                 printf("Couldn't find sun.security.krb5.Credentials constructor\n");
                 break;
@@ -510,88 +510,88 @@
             msticket = &(pTicketResponse->Ticket);
         }
 
-/*
+        /*
 
-typedef struct _KERB_RETRIEVE_TKT_RESPONSE {
-    KERB_EXTERNAL_TICKET Ticket;
-} KERB_RETRIEVE_TKT_RESPONSE, *PKERB_RETRIEVE_TKT_RESPONSE;
+        typedef struct _KERB_RETRIEVE_TKT_RESPONSE {
+            KERB_EXTERNAL_TICKET Ticket;
+        } KERB_RETRIEVE_TKT_RESPONSE, *PKERB_RETRIEVE_TKT_RESPONSE;
 
-typedef struct _KERB_EXTERNAL_TICKET {
-    PKERB_EXTERNAL_NAME ServiceName;
-    PKERB_EXTERNAL_NAME TargetName;
-    PKERB_EXTERNAL_NAME ClientName;
-    UNICODE_STRING DomainName;
-    UNICODE_STRING TargetDomainName;
-    UNICODE_STRING AltTargetDomainName;
-    KERB_CRYPTO_KEY SessionKey;
-    ULONG TicketFlags;
-    ULONG Flags;
-    LARGE_INTEGER KeyExpirationTime;
-    LARGE_INTEGER StartTime;
-    LARGE_INTEGER EndTime;
-    LARGE_INTEGER RenewUntil;
-    LARGE_INTEGER TimeSkew;
-    ULONG EncodedTicketSize;
-    PUCHAR EncodedTicket; <========== Here's the good stuff
-} KERB_EXTERNAL_TICKET, *PKERB_EXTERNAL_TICKET;
+        typedef struct _KERB_EXTERNAL_TICKET {
+            PKERB_EXTERNAL_NAME ServiceName;
+            PKERB_EXTERNAL_NAME TargetName;
+            PKERB_EXTERNAL_NAME ClientName;
+            UNICODE_STRING DomainName;
+            UNICODE_STRING TargetDomainName;
+            UNICODE_STRING AltTargetDomainName;
+            KERB_CRYPTO_KEY SessionKey;
+            ULONG TicketFlags;
+            ULONG Flags;
+            LARGE_INTEGER KeyExpirationTime;
+            LARGE_INTEGER StartTime;
+            LARGE_INTEGER EndTime;
+            LARGE_INTEGER RenewUntil;
+            LARGE_INTEGER TimeSkew;
+            ULONG EncodedTicketSize;
+            PUCHAR EncodedTicket; <========== Here's the good stuff
+        } KERB_EXTERNAL_TICKET, *PKERB_EXTERNAL_TICKET;
 
-typedef struct _KERB_EXTERNAL_NAME {
-    SHORT NameType;
-    USHORT NameCount;
-    UNICODE_STRING Names[ANYSIZE_ARRAY];
-} KERB_EXTERNAL_NAME, *PKERB_EXTERNAL_NAME;
+        typedef struct _KERB_EXTERNAL_NAME {
+            SHORT NameType;
+            USHORT NameCount;
+            UNICODE_STRING Names[ANYSIZE_ARRAY];
+        } KERB_EXTERNAL_NAME, *PKERB_EXTERNAL_NAME;
 
-typedef struct _LSA_UNICODE_STRING {
-    USHORT Length;
-    USHORT MaximumLength;
-    PWSTR  Buffer;
-} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING;
+        typedef struct _LSA_UNICODE_STRING {
+            USHORT Length;
+            USHORT MaximumLength;
+            PWSTR  Buffer;
+        } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING;
 
-typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;
+        typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;
 
-typedef struct KERB_CRYPTO_KEY {
-    LONG KeyType;
-    ULONG Length;
-    PUCHAR Value;
-} KERB_CRYPTO_KEY, *PKERB_CRYPTO_KEY;
+        typedef struct KERB_CRYPTO_KEY {
+            LONG KeyType;
+            ULONG Length;
+            PUCHAR Value;
+        } KERB_CRYPTO_KEY, *PKERB_CRYPTO_KEY;
 
-*/
+        */
         // Build a com.sun.security.krb5.Ticket
         ticket = BuildTicket(env, msticket->EncodedTicket,
                                 msticket->EncodedTicketSize);
         if (ticket == NULL) {
-                break;
+            break;
         }
         // OK, have a Ticket, now need to get the client name
         clientPrincipal = BuildPrincipal(env, msticket->ClientName,
                                 msticket->TargetDomainName); // mdu
         if (clientPrincipal == NULL) {
-                break;
+            break;
         }
 
         // and the "name" of tgt
         targetPrincipal = BuildPrincipal(env, msticket->ServiceName,
                         msticket->DomainName);
         if (targetPrincipal == NULL) {
-                break;
+            break;
         }
 
         // Get the encryption key
         encryptionKey = BuildEncryptionKey(env, &(msticket->SessionKey));
         if (encryptionKey == NULL) {
-                break;
+            break;
         }
 
         // and the ticket flags
         ticketFlags = BuildTicketFlags(env, &(msticket->TicketFlags));
         if (ticketFlags == NULL) {
-                break;
+            break;
         }
 
         // Get the start time
         startTime = BuildKerberosTime(env, &(msticket->StartTime));
         if (startTime == NULL) {
-                break;
+            break;
         }
 
         /*
@@ -604,13 +604,13 @@
         // and the end time
         endTime = BuildKerberosTime(env, &(msticket->EndTime));
         if (endTime == NULL) {
-                break;
+            break;
         }
 
         // Get the renew till time
         renewTillTime = BuildKerberosTime(env, &(msticket->RenewUntil));
         if (renewTillTime == NULL) {
-                break;
+            break;
         }
 
         // and now go build a KrbCreds object
@@ -630,87 +630,87 @@
                 hostAddresses);
 
         break;
-        } // end of WHILE
+    } // end of WHILE
 
-        // clean up resources
-        if (TktCacheResponse != NULL) {
-                LsaFreeReturnBuffer(TktCacheResponse);
-        }
-        if (pTicketRequest) {
-                LocalFree(pTicketRequest);
-        }
-        if (pTicketResponse != NULL) {
-                LsaFreeReturnBuffer(pTicketResponse);
-        }
+    // clean up resources
+    if (TktCacheResponse != NULL) {
+        LsaFreeReturnBuffer(TktCacheResponse);
+    }
+    if (pTicketRequest) {
+        LocalFree(pTicketRequest);
+    }
+    if (pTicketResponse != NULL) {
+        LsaFreeReturnBuffer(pTicketResponse);
+    }
 
-        return krbCreds;
+    return krbCreds;
 }
 
 static NTSTATUS
 ConstructTicketRequest(UNICODE_STRING DomainName,
                 PKERB_RETRIEVE_TKT_REQUEST *outRequest, ULONG *outSize)
 {
-        NTSTATUS Status;
-        UNICODE_STRING TargetPrefix;
-        USHORT TargetSize;
-        ULONG RequestSize;
-        ULONG Length;
-        PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL;
+    NTSTATUS Status;
+    UNICODE_STRING TargetPrefix;
+    USHORT TargetSize;
+    ULONG RequestSize;
+    ULONG Length;
+    PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL;
 
-        *outRequest = NULL;
-        *outSize = 0;
+    *outRequest = NULL;
+    *outSize = 0;
 
-        //
-        // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we
-        // can easily concatenate it later.
-        //
+    //
+    // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we
+    // can easily concatenate it later.
+    //
 
-        TargetPrefix.Buffer = L"krbtgt/";
-        Length = (ULONG)wcslen(TargetPrefix.Buffer) * sizeof(WCHAR);
-        TargetPrefix.Length = (USHORT)Length;
-        TargetPrefix.MaximumLength = TargetPrefix.Length;
+    TargetPrefix.Buffer = L"krbtgt/";
+    Length = (ULONG)wcslen(TargetPrefix.Buffer) * sizeof(WCHAR);
+    TargetPrefix.Length = (USHORT)Length;
+    TargetPrefix.MaximumLength = TargetPrefix.Length;
 
-        //
-        // We will need to concatenate the "krbtgt/" prefix and the
-        // Logon Session's DnsDomainName into our request's target name.
-        //
-        // Therefore, first compute the necessary buffer size for that.
-        //
-        // Note that we might theoretically have integer overflow.
-        //
+    //
+    // We will need to concatenate the "krbtgt/" prefix and the
+    // Logon Session's DnsDomainName into our request's target name.
+    //
+    // Therefore, first compute the necessary buffer size for that.
+    //
+    // Note that we might theoretically have integer overflow.
+    //
 
-        TargetSize = TargetPrefix.Length + DomainName.Length;
+    TargetSize = TargetPrefix.Length + DomainName.Length;
 
-        //
-        // The ticket request buffer needs to be a single buffer.  That buffer
-        // needs to include the buffer for the target name.
-        //
+    //
+    // The ticket request buffer needs to be a single buffer.  That buffer
+    // needs to include the buffer for the target name.
+    //
 
-        RequestSize = sizeof (*pTicketRequest) + TargetSize;
+    RequestSize = sizeof (*pTicketRequest) + TargetSize;
 
-        //
-        // Allocate the request buffer and make sure it's zero-filled.
-        //
+    //
+    // Allocate the request buffer and make sure it's zero-filled.
+    //
 
-        pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST)
-                        LocalAlloc(LMEM_ZEROINIT, RequestSize);
-        if (!pTicketRequest)
-            return GetLastError();
+    pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST)
+                    LocalAlloc(LMEM_ZEROINIT, RequestSize);
+    if (!pTicketRequest)
+        return GetLastError();
 
-        //
-        // Concatenate the target prefix with the previous reponse's
-        // target domain.
-        //
+    //
+    // Concatenate the target prefix with the previous reponse's
+    // target domain.
+    //
 
-        pTicketRequest->TargetName.Length = 0;
-        pTicketRequest->TargetName.MaximumLength = TargetSize;
-        pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1);
-        Status = ConcatenateUnicodeStrings(&(pTicketRequest->TargetName),
-                                        TargetPrefix,
-                                        DomainName);
-        *outRequest = pTicketRequest;
-        *outSize    = RequestSize;
-        return Status;
+    pTicketRequest->TargetName.Length = 0;
+    pTicketRequest->TargetName.MaximumLength = TargetSize;
+    pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1);
+    Status = ConcatenateUnicodeStrings(&(pTicketRequest->TargetName),
+                                    TargetPrefix,
+                                    DomainName);
+    *outRequest = pTicketRequest;
+    *outSize    = RequestSize;
+    return Status;
 }
 
 DWORD
@@ -720,22 +720,22 @@
     UNICODE_STRING Source2
     )
 {
-        //
-        // The buffers for Source1 and Source2 cannot overlap pTarget's
-        // buffer.  Source1.Length + Source2.Length must be <= 0xFFFF,
-        // otherwise we overflow...
-        //
+    //
+    // The buffers for Source1 and Source2 cannot overlap pTarget's
+    // buffer.  Source1.Length + Source2.Length must be <= 0xFFFF,
+    // otherwise we overflow...
+    //
 
-        USHORT TotalSize = Source1.Length + Source2.Length;
-        PBYTE buffer = (PBYTE) pTarget->Buffer;
+    USHORT TotalSize = Source1.Length + Source2.Length;
+    PBYTE buffer = (PBYTE) pTarget->Buffer;
 
-        if (TotalSize > pTarget->MaximumLength)
-            return ERROR_INSUFFICIENT_BUFFER;
+    if (TotalSize > pTarget->MaximumLength)
+        return ERROR_INSUFFICIENT_BUFFER;
 
-        pTarget->Length = TotalSize;
-        memcpy(buffer, Source1.Buffer, Source1.Length);
-        memcpy(buffer + Source1.Length, Source2.Buffer, Source2.Length);
-        return ERROR_SUCCESS;
+    pTarget->Length = TotalSize;
+    memcpy(buffer, Source1.Buffer, Source1.Length);
+    memcpy(buffer + Source1.Length, Source2.Buffer, Source2.Length);
+    return ERROR_SUCCESS;
 }
 
 BOOL
@@ -783,27 +783,27 @@
         DWORD dwError
         )
 {
-   #define MAX_MSG_SIZE 256
+    #define MAX_MSG_SIZE 256
 
-   static WCHAR szMsgBuf[MAX_MSG_SIZE];
-   DWORD dwRes;
+    static WCHAR szMsgBuf[MAX_MSG_SIZE];
+    DWORD dwRes;
 
-   printf("Error calling function %s: %lu\n", szAPI, dwError);
+    printf("Error calling function %s: %lu\n", szAPI, dwError);
 
-   dwRes = FormatMessage (
-      FORMAT_MESSAGE_FROM_SYSTEM,
-      NULL,
-      dwError,
-      0,
-      szMsgBuf,
-      MAX_MSG_SIZE,
-      NULL);
-   if (0 == dwRes) {
-      printf("FormatMessage failed with %d\n", GetLastError());
-      // ExitProcess(EXIT_FAILURE);
-   } else {
-      printf("%S",szMsgBuf);
-   }
+    dwRes = FormatMessage (
+            FORMAT_MESSAGE_FROM_SYSTEM,
+            NULL,
+            dwError,
+            0,
+            szMsgBuf,
+            MAX_MSG_SIZE,
+            NULL);
+    if (0 == dwRes) {
+        printf("FormatMessage failed with %d\n", GetLastError());
+        // ExitProcess(EXIT_FAILURE);
+    } else {
+        printf("%S",szMsgBuf);
+    }
 }
 
 VOID
@@ -831,189 +831,189 @@
         Length = (ULONG)wcslen( SourceString ) * sizeof( WCHAR );
         DestinationString->Length = (USHORT)Length;
         DestinationString->MaximumLength = (USHORT)(Length + sizeof(UNICODE_NULL));
-        }
+    }
     else {
         DestinationString->MaximumLength = 0;
         DestinationString->Length = 0;
-        }
+    }
 }
 
 jobject BuildTicket(JNIEnv *env, PUCHAR encodedTicket, ULONG encodedTicketSize) {
 
-        /* To build a Ticket, we first need to build a DerValue out of the EncodedTicket.
-         * But before we can do that, we need to make a byte array out of the ET.
-         */
+    /* To build a Ticket, we first need to build a DerValue out of the EncodedTicket.
+     * But before we can do that, we need to make a byte array out of the ET.
+     */
 
-        jobject derValue, ticket;
-        jbyteArray ary;
+    jobject derValue, ticket;
+    jbyteArray ary;
 
-        ary = (*env)->NewByteArray(env,encodedTicketSize);
-        if ((*env)->ExceptionOccurred(env)) {
-                return (jobject) NULL;
-        }
+    ary = (*env)->NewByteArray(env,encodedTicketSize);
+    if ((*env)->ExceptionOccurred(env)) {
+        return (jobject) NULL;
+    }
 
-        (*env)->SetByteArrayRegion(env, ary, (jsize) 0, encodedTicketSize,
-                                        (jbyte *)encodedTicket);
-        if ((*env)->ExceptionOccurred(env)) {
-                (*env)->DeleteLocalRef(env, ary);
-                return (jobject) NULL;
-        }
+    (*env)->SetByteArrayRegion(env, ary, (jsize) 0, encodedTicketSize,
+                                    (jbyte *)encodedTicket);
+    if ((*env)->ExceptionOccurred(env)) {
+        (*env)->DeleteLocalRef(env, ary);
+        return (jobject) NULL;
+    }
 
-        derValue = (*env)->NewObject(env, derValueClass, derValueConstructor, ary);
-        if ((*env)->ExceptionOccurred(env)) {
-                (*env)->DeleteLocalRef(env, ary);
-                return (jobject) NULL;
-        }
-
+    derValue = (*env)->NewObject(env, derValueClass, derValueConstructor, ary);
+    if ((*env)->ExceptionOccurred(env)) {
         (*env)->DeleteLocalRef(env, ary);
-        ticket = (*env)->NewObject(env, ticketClass, ticketConstructor, derValue);
-        if ((*env)->ExceptionOccurred(env)) {
-                (*env)->DeleteLocalRef(env, derValue);
-                return (jobject) NULL;
-        }
+        return (jobject) NULL;
+    }
+
+    (*env)->DeleteLocalRef(env, ary);
+    ticket = (*env)->NewObject(env, ticketClass, ticketConstructor, derValue);
+    if ((*env)->ExceptionOccurred(env)) {
         (*env)->DeleteLocalRef(env, derValue);
-        return ticket;
+        return (jobject) NULL;
+    }
+    (*env)->DeleteLocalRef(env, derValue);
+    return ticket;
 }
 
 // mdu
 jobject BuildPrincipal(JNIEnv *env, PKERB_EXTERNAL_NAME principalName,
                                 UNICODE_STRING domainName) {
 
-        /*
-         * To build the Principal, we need to get the names out of
-         * this goofy MS structure
-         */
-        jobject principal = NULL;
-        jobject realmStr = NULL;
-        jobjectArray stringArray;
-        jstring tempString;
-        int nameCount,i;
-        PUNICODE_STRING scanner;
-        WCHAR *realm;
-        ULONG realmLen;
+    /*
+     * To build the Principal, we need to get the names out of
+     * this goofy MS structure
+     */
+    jobject principal = NULL;
+    jobject realmStr = NULL;
+    jobjectArray stringArray;
+    jstring tempString;
+    int nameCount,i;
+    PUNICODE_STRING scanner;
+    WCHAR *realm;
+    ULONG realmLen;
 
-        realm = (WCHAR *) LocalAlloc(LMEM_ZEROINIT,
-                ((domainName.Length)*sizeof(WCHAR) + sizeof(UNICODE_NULL)));
-        wcsncpy(realm, domainName.Buffer, domainName.Length/sizeof(WCHAR));
+    realm = (WCHAR *) LocalAlloc(LMEM_ZEROINIT,
+            ((domainName.Length)*sizeof(WCHAR) + sizeof(UNICODE_NULL)));
+    wcsncpy(realm, domainName.Buffer, domainName.Length/sizeof(WCHAR));
 
-        #ifdef DEBUG
-        printf("Principal domain is %S\n", realm);
-        printf("Name type is %x\n", principalName->NameType);
-        printf("Name count is %x\n", principalName->NameCount);
-        #endif
+    #ifdef DEBUG
+    printf("Principal domain is %S\n", realm);
+    printf("Name type is %x\n", principalName->NameType);
+    printf("Name count is %x\n", principalName->NameCount);
+    #endif
 
-        nameCount = principalName->NameCount;
-        stringArray = (*env)->NewObjectArray(env, nameCount,
-                                javaLangStringClass, NULL);
-        if (stringArray == NULL) {
-            printf("Can't allocate String array for Principal\n");
-            LocalFree(realm);
-            return principal;
-        }
+    nameCount = principalName->NameCount;
+    stringArray = (*env)->NewObjectArray(env, nameCount,
+                            javaLangStringClass, NULL);
+    if (stringArray == NULL) {
+        printf("Can't allocate String array for Principal\n");
+        LocalFree(realm);
+        return principal;
+    }
 
-        for (i=0; i<nameCount; i++) {
-            // get the principal name
-            scanner = &(principalName->Names[i]);
+    for (i=0; i<nameCount; i++) {
+        // get the principal name
+        scanner = &(principalName->Names[i]);
 
-            // OK, got a Char array, so construct a String
-            tempString = (*env)->NewString(env, (const jchar*)scanner->Buffer,
-                                scanner->Length/sizeof(WCHAR));
-            // Set the String into the StringArray
-            (*env)->SetObjectArrayElement(env, stringArray, i, tempString);
+        // OK, got a Char array, so construct a String
+        tempString = (*env)->NewString(env, (const jchar*)scanner->Buffer,
+                            scanner->Length/sizeof(WCHAR));
+        // Set the String into the StringArray
+        (*env)->SetObjectArrayElement(env, stringArray, i, tempString);
 
-            // Do I have to worry about storage reclamation here?
-        }
-        principal = (*env)->NewObject(env, principalNameClass,
-                        principalNameConstructor, stringArray);
+        // Do I have to worry about storage reclamation here?
+    }
+    principal = (*env)->NewObject(env, principalNameClass,
+                    principalNameConstructor, stringArray);
 
-        // now set the realm in the principal
-        realmLen = (ULONG)wcslen((PWCHAR)realm);
-        realmStr = (*env)->NewString(env, (PWCHAR)realm, (USHORT)realmLen);
-        (*env)->CallVoidMethod(env, principal, setRealmMethod, realmStr);
+    // now set the realm in the principal
+    realmLen = (ULONG)wcslen((PWCHAR)realm);
+    realmStr = (*env)->NewString(env, (PWCHAR)realm, (USHORT)realmLen);
+    (*env)->CallVoidMethod(env, principal, setRealmMethod, realmStr);
 
-        // free local resources
-        LocalFree(realm);
+    // free local resources
+    LocalFree(realm);
 
-        return principal;
+    return principal;
 }
 
 jobject BuildEncryptionKey(JNIEnv *env, PKERB_CRYPTO_KEY cryptoKey) {
-        // First, need to build a byte array
-        jbyteArray ary;
-        jobject encryptionKey = NULL;
+    // First, need to build a byte array
+    jbyteArray ary;
+    jobject encryptionKey = NULL;
 
-        ary = (*env)->NewByteArray(env,cryptoKey->Length);
-        (*env)->SetByteArrayRegion(env, ary, (jsize) 0, cryptoKey->Length,
-                                        (jbyte *)cryptoKey->Value);
-        if ((*env)->ExceptionOccurred(env)) {
-                (*env)->DeleteLocalRef(env, ary);
-        } else {
-                encryptionKey = (*env)->NewObject(env, encryptionKeyClass,
-                        encryptionKeyConstructor, cryptoKey->KeyType, ary);
-        }
+    ary = (*env)->NewByteArray(env,cryptoKey->Length);
+    (*env)->SetByteArrayRegion(env, ary, (jsize) 0, cryptoKey->Length,
+                                    (jbyte *)cryptoKey->Value);
+    if ((*env)->ExceptionOccurred(env)) {
+        (*env)->DeleteLocalRef(env, ary);
+    } else {
+        encryptionKey = (*env)->NewObject(env, encryptionKeyClass,
+                encryptionKeyConstructor, cryptoKey->KeyType, ary);
+    }
 
-        return encryptionKey;
+    return encryptionKey;
 }
 
 jobject BuildTicketFlags(JNIEnv *env, PULONG flags) {
-        jobject ticketFlags = NULL;
-        jbyteArray ary;
-        /*
-         * mdu: Convert the bytes to nework byte order before copying
-         * them to a Java byte array.
-         */
-        ULONG nlflags = htonl(*flags);
+    jobject ticketFlags = NULL;
+    jbyteArray ary;
+    /*
+     * mdu: Convert the bytes to nework byte order before copying
+     * them to a Java byte array.
+     */
+    ULONG nlflags = htonl(*flags);
 
-        ary = (*env)->NewByteArray(env, sizeof(*flags));
-        (*env)->SetByteArrayRegion(env, ary, (jsize) 0, sizeof(*flags),
-                                        (jbyte *)&nlflags);
-        if ((*env)->ExceptionOccurred(env)) {
-                (*env)->DeleteLocalRef(env, ary);
-        } else {
-                ticketFlags = (*env)->NewObject(env, ticketFlagsClass,
-                        ticketFlagsConstructor, sizeof(*flags)*8, ary);
-        }
+    ary = (*env)->NewByteArray(env, sizeof(*flags));
+    (*env)->SetByteArrayRegion(env, ary, (jsize) 0, sizeof(*flags),
+                                    (jbyte *)&nlflags);
+    if ((*env)->ExceptionOccurred(env)) {
+        (*env)->DeleteLocalRef(env, ary);
+    } else {
+        ticketFlags = (*env)->NewObject(env, ticketFlagsClass,
+                ticketFlagsConstructor, sizeof(*flags)*8, ary);
+    }
 
-        return ticketFlags;
+    return ticketFlags;
 }
 
 jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime) {
-        jobject kerberosTime = NULL;
-        jstring stringTime = NULL;
-        SYSTEMTIME systemTime;
-        WCHAR timeString[16];
-        WCHAR month[3];
-        WCHAR day[3];
-        WCHAR hour[3];
-        WCHAR minute[3];
-        WCHAR second[3];
+    jobject kerberosTime = NULL;
+    jstring stringTime = NULL;
+    SYSTEMTIME systemTime;
+    WCHAR timeString[16];
+    WCHAR month[3];
+    WCHAR day[3];
+    WCHAR hour[3];
+    WCHAR minute[3];
+    WCHAR second[3];
 
-        if (FileTimeToSystemTime((FILETIME *)kerbtime, &systemTime)) {
-// XXX Cannot use %02.2ld, because the leading 0 is ignored for integers.
-// So, print them to strings, and then print them to the master string with a
-// format pattern that makes it two digits and prefix with a 0 if necessary.
-                swprintf( (wchar_t *)month, L"%2.2d", systemTime.wMonth);
-                swprintf( (wchar_t *)day, L"%2.2d", systemTime.wDay);
-                swprintf( (wchar_t *)hour, L"%2.2d", systemTime.wHour);
-                swprintf( (wchar_t *)minute, L"%2.2d", systemTime.wMinute);
-                swprintf( (wchar_t *)second, L"%2.2d", systemTime.wSecond);
-                swprintf( (wchar_t *)timeString,
-                                L"%ld%02.2s%02.2s%02.2s%02.2s%02.2sZ",
+    if (FileTimeToSystemTime((FILETIME *)kerbtime, &systemTime)) {
+        // XXX Cannot use %02.2ld, because the leading 0 is ignored for integers.
+        // So, print them to strings, and then print them to the master string with a
+        // format pattern that makes it two digits and prefix with a 0 if necessary.
+        swprintf( (wchar_t *)month, L"%2.2d", systemTime.wMonth);
+        swprintf( (wchar_t *)day, L"%2.2d", systemTime.wDay);
+        swprintf( (wchar_t *)hour, L"%2.2d", systemTime.wHour);
+        swprintf( (wchar_t *)minute, L"%2.2d", systemTime.wMinute);
+        swprintf( (wchar_t *)second, L"%2.2d", systemTime.wSecond);
+        swprintf( (wchar_t *)timeString,
+                L"%ld%02.2s%02.2s%02.2s%02.2s%02.2sZ",
                 systemTime.wYear,
                 month,
                 day,
                 hour,
                 minute,
                 second );
-                #ifdef DEBUG
-                printf("%S\n", (wchar_t *)timeString);
-                #endif /* DEBUG */
-                stringTime = (*env)->NewString(env, timeString,
-                                (sizeof(timeString)/sizeof(WCHAR))-1);
-                if (stringTime != NULL) { // everything's OK so far
-                        kerberosTime = (*env)->NewObject(env, kerberosTimeClass,
-                                kerberosTimeConstructor, stringTime);
-                }
+        #ifdef DEBUG
+        printf("%S\n", (wchar_t *)timeString);
+        #endif /* DEBUG */
+        stringTime = (*env)->NewString(env, timeString,
+                (sizeof(timeString)/sizeof(WCHAR))-1);
+        if (stringTime != NULL) { // everything's OK so far
+            kerberosTime = (*env)->NewObject(env, kerberosTimeClass,
+                    kerberosTimeConstructor, stringTime);
         }
-        return kerberosTime;
+    }
+    return kerberosTime;
 }
--- a/src/windows/native/sun/windows/awt.h	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/windows/awt.h	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,7 @@
     JNI_CHECK_NULL_GOTO(peer, "peer", where);                             \
     pData = JNI_GET_PDATA(peer);                                          \
     if (pData == NULL) {                                                  \
-        JNU_ThrowNullPointerException(env, "null pData");                 \
+        THROW_NULL_PDATA_IF_NOT_DESTROYED(peer);                          \
         goto where;                                                       \
     }                                                                     \
 }
@@ -63,7 +63,7 @@
     JNI_CHECK_NULL_RETURN(peer, "peer");                                  \
     pData = JNI_GET_PDATA(peer);                                          \
     if (pData == NULL) {                                                  \
-        JNU_ThrowNullPointerException(env, "null pData");                 \
+        THROW_NULL_PDATA_IF_NOT_DESTROYED(peer);                          \
         return;                                                           \
     }                                                                     \
 }
@@ -96,7 +96,7 @@
     JNI_CHECK_NULL_RETURN_NULL(peer, "peer");                             \
     pData = JNI_GET_PDATA(peer);                                          \
     if (pData == NULL) {                                                  \
-        JNU_ThrowNullPointerException(env, "null pData");                 \
+        THROW_NULL_PDATA_IF_NOT_DESTROYED(peer);                          \
         return 0;                                                         \
     }                                                                     \
 }
@@ -105,16 +105,27 @@
     JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val);                         \
     pData = JNI_GET_PDATA(peer);                                          \
     if (pData == NULL) {                                                  \
-        JNU_ThrowNullPointerException(env, "null pData");                 \
+        THROW_NULL_PDATA_IF_NOT_DESTROYED(peer);                          \
         return val;                                                       \
     }                                                                     \
 }
 
+#define THROW_NULL_PDATA_IF_NOT_DESTROYED(peer) {                         \
+    jboolean destroyed = JNI_GET_DESTROYED(peer);                         \
+    if (destroyed != JNI_TRUE) {                                          \
+        JNU_ThrowNullPointerException(env, "null pData");                 \
+    }                                                                     \
+}
+
 #define JNI_GET_PDATA(peer) (PDATA) env->GetLongField(peer, AwtObject::pDataID)
+#define JNI_GET_DESTROYED(peer) env->GetBooleanField(peer, AwtObject::destroyedID)
 
 #define JNI_SET_PDATA(peer, data) env->SetLongField(peer,                  \
-                                                   AwtObject::pDataID,    \
-                                                   (jlong)data)
+                                                    AwtObject::pDataID,    \
+                                                    (jlong)data)
+#define JNI_SET_DESTROYED(peer) env->SetBooleanField(peer,                   \
+                                                     AwtObject::destroyedID, \
+                                                     JNI_TRUE)
 /*  /NEW JNI */
 
 /*
--- a/src/windows/native/sun/windows/awt_Component.cpp	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/windows/awt_Component.cpp	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -226,6 +226,8 @@
 CriticalSection windowMoveLock;
 BOOL windowMoveLockHeld = FALSE;
 
+int AwtComponent::sm_wheelRotationAmount = 0;
+
 /************************************************************************
  * AwtComponent methods
  */
@@ -2074,6 +2076,8 @@
         sm_realFocusOpposite = NULL;
     }
 
+    sm_wheelRotationAmount = 0;
+
     SendFocusEvent(java_awt_event_FocusEvent_FOCUS_GAINED, hWndLostFocus);
 
     return mrDoDefault;
@@ -2105,6 +2109,7 @@
     }
 
     sm_focusOwner = NULL;
+    sm_wheelRotationAmount = 0;
 
     SendFocusEvent(java_awt_event_FocusEvent_FOCUS_LOST, hWndGotFocus);
     return mrDoDefault;
@@ -2190,8 +2195,11 @@
         DWORD fgProcessID;
         ::GetWindowThreadProcessId(fgWindow, &fgProcessID);
 
-        if (fgProcessID != ::GetCurrentProcessId()) {
-            // fix for 6458497.  we shouldn't request focus if it is out of our application.
+        if (fgProcessID != ::GetCurrentProcessId()
+            && !AwtToolkit::GetInstance().IsEmbedderProcessId(fgProcessID))
+        {
+            // fix for 6458497.  we shouldn't request focus if it is out of both
+            // our and embedder process.
             return FALSE;
         }
     }
@@ -2619,9 +2627,13 @@
     BOOL result;
     UINT platformLines;
 
+    sm_wheelRotationAmount += wheelRotation;
+
     // AWT interprets wheel rotation differently than win32, so we need to
     // decode wheel amount.
-    jint newWheelRotation = wheelRotation / (-1 * WHEEL_DELTA);
+    jint roundedWheelRotation = sm_wheelRotationAmount / (-1 * WHEEL_DELTA);
+    jdouble preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA);
+
     MSG msg;
 
     if (IS_WIN95 && !IS_WIN98) {
@@ -2654,7 +2666,9 @@
 
     SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, TimeHelper::getMessageTimeUTC(),
                         eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType,
-                        scrollLines, newWheelRotation, &msg);
+                        scrollLines, roundedWheelRotation, preciseWheelRotation, &msg);
+
+    sm_wheelRotationAmount %= WHEEL_DELTA;
     return mrConsume;
 }
 
@@ -4986,8 +5000,8 @@
 AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
                                   jint modifiers, jint clickCount,
                                   jboolean popupTrigger, jint scrollType,
-                                  jint scrollAmount, jint wheelRotation,
-                                  MSG *pMsg)
+                                  jint scrollAmount, jint roundedWheelRotation,
+                                  jdouble preciseWheelRotation, MSG *pMsg)
 {
     /* Code based not so loosely on AwtComponent::SendMouseEvent */
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -5015,7 +5029,7 @@
     if (mouseWheelEventConst == NULL) {
         mouseWheelEventConst =
             env->GetMethodID(mouseWheelEventCls, "<init>",
-                           "(Ljava/awt/Component;IJIIIIZIII)V");
+                           "(Ljava/awt/Component;IJIIIIIIZIIID)V");
         DASSERT(mouseWheelEventConst);
     }
     if (env->EnsureLocalCapacity(2) < 0) {
@@ -5023,14 +5037,16 @@
     }
     jobject target = GetTarget(env);
     DTRACE_PRINTLN("creating MWE in JNI");
+
     jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls,
                                              mouseWheelEventConst,
                                              target,
                                              id, when, modifiers,
                                              x+insets.left, y+insets.top,
+                                             0, 0,
                                              clickCount, popupTrigger,
                                              scrollType, scrollAmount,
-                                             wheelRotation);
+                                             roundedWheelRotation, preciseWheelRotation);
     if (safe_ExceptionOccurred(env)) {
         env->ExceptionDescribe();
         env->ExceptionClear();
@@ -5400,6 +5416,7 @@
     if (m_peerObject) {
         env->SetLongField(m_peerObject, AwtComponent::hwndID, 0);
         JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL));
+        JNI_SET_DESTROYED(m_peerObject);
         env->DeleteGlobalRef(m_peerObject);
         m_peerObject = NULL;
     }
@@ -5408,7 +5425,13 @@
 void AwtComponent::Enable(BOOL bEnable)
 {
     sm_suppressFocusAndActivation = TRUE;
+
+    if (bEnable && IsTopLevel()) {
+        // we should not enable blocked toplevels
+        bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()));
+    }
     ::EnableWindow(GetHWnd(), bEnable);
+
     sm_suppressFocusAndActivation = FALSE;
     CriticalSection::Lock l(GetLock());
     VerifyState();
--- a/src/windows/native/sun/windows/awt_Component.h	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/windows/awt_Component.h	Mon Apr 14 11:34:15 2008 -0700
@@ -392,7 +392,7 @@
                              jint modifiers, jint clickCount,
                              jboolean popupTrigger, jint scrollType,
                              jint scrollAmount, jint wheelRotation,
-                             MSG *msg = NULL);
+                             jdouble preciseWheelRotation, MSG *msg = NULL);
 
     /*
      * Allocate and initialize a new java.awt.event.FocusEvent, and
@@ -785,7 +785,9 @@
     int windowMoveLockPosCX;
     int windowMoveLockPosCY;
 
-private:
+    // 6524352: support finer-resolution
+    static int sm_wheelRotationAmount;
+
     /*
      * The association list of children's IDs and corresponding components.
      * Some components like Choice or List are required their sizes while
--- a/src/windows/native/sun/windows/awt_Dialog.cpp	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/windows/awt_Dialog.cpp	Mon Apr 14 11:34:15 2008 -0700
@@ -273,6 +273,10 @@
         {
             HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd));
             HWND topMostBlocker = blocker;
+            HWND prevForegroundWindow = ::GetForegroundWindow();
+            if (::IsWindow(blocker)) {
+                ::BringWindowToTop(hWnd);
+            }
             while (::IsWindow(blocker)) {
                 topMostBlocker = blocker;
                 ::BringWindowToTop(blocker);
@@ -282,7 +286,7 @@
                 // no beep/flash if the mouse was clicked in the taskbar menu
                 // or the dialog is currently inactive
                 if ((::WindowFromPoint(mhs->pt) == hWnd) &&
-                    (::GetForegroundWindow() == topMostBlocker))
+                    (prevForegroundWindow == topMostBlocker))
                 {
                     ::MessageBeep(MB_OK);
                     // some heuristics: 3 times x 64 milliseconds
@@ -292,6 +296,7 @@
                     ::BringWindowToTop(topMostBlocker);
                     ::SetForegroundWindow(topMostBlocker);
                 }
+                return 1;
             }
         }
     }
--- a/src/windows/native/sun/windows/awt_Frame.cpp	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/windows/awt_Frame.cpp	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -221,8 +221,7 @@
 
                 // Update target's dimensions to reflect this embedded window.
                 ::GetClientRect(frame->m_hwnd, &rect);
-                ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect,
-                                  2);
+                ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, 2);
 
                 env->SetIntField(target, AwtComponent::xID, rect.left);
                 env->SetIntField(target, AwtComponent::yID, rect.top);
@@ -231,6 +230,7 @@
                 env->SetIntField(target, AwtComponent::heightID,
                                  rect.bottom-rect.top);
                 frame->InitPeerGraphicsConfig(env, self);
+                AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent);
             } else {
                 jint state = env->GetIntField(target, AwtFrame::stateID);
                 DWORD exStyle;
@@ -408,8 +408,9 @@
      * message. This breaks Java focus. To workaround the problem we
      * set the toplevel being shown foreground programmatically.
      * The fix is localized to non-foreground process case only.
+     * (See also: 6599270)
      */
-    if (show == TRUE && status == 0) {
+    if (!IsEmbeddedFrame() && show == TRUE && status == 0) {
         HWND fgHWnd = ::GetForegroundWindow();
         if (fgHWnd != NULL) {
             DWORD fgProcessID;
@@ -495,7 +496,7 @@
 
             ::SetWindowPos(GetHWnd(), NULL, r.left, r.top,
                            r.right-r.left, r.bottom-r.top,
-                           SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_NOZORDER |
+                           SWP_NOACTIVATE | SWP_NOZORDER |
                            SWP_NOCOPYBITS | SWP_DEFERERASE);
         }
         return mrConsume;
--- a/src/windows/native/sun/windows/awt_Object.cpp	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/windows/awt_Object.cpp	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
  */
 
 jfieldID AwtObject::pDataID;
+jfieldID AwtObject::destroyedID;
 jfieldID AwtObject::targetID;
 jclass AwtObject::wObjectPeerClass;
 jmethodID AwtObject::getPeerForTargetMID;
@@ -223,6 +224,7 @@
 
     AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls);
     AwtObject::pDataID = env->GetFieldID(cls, "pData", "J");
+    AwtObject::destroyedID = env->GetFieldID(cls, "destroyed", "Z");
     AwtObject::targetID = env->GetFieldID(cls, "target",
                                               "Ljava/lang/Object;");
 
@@ -233,6 +235,7 @@
     AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;");
 
     DASSERT(AwtObject::pDataID != NULL);
+    DASSERT(AwtObject::destroyedID != NULL);
     DASSERT(AwtObject::targetID != NULL);
     DASSERT(AwtObject::getPeerForTargetMID != NULL);
     DASSERT(AwtObject::createErrorID != NULL);
--- a/src/windows/native/sun/windows/awt_Object.h	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/windows/awt_Object.h	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,6 +51,7 @@
 
     /* sun.awt.windows.WObjectPeer field and method ids */
     static jfieldID pDataID;
+    static jfieldID destroyedID;
     static jfieldID targetID;
 
     static jmethodID getPeerForTargetMID;
--- a/src/windows/native/sun/windows/awt_Toolkit.cpp	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/windows/awt_Toolkit.cpp	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -354,6 +354,7 @@
     m_dllHandle = NULL;
 
     m_displayChanged = FALSE;
+    m_embedderProcessID = 0;
 
     // XXX: keyboard mapping should really be moved out of AwtComponent
     AwtComponent::InitDynamicKeyMapTable();
@@ -1442,49 +1443,17 @@
     }
 }
 
-/*
- * Returns a reference to the class java.awt.Component.
- */
-jclass
-getComponentClass(JNIEnv *env)
+// for now we support only one embedder, but should be ready for future
+void AwtToolkit::RegisterEmbedderProcessId(HWND embedder)
 {
-    static jclass componentCls = NULL;
-
-    // get global reference of java/awt/Component class (run only once)
-    if (componentCls == NULL) {
-        jclass componentClsLocal = env->FindClass("java/awt/Component");
-        DASSERT(componentClsLocal != NULL);
-        if (componentClsLocal == NULL) {
-            /* exception already thrown */
-            return NULL;
-        }
-        componentCls = (jclass)env->NewGlobalRef(componentClsLocal);
-        env->DeleteLocalRef(componentClsLocal);
+    if (m_embedderProcessID) {
+        // we already set embedder process and do not expect
+        // two different processes to embed the same AwtToolkit
+        return;
     }
-    return componentCls;
-}
 
-
-/*
- * Returns a reference to the class java.awt.MenuComponent.
- */
-jclass
-getMenuComponentClass(JNIEnv *env)
-{
-    static jclass menuComponentCls = NULL;
-
-    // get global reference of java/awt/MenuComponent class (run only once)
-    if (menuComponentCls == NULL) {
-        jclass menuComponentClsLocal = env->FindClass("java/awt/MenuComponent");
-        DASSERT(menuComponentClsLocal != NULL);
-        if (menuComponentClsLocal == NULL) {
-            /* exception already thrown */
-            return NULL;
-        }
-        menuComponentCls = (jclass)env->NewGlobalRef(menuComponentClsLocal);
-        env->DeleteLocalRef(menuComponentClsLocal);
-    }
-    return menuComponentCls;
+    embedder = ::GetAncestor(embedder, GA_ROOT);
+    ::GetWindowThreadProcessId(embedder, &m_embedderProcessID);
 }
 
 JNIEnv* AwtToolkit::m_env;
--- a/src/windows/native/sun/windows/awt_Toolkit.h	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/windows/awt_Toolkit.h	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -426,10 +426,17 @@
   */
 private:
     BOOL m_displayChanged;  /* Tracks displayChanged events */
+    // 0 means we are not embedded.
+    DWORD m_embedderProcessID;
 
 public:
     BOOL HasDisplayChanged() { return m_displayChanged; }
     void ResetDisplayChanged() { m_displayChanged = FALSE; }
+    void RegisterEmbedderProcessId(HWND);
+    BOOL IsEmbedderProcessId(const DWORD processID) const
+    {
+        return m_embedderProcessID && (processID == m_embedderProcessID);
+    }
 
  private:
     static JNIEnv *m_env;
--- a/src/windows/native/sun/windows/awt_Window.cpp	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/windows/awt_Window.cpp	Mon Apr 14 11:34:15 2008 -0700
@@ -125,6 +125,11 @@
 jclass AwtWindow::wwindowPeerCls;
 jmethodID AwtWindow::getActiveWindowsMID;
 
+jfieldID AwtWindow::sysXID;
+jfieldID AwtWindow::sysYID;
+jfieldID AwtWindow::sysWID;
+jfieldID AwtWindow::sysHID;
+
 int AwtWindow::ms_instanceCounter = 0;
 HHOOK AwtWindow::ms_hCBTFilter;
 AwtWindow * AwtWindow::m_grabbedWindow = NULL;
@@ -180,7 +185,6 @@
     }
 
     ::RemoveProp(GetHWnd(), ModalBlockerProp);
-    ::RemoveProp(GetHWnd(), ModalSaveWSEXProp);
 
     if (m_grabbedWindow == this) {
         Ungrab();
@@ -330,8 +334,11 @@
     if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) {
         AwtComponent *comp = AwtComponent::GetComponent((HWND)wParam);
 
-        if (comp != NULL && comp->IsTopLevel() && !((AwtWindow*)comp)->IsFocusableWindow()) {
-            return 1; // Don't change focus/activation.
+        if (comp != NULL && comp->IsTopLevel()) {
+            AwtWindow* win = (AwtWindow*)comp;
+            if (!win->IsFocusableWindow() || win->m_filterFocusAndActivation) {
+                return 1; // Don't change focus/activation.
+            }
         }
     }
     return ::CallNextHookEx(AwtWindow::ms_hCBTFilter, nCode, wParam, lParam);
@@ -1053,6 +1060,8 @@
 
     (env)->SetIntField(target, AwtComponent::xID, rect.left);
     (env)->SetIntField(target, AwtComponent::yID, rect.top);
+    (env)->SetIntField(peer, AwtWindow::sysXID, rect.left);
+    (env)->SetIntField(peer, AwtWindow::sysYID, rect.top);
     SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED);
 
     env->DeleteLocalRef(target);
@@ -1116,6 +1125,11 @@
 
     (env)->SetIntField(target, AwtComponent::widthID, newWidth);
     (env)->SetIntField(target, AwtComponent::heightID, newHeight);
+
+    jobject peer = GetPeer(env);
+    (env)->SetIntField(peer, AwtWindow::sysWID, newWidth);
+    (env)->SetIntField(peer, AwtWindow::sysHID, newHeight);
+
     if (!AwtWindow::IsResizing()) {
         WindowResized();
     }
@@ -1455,20 +1469,17 @@
     if (!::IsWindow(window)) {
         return;
     }
-    DWORD exStyle = ::GetWindowLong(window, GWL_EXSTYLE);
+
     if (::IsWindow(blocker)) {
-        // save WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles
-        DWORD saveStyle = exStyle & (AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW);
-        ::SetProp(window, ModalSaveWSEXProp, reinterpret_cast<HANDLE>(saveStyle));
-        ::SetWindowLong(window, GWL_EXSTYLE, (exStyle | AWT_WS_EX_NOACTIVATE) & ~WS_EX_APPWINDOW);
         ::SetProp(window, ModalBlockerProp, reinterpret_cast<HANDLE>(blocker));
+        ::EnableWindow(window, FALSE);
     } else {
-        // restore WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles
-        DWORD saveStyle = reinterpret_cast<DWORD>(::GetProp(window, ModalSaveWSEXProp));
-        ::SetWindowLong(window, GWL_EXSTYLE,
-                        (exStyle & ~(AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW)) | saveStyle);
-        ::RemoveProp(window, ModalSaveWSEXProp);
         ::RemoveProp(window, ModalBlockerProp);
+         AwtComponent *comp = AwtComponent::GetComponent(window);
+         // we don't expect to be called with non-java HWNDs
+         DASSERT(comp && comp->IsTopLevel());
+         // we should not unblock disabled toplevels
+         ::EnableWindow(window, comp->isEnabled());
     }
 }
 
@@ -1754,17 +1765,22 @@
             // Fix for 4459064 : do not enforce thresholds for embedded frames
             if (!p->IsEmbeddedFrame())
             {
+                jobject peer = p->GetPeer(env);
                 int minWidth = ::GetSystemMetrics(SM_CXMIN);
                 int minHeight = ::GetSystemMetrics(SM_CYMIN);
                 if (w < minWidth)
                 {
                     env->SetIntField(target, AwtComponent::widthID,
                         w = minWidth);
+                    env->SetIntField(peer, AwtWindow::sysWID,
+                        w);
                 }
                 if (h < minHeight)
                 {
                     env->SetIntField(target, AwtComponent::heightID,
                         h = minHeight);
+                    env->SetIntField(peer, AwtWindow::sysHID,
+                        h);
                 }
             }
             env->DeleteLocalRef(target);
@@ -2148,6 +2164,11 @@
         env->GetStaticMethodID(cls, "getActiveWindowHandles", "()[J");
     DASSERT(AwtWindow::getActiveWindowsMID != NULL);
 
+    AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I");
+    AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I");
+    AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I");
+    AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I");
+
     CATCH_BAD_ALLOC;
 }
 
--- a/src/windows/native/sun/windows/awt_Window.h	Thu Apr 10 13:57:15 2008 -0700
+++ b/src/windows/native/sun/windows/awt_Window.h	Mon Apr 14 11:34:15 2008 -0700
@@ -33,7 +33,6 @@
 
 // property name tagging windows disabled by modality
 static LPCTSTR ModalBlockerProp = TEXT("SunAwtModalBlockerProp");
-static LPCTSTR ModalSaveWSEXProp = TEXT("SunAwtModalSaveWSEXProp");
 static LPCTSTR ModalDialogPeerProp = TEXT("SunAwtModalDialogPeerProp");
 
 #ifndef WH_MOUSE_LL
@@ -63,6 +62,12 @@
     /* long[] getActiveWindowHandles() method in WWindowPeer */
     static jmethodID getActiveWindowsMID;
 
+    // The coordinates at the peer.
+    static jfieldID sysXID;
+    static jfieldID sysYID;
+    static jfieldID sysWID;
+    static jfieldID sysHID;
+
     AwtWindow();
     virtual ~AwtWindow();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/KeyFactory/TestProviderLeak.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6578538
+ * @summary com.sun.crypto.provider.SunJCE instance leak using KRB5 and
+ *     LoginContext
+ * @author Brad Wetmore
+ *
+ * @run main/othervm -Xmx2m TestProviderLeak
+ */
+
+/*
+ * We force the leak to become a problem by specifying the minimum
+ * size heap we can (above).  In current runs on a server and client
+ * machine, it took roughly 220-240 iterations to have the memory leak
+ * shut down other operations.  It complained about "Unable to verify
+ * the SunJCE provider."
+ */
+
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class TestProviderLeak {
+    private static void dumpMemoryStats(String s) throws Exception {
+        Runtime rt = Runtime.getRuntime();
+        System.out.println(s + ":\t" +
+            rt.freeMemory() + " bytes free");
+    }
+
+    public static void main(String [] args) throws Exception {
+        SecretKeyFactory skf =
+            SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1", "SunJCE");
+        PBEKeySpec pbeKS = new PBEKeySpec(
+            "passPhrase".toCharArray(), new byte [] { 0 }, 5, 512);
+        for (int i = 0; i <= 1000; i++) {
+            try {
+                skf.generateSecret(pbeKS);
+                if ((i % 20) == 0) {
+                     // Calling gc() isn't dependable, but doesn't hurt.
+                     // Gives better output in leak cases.
+                    System.gc();
+                    dumpMemoryStats("Iteration " + i);
+                }
+            } catch (Exception e) {
+                dumpMemoryStats("\nException seen at iteration " + i);
+                throw e;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Focus/NonFocusableResizableTooSmall/NonFocusableResizableTooSmall.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,413 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+  @test
+  @bug 6581927
+  @summary Non-focusable frame should honor the size of the frame buttons/decorations when resizing
+  @library ../../regtesthelpers
+  @build Util
+  @author anthony.petrov@...: area=awt.toplevel
+  @run main NonFocusableResizableTooSmall
+*/
+
+/**
+ * NonFocusableResizableTooSmall.java
+ *
+ * summary:  Non-focusable frame should honor the size of the frame buttons/decorations when resizing
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class NonFocusableResizableTooSmall
+{
+
+    //*** test-writer defined static variables go here ***
+
+
+    private static void init()
+    {
+        //*** Create instructions for the user here ***
+
+        String[] instructions =
+        {
+            "This is an AUTOMATIC test, simply wait until it is done.",
+            "The result (passed or failed) will be shown in the",
+            "message window below."
+        };
+        Sysout.createDialog( );
+        Sysout.printInstructions( instructions );
+
+        final Frame frame = new Frame();
+        frame.setFocusableWindowState(false);
+        frame.setSize(200, 100);
+        frame.setVisible(true);
+
+        final Robot robot = Util.createRobot();
+        robot.setAutoDelay(20);
+
+        // To be sure the window is shown and packed
+        Util.waitForIdle(robot);
+
+        final Insets insets = frame.getInsets();
+        System.out.println("The insets of the frame: " + insets);
+        if (insets.right == 0 || insets.bottom == 0) {
+            System.out.println("The test environment must have non-zero right & bottom insets!");
+            pass();
+            return;
+        }
+
+        // Let's move the mouse pointer to the bottom-right coner of the frame (the "size-grip")
+        final Rectangle bounds1 = frame.getBounds();
+        System.out.println("The bounds before resizing: " + bounds1);
+
+        robot.mouseMove(bounds1.x + bounds1.width - 1, bounds1.y + bounds1.height - 1);
+
+        // ... and start resizing to some very small
+        robot.mousePress( InputEvent.BUTTON1_MASK );
+
+        // Now resize the frame so that the width is smaller
+        // than the widths of the left and the right borders.
+        // The sum of widths of the icon of the frame + the control-buttons
+        // (close, minimize, etc.) should be definitely larger!
+        robot.mouseMove(bounds1.x + insets.left + insets.right - 5, bounds1.y + bounds1.height - 1);
+        Util.waitForIdle(robot);
+
+        robot.mouseRelease( InputEvent.BUTTON1_MASK );
+
+        Util.waitForIdle(robot);
+
+        // Check the current bounds of the frame
+        final Rectangle bounds2 = frame.getBounds();
+        System.out.println("The bounds after resizing: " + bounds2);
+
+        if (bounds2.width <= (insets.left + insets.right)) {
+            fail("The frame has been resized to very small.");
+        }
+        pass();
+    }//End  init()
+
+
+
+    /*****************************************************
+     * Standard Test Machinery Section
+     * DO NOT modify anything in this section -- it's a
+     * standard chunk of code which has all of the
+     * synchronisation necessary for the test harness.
+     * By keeping it the same in all tests, it is easier
+     * to read and understand someone else's test, as
+     * well as insuring that all tests behave correctly
+     * with the test harness.
+     * There is a section following this for test-
+     * classes
+     ******************************************************/
+    private static boolean theTestPassed = false;
+    private static boolean testGeneratedInterrupt = false;
+    private static String failureMessage = "";
+
+    private static Thread mainThread = null;
+
+    private static int sleepTime = 300000;
+
+    // Not sure about what happens if multiple of this test are
+    //  instantiated in the same VM.  Being static (and using
+    //  static vars), it aint gonna work.  Not worrying about
+    //  it for now.
+    public static void main( String args[] ) throws InterruptedException
+    {
+        mainThread = Thread.currentThread();
+        try
+        {
+            init();
+        }
+        catch( TestPassedException e )
+        {
+            //The test passed, so just return from main and harness will
+            // interepret this return as a pass
+            return;
+        }
+        //At this point, neither test pass nor test fail has been
+        // called -- either would have thrown an exception and ended the
+        // test, so we know we have multiple threads.
+
+        //Test involves other threads, so sleep and wait for them to
+        // called pass() or fail()
+        try
+        {
+            Thread.sleep( sleepTime );
+            //Timed out, so fail the test
+            throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+        }
+        catch (InterruptedException e)
+        {
+            //The test harness may have interrupted the test.  If so, rethrow the exception
+            // so that the harness gets it and deals with it.
+            if( ! testGeneratedInterrupt ) throw e;
+
+            //reset flag in case hit this code more than once for some reason (just safety)
+            testGeneratedInterrupt = false;
+
+            if ( theTestPassed == false )
+            {
+                throw new RuntimeException( failureMessage );
+            }
+        }
+
+    }//main
+
+    public static synchronized void setTimeoutTo( int seconds )
+    {
+        sleepTime = seconds * 1000;
+    }
+
+    public static synchronized void pass()
+    {
+        Sysout.println( "The test passed." );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //first check if this is executing in main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //Still in the main thread, so set the flag just for kicks,
+            // and throw a test passed exception which will be caught
+            // and end the test.
+            theTestPassed = true;
+            throw new TestPassedException();
+        }
+        theTestPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }//pass()
+
+    public static synchronized void fail()
+    {
+        //test writer didn't specify why test failed, so give generic
+        fail( "it just plain failed! :-)" );
+    }
+
+    public static synchronized void fail( String whyFailed )
+    {
+        Sysout.println( "The test failed: " + whyFailed );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //check if this called from main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //If main thread, fail now 'cause not sleeping
+            throw new RuntimeException( whyFailed );
+        }
+        theTestPassed = false;
+        testGeneratedInterrupt = true;
+        failureMessage = whyFailed;
+        mainThread.interrupt();
+    }//fail()
+
+}// class NonFocusableResizableTooSmall
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// if want to make listeners, here is the recommended place for them, then instantiate
+//  them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         NonFocusableResizableTooSmall.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         NonFocusableResizableTooSmall.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+{
+    private static TestDialog dialog;
+
+    public static void createDialogWithInstructions( String[] instructions )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        dialog.printInstructions( instructions );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+    public static void createDialog( )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        String[] defInstr = { "Instructions will appear here. ", "" } ;
+        dialog.printInstructions( defInstr );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+
+    public static void printInstructions( String[] instructions )
+    {
+        dialog.printInstructions( instructions );
+    }
+
+
+    public static void println( String messageIn )
+    {
+        dialog.displayMessage( messageIn );
+        System.out.println(messageIn);
+    }
+
+}// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog
+{
+
+    TextArea instructionsText;
+    TextArea messageText;
+    int maxStringLength = 80;
+
+    //DO NOT call this directly, go through Sysout
+    public TestDialog( Frame frame, String name )
+    {
+        super( frame, name );
+        int scrollBoth = TextArea.SCROLLBARS_BOTH;
+        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+        add( "North", instructionsText );
+
+        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+        add("Center", messageText);
+
+        pack();
+
+        setVisible(true);
+    }// TestDialog()
+
+    //DO NOT call this directly, go through Sysout
+    public void printInstructions( String[] instructions )
+    {
+        //Clear out any current instructions
+        instructionsText.setText( "" );
+
+        //Go down array of instruction strings
+
+        String printStr, remainingStr;
+        for( int i=0; i < instructions.length; i++ )
+        {
+            //chop up each into pieces maxSringLength long
+            remainingStr = instructions[ i ];
+            while( remainingStr.length() > 0 )
+            {
+                //if longer than max then chop off first max chars to print
+                if( remainingStr.length() >= maxStringLength )
+                {
+                    //Try to chop on a word boundary
+                    int posOfSpace = remainingStr.
+                        lastIndexOf( ' ', maxStringLength - 1 );
+
+                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
+                    remainingStr = remainingStr.substring( posOfSpace + 1 );
+                }
+                //else just print
+                else
+                {
+                    printStr = remainingStr;
+                    remainingStr = "";
+                }
+
+                instructionsText.append( printStr + "\n" );
+
+            }// while
+
+        }// for
+
+    }//printInstructions()
+
+    //DO NOT call this directly, go through Sysout
+    public void displayMessage( String messageIn )
+    {
+        messageText.append( messageIn + "\n" );
+        System.out.println(messageIn);
+    }
+
+}// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Focus/RestoreFocusOnDisabledComponentTest/RestoreFocusOnDisabledComponentTest.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+  @test      %W% %E%
+  @bug       6598089
+  @summary   Tests restoring focus on a single disabled coponent
+  @author    Anton Tarasov: area=awt-focus
+  @library   ../../regtesthelpers
+  @build     Util
+  @run       main RestoreFocusOnDisabledComponentTest
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+import java.applet.Applet;
+import test.java.awt.regtesthelpers.Util;
+
+/*
+ * The bug is not reproducible on Windows.
+ */
+public class RestoreFocusOnDisabledComponentTest extends Applet {
+    Frame frame = new Frame("Frame") {public String toString() {return "FRAME";}};
+    Button b0 = new Button("button0") {public String toString() {return "B-0";}};
+    Button b1 = new Button("button1") {public String toString() {return "B-1";}};
+    volatile int nFocused;
+    Robot robot;
+
+    public static void main(String[] args) {
+        RestoreFocusOnDisabledComponentTest app = new RestoreFocusOnDisabledComponentTest();
+        app.init();
+        app.start();
+    }
+
+    public void init() {
+        robot = Util.createRobot();
+    }
+
+    public void start() {
+        frame.add(b0);
+        frame.add(b1);
+        frame.setLayout(new FlowLayout());
+        frame.pack();
+
+        frame.setVisible(true);
+
+        Util.waitForIdle(robot);
+        KeyboardFocusManager.setCurrentKeyboardFocusManager(new DefaultKeyboardFocusManager() {
+            public boolean dispatchEvent(AWTEvent e) {
+                if (e.getID() == FocusEvent.FOCUS_GAINED) {
+                    // Trying to emulate timings. b1 should be disabled just by the time it gets
+                    // FOCUS_GAINED event. The latter is a result of disabling b0 that initiates
+                    // focus auto transfer.
+                    if (e.getSource() == b1) {
+                        b1.setEnabled(false);
+
+                    } else if (e.getSource() == b0) {
+                        if (++nFocused > 10) {
+                            nFocused = -1;
+                            throw new TestFailedException("Focus went into busy loop!");
+                        }
+                    }
+                }
+                return super.dispatchEvent(e);
+            }
+        });
+        // Initiating focus auto transfer.
+        // Focus will be requested to b1. When FOCUS_GAINED is being dispatched to b1, it will
+        // be disabled. This will trigger focus restoring. Focus will be requested to b0 (the
+        // last opposite component). When FOCUS_GAINED is being dispatched to b0, it will
+        // also be disabled. However, the last opposite component (and the most recent focus owner)
+        // will still be b0. When DKFM initiates focus restoring it should detect restoring
+        // on the same component and break.
+        b0.setEnabled(false);
+
+        Util.waitForIdle(robot);
+        if (nFocused != -1) {
+            System.out.println("Test passed.");
+        }
+    }
+}
+
+class TestFailedException extends RuntimeException {
+    TestFailedException(String msg) {
+        super("Test failed: " + msg);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Mixing/ValidBounds.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,411 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+  @test
+  @bug 6637796
+  @summary Shape should be correctly updated on invalid components
+  @author anthony.petrov@...: area=awt.mixing
+  @library ../regtesthelpers
+  @build Util
+  @run main ValidBounds
+*/
+
+/**
+ * ValidBounds.java
+ *
+ * summary:  Shape should be correctly updated on invalid components
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class ValidBounds
+{
+
+    static volatile boolean clickPassed = false;
+
+    private static void init()
+    {
+        //*** Create instructions for the user here ***
+
+        String[] instructions =
+        {
+            "This is an AUTOMATIC test, simply wait until it is done.",
+            "The result (passed or failed) will be shown in the",
+            "message window below."
+        };
+        Sysout.createDialog( );
+        Sysout.printInstructions( instructions );
+
+
+        // Create the frame and the button
+        Frame f = new Frame();
+        f.setBounds(100, 100, 400, 300);
+
+        Button b = new Button("OK");
+
+        f.setLayout(null);
+        f.add(b);
+        b.setBounds(50, 50, 200, 50);
+
+        b.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent e) {
+                clickPassed = true;
+            }
+        });
+
+        f.setVisible(true);
+
+        // Let's make the button much smaller first...
+        Robot robot = Util.createRobot();
+        robot.setAutoDelay(20);
+
+        Util.waitForIdle(robot);
+
+        b.setBounds(50, 50, 5, 5);
+        Util.waitForIdle(robot);
+
+        // ... and now let's enlarge it.
+        b.setBounds(50, 50, 200, 50);
+        Util.waitForIdle(robot);
+
+        // If the button doesn't receive the click, it means that the test
+        // failed: the shape of the button was not enlarged.
+        Point heavyLoc = b.getLocationOnScreen();
+        robot.mouseMove(heavyLoc.x + 20, heavyLoc.y + 20);
+
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        Util.waitForIdle(robot);
+
+        if (clickPassed) {
+            pass();
+        } else {
+            fail("The button cannot be clicked.");
+        }
+    }//End  init()
+
+
+
+    /*****************************************************
+     * Standard Test Machinery Section
+     * DO NOT modify anything in this section -- it's a
+     * standard chunk of code which has all of the
+     * synchronisation necessary for the test harness.
+     * By keeping it the same in all tests, it is easier
+     * to read and understand someone else's test, as
+     * well as insuring that all tests behave correctly
+     * with the test harness.
+     * There is a section following this for test-
+     * classes
+     ******************************************************/
+    private static boolean theTestPassed = false;
+    private static boolean testGeneratedInterrupt = false;
+    private static String failureMessage = "";
+
+    private static Thread mainThread = null;
+
+    private static int sleepTime = 300000;
+
+    // Not sure about what happens if multiple of this test are
+    //  instantiated in the same VM.  Being static (and using
+    //  static vars), it aint gonna work.  Not worrying about
+    //  it for now.
+    public static void main( String args[] ) throws InterruptedException
+    {
+        mainThread = Thread.currentThread();
+        try
+        {
+            init();
+        }
+        catch( TestPassedException e )
+        {
+            //The test passed, so just return from main and harness will
+            // interepret this return as a pass
+            return;
+        }
+        //At this point, neither test pass nor test fail has been
+        // called -- either would have thrown an exception and ended the
+        // test, so we know we have multiple threads.
+
+        //Test involves other threads, so sleep and wait for them to
+        // called pass() or fail()
+        try
+        {
+            Thread.sleep( sleepTime );
+            //Timed out, so fail the test
+            throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+        }
+        catch (InterruptedException e)
+        {
+            //The test harness may have interrupted the test.  If so, rethrow the exception
+            // so that the harness gets it and deals with it.
+            if( ! testGeneratedInterrupt ) throw e;
+
+            //reset flag in case hit this code more than once for some reason (just safety)
+            testGeneratedInterrupt = false;
+
+            if ( theTestPassed == false )
+            {
+                throw new RuntimeException( failureMessage );
+            }
+        }
+
+    }//main
+
+    public static synchronized void setTimeoutTo( int seconds )
+    {
+        sleepTime = seconds * 1000;
+    }
+
+    public static synchronized void pass()
+    {
+        Sysout.println( "The test passed." );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //first check if this is executing in main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //Still in the main thread, so set the flag just for kicks,
+            // and throw a test passed exception which will be caught
+            // and end the test.
+            theTestPassed = true;
+            throw new TestPassedException();
+        }
+        theTestPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }//pass()
+
+    public static synchronized void fail()
+    {
+        //test writer didn't specify why test failed, so give generic
+        fail( "it just plain failed! :-)" );
+    }
+
+    public static synchronized void fail( String whyFailed )
+    {
+        Sysout.println( "The test failed: " + whyFailed );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //check if this called from main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //If main thread, fail now 'cause not sleeping
+            throw new RuntimeException( whyFailed );
+        }
+        theTestPassed = false;
+        testGeneratedInterrupt = true;
+        failureMessage = whyFailed;
+        mainThread.interrupt();
+    }//fail()
+
+}// class ValidBounds
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// if want to make listeners, here is the recommended place for them, then instantiate
+//  them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         ValidBounds.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         ValidBounds.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+{
+    private static TestDialog dialog;
+
+    public static void createDialogWithInstructions( String[] instructions )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        dialog.printInstructions( instructions );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+    public static void createDialog( )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        String[] defInstr = { "Instructions will appear here. ", "" } ;
+        dialog.printInstructions( defInstr );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+
+    public static void printInstructions( String[] instructions )
+    {
+        dialog.printInstructions( instructions );
+    }
+
+
+    public static void println( String messageIn )
+    {
+        dialog.displayMessage( messageIn );
+        System.out.println(messageIn);
+    }
+
+}// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog
+{
+
+    TextArea instructionsText;
+    TextArea messageText;
+    int maxStringLength = 80;
+
+    //DO NOT call this directly, go through Sysout
+    public TestDialog( Frame frame, String name )
+    {
+        super( frame, name );
+        int scrollBoth = TextArea.SCROLLBARS_BOTH;
+        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+        add( "North", instructionsText );
+
+        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+        add("Center", messageText);
+
+        pack();
+
+        setVisible(true);
+    }// TestDialog()
+
+    //DO NOT call this directly, go through Sysout
+    public void printInstructions( String[] instructions )
+    {
+        //Clear out any current instructions
+        instructionsText.setText( "" );
+
+        //Go down array of instruction strings
+
+        String printStr, remainingStr;
+        for( int i=0; i < instructions.length; i++ )
+        {
+            //chop up each into pieces maxSringLength long
+            remainingStr = instructions[ i ];
+            while( remainingStr.length() > 0 )
+            {
+                //if longer than max then chop off first max chars to print
+                if( remainingStr.length() >= maxStringLength )
+                {
+                    //Try to chop on a word boundary
+                    int posOfSpace = remainingStr.
+                        lastIndexOf( ' ', maxStringLength - 1 );
+
+                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
+                    remainingStr = remainingStr.substring( posOfSpace + 1 );
+                }
+                //else just print
+                else
+                {
+                    printStr = remainingStr;
+                    remainingStr = "";
+                }
+
+                instructionsText.append( printStr + "\n" );
+
+            }// while
+
+        }// for
+
+    }//printInstructions()
+
+    //DO NOT call this directly, go through Sysout
+    public void displayMessage( String messageIn )
+    {
+        messageText.append( messageIn + "\n" );
+        System.out.println(messageIn);
+    }
+
+}// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,466 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+  @test %I% %E%
+  @bug 4080029
+  @summary Modal Dialog block input to all frame windows not just its parent.
+  @author dmitry.cherepanov: area=awt.modal
+  @run main/manual CloseBlocker
+*/
+
+/**
+ * ManualMainTest.java
+ *
+ * summary: The test opens and closes blocker dialog, the test verifies
+ *          that active window is correct when the dialog is closed.
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class CloseBlocker
+{
+
+    private static void init()
+    {
+        //*** Create instructions for the user here ***
+
+        String[] instructions =
+        {
+            " the test will be run 6 times, to start next test just close all ",
+            " windows of previous; the instructions are the same for all tests: ",
+            " 1) there are two frames (one the frames has 'show modal' button), ",
+            " 2) press the button to show a dialog, ",
+            " 3) close the dialog (an alternative scenario - activate another",
+            "    native window before closing the dialog), ",
+            " 4) the frame with button should become next active window, ",
+            "    if it's true, then the test passed, otherwise, it failed. ",
+            " Press 'pass' button only after all of the 6 tests are completed, ",
+            " the number of the currently executed test is displayed on the ",
+            " output window. "
+        };
+        Sysout.createDialog( );
+        Sysout.printInstructions( instructions );
+
+        test(true, true, false);
+        test(true, true, true);
+        test(false, true, false); // 3rd parameter has no affect for ownerless
+
+        test(true, false, false);
+        test(true, false, true);
+        test(false, false, false); // 3rd parameter has no affect for ownerless
+
+    }//End  init()
+
+    private static final Object obj = new Object();
+    private static int counter = 0;
+
+    /*
+     * The ownerless parameter indicates whether the blocker dialog
+     * has owner. The usual parameter indicates whether the blocker
+     * dialog is a Java dialog (non-native dialog like file dialog).
+     */
+    private static void test(final boolean ownerless, final boolean usual, final boolean initiallyOwnerIsActive) {
+
+        Sysout.print(" * test #" + (++counter) + " is running ... ");
+
+        final Frame active = new Frame();
+        final Frame nonactive = new Frame();
+        Button button = new Button("show modal");
+        button.addActionListener(new ActionListener() {
+               public void actionPerformed(ActionEvent ae) {
+                    Dialog dialog = null;
+                    Frame parent = ownerless ? null : (initiallyOwnerIsActive? active : nonactive);
+                    if (usual) {
+                        dialog = new Dialog(parent, "Sample", true);
+                    } else {
+                        dialog = new FileDialog(parent, "Sample", FileDialog.LOAD);
+                    }
+                    dialog.addWindowListener(new WindowAdapter(){
+                        public void windowClosing(WindowEvent e){
+                                e.getWindow().dispose();
+                        }
+                    });
+                    dialog.setBounds(200, 200, 200, 200);
+                    dialog.setVisible(true);
+                }
+        });
+
+        active.add(button);
+        active.setBounds(200, 400, 200, 200);
+        WindowAdapter adapter = new WindowAdapter(){
+              public void windowClosing(WindowEvent e){
+                    active.dispose();
+                    nonactive.dispose();
+                    synchronized(obj) {
+                        obj.notify();
+                    }
+                }
+             };
+        active.addWindowListener(adapter);
+        active.setVisible(true);
+
+        nonactive.setBounds(400, 400, 200, 200);
+        nonactive.addWindowListener(adapter);
+        nonactive.setVisible(true);
+
+        synchronized(obj) {
+            try{
+                obj.wait();
+            } catch(Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        Sysout.println(" completed. ");
+
+    }
+
+    /*****************************************************
+     * Standard Test Machinery Section
+     * DO NOT modify anything in this section -- it's a
+     * standard chunk of code which has all of the
+     * synchronisation necessary for the test harness.
+     * By keeping it the same in all tests, it is easier
+     * to read and understand someone else's test, as
+     * well as insuring that all tests behave correctly
+     * with the test harness.
+     * There is a section following this for test-defined
+     * classes
+     ******************************************************/
+    private static boolean theTestPassed = false;
+    private static boolean testGeneratedInterrupt = false;
+    private static String failureMessage = "";
+
+    private static Thread mainThread = null;
+
+    private static int sleepTime = 300000;
+
+    public static void main( String args[] ) throws InterruptedException
+    {
+        mainThread = Thread.currentThread();
+        try
+        {
+            init();
+        }
+        catch( TestPassedException e )
+        {
+            //The test passed, so just return from main and harness will
+            // interepret this return as a pass
+            return;
+        }
+        //At this point, neither test passed nor test failed has been
+        // called -- either would have thrown an exception and ended the
+        // test, so we know we have multiple threads.
+
+        //Test involves other threads, so sleep and wait for them to
+        // called pass() or fail()
+        try
+        {
+            Thread.sleep( sleepTime );
+            //Timed out, so fail the test
+            throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+        }
+        catch (InterruptedException e)
+        {
+            if( ! testGeneratedInterrupt ) throw e;
+
+            //reset flag in case hit this code more than once for some reason (just safety)
+            testGeneratedInterrupt = false;
+            if ( theTestPassed == false )
+            {
+                throw new RuntimeException( failureMessage );
+            }
+        }
+
+    }//main
+
+    public static synchronized void setTimeoutTo( int seconds )
+    {
+        sleepTime = seconds * 1000;
+    }
+
+    public static synchronized void pass()
+    {
+        Sysout.println( "The test passed." );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //first check if this is executing in main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //Still in the main thread, so set the flag just for kicks,
+            // and throw a test passed exception which will be caught
+            // and end the test.
+            theTestPassed = true;
+            throw new TestPassedException();
+        }
+        //pass was called from a different thread, so set the flag and interrupt
+        // the main thead.
+        theTestPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }//pass()
+
+    public static synchronized void fail()
+    {
+        //test writer didn't specify why test failed, so give generic
+        fail( "it just plain failed! :-)" );
+    }
+
+    public static synchronized void fail( String whyFailed )
+    {
+        Sysout.println( "The test failed: " + whyFailed );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //check if this called from main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //If main thread, fail now 'cause not sleeping
+            throw new RuntimeException( whyFailed );
+        }
+        theTestPassed = false;
+        testGeneratedInterrupt = true;
+        failureMessage = whyFailed;
+        mainThread.interrupt();
+    }//fail()
+
+}// class ManualMainTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         ManualMainTest.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         ManualMainTest.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+{
+    private static TestDialog dialog;
+
+    public static void createDialogWithInstructions( String[] instructions )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        dialog.printInstructions( instructions );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+    public static void createDialog( )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        String[] defInstr = { "Instructions will appear here. ", "" } ;
+        dialog.printInstructions( defInstr );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+
+    public static void printInstructions( String[] instructions )
+    {
+        dialog.printInstructions( instructions );
+    }
+
+
+    public static void println( String messageIn )
+    {
+        dialog.displayMessage( messageIn, true );
+    }
+
+    public static void print( String messageIn )
+    {
+        dialog.displayMessage( messageIn, false );
+    }
+
+}// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog implements ActionListener
+{
+
+    TextArea instructionsText;
+    TextArea messageText;
+    int maxStringLength = 80;
+    Panel  buttonP = new Panel();
+    Button passB = new Button( "pass" );
+    Button failB = new Button( "fail" );
+
+    //DO NOT call this directly, go through Sysout
+    public TestDialog( Frame frame, String name )
+    {
+        super( frame, name );
+        int scrollBoth = TextArea.SCROLLBARS_BOTH;
+        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+        add( "North", instructionsText );
+
+        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+        add("Center", messageText);
+
+        passB = new Button( "pass" );
+        passB.setActionCommand( "pass" );
+        passB.addActionListener( this );
+        buttonP.add( "East", passB );
+
+        failB = new Button( "fail" );
+        failB.setActionCommand( "fail" );
+        failB.addActionListener( this );
+        buttonP.add( "West", failB );
+
+        add( "South", buttonP );
+        pack();
+
+        setVisible(true);
+    }// TestDialog()
+
+    //DO NOT call this directly, go through Sysout
+    public void printInstructions( String[] instructions )
+    {
+        //Clear out any current instructions
+        instructionsText.setText( "" );
+
+        //Go down array of instruction strings
+
+        String printStr, remainingStr;
+        for( int i=0; i < instructions.length; i++ )
+        {
+            //chop up each into pieces maxSringLength long
+            remainingStr = instructions[ i ];
+            while( remainingStr.length() > 0 )
+            {
+                //if longer than max then chop off first max chars to print
+                if( remainingStr.length() >= maxStringLength )
+                {
+                    //Try to chop on a word boundary
+                    int posOfSpace = remainingStr.
+                        lastIndexOf( ' ', maxStringLength - 1 );
+
+                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
+                    remainingStr = remainingStr.substring( posOfSpace + 1 );
+                }
+                //else just print
+                else
+                {
+                    printStr = remainingStr;
+                    remainingStr = "";
+                }
+
+                instructionsText.append( printStr + "\n" );
+
+            }// while
+
+        }// for
+
+    }//printInstructions()
+
+    //DO NOT call this directly, go through Sysout
+    public void displayMessage( String messageIn, boolean nextLine )
+    {
+        messageText.append( messageIn + (nextLine? "\n" : "") );
+        System.out.println(messageIn);
+    }
+
+    //catch presses of the passed and failed buttons.
+    //simply call the standard pass() or fail() static methods of
+    //ManualMainTest
+    public void actionPerformed( ActionEvent e )
+    {
+        if( e.getActionCommand() == "pass" )
+        {
+            CloseBlocker.pass();
+        }
+        else
+        {
+            CloseBlocker.fail();
+        }
+    }
+
+}// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,456 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+  @test %I% %E%
+  @bug 4080029
+  @summary Modal Dialog block input to all frame windows not just its parent.
+  @author dmitry.cherepanov: area=awt.modal
+  @run main/manual OverBlocker
+*/
+
+/**
+ * OverBlocker.java
+ *
+ * summary: The test verifies that if user tries to activate the blocked dialog
+ *          then the blocker dialog appears over the other windows
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class OverBlocker
+{
+
+    private static void init()
+    {
+        //*** Create instructions for the user here ***
+
+        String[] instructions =
+        {
+            " the test will be run 4 times, to start next test just close all ",
+            " windows of previous; the instructions are the same for all tests: ",
+            " 1) there is a frame with 'show modal' button, ",
+            " 2) press the button to show a dialog, ",
+            " 3) activate any non-Java application, move the app over the dialog, ",
+            " 4) click on the frame by mouse, ",
+            " 5) make sure that the dialog comes up from the application and ",
+            "    now the dialog overlaps the app as well as the frame, ",
+            "    if it's true, then the test passed, otherwise, it failed. ",
+            " Press 'pass' button only after all of the 4 tests are completed, ",
+            " the number of the currently executed test is displayed on the ",
+            " output window. "
+        };
+        Sysout.createDialog( );
+        Sysout.printInstructions( instructions );
+
+        test(false, true);
+        test(true, true);
+        test(true, false);
+        test(false, false);
+
+    }//End  init()
+
+    private static final Object obj = new Object();
+    private static int counter = 0;
+
+    /*
+     * The ownerless parameter indicates whether the blocker dialog
+     * has owner. The usual parameter indicates whether the blocker
+     * dialog is a Java dialog (non-native dialog like file dialog).
+     */
+    private static void test(final boolean ownerless, final boolean usual) {
+
+        Sysout.print(" * test #" + (++counter) + " is running ... ");
+
+        final Frame frame = new Frame();
+        Button button = new Button("show modal");
+        button.addActionListener(new ActionListener() {
+              public void actionPerformed(ActionEvent ae) {
+                    Dialog dialog = null;
+                    Frame parent = ownerless ? null : frame;
+                    if (usual) {
+                        dialog = new Dialog(parent, "Sample", true);
+                    } else {
+                        dialog = new FileDialog(parent, "Sample", FileDialog.LOAD);
+                    }
+                    dialog.addWindowListener(new WindowAdapter(){
+                            public void windowClosing(WindowEvent e){
+                                e.getWindow().dispose();
+                            }
+                       });
+                    dialog.setBounds(200, 200, 200, 200);
+                    dialog.setVisible(true);
+                }
+            });
+        frame.add(button);
+        frame.setBounds(400, 400, 200, 200);
+        frame.addWindowListener(new WindowAdapter(){
+              public void windowClosing(WindowEvent e){
+                    e.getWindow().dispose();
+                    synchronized(obj) {
+                        obj.notify();
+                    }
+                }
+             });
+        frame.setVisible(true);
+
+        synchronized(obj) {
+            try{
+                obj.wait();
+            } catch(Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        Sysout.println(" completed. ");
+
+    }
+
+    /*****************************************************
+     * Standard Test Machinery Section
+     * DO NOT modify anything in this section -- it's a
+     * standard chunk of code which has all of the
+     * synchronisation necessary for the test harness.
+     * By keeping it the same in all tests, it is easier
+     * to read and understand someone else's test, as
+     * well as insuring that all tests behave correctly
+     * with the test harness.
+     * There is a section following this for test-defined
+     * classes
+     ******************************************************/
+    private static boolean theTestPassed = false;
+    private static boolean testGeneratedInterrupt = false;
+    private static String failureMessage = "";
+
+    private static Thread mainThread = null;
+
+    private static int sleepTime = 300000;
+
+    public static void main( String args[] ) throws InterruptedException
+    {
+        mainThread = Thread.currentThread();
+        try
+        {
+            init();
+        }
+        catch( TestPassedException e )
+        {
+            //The test passed, so just return from main and harness will
+            // interepret this return as a pass
+            return;
+        }
+        //At this point, neither test passed nor test failed has been
+        // called -- either would have thrown an exception and ended the
+        // test, so we know we have multiple threads.
+
+        //Test involves other threads, so sleep and wait for them to
+        // called pass() or fail()
+        try
+        {
+            Thread.sleep( sleepTime );
+            //Timed out, so fail the test
+            throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+        }
+        catch (InterruptedException e)
+        {
+            if( ! testGeneratedInterrupt ) throw e;
+
+            //reset flag in case hit this code more than once for some reason (just safety)
+            testGeneratedInterrupt = false;
+            if ( theTestPassed == false )
+            {
+                throw new RuntimeException( failureMessage );
+            }
+        }
+
+    }//main
+
+    public static synchronized void setTimeoutTo( int seconds )
+    {
+        sleepTime = seconds * 1000;
+    }
+
+    public static synchronized void pass()
+    {
+        Sysout.println( "The test passed." );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //first check if this is executing in main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //Still in the main thread, so set the flag just for kicks,
+            // and throw a test passed exception which will be caught
+            // and end the test.
+            theTestPassed = true;
+            throw new TestPassedException();
+        }
+        //pass was called from a different thread, so set the flag and interrupt
+        // the main thead.
+        theTestPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }//pass()
+
+    public static synchronized void fail()
+    {
+        //test writer didn't specify why test failed, so give generic
+        fail( "it just plain failed! :-)" );
+    }
+
+    public static synchronized void fail( String whyFailed )
+    {
+        Sysout.println( "The test failed: " + whyFailed );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //check if this called from main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //If main thread, fail now 'cause not sleeping
+            throw new RuntimeException( whyFailed );
+        }
+        theTestPassed = false;
+        testGeneratedInterrupt = true;
+        failureMessage = whyFailed;
+        mainThread.interrupt();
+    }//fail()
+
+}// class ManualMainTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         ManualMainTest.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         ManualMainTest.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+{
+    private static TestDialog dialog;
+
+    public static void createDialogWithInstructions( String[] instructions )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        dialog.printInstructions( instructions );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+    public static void createDialog( )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        String[] defInstr = { "Instructions will appear here. ", "" } ;
+        dialog.printInstructions( defInstr );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+
+    public static void printInstructions( String[] instructions )
+    {
+        dialog.printInstructions( instructions );
+    }
+
+
+    public static void println( String messageIn )
+    {
+        dialog.displayMessage( messageIn, true );
+    }
+
+    public static void print( String messageIn )
+    {
+        dialog.displayMessage( messageIn, false );
+    }
+
+}// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog implements ActionListener
+{
+
+    TextArea instructionsText;
+    TextArea messageText;
+    int maxStringLength = 80;
+    Panel  buttonP = new Panel();
+    Button passB = new Button( "pass" );
+    Button failB = new Button( "fail" );
+
+    //DO NOT call this directly, go through Sysout
+    public TestDialog( Frame frame, String name )
+    {
+        super( frame, name );
+        int scrollBoth = TextArea.SCROLLBARS_BOTH;
+        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+        add( "North", instructionsText );
+
+        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+        add("Center", messageText);
+
+        passB = new Button( "pass" );
+        passB.setActionCommand( "pass" );
+        passB.addActionListener( this );
+        buttonP.add( "East", passB );
+
+        failB = new Button( "fail" );
+        failB.setActionCommand( "fail" );
+        failB.addActionListener( this );
+        buttonP.add( "West", failB );
+
+        add( "South", buttonP );
+        pack();
+
+        setVisible(true);
+    }// TestDialog()
+
+    //DO NOT call this directly, go through Sysout
+    public void printInstructions( String[] instructions )
+    {
+        //Clear out any current instructions
+        instructionsText.setText( "" );
+
+        //Go down array of instruction strings
+
+        String printStr, remainingStr;
+        for( int i=0; i < instructions.length; i++ )
+        {
+            //chop up each into pieces maxSringLength long
+            remainingStr = instructions[ i ];
+            while( remainingStr.length() > 0 )
+            {
+                //if longer than max then chop off first max chars to print
+                if( remainingStr.length() >= maxStringLength )
+                {
+                    //Try to chop on a word boundary
+                    int posOfSpace = remainingStr.
+                        lastIndexOf( ' ', maxStringLength - 1 );
+
+                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
+                    remainingStr = remainingStr.substring( posOfSpace + 1 );
+                }
+                //else just print
+                else
+                {
+                    printStr = remainingStr;
+                    remainingStr = "";
+                }
+
+                instructionsText.append( printStr + "\n" );
+
+            }// while
+
+        }// for
+
+    }//printInstructions()
+
+    //DO NOT call this directly, go through Sysout
+    public void displayMessage( String messageIn, boolean nextLine )
+    {
+        messageText.append( messageIn + (nextLine? "\n" : "") );
+        System.out.println(messageIn);
+    }
+
+    //catch presses of the passed and failed buttons.
+    //simply call the standard pass() or fail() static methods of
+    //ManualMainTest
+    public void actionPerformed( ActionEvent e )
+    {
+        if( e.getActionCommand() == "pass" )
+        {
+            OverBlocker.pass();
+        }
+        else
+        {
+            OverBlocker.fail();
+        }
+    }
+
+}// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,403 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+  @test %I% %E%
+  @bug 6572263 6571808
+  @summary  PIT:FileDialog minimized to taskbar(through 'Show Desktop')selecting the fileDialog using windowList
+  @author dmitry.cherepanov: area=awt.modal
+  @run main/manual Winkey
+*/
+
+/**
+ * Winkey.java
+ *
+ * summary: the test verifies that pressing combination of Windows key
+ *          and M key to minimize all windows doesn't break AWT modality
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class Winkey
+{
+
+    private static void init()
+    {
+        //*** Create instructions for the user here ***
+
+        String[] instructions =
+        {
+            " 1. there is a frame with a 'show modal' button, ",
+            " 2. press the button to show a modal dialog, ",
+            " 3. the modal dialog will be shown over the frame, ",
+            " 4. please verify that all (5.1, 5.2.1, 5.2.2) the following tests pass: ",
+            " ",
+            " 5.1. press combination Windows Key and M key to minimize all windows, ",
+            " 5.2. press combination Windows Key and D key to show desktop, ",
+            "      5.2.1. restore the dialog by choosing this one in the ALT-TAB list, ",
+            "      5.2.2. restore the dialog by mouse click on taskbar (on java or any other item)",
+            " ",
+            " 6. make sure that the dialog and the frame are visible, ",
+            "    the bounds of the windows should be the same as before, ",
+            "    if it's true, then the test passed; otherwise, it failed. "
+        };
+        Sysout.createDialog( );
+        Sysout.printInstructions( instructions );
+
+        final Frame frame = new Frame();
+        Button button = new Button("show modal");
+        button.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent ae) {
+                    FileDialog dialog = new FileDialog((Frame)null, "Sample", FileDialog.LOAD);
+                    dialog.setVisible(true);
+                }
+            });
+        frame.add(button);
+        frame.setBounds(400, 400, 200, 200);
+        frame.setVisible(true);
+
+    }//End  init()
+
+    /*****************************************************
+     * Standard Test Machinery Section
+     * DO NOT modify anything in this section -- it's a
+     * standard chunk of code which has all of the
+     * synchronisation necessary for the test harness.
+     * By keeping it the same in all tests, it is easier
+     * to read and understand someone else's test, as
+     * well as insuring that all tests behave correctly
+     * with the test harness.
+     * There is a section following this for test-defined
+     * classes
+     ******************************************************/
+    private static boolean theTestPassed = false;
+    private static boolean testGeneratedInterrupt = false;
+    private static String failureMessage = "";
+
+    private static Thread mainThread = null;
+
+    private static int sleepTime = 300000;
+
+    public static void main( String args[] ) throws InterruptedException
+    {
+        mainThread = Thread.currentThread();
+        try
+        {
+            init();
+        }
+        catch( TestPassedException e )
+        {
+            //The test passed, so just return from main and harness will
+            // interepret this return as a pass
+            return;
+        }
+        //At this point, neither test passed nor test failed has been
+        // called -- either would have thrown an exception and ended the
+        // test, so we know we have multiple threads.
+
+        //Test involves other threads, so sleep and wait for them to
+        // called pass() or fail()
+        try
+        {
+            Thread.sleep( sleepTime );
+            //Timed out, so fail the test
+            throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+        }
+        catch (InterruptedException e)
+        {
+            if( ! testGeneratedInterrupt ) throw e;
+
+            //reset flag in case hit this code more than once for some reason (just safety)
+            testGeneratedInterrupt = false;
+            if ( theTestPassed == false )
+            {
+                throw new RuntimeException( failureMessage );
+            }
+        }
+
+    }//main
+
+    public static synchronized void setTimeoutTo( int seconds )
+    {
+        sleepTime = seconds * 1000;
+    }
+
+    public static synchronized void pass()
+    {
+        Sysout.println( "The test passed." );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //first check if this is executing in main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //Still in the main thread, so set the flag just for kicks,
+            // and throw a test passed exception which will be caught
+            // and end the test.
+            theTestPassed = true;
+            throw new TestPassedException();
+        }
+        //pass was called from a different thread, so set the flag and interrupt
+        // the main thead.
+        theTestPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }//pass()
+
+    public static synchronized void fail()
+    {
+        //test writer didn't specify why test failed, so give generic
+        fail( "it just plain failed! :-)" );
+    }
+
+    public static synchronized void fail( String whyFailed )
+    {
+        Sysout.println( "The test failed: " + whyFailed );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //check if this called from main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //If main thread, fail now 'cause not sleeping
+            throw new RuntimeException( whyFailed );
+        }
+        theTestPassed = false;
+        testGeneratedInterrupt = true;
+        failureMessage = whyFailed;
+        mainThread.interrupt();
+    }//fail()
+
+}// class ManualMainTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         ManualMainTest.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         ManualMainTest.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+{
+    private static TestDialog dialog;
+
+    public static void createDialogWithInstructions( String[] instructions )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        dialog.printInstructions( instructions );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+    public static void createDialog( )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        String[] defInstr = { "Instructions will appear here. ", "" } ;
+        dialog.printInstructions( defInstr );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+
+    public static void printInstructions( String[] instructions )
+    {
+        dialog.printInstructions( instructions );
+    }
+
+
+    public static void println( String messageIn )
+    {
+        dialog.displayMessage( messageIn );
+    }
+
+}// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog implements ActionListener
+{
+
+    TextArea instructionsText;
+    TextArea messageText;
+    int maxStringLength = 80;
+    Panel  buttonP = new Panel();
+    Button passB = new Button( "pass" );
+    Button failB = new Button( "fail" );
+
+    //DO NOT call this directly, go through Sysout
+    public TestDialog( Frame frame, String name )
+    {
+        super( frame, name );
+        int scrollBoth = TextArea.SCROLLBARS_BOTH;
+        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+        add( "North", instructionsText );
+
+        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+        add("Center", messageText);
+
+        passB = new Button( "pass" );
+        passB.setActionCommand( "pass" );
+        passB.addActionListener( this );
+        buttonP.add( "East", passB );
+
+        failB = new Button( "fail" );
+        failB.setActionCommand( "fail" );
+        failB.addActionListener( this );
+        buttonP.add( "West", failB );
+
+        add( "South", buttonP );
+        pack();
+
+        setVisible(true);
+    }// TestDialog()
+
+    //DO NOT call this directly, go through Sysout
+    public void printInstructions( String[] instructions )
+    {
+        //Clear out any current instructions
+        instructionsText.setText( "" );
+
+        //Go down array of instruction strings
+
+        String printStr, remainingStr;
+        for( int i=0; i < instructions.length; i++ )
+        {
+            //chop up each into pieces maxSringLength long
+            remainingStr = instructions[ i ];
+            while( remainingStr.length() > 0 )
+            {
+                //if longer than max then chop off first max chars to print
+                if( remainingStr.length() >= maxStringLength )
+                {
+                    //Try to chop on a word boundary
+                    int posOfSpace = remainingStr.
+                        lastIndexOf( ' ', maxStringLength - 1 );
+
+                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
+                    remainingStr = remainingStr.substring( posOfSpace + 1 );
+                }
+                //else just print
+                else
+                {
+                    printStr = remainingStr;
+                    remainingStr = "";
+                }
+
+                instructionsText.append( printStr + "\n" );
+
+            }// while
+
+        }// for
+
+    }//printInstructions()
+
+    //DO NOT call this directly, go through Sysout
+    public void displayMessage( String messageIn )
+    {
+        messageText.append( messageIn + "\n" );
+        System.out.println(messageIn);
+    }
+
+    //catch presses of the passed and failed buttons.
+    //simply call the standard pass() or fail() static methods of
+    //ManualMainTest
+    public void actionPerformed( ActionEvent e )
+    {
+        if( e.getActionCommand() == "pass" )
+        {
+            Winkey.pass();
+        }
+        else
+        {
+            Winkey.fail();
+        }
+    }
+
+}// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,432 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+  @test %W% %E%  %I%, %G%
+  @bug 6524352
+  @summary support for high-resolution mouse wheel
+  @author dmitry cherepanov: area=awt.event
+  @run main/manual SmoothWheel
+*/
+
+/**
+ * SmoothWheel.java
+ *
+ * summary:
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class SmoothWheel
+{
+
+    //*** test-writer defined static variables go here ***
+
+
+    private static void init()
+    {
+        String[] instructions =
+        {
+            "1. the test is for high-resolution mouse wheel only, ",
+            "   refer to the cr# 6524352 for more info about such devices, ",
+            "2. you'll see a frame, the frame contains a checkbox, ",
+            "3. initially, the state of the checkbox is off, ",
+            "   use mouse wheel over the frame, ",
+            "   and the frame will change its size gradually, ",
+            "4. turn on the checkbox, ",
+            "   use mouse wheel again over the frame, ",
+            "   now the frame will change its size smoothly, ",
+            "5. if the frame has always the same size or",
+            "   if the frame changes its size equally in 3,4 cases, ",
+            "   then the test failed. Otherwise, it passed."
+        };
+
+        Sysout.createDialog( );
+        Sysout.printInstructions( instructions );
+
+        final Frame frame = new Frame();
+        final Checkbox checkbox = new Checkbox("smooth wheel?");
+        checkbox.setState(false);
+
+        frame.setLayout (new FlowLayout());
+        frame.add(checkbox);
+
+        frame.addMouseWheelListener(new MouseWheelListener() {
+            public void mouseWheelMoved(MouseWheelEvent e) {
+                Sysout.println(e.toString());
+                double wheelRotation = 0;
+                if (checkbox.getState()) {
+                    wheelRotation = e.getPreciseWheelRotation();
+                } else {
+                    wheelRotation = e.getWheelRotation();
+                }
+                Dimension size = frame.getSize();
+                size.width += 10 * wheelRotation;
+                size.height += 10 * wheelRotation;
+                frame.setSize(size);
+            }
+        });
+
+        frame.setBounds(200, 200, 200, 200);
+        frame.setVisible(true);
+
+    }//End  init()
+
+
+
+    /*****************************************************
+     * Standard Test Machinery Section
+     * DO NOT modify anything in this section -- it's a
+     * standard chunk of code which has all of the
+     * synchronisation necessary for the test harness.
+     * By keeping it the same in all tests, it is easier
+     * to read and understand someone else's test, as
+     * well as insuring that all tests behave correctly
+     * with the test harness.
+     * There is a section following this for test-defined
+     * classes
+     ******************************************************/
+    private static boolean theTestPassed = false;
+    private static boolean testGeneratedInterrupt = false;
+    private static String failureMessage = "";
+
+    private static Thread mainThread = null;
+
+    private static int sleepTime = 300000;
+
+    public static void main( String args[] ) throws InterruptedException
+    {
+        mainThread = Thread.currentThread();
+        try
+        {
+            init();
+        }
+        catch( TestPassedException e )
+        {
+            //The test passed, so just return from main and harness will
+            // interepret this return as a pass
+            return;
+        }
+        //At this point, neither test passed nor test failed has been
+        // called -- either would have thrown an exception and ended the
+        // test, so we know we have multiple threads.
+
+        //Test involves other threads, so sleep and wait for them to
+        // called pass() or fail()
+        try
+        {
+            Thread.sleep( sleepTime );
+            //Timed out, so fail the test
+            throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+        }
+        catch (InterruptedException e)
+        {
+            if( ! testGeneratedInterrupt ) throw e;
+
+            //reset flag in case hit this code more than once for some reason (just safety)
+            testGeneratedInterrupt = false;
+            if ( theTestPassed == false )
+            {
+                throw new RuntimeException( failureMessage );
+            }
+        }
+
+    }//main
+
+    public static synchronized void setTimeoutTo( int seconds )
+    {
+        sleepTime = seconds * 1000;
+    }
+
+    public static synchronized void pass()
+    {
+        Sysout.println( "The test passed." );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //first check if this is executing in main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //Still in the main thread, so set the flag just for kicks,
+            // and throw a test passed exception which will be caught
+            // and end the test.
+            theTestPassed = true;
+            throw new TestPassedException();
+        }
+        //pass was called from a different thread, so set the flag and interrupt
+        // the main thead.
+        theTestPassed = true;
+        testGeneratedInterrupt = true;
+        if (mainThread != null){
+            mainThread.interrupt();
+        }
+    }//pass()
+
+    public static synchronized void fail()
+    {
+        //test writer didn't specify why test failed, so give generic
+        fail( "it just plain failed! :-)" );
+    }
+
+    public static synchronized void fail( String whyFailed )
+    {
+        Sysout.println( "The test failed: " + whyFailed );
+        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
+        //check if this called from main thread
+        if ( mainThread == Thread.currentThread() )
+        {
+            //If main thread, fail now 'cause not sleeping
+            throw new RuntimeException( whyFailed );
+        }
+        theTestPassed = false;
+        testGeneratedInterrupt = true;
+        failureMessage = whyFailed;
+        mainThread.interrupt();
+    }//fail()
+
+}// class ManualMainTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+   static int newVar = 0;
+
+   public void eventDispatched(AWTEvent e)
+    {
+      //Counting events to see if we get enough
+      eventCount++;
+
+      if( eventCount == 20 )
+       {
+         //got enough events, so pass
+
+         ManualMainTest.pass();
+       }
+      else if( tries == 20 )
+       {
+         //tried too many times without getting enough events so fail
+
+         ManualMainTest.fail();
+       }
+
+    }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+{
+    private static TestDialog dialog;
+    private static boolean numbering = false;
+    private static int messageNumber = 0;
+
+    public static void createDialogWithInstructions( String[] instructions )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        dialog.printInstructions( instructions );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+    public static void createDialog( )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        String[] defInstr = { "Instructions will appear here. ", "" } ;
+        dialog.printInstructions( defInstr );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+
+    /* Enables message counting for the tester. */
+    public static void enableNumbering(boolean enable){
+        numbering = enable;
+    }
+
+    public static void printInstructions( String[] instructions )
+    {
+        dialog.printInstructions( instructions );
+    }
+
+
+    public static void println( String messageIn )
+    {
+        if (numbering) {
+            messageIn = "" + messageNumber + " " + messageIn;
+            messageNumber++;
+        }
+        dialog.displayMessage( messageIn );
+    }
+
+}// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog implements ActionListener
+{
+
+    TextArea instructionsText;
+    TextArea messageText;
+    int maxStringLength = 80;
+    Panel  buttonP = new Panel();
+    Button passB = new Button( "pass" );
+    Button failB = new Button( "fail" );
+
+    //DO NOT call this directly, go through Sysout
+    public TestDialog( Frame frame, String name )
+    {
+        super( frame, name );
+        int scrollBoth = TextArea.SCROLLBARS_BOTH;
+        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+        add( "North", instructionsText );
+
+        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+        add("Center", messageText);
+
+        passB = new Button( "pass" );
+        passB.setActionCommand( "pass" );
+        passB.addActionListener( this );
+        buttonP.add( "East", passB );
+
+        failB = new Button( "fail" );
+        failB.setActionCommand( "fail" );
+        failB.addActionListener( this );
+        buttonP.add( "West", failB );
+
+        add( "South", buttonP );
+        pack();
+
+        setVisible(true);
+    }// TestDialog()
+
+    //DO NOT call this directly, go through Sysout
+    public void printInstructions( String[] instructions )
+    {
+        //Clear out any current instructions
+        instructionsText.setText( "" );
+
+        //Go down array of instruction strings
+
+        String printStr, remainingStr;
+        for( int i=0; i < instructions.length; i++ )
+        {
+            //chop up each into pieces maxSringLength long
+            remainingStr = instructions[ i ];
+            while( remainingStr.length() > 0 )
+            {
+                //if longer than max then chop off first max chars to print
+                if( remainingStr.length() >= maxStringLength )
+                {
+                    //Try to chop on a word boundary
+                    int posOfSpace = remainingStr.
+                        lastIndexOf( ' ', maxStringLength - 1 );
+
+                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
+                    remainingStr = remainingStr.substring( posOfSpace + 1 );
+                }
+                //else just print
+                else
+                {
+                    printStr = remainingStr;
+                    remainingStr = "";
+                }
+
+                instructionsText.append( printStr + "\n" );
+
+            }// while
+
+        }// for
+
+    }//printInstructions()
+
+    //DO NOT call this directly, go through Sysout
+    public void displayMessage( String messageIn )
+    {
+        messageText.append( messageIn + "\n" );
+        System.out.println(messageIn);
+    }
+
+    //catch presses of the passed and failed buttons.
+    //simply call the standard pass() or fail() static methods of
+    //ManualMainTest
+    public void actionPerformed( ActionEvent e )
+    {
+        if( e.getActionCommand() == "pass" )
+        {
+            SmoothWheel.pass();
+        }
+        else
+        {
+            SmoothWheel.fail();
+        }
+    }
+
+}// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/io/FileOutputStream/AtomicAppend.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6631352
+ * @summary Check that appends are atomic
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public class AtomicAppend {
+    // Before the fix for
+    // 6631352: Implement atomic append mode using FILE_APPEND_DATA (win)
+    // this would fail intermittently on windows
+    void test(String[] args) throws Throwable {
+        final int nThreads = 10;
+        final int writes = 1000;
+        final File file = new File("foo");
+        file.delete();
+        try {
+            final ExecutorService es = Executors.newFixedThreadPool(nThreads);
+            for (int i = 0; i < nThreads; i++)
+                es.execute(new Runnable() { public void run() {
+                    try {
+                        FileOutputStream s = new FileOutputStream(file, true);
+                        for (int j = 0; j < 1000; j++) {
+                            s.write((int) 'x');
+                            s.flush();
+                        }
+                        s.close();
+                    } catch (Throwable t) { unexpected(t); }}});
+            es.shutdown();
+            es.awaitTermination(10L, TimeUnit.MINUTES);
+            equal(file.length(), (long) (nThreads * writes));
+        } finally {
+            file.delete();
+        }
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    volatile int passed = 0, failed = 0;
+    void pass() {passed++;}
+    void fail() {failed++; Thread.dumpStack();}
+    void fail(String msg) {System.err.println(msg); fail();}
+    void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    void check(boolean cond) {if (cond) pass(); else fail();}
+    void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        new AtomicAppend().instanceMain(args);}
+    void instanceMain(String[] args) throws Throwable {
+        try {test(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+}
--- a/test/java/lang/ProcessBuilder/Basic.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/test/java/lang/ProcessBuilder/Basic.java	Mon Apr 14 11:34:15 2008 -0700
@@ -25,12 +25,15 @@
  * @test
  * @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
  *      5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
- *      6464154 6523983 6206031
+ *      6464154 6523983 6206031 4960438 6631352 6631966
  * @summary Basic tests for Process and Environment Variable code
  * @run main/othervm Basic
  * @author Martin Buchholz
  */
 
+import java.lang.ProcessBuilder.Redirect;
+import static java.lang.ProcessBuilder.Redirect.*;
+
 import java.io.*;
 import java.util.*;
 import java.security.*;
@@ -257,7 +260,29 @@
     public static class JavaChild {
         public static void main(String args[]) throws Throwable {
             String action = args[0];
-            if (action.equals("System.getenv(String)")) {
+            if (action.equals("testIO")) {
+                String expected = "standard input";
+                char[] buf = new char[expected.length()+1];
+                int n = new InputStreamReader(System.in).read(buf,0,buf.length);
+                if (n != expected.length())
+                    System.exit(5);
+                if (! new String(buf,0,n).equals(expected))
+                    System.exit(5);
+                System.err.print("standard error");
+                System.out.print("standard output");
+            } else if (action.equals("testInheritIO")) {
+                List<String> childArgs = new ArrayList<String>(javaChildArgs);
+                childArgs.add("testIO");
+                ProcessBuilder pb = new ProcessBuilder(childArgs);
+                pb.inheritIO();
+                ProcessResults r = run(pb);
+                if (! r.out().equals(""))
+                    System.exit(7);
+                if (! r.err().equals(""))
+                    System.exit(8);
+                if (r.exitValue() != 0)
+                    System.exit(9);
+            } else if (action.equals("System.getenv(String)")) {
                 String val = System.getenv(args[1]);
                 printUTF8(val == null ? "null" : val);
             } else if (action.equals("System.getenv(\\u1234)")) {
@@ -599,6 +624,333 @@
         } catch (Throwable t) { unexpected(t); }
     }
 
+    static void checkRedirects(ProcessBuilder pb,
+                               Redirect in, Redirect out, Redirect err) {
+        equal(pb.redirectInput(),  in);
+        equal(pb.redirectOutput(), out);
+        equal(pb.redirectError(),  err);
+    }
+
+    static void redirectIO(ProcessBuilder pb,
+                           Redirect in, Redirect out, Redirect err) {
+        pb.redirectInput(in);
+        pb.redirectOutput(out);
+        pb.redirectError(err);
+    }
+
+    static void setFileContents(File file, String contents) {
+        try {
+            Writer w = new FileWriter(file);
+            w.write(contents);
+            w.close();
+        } catch (Throwable t) { unexpected(t); }
+    }
+
+    static String fileContents(File file) {
+        try {
+            Reader r = new FileReader(file);
+            StringBuilder sb = new StringBuilder();
+            char[] buffer = new char[1024];
+            int n;
+            while ((n = r.read(buffer)) != -1)
+                sb.append(buffer,0,n);
+            r.close();
+            return new String(sb);
+        } catch (Throwable t) { unexpected(t); return ""; }
+    }
+
+    static void testIORedirection() throws Throwable {
+        final File ifile = new File("ifile");
+        final File ofile = new File("ofile");
+        final File efile = new File("efile");
+        ifile.delete();
+        ofile.delete();
+        efile.delete();
+
+        //----------------------------------------------------------------
+        // Check mutual inequality of different types of Redirect
+        //----------------------------------------------------------------
+        Redirect[] redirects =
+            { PIPE,
+              INHERIT,
+              Redirect.from(ifile),
+              Redirect.to(ifile),
+              Redirect.appendTo(ifile),
+              Redirect.from(ofile),
+              Redirect.to(ofile),
+              Redirect.appendTo(ofile),
+            };
+        for (int i = 0; i < redirects.length; i++)
+            for (int j = 0; j < redirects.length; j++)
+                equal(redirects[i].equals(redirects[j]), (i == j));
+
+        //----------------------------------------------------------------
+        // Check basic properties of different types of Redirect
+        //----------------------------------------------------------------
+        equal(PIPE.type(), Redirect.Type.PIPE);
+        equal(PIPE.toString(), "PIPE");
+        equal(PIPE.file(), null);
+
+        equal(INHERIT.type(), Redirect.Type.INHERIT);
+        equal(INHERIT.toString(), "INHERIT");
+        equal(INHERIT.file(), null);
+
+        equal(Redirect.from(ifile).type(), Redirect.Type.READ);
+        equal(Redirect.from(ifile).toString(),
+              "redirect to read from file \"ifile\"");
+        equal(Redirect.from(ifile).file(), ifile);
+        equal(Redirect.from(ifile),
+              Redirect.from(ifile));
+        equal(Redirect.from(ifile).hashCode(),
+              Redirect.from(ifile).hashCode());
+
+        equal(Redirect.to(ofile).type(), Redirect.Type.WRITE);
+        equal(Redirect.to(ofile).toString(),
+              "redirect to write to file \"ofile\"");
+        equal(Redirect.to(ofile).file(), ofile);
+        equal(Redirect.to(ofile),
+              Redirect.to(ofile));
+        equal(Redirect.to(ofile).hashCode(),
+              Redirect.to(ofile).hashCode());
+
+        equal(Redirect.appendTo(ofile).type(), Redirect.Type.APPEND);
+        equal(Redirect.appendTo(efile).toString(),
+              "redirect to append to file \"efile\"");
+        equal(Redirect.appendTo(efile).file(), efile);
+        equal(Redirect.appendTo(efile),
+              Redirect.appendTo(efile));
+        equal(Redirect.appendTo(efile).hashCode(),
+              Redirect.appendTo(efile).hashCode());
+
+        //----------------------------------------------------------------
+        // Check initial values of redirects
+        //----------------------------------------------------------------
+        List<String> childArgs = new ArrayList<String>(javaChildArgs);
+        childArgs.add("testIO");
+        final ProcessBuilder pb = new ProcessBuilder(childArgs);
+        checkRedirects(pb, PIPE, PIPE, PIPE);
+
+        //----------------------------------------------------------------
+        // Check inheritIO
+        //----------------------------------------------------------------
+        pb.inheritIO();
+        checkRedirects(pb, INHERIT, INHERIT, INHERIT);
+
+        //----------------------------------------------------------------
+        // Check setters and getters agree
+        //----------------------------------------------------------------
+        pb.redirectInput(ifile);
+        equal(pb.redirectInput().file(), ifile);
+        equal(pb.redirectInput(), Redirect.from(ifile));
+
+        pb.redirectOutput(ofile);
+        equal(pb.redirectOutput().file(), ofile);
+        equal(pb.redirectOutput(), Redirect.to(ofile));
+
+        pb.redirectError(efile);
+        equal(pb.redirectError().file(), efile);
+        equal(pb.redirectError(), Redirect.to(efile));
+
+        THROWS(IllegalArgumentException.class,
+            new Fun(){void f() {
+                pb.redirectInput(Redirect.to(ofile)); }},
+            new Fun(){void f() {
+                pb.redirectInput(Redirect.appendTo(ofile)); }},
+            new Fun(){void f() {
+                pb.redirectOutput(Redirect.from(ifile)); }},
+            new Fun(){void f() {
+                pb.redirectError(Redirect.from(ifile)); }});
+
+        THROWS(IOException.class,
+               // Input file does not exist
+               new Fun(){void f() throws Throwable { pb.start(); }});
+        setFileContents(ifile, "standard input");
+
+        //----------------------------------------------------------------
+        // Writing to non-existent files
+        //----------------------------------------------------------------
+        {
+            ProcessResults r = run(pb);
+            equal(r.exitValue(), 0);
+            equal(fileContents(ofile), "standard output");
+            equal(fileContents(efile), "standard error");
+            equal(r.out(), "");
+            equal(r.err(), "");
+            ofile.delete();
+            efile.delete();
+        }
+
+        //----------------------------------------------------------------
+        // Both redirectErrorStream + redirectError
+        //----------------------------------------------------------------
+        {
+            pb.redirectErrorStream(true);
+            ProcessResults r = run(pb);
+            equal(r.exitValue(), 0);
+            equal(fileContents(ofile),
+                  "standard error" + "standard output");
+            equal(fileContents(efile), "");
+            equal(r.out(), "");
+            equal(r.err(), "");
+            ofile.delete();
+            efile.delete();
+        }
+
+        //----------------------------------------------------------------
+        // Appending to existing files
+        //----------------------------------------------------------------
+        {
+            setFileContents(ofile, "ofile-contents");
+            setFileContents(efile, "efile-contents");
+            pb.redirectOutput(Redirect.appendTo(ofile));
+            pb.redirectError(Redirect.appendTo(efile));
+            pb.redirectErrorStream(false);
+            ProcessResults r = run(pb);
+            equal(r.exitValue(), 0);
+            equal(fileContents(ofile),
+                  "ofile-contents" + "standard output");
+            equal(fileContents(efile),
+                  "efile-contents" + "standard error");
+            equal(r.out(), "");
+            equal(r.err(), "");
+            ofile.delete();
+            efile.delete();
+        }
+
+        //----------------------------------------------------------------
+        // Replacing existing files
+        //----------------------------------------------------------------
+        {
+            setFileContents(ofile, "ofile-contents");
+            setFileContents(efile, "efile-contents");
+            pb.redirectOutput(ofile);
+            pb.redirectError(Redirect.to(efile));
+            ProcessResults r = run(pb);
+            equal(r.exitValue(), 0);
+            equal(fileContents(ofile), "standard output");
+            equal(fileContents(efile), "standard error");
+            equal(r.out(), "");
+            equal(r.err(), "");
+            ofile.delete();
+            efile.delete();
+        }
+
+        //----------------------------------------------------------------
+        // Appending twice to the same file?
+        //----------------------------------------------------------------
+        {
+            setFileContents(ofile, "ofile-contents");
+            setFileContents(efile, "efile-contents");
+            Redirect appender = Redirect.appendTo(ofile);
+            pb.redirectOutput(appender);
+            pb.redirectError(appender);
+            ProcessResults r = run(pb);
+            equal(r.exitValue(), 0);
+            equal(fileContents(ofile),
+                  "ofile-contents" +
+                  "standard error" +
+                  "standard output");
+            equal(fileContents(efile), "efile-contents");
+            equal(r.out(), "");
+            equal(r.err(), "");
+            ifile.delete();
+            ofile.delete();
+            efile.delete();
+        }
+
+        //----------------------------------------------------------------
+        // Testing INHERIT is harder.
+        // Note that this requires __FOUR__ nested JVMs involved in one test,
+        // if you count the harness JVM.
+        //----------------------------------------------------------------
+        {
+            redirectIO(pb, PIPE, PIPE, PIPE);
+            List<String> command = pb.command();
+            command.set(command.size() - 1, "testInheritIO");
+            Process p = pb.start();
+            new PrintStream(p.getOutputStream()).print("standard input");
+            p.getOutputStream().close();
+            ProcessResults r = run(p);
+            equal(r.exitValue(), 0);
+            equal(r.out(), "standard output");
+            equal(r.err(), "standard error");
+        }
+
+        //----------------------------------------------------------------
+        // Test security implications of I/O redirection
+        //----------------------------------------------------------------
+
+        // Read access to current directory is always granted;
+        // So create a tmpfile for input instead.
+        final File tmpFile = File.createTempFile("Basic", "tmp");
+        setFileContents(tmpFile, "standard input");
+
+        final Policy policy = new Policy();
+        Policy.setPolicy(policy);
+        System.setSecurityManager(new SecurityManager());
+        try {
+            final Permission xPermission
+                = new FilePermission("<<ALL FILES>>", "execute");
+            final Permission rxPermission
+                = new FilePermission("<<ALL FILES>>", "read,execute");
+            final Permission wxPermission
+                = new FilePermission("<<ALL FILES>>", "write,execute");
+            final Permission rwxPermission
+                = new FilePermission("<<ALL FILES>>", "read,write,execute");
+
+            THROWS(SecurityException.class,
+               new Fun() { void f() throws IOException {
+                   policy.setPermissions(xPermission);
+                   redirectIO(pb, from(tmpFile), PIPE, PIPE);
+                   pb.start();}},
+               new Fun() { void f() throws IOException {
+                   policy.setPermissions(rxPermission);
+                   redirectIO(pb, PIPE, to(ofile), PIPE);
+                   pb.start();}},
+               new Fun() { void f() throws IOException {
+                   policy.setPermissions(rxPermission);
+                   redirectIO(pb, PIPE, PIPE, to(efile));
+                   pb.start();}});
+
+            {
+                policy.setPermissions(rxPermission);
+                redirectIO(pb, from(tmpFile), PIPE, PIPE);
+                ProcessResults r = run(pb);
+                equal(r.out(), "standard output");
+                equal(r.err(), "standard error");
+            }
+
+            {
+                policy.setPermissions(wxPermission);
+                redirectIO(pb, PIPE, to(ofile), to(efile));
+                Process p = pb.start();
+                new PrintStream(p.getOutputStream()).print("standard input");
+                p.getOutputStream().close();
+                ProcessResults r = run(p);
+                policy.setPermissions(rwxPermission);
+                equal(fileContents(ofile), "standard output");
+                equal(fileContents(efile), "standard error");
+            }
+
+            {
+                policy.setPermissions(rwxPermission);
+                redirectIO(pb, from(tmpFile), to(ofile), to(efile));
+                ProcessResults r = run(pb);
+                policy.setPermissions(rwxPermission);
+                equal(fileContents(ofile), "standard output");
+                equal(fileContents(efile), "standard error");
+            }
+
+        } finally {
+            policy.setPermissions(new RuntimePermission("setSecurityManager"));
+            System.setSecurityManager(null);
+            tmpFile.delete();
+            ifile.delete();
+            ofile.delete();
+            efile.delete();
+        }
+    }
+
     private static void realMain(String[] args) throws Throwable {
         if (Windows.is())
             System.out.println("This appears to be a Windows system.");
@@ -607,6 +959,9 @@
         if (UnicodeOS.is())
             System.out.println("This appears to be a Unicode-based OS.");
 
+        try { testIORedirection(); }
+        catch (Throwable t) { unexpected(t); }
+
         //----------------------------------------------------------------
         // Basic tests for setting, replacing and deleting envvars
         //----------------------------------------------------------------
@@ -1354,7 +1709,8 @@
                                   execPermission);
             ProcessBuilder pb = new ProcessBuilder("env");
             pb.environment().put("foo","bar");
-            pb.start();
+            Process p = pb.start();
+            closeStreams(p);
         } catch (IOException e) { // OK
         } catch (Throwable t) { unexpected(t); }
 
@@ -1378,6 +1734,14 @@
 
     }
 
+    static void closeStreams(Process p) {
+        try {
+            p.getOutputStream().close();
+            p.getInputStream().close();
+            p.getErrorStream().close();
+        } catch (Throwable t) { unexpected(t); }
+    }
+
     //----------------------------------------------------------------
     // A Policy class designed to make permissions fiddling very easy.
     //----------------------------------------------------------------
@@ -1432,10 +1796,19 @@
                 }
             } catch (Throwable t) {
                 throwable = t;
+            } finally {
+                try { is.close(); }
+                catch (Throwable t) { throwable = t; }
             }
         }
     }
 
+    static ProcessResults run(ProcessBuilder pb) {
+        try {
+            return run(pb.start());
+        } catch (Throwable t) { unexpected(t); return null; }
+    }
+
     private static ProcessResults run(Process p) {
         Throwable throwable = null;
         int exitValue = -1;
--- a/test/java/net/CookieHandler/CookieManagerTest.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/test/java/net/CookieHandler/CookieManagerTest.java	Mon Apr 14 11:34:15 2008 -0700
@@ -132,17 +132,17 @@
                 ),
                 new CookieTestCase("Set-Cookie",
                 "PART_NUMBER=ROCKET_LAUNCHER_0001; path=/;" + "domain=." + localHostAddr,
-                "CUSTOMER=WILE:BOB;PART_NUMBER=ROCKET_LAUNCHER_0001",
+                "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001",
                 "/"
                 ),
                 new CookieTestCase("Set-Cookie",
                 "SHIPPING=FEDEX; path=/foo;" + "domain=." + localHostAddr,
-                "CUSTOMER=WILE:BOB;PART_NUMBER=ROCKET_LAUNCHER_0001",
+                "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001",
                 "/"
                 ),
                 new CookieTestCase("Set-Cookie",
                 "SHIPPING=FEDEX; path=/foo;" + "domain=." + localHostAddr,
-                "CUSTOMER=WILE:BOB;PART_NUMBER=ROCKET_LAUNCHER_0001;SHIPPING=FEDEX",
+                "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX",
                 "/foo"
                 )
                 };
@@ -157,7 +157,7 @@
                 ),
                 new CookieTestCase("Set-Cookie",
                 "PART_NUMBER=RIDING_ROCKET_0023; path=/ammo;" + "domain=." + localHostAddr,
-                "PART_NUMBER=RIDING_ROCKET_0023;PART_NUMBER=ROCKET_LAUNCHER_0001",
+                "PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001",
                 "/ammo"
                 )
                 };
@@ -167,17 +167,17 @@
         testCases[count++] = new CookieTestCase[]{
                 new CookieTestCase("Set-Cookie2",
                 "Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr,
-                "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"",
+                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"",
                 "/acme/login"
                 ),
                 new CookieTestCase("Set-Cookie2",
                 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\";Path=\"/acme\";" + "domain=." + localHostAddr,
-                "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  + "\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr +  "\"",
+                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr +  "\"",
                 "/acme/pickitem"
                 ),
                 new CookieTestCase("Set-Cookie2",
                 "Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr,
-                "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  + "\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  + "\"" + ";Shipping=\"FedEx\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"",
+                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr  + "\"" + "; Shipping=\"FedEx\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"",
                 "/acme/shipping"
                 )
                 };
@@ -187,17 +187,17 @@
         testCases[count++] = new CookieTestCase[]{
                 new CookieTestCase("Set-Cookie2",
                 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr,
-                "$Version=\"1\";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"",
+                "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"",
                 "/acme/ammo"
                 ),
                 new CookieTestCase("Set-Cookie2",
                 "Part_Number=\"Riding_Rocket_0023\"; Version=\"1\"; Path=\"/acme/ammo\";" + "domain=." + localHostAddr,
-                "$Version=\"1\";Part_Number=\"Riding_Rocket_0023\";$Path=\"/acme/ammo\";$Domain=\"." + localHostAddr  + "\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"",
+                "$Version=\"1\"; Part_Number=\"Riding_Rocket_0023\";$Path=\"/acme/ammo\";$Domain=\"." + localHostAddr  + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"",
                 "/acme/ammo"
                 ),
                 new CookieTestCase("",
                 "",
-                "$Version=\"1\";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"",
+                "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"",
                 "/acme/parts"
                 )
                 };
@@ -207,12 +207,12 @@
         testCases[count++] = new CookieTestCase[]{
                 new CookieTestCase("Set-Cookie2",
                 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr,
-                "$Version=\"1\";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"",
+                "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"",
                 "/acme"
                 ),
                 new CookieTestCase("Set-Cookie2",
                 "Part_Number=\"Rocket_Launcher_2000\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr,
-                "$Version=\"1\";Part_Number=\"Rocket_Launcher_2000\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"",
+                "$Version=\"1\"; Part_Number=\"Rocket_Launcher_2000\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"",
                 "/acme"
                 )
                 };
@@ -222,17 +222,17 @@
         testCases[count++] = new CookieTestCase[]{
                 new CookieTestCase("Set-Cookie2",
                 "Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\"",
-                "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"",
+                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"",
                 "/acme/login"
                 ),
                 new CookieTestCase("Set-Cookie2",
                 "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\";Path=\"/acme\"",
-                "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\"",
+                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\"",
                 "/acme/pickitem"
                 ),
                 new CookieTestCase("Set-Cookie2",
                 "Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\"",
-                "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\"" + ";Shipping=\"FedEx\";$Path=\"/acme\"",
+                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\"" + "; Shipping=\"FedEx\";$Path=\"/acme\"",
                 "/acme/shipping"
                 )
                 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/InterfaceAddress/Equals.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 6628576
+ * @summary InterfaceAddress.equals() NPE when broadcast field == null
+ */
+
+import java.net.InterfaceAddress;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+
+public class Equals
+{
+    public static void main(String[] args) {
+        InterfaceAddress ia1;
+        InterfaceAddress ia2;
+        InetAddress loopbackAddr = InetAddress.getLoopbackAddress();
+        InetAddress broadcast1 = null;
+        InetAddress broadcast2 = null;
+
+        try {
+            broadcast1 = InetAddress.getByName("255.255.255.0");
+            broadcast2 = InetAddress.getByName("255.255.0.0");
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+
+        ia1 = createInterfaceAddress(loopbackAddr, (InetAddress) null, (short)45);
+        ia2 = createInterfaceAddress(loopbackAddr, (InetAddress) null, (short)45);
+
+        compare(ia1, ia2, true);
+
+        ia2 = createInterfaceAddress(loopbackAddr, broadcast1, (short)45);
+        compare(ia1, ia2, false);
+
+        ia2 = createInterfaceAddress((InetAddress)null, broadcast1, (short)45);
+        compare(ia1, ia2, false);
+
+        ia1 = createInterfaceAddress(loopbackAddr, broadcast2, (short)45);
+        ia2 = createInterfaceAddress(loopbackAddr, broadcast2, (short)45);
+        compare(ia1, ia2, true);
+
+        ia1.equals(null);
+    }
+
+    static void compare(InterfaceAddress ia1, InterfaceAddress ia2, boolean equal) {
+        if (ia1.equals(ia2) != equal)
+            throw new RuntimeException("Failed: " + ia1 + " not equals to " + ia2);
+
+        if (ia2.equals(ia1) != equal)
+            throw new RuntimeException("Failed: " + ia2 + " not equals to " + ia1);
+    }
+
+    /**
+     * Returns an InterfaceAddress instance with its fields set the the values
+     * specificed.
+     */
+    static InterfaceAddress createInterfaceAddress(
+                InetAddress address, InetAddress broadcast, short prefixlength) {
+        try {
+            Class<InterfaceAddress> IAClass = InterfaceAddress.class;
+            InterfaceAddress ia;
+            Constructor<InterfaceAddress> ctr = IAClass.getDeclaredConstructor();
+            ctr.setAccessible(true);
+
+            Field addressField = IAClass.getDeclaredField("address");
+            addressField.setAccessible(true);
+
+            Field broadcastField = IAClass.getDeclaredField("broadcast");
+            broadcastField.setAccessible(true);
+
+            Field maskLengthField = IAClass.getDeclaredField("maskLength");
+            maskLengthField.setAccessible(true);
+
+            ia = ctr.newInstance();
+            addressField.set(ia, address);
+            broadcastField.set(ia, broadcast);
+            maskLengthField.setShort(ia, prefixlength);
+
+            return ia;
+        } catch (NoSuchFieldException nsfe) {
+            nsfe.printStackTrace();
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();
+        } catch (InstantiationException ie) {
+            ie.printStackTrace();
+        } catch (IllegalAccessException iae) {
+            iae.printStackTrace();
+        } catch (InvocationTargetException ite) {
+            ite.printStackTrace();
+        }
+
+        return null;
+    }
+}
--- a/test/java/net/ResponseCache/file2.1	Thu Apr 10 13:57:15 2008 -0700
+++ b/test/java/net/ResponseCache/file2.1	Mon Apr 14 11:34:15 2008 -0700
@@ -1,4 +1,4 @@
-/* @test
+/* @test @(#)file2.1	1.1 03/08/09
  * @summary Unit test for java.net.ResponseCacheHandler
  * @bug 4837267
  * @author Yingxian Wang
--- a/test/java/nio/Buffer/StringCharBufferSliceTest.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/test/java/nio/Buffer/StringCharBufferSliceTest.java	Mon Apr 14 11:34:15 2008 -0700
@@ -53,6 +53,57 @@
         buff = CharBuffer.wrap(in, 3, in.length());
         test(buff, buff.slice());
 
+        System.out.println(
+            ">>> StringCharBufferSliceTest-main: testing slice result with get()");
+        buff.position(4);
+        buff.limit(7);
+        CharBuffer slice = buff.slice();
+        for (int i = 0; i < 3; i++) {
+            if (slice.get() != buff.get()) {
+                throw new RuntimeException("Wrong characters in slice result.");
+            }
+        }
+
+        System.out.println(
+            ">>> StringCharBufferSliceTest-main: testing slice result with get(int)");
+        buff.position(4);
+        buff.limit(7);
+        slice = buff.slice();
+        for (int i = 0; i < 3; i++) {
+            if (slice.get(i) != buff.get(4 + i)) {
+                throw new RuntimeException("Wrong characters in slice result.");
+            }
+        }
+
+        System.out.println(
+          ">>> StringCharBufferSliceTest-main: testing toString.");
+        buff.position(4);
+        buff.limit(7);
+        slice = buff.slice();
+        if (! slice.toString().equals("tes")) {
+            throw new RuntimeException("bad toString() after slice(): " + slice.toString());
+        }
+
+        System.out.println(
+          ">>> StringCharBufferSliceTest-main: testing subSequence.");
+        buff.position(4);
+        buff.limit(8);
+        slice = buff.slice();
+        CharSequence subSeq = slice.subSequence(1, 3);
+        if (subSeq.charAt(0) != 'e' || subSeq.charAt(1) != 's') {
+            throw new RuntimeException("bad subSequence() after slice(): '" + subSeq + "'");
+        }
+
+        System.out.println(
+          ">>> StringCharBufferSliceTest-main: testing duplicate.");
+        buff.position(4);
+        buff.limit(8);
+        slice = buff.slice();
+        CharBuffer dupe = slice.duplicate();
+        if (dupe.charAt(0) != 't' || dupe.charAt(1) != 'e'
+            || dupe.charAt(2) != 's' || dupe.charAt(3) != 't') {
+            throw new RuntimeException("bad duplicate() after slice(): '" + dupe + "'");
+        }
         System.out.println(">>> StringCharBufferSliceTest-main: done!");
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/nio/channels/Channels/ShortWrite.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 6448457
+ * @summary Test Channels.newOutputStream returns OutputStream that handles
+ *     short writes from the underlying channel
+ */
+
+import java.io.OutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.util.Random;
+
+public class ShortWrite {
+
+    static Random rand = new Random();
+    static int bytesWritten = 0;
+
+    public static void main(String[] args) throws IOException {
+
+        WritableByteChannel wbc = new WritableByteChannel() {
+            public int write(ByteBuffer src) {
+                int rem = src.remaining();
+                if (rem > 0) {
+                    // short write
+                    int n = rand.nextInt(rem) + 1;
+                    src.position(src.position() + n);
+                    bytesWritten += n;
+                    return n;
+                } else {
+                    return 0;
+                }
+            }
+            public void close() throws IOException {
+                throw new RuntimeException("not implemented");
+            }
+            public boolean isOpen() {
+                throw new RuntimeException("not implemented");
+            }
+        };
+
+        // wrap Channel with OutputStream
+        OutputStream out = Channels.newOutputStream(wbc);
+
+
+        // write 100, 99, 98, ... 1
+        // and check that the expected number of bytes is written
+        int expected = 0;
+        byte[] buf = new byte[100];
+        for (int i=0; i<buf.length; i++) {
+            int len = buf.length-i;
+            out.write(buf, i, len);
+            expected += len;
+        }
+        System.out.format("Bytes written: %d, expected: %d\n", bytesWritten,
+            expected);
+        if (bytesWritten != expected)
+            throw new RuntimeException("incorrect number of bytes written");
+
+    }
+}
--- a/test/java/nio/channels/TestUtil.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/test/java/nio/channels/TestUtil.java	Mon Apr 14 11:34:15 2008 -0700
@@ -37,7 +37,7 @@
     // Test hosts used by the channels tests - change these when
     // executing in a different network.
     public static final String HOST = "javaweb.sfbay.sun.com";
-    public static final String REFUSING_HOST = "jano.sfbay.sun.com";
+    public static final String REFUSING_HOST = "jano1.sfbay.sun.com";
     public static final String FAR_HOST = "theclub.ireland.sun.com";
     public static final String UNRESOLVABLE_HOST = "blah-blah.blah-blah.blah";
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/AccessControlContext/FailureDebugOption.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6648816
+ * @summary REGRESSION: setting -Djava.security.debug=failure result in NPE
+ * in ACC
+ * @run main/othervm -Djava.security.debug=failure FailureDebugOption
+ */
+
+import java.security.ProtectionDomain;
+import java.security.AccessController;
+import java.security.AccessControlException;
+import java.security.BasicPermission;
+
+public class FailureDebugOption {
+
+   public static void main (String argv[]) throws Exception {
+        try {
+            AccessController.checkPermission(
+                        new BasicPermission("no such permission"){});
+        } catch (NullPointerException npe) {
+           throw new Exception("Unexpected NullPointerException for security" +
+                        " debug option, -Djava.security.debug=failure");
+        } catch (AccessControlException ace) {
+        }
+   }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Map/LockStep.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6612102
+ * @summary Test Map implementations for mutual compatibility
+ */
+
+import java.util.*;
+import java.util.concurrent.*;
+
+/**
+ * Based on the strange scenario required to reproduce
+ * (coll) IdentityHashMap.iterator().remove() might decrement size twice
+ *
+ * It would be good to add more "Lockstep-style" tests to this file.
+ */
+public class LockStep {
+    void mapsEqual(Map m1, Map m2) {
+        equal(m1, m2);
+        equal(m2, m1);
+        equal(m1.size(), m2.size());
+        equal(m1.isEmpty(), m2.isEmpty());
+        equal(m1.keySet(), m2.keySet());
+        equal(m2.keySet(), m1.keySet());
+    }
+
+    void mapsEqual(List<Map> maps) {
+        Map first = maps.get(0);
+        for (Map map : maps)
+            mapsEqual(first, map);
+    }
+
+    void put(List<Map> maps, Object key, Object val) {
+        for (Map map : maps)
+            map.put(key, val);
+        mapsEqual(maps);
+    }
+
+    void removeLastTwo(List<Map> maps) {
+        Map first = maps.get(0);
+        int size = first.size();
+        Iterator fit = first.keySet().iterator();
+        for (int j = 0; j < size - 2; j++)
+            fit.next();
+        Object x1 = fit.next();
+        Object x2 = fit.next();
+
+        for (Map map : maps) {
+            Iterator it = map.keySet().iterator();
+            while (it.hasNext()) {
+                Object x = it.next();
+                if (x == x1 || x == x2)
+                    it.remove();
+            }
+        }
+        mapsEqual(maps);
+    }
+
+    void remove(Map m, Iterator it) {
+        int size = m.size();
+        it.remove();
+        if (m.size() != size-1)
+            throw new Error(String.format("Incorrect size!%nmap=%s, size=%d%n",
+                                          m.toString(), m.size()));
+    }
+
+    void test(String[] args) throws Throwable {
+        final int iterations = 100;
+        final Random r = new Random();
+
+        for (int i = 0; i < iterations; i++) {
+            List<Map> maps = Arrays.asList(
+                new Map[] {
+                    new IdentityHashMap(11),
+                    new HashMap(16),
+                    new LinkedHashMap(16),
+                    new WeakHashMap(16),
+                    new Hashtable(16),
+                    new TreeMap(),
+                    new ConcurrentHashMap(16),
+                    new ConcurrentSkipListMap() });
+
+            for (int j = 0; j < 10; j++)
+                put(maps, r.nextInt(100), r.nextInt(100));
+            removeLastTwo(maps);
+        }
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    volatile int passed = 0, failed = 0;
+    void pass() {passed++;}
+    void fail() {failed++; Thread.dumpStack();}
+    void fail(String msg) {System.err.println(msg); fail();}
+    void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    void check(boolean cond) {if (cond) pass(); else fail();}
+    void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        new LockStep().instanceMain(args);}
+    void instanceMain(String[] args) throws Throwable {
+        try {test(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/DelayQueue/Stress.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.*;
+
+/**
+ * This is not a regression test, but a stress benchmark test for
+ * 6609775: Reduce context switches in DelayQueue due to signalAll
+ *
+ * This runs in the same wall clock time, but much reduced cpu time,
+ * with the changes for 6609775.
+ */
+public class Stress {
+
+    public static void main(String[] args) throws Throwable {
+
+        final DelayQueue<Delayed> q = new DelayQueue<Delayed>();
+        final long t0 = System.nanoTime();
+        for (long i = 0; i < 1000; i++) {
+            final long expiry = t0 + i*10L*1000L*1000L;
+            q.add(new Delayed() {
+                    public long getDelay(TimeUnit unit) {
+                        return unit.convert(expiry - System.nanoTime(),
+                                            NANOSECONDS);
+                    }
+                    public int compareTo(Delayed x) {
+                        long d = getDelay(NANOSECONDS)
+                            - x.getDelay(NANOSECONDS);
+                        return d < 0 ? -1 : d > 0 ? 1 : 0; }});
+        }
+
+        for (int i = 0; i < 300; i++)
+            new Thread() { public void run() {
+                try {
+                    while (!q.isEmpty())
+                        q.poll(10L, TimeUnit.SECONDS);
+                } catch (Throwable t) { t.printStackTrace(); }
+            }}.start();
+    }
+}
--- a/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java	Mon Apr 14 11:34:15 2008 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6316155
+ * @bug 6316155 6595669
  * @summary Test concurrent offer vs. remove
  * @author Martin Buchholz
  */
@@ -50,15 +50,18 @@
     private static void testQueue(final BlockingQueue<String> q) throws Throwable {
         System.out.println(q.getClass());
         final int count = 10000;
+        final long quittingTime = System.nanoTime() + 1L * 1000L * 1000L * 1000L;
         Thread t1 = new ControlledThread() {
                 protected void realRun() {
                     for (int i = 0, j = 0; i < count; i++)
-                        while (! q.remove(String.valueOf(i)))
+                        while (! q.remove(String.valueOf(i))
+                               && System.nanoTime() - quittingTime < 0)
                             Thread.yield();}};
         Thread t2 = new ControlledThread() {
                 protected void realRun() {
                     for (int i = 0, j = 0; i < count; i++)
-                        while (! q.offer(String.valueOf(i)))
+                        while (! q.offer(String.valueOf(i))
+                               && System.nanoTime() - quittingTime < 0)
                             Thread.yield();}};
         t1.setDaemon(true); t2.setDaemon(true);
         t1.start(); t2.start();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6602600
+ * @run main/othervm -Xmx8m BasicCancelTest
+ * @summary Check effectiveness of RemoveOnCancelPolicy
+ */
+
+import java.util.concurrent.*;
+import java.util.Random;
+
+/**
+ * Simple timer cancellation test. Submits tasks to a scheduled executor
+ * service and immediately cancels them.
+ */
+public class BasicCancelTest {
+
+    void checkShutdown(final ExecutorService es) {
+        final Runnable nop = new Runnable() {public void run() {}};
+        try {
+            if (new Random().nextBoolean()) {
+                check(es.isShutdown());
+                if (es instanceof ThreadPoolExecutor)
+                    check(((ThreadPoolExecutor) es).isTerminating()
+                          || es.isTerminated());
+                THROWS(RejectedExecutionException.class,
+                       new F(){void f(){es.execute(nop);}});
+            }
+        } catch (Throwable t) { unexpected(t); }
+    }
+
+    void checkTerminated(final ThreadPoolExecutor tpe) {
+        try {
+            checkShutdown(tpe);
+            check(tpe.getQueue().isEmpty());
+            check(tpe.isTerminated());
+            check(! tpe.isTerminating());
+            equal(tpe.getActiveCount(), 0);
+            equal(tpe.getPoolSize(), 0);
+            equal(tpe.getTaskCount(), tpe.getCompletedTaskCount());
+            check(tpe.awaitTermination(0, TimeUnit.SECONDS));
+        } catch (Throwable t) { unexpected(t); }
+    }
+
+    void test(String[] args) throws Throwable {
+
+        final ScheduledThreadPoolExecutor pool =
+            new ScheduledThreadPoolExecutor(1);
+
+        // Needed to avoid OOME
+        pool.setRemoveOnCancelPolicy(true);
+
+        final long moreThanYouCanChew = Runtime.getRuntime().freeMemory() / 4;
+        System.out.printf("moreThanYouCanChew=%d%n", moreThanYouCanChew);
+
+        Runnable noopTask = new Runnable() { public void run() {}};
+
+        for (long i = 0; i < moreThanYouCanChew; i++)
+            pool.schedule(noopTask, 10, TimeUnit.MINUTES).cancel(true);
+
+        pool.shutdown();
+        check(pool.awaitTermination(1L, TimeUnit.DAYS));
+        checkTerminated(pool);
+        equal(pool.getTaskCount(), 0L);
+        equal(pool.getCompletedTaskCount(), 0L);
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    volatile int passed = 0, failed = 0;
+    void pass() {passed++;}
+    void fail() {failed++; Thread.dumpStack();}
+    void fail(String msg) {System.err.println(msg); fail();}
+    void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    void check(boolean cond) {if (cond) pass(); else fail();}
+    void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        new BasicCancelTest().instanceMain(args);}
+    void instanceMain(String[] args) throws Throwable {
+        try {test(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+    abstract class F {abstract void f() throws Throwable;}
+    void THROWS(Class<? extends Throwable> k, F... fs) {
+        for (F f : fs)
+            try {f.f(); fail("Expected " + k.getName() + " not thrown");}
+            catch (Throwable t) {
+                if (k.isAssignableFrom(t.getClass())) pass();
+                else unexpected(t);}}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.util.concurrent.*;
+
+/**
+ * This is not a regression test, but a stress benchmark test for
+ * 6602600: Fast removal of cancelled scheduled thread pool tasks
+ *
+ * This runs in the same wall clock time, but much reduced cpu time,
+ * with the changes for 6602600.
+ */
+public class Stress {
+
+    public static void main(String[] args) throws Throwable {
+
+        final CountDownLatch count = new CountDownLatch(1000);
+
+        final ScheduledThreadPoolExecutor pool =
+            new ScheduledThreadPoolExecutor(100);
+        pool.prestartAllCoreThreads();
+
+        final Runnable incTask = new Runnable() { public void run() {
+            count.countDown();
+        }};
+
+        pool.scheduleAtFixedRate(incTask, 0, 10, TimeUnit.MILLISECONDS);
+
+        count.await();
+
+        pool.shutdown();
+        pool.awaitTermination(1L, TimeUnit.DAYS);
+    }
+}
--- a/test/java/util/concurrent/SynchronousQueue/Fairness.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/test/java/util/concurrent/SynchronousQueue/Fairness.java	Mon Apr 14 11:34:15 2008 -0700
@@ -23,36 +23,49 @@
 
 /*
  * @test
- * @bug 4992438
- * @compile -source 1.5 Fairness.java
- * @run main Fairness
+ * @bug 4992438 6633113
  * @summary Checks that fairness setting is respected.
  */
 
 import java.util.concurrent.*;
+import java.util.concurrent.locks.*;
 
 public class Fairness {
     private static void testFairness(boolean fair,
                                      final BlockingQueue<Integer> q)
-        throws Exception
+        throws Throwable
     {
-        for (int i = 0; i < 3; i++) {
-            final Integer I = new Integer(i);
-            new Thread() { public void run() {
-                try { q.put(I); } catch (Exception e) {}
-            }}.start();
-            Thread.currentThread().sleep(100);
+        final ReentrantLock lock = new ReentrantLock();
+        final Condition ready = lock.newCondition();
+        final int threadCount = 10;
+        final Throwable[] badness = new Throwable[1];
+        lock.lock();
+        for (int i = 0; i < threadCount; i++) {
+            final Integer I = i;
+            Thread t = new Thread() { public void run() {
+                try {
+                    lock.lock();
+                    ready.signal();
+                    lock.unlock();
+                    q.put(I);
+                } catch (Throwable t) { badness[0] = t; }}};
+            t.start();
+            ready.await();
+            // Probably unnecessary, but should be bullet-proof
+            while (t.getState() == Thread.State.RUNNABLE)
+                Thread.yield();
         }
-        for (int i = 0; i < 3; i++) {
-            int j = q.take().intValue();
-            System.err.printf("%d%n",j);
+        for (int i = 0; i < threadCount; i++) {
+            int j = q.take();
             // Non-fair queues are lifo in our implementation
-            if (fair ? j != i : j != 2-i)
-                throw new Exception("No fair!");
+            if (fair ? j != i : j != threadCount - 1 - i)
+                throw new Error(String.format("fair=%b i=%d j=%d%n",
+                                              fair, i, j));
         }
+        if (badness[0] != null) throw new Error(badness[0]);
     }
 
-    public static void main(String[] args) throws Exception {
+    public static void main(String[] args) throws Throwable {
         testFairness(false, new SynchronousQueue<Integer>());
         testFairness(false, new SynchronousQueue<Integer>(false));
         testFairness(true,  new SynchronousQueue<Integer>(true));
--- a/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java	Mon Apr 14 11:34:15 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,21 +23,89 @@
 
 /*
  * @test
- * @bug 6207928 6328220 6378321
+ * @bug 6207928 6328220 6378321 6625723
  * @summary Recursive lock invariant sanity checks
  * @author Martin Buchholz
  */
 
+import java.io.*;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.locks.*;
 
 // I am the Cownt, and I lahve to cownt.
 public class Count {
-    private static void realMain(String[] args) throws Throwable {
-        final ReentrantLock rl = new ReentrantLock();
-        final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
+    final Random rnd = new Random();
+
+    void lock(Lock lock) {
+        try {
+            switch (rnd.nextInt(4)) {
+            case 0: lock.lock(); break;
+            case 1: lock.lockInterruptibly(); break;
+            case 2: check(lock.tryLock()); break;
+            case 3: check(lock.tryLock(45, TimeUnit.MINUTES)); break;
+            }
+        } catch (Throwable t) { unexpected(t); }
+    }
+
+    void test(String[] args) throws Throwable {
+        for (boolean fair : new boolean[] { true, false })
+            for (boolean serialClone : new boolean[] { true, false }) {
+                testReentrantLocks(fair, serialClone);
+                testConcurrentReadLocks(fair, serialClone);
+            }
+    }
+
+    void testConcurrentReadLocks(final boolean fair,
+                                 final boolean serialClone) throws Throwable {
+        final int nThreads = 10;
+        final CyclicBarrier barrier = new CyclicBarrier(nThreads);
+        final ExecutorService es = Executors.newFixedThreadPool(nThreads);
+        final ReentrantReadWriteLock rwl = serialClone ?
+            serialClone(new ReentrantReadWriteLock(fair)) :
+            new ReentrantReadWriteLock(fair);
+        for (int i = 0; i < nThreads; i++) {
+            es.submit(new Runnable() { public void run() {
+                try {
+                    int n = 5;
+                    for (int i = 0; i < n; i++) {
+                        barrier.await();
+                        equal(rwl.getReadHoldCount(), i);
+                        equal(rwl.getWriteHoldCount(), 0);
+                        check(! rwl.isWriteLocked());
+                        equal(rwl.getReadLockCount(), nThreads * i);
+                        barrier.await();
+                        lock(rwl.readLock());
+                    }
+                    for (int i = 0; i < n; i++) {
+                        rwl.readLock().unlock();
+                        barrier.await();
+                        equal(rwl.getReadHoldCount(), n-i-1);
+                        equal(rwl.getReadLockCount(), nThreads*(n-i-1));
+                        equal(rwl.getWriteHoldCount(), 0);
+                        check(! rwl.isWriteLocked());
+                        barrier.await();
+                    }
+                    THROWS(IllegalMonitorStateException.class,
+                           new F(){void f(){rwl.readLock().unlock();}},
+                           new F(){void f(){rwl.writeLock().unlock();}});
+                    barrier.await();
+                } catch (Throwable t) { unexpected(t); }}});}
+        es.shutdown();
+        check(es.awaitTermination(10, TimeUnit.SECONDS));
+    }
+
+    void testReentrantLocks(final boolean fair,
+                            final boolean serialClone) throws Throwable {
+        final ReentrantLock rl = serialClone ?
+            serialClone(new ReentrantLock(fair)) :
+            new ReentrantLock(fair);
+        final ReentrantReadWriteLock rwl = serialClone ?
+            serialClone(new ReentrantReadWriteLock(fair)) :
+            new ReentrantReadWriteLock(fair);
         final int depth = 10;
+        equal(rl.isFair(), fair);
+        equal(rwl.isFair(), fair);
         check(! rl.isLocked());
         check(! rwl.isWriteLocked());
         check(! rl.isHeldByCurrentThread());
@@ -50,28 +118,11 @@
             equal(rwl.getReadHoldCount(), i);
             equal(rwl.getWriteHoldCount(), i);
             equal(rwl.writeLock().getHoldCount(), i);
-            switch (i%4) {
-            case 0:
-                rl.lock();
-                rwl.writeLock().lock();
-                rwl.readLock().lock();
-                break;
-            case 1:
-                rl.lockInterruptibly();
-                rwl.writeLock().lockInterruptibly();
-                rwl.readLock().lockInterruptibly();
-                break;
-            case 2:
-                check(rl.tryLock());
-                check(rwl.writeLock().tryLock());
-                check(rwl.readLock().tryLock());
-                break;
-            case 3:
-                check(rl.tryLock(454, TimeUnit.MILLISECONDS));
-                check(rwl.writeLock().tryLock(454, TimeUnit.NANOSECONDS));
-                check(rwl.readLock().tryLock(454, TimeUnit.HOURS));
-                break;
-            }
+            equal(rl.isLocked(), i > 0);
+            equal(rwl.isWriteLocked(), i > 0);
+            lock(rl);
+            lock(rwl.writeLock());
+            lock(rwl.readLock());
         }
 
         for (int i = depth; i > 0; i--) {
@@ -95,20 +146,48 @@
             rwl.writeLock().unlock();
             rl.unlock();
         }
+        THROWS(IllegalMonitorStateException.class,
+               new F(){void f(){rl.unlock();}},
+               new F(){void f(){rwl.readLock().unlock();}},
+               new F(){void f(){rwl.writeLock().unlock();}});
     }
 
     //--------------------- Infrastructure ---------------------------
-    static volatile int passed = 0, failed = 0;
-    static void pass() {passed++;}
-    static void fail() {failed++; Thread.dumpStack();}
-    static void fail(String msg) {System.out.println(msg); fail();}
-    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
-    static void check(boolean cond) {if (cond) pass(); else fail();}
-    static void equal(Object x, Object y) {
+    volatile int passed = 0, failed = 0;
+    void pass() {passed++;}
+    void fail() {failed++; Thread.dumpStack();}
+    void fail(String msg) {System.err.println(msg); fail();}
+    void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    void check(boolean cond) {if (cond) pass(); else fail();}
+    void equal(Object x, Object y) {
         if (x == null ? y == null : x.equals(y)) pass();
         else fail(x + " not equal to " + y);}
     public static void main(String[] args) throws Throwable {
-        try {realMain(args);} catch (Throwable t) {unexpected(t);}
+        new Count().instanceMain(args);}
+    void instanceMain(String[] args) throws Throwable {
+        try {test(args);} catch (Throwable t) {unexpected(t);}
         System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
         if (failed > 0) throw new AssertionError("Some tests failed");}
+    abstract class F {abstract void f() throws Throwable;}
+    void THROWS(Class<? extends Throwable> k, F... fs) {
+        for (F f : fs)
+            try {f.f(); fail("Expected " + k.getName() + " not thrown");}
+            catch (Throwable t) {
+                if (k.isAssignableFrom(t.getClass())) pass();
+                else unexpected(t);}}
+
+    static byte[] serializedForm(Object obj) {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            new ObjectOutputStream(baos).writeObject(obj);
+            return baos.toByteArray();
+        } catch (IOException e) { throw new RuntimeException(e); }}
+    static Object readObject(byte[] bytes)
+        throws IOException, ClassNotFoundException {
+        InputStream is = new ByteArrayInputStream(bytes);
+        return new ObjectInputStream(is).readObject();}
+    @SuppressWarnings("unchecked")
+    static <T> T serialClone(T obj) {
+        try { return (T) readObject(serializedForm(obj)); }
+        catch (Exception e) { throw new RuntimeException(e); }}
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/JMXServiceURLTest.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test JMXServiceURLTest
+ * @bug 6607114 6670375
+ * @summary Test that JMXServiceURL works correctly in MXBeans
+ * @author Eamonn McManus
+ */
+
+import java.lang.management.ManagementFactory;
+import javax.management.JMX;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.remote.JMXServiceURL;
+
+public class JMXServiceURLTest {
+    public static interface UrlMXBean {
+        public JMXServiceURL getUrl();
+        public void setUrl(JMXServiceURL url);
+    }
+
+    public static class UrlImpl implements UrlMXBean {
+        volatile JMXServiceURL url;
+
+        public JMXServiceURL getUrl() {
+            return url;
+        }
+
+        public void setUrl(JMXServiceURL url) {
+            this.url = url;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+        ObjectName name = new ObjectName("a:b=c");
+        UrlImpl urlImpl = new UrlImpl();
+        mbs.registerMBean(urlImpl, name);
+
+        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://host:8000/noddy");
+        UrlMXBean proxy = JMX.newMXBeanProxy(mbs, name, UrlMXBean.class);
+        proxy.setUrl(url);
+        assertEquals(url, urlImpl.url);
+        JMXServiceURL url2 = proxy.getUrl();
+        assertEquals(url, url2);
+
+        CompositeData cd = (CompositeData) mbs.getAttribute(name, "Url");
+        CompositeType ct = cd.getCompositeType();
+        // Make sure it looks like what we expect.  This will have to be
+        // changed if ever we add new properties to CompositeType.  In that
+        // case this test should also check interoperability between the
+        // current version and the new version.
+        assertEquals(4, ct.keySet().size());
+        Object[][] expectedItems = {
+            {"protocol", SimpleType.STRING, "rmi"},
+            {"host", SimpleType.STRING, "host"},
+            {"port", SimpleType.INTEGER, 8000},
+            {"URLPath", SimpleType.STRING, "/noddy"},
+        };
+        for (Object[] expectedItem : expectedItems) {
+            String itemName = (String) expectedItem[0];
+            OpenType expectedType = (OpenType) expectedItem[1];
+            Object expectedValue = expectedItem[2];
+            OpenType actualType = ct.getType(itemName);
+            assertEquals(expectedType, actualType);
+            Object actualValue = cd.get(itemName);
+            assertEquals(expectedValue, actualValue);
+        }
+    }
+
+    private static void assertEquals(Object expect, Object actual)
+            throws Exception {
+        if (expect.equals(actual))
+            System.out.println("Equal: " + expect);
+        else
+            throw new Exception("Expected " + expect + ", got " + actual);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/query/QueryDottedAttrTest.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test QueryDottedAttrTest
+ * @bug 6602310
+ * @summary Test that Query.attr can understand a.b etc.
+ * @author Eamonn McManus
+ */
+
+import java.beans.ConstructorProperties;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Collections;
+import java.util.Set;
+import javax.management.AttributeNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
+import javax.management.Query;
+import javax.management.QueryExp;
+import javax.management.ReflectionException;
+import javax.management.StandardMBean;
+
+public class QueryDottedAttrTest {
+    public static class Complex {
+        private final double re, im;
+
+        @ConstructorProperties({"real", "imaginary"})
+        public Complex(double re, double im) {
+            this.re = re;
+            this.im = im;
+        }
+
+        public double getRe() {
+            return re;
+        }
+
+        public double getIm() {
+            return im;
+        }
+    }
+
+    public static interface Intf {
+        Complex getComplex();
+        int[] getIntArray();
+        String[] getStringArray();
+    }
+
+    public static class Impl implements Intf {
+        public Complex getComplex() {
+            return new Complex(1.0, 1.0);
+        }
+
+        public int[] getIntArray() {
+            return new int[] {1, 2, 3};
+        }
+
+        public String[] getStringArray() {
+            return new String[] {"one", "two", "three"};
+        }
+    }
+
+    public static interface TestMBean extends Intf {}
+
+    public static class Test extends Impl implements TestMBean {}
+
+    public static interface TestMXBean extends Intf {}
+
+    public static class TestMX extends Impl implements TestMXBean {}
+
+    public static class AttrWithDot extends StandardMBean {
+        public <T> AttrWithDot(Object impl, Class<T> intf) {
+            super(intf.cast(impl), intf, (intf == TestMXBean.class));
+        }
+
+        public Object getAttribute(String attribute)
+        throws AttributeNotFoundException, MBeanException, ReflectionException {
+            if (attribute.equals("Complex.re"))
+                return 2.0;
+            else
+                return super.getAttribute(attribute);
+        }
+    }
+
+    private static final boolean[] booleans = {false, true};
+
+    private static final QueryExp[] alwaysTrueQueries = {
+        Query.eq(Query.attr("IntArray.length"), Query.value(3)),
+        Query.eq(Query.attr("StringArray.length"), Query.value(3)),
+        Query.eq(Query.attr("Complex.im"), Query.value(1.0)),
+    };
+
+    private static final QueryExp[] alwaysFalseQueries = {
+        Query.eq(Query.attr("IntArray.length"), Query.value("3")),
+        Query.eq(Query.attr("IntArray.length"), Query.value(2)),
+        Query.eq(Query.attr("Complex.im"), Query.value(-1.0)),
+        Query.eq(Query.attr("Complex.xxx"), Query.value(0)),
+    };
+
+    private static final QueryExp[] attrWithDotTrueQueries = {
+        Query.eq(Query.attr("Complex.re"), Query.value(2.0)),
+    };
+
+    private static final QueryExp[] attrWithDotFalseQueries = {
+        Query.eq(Query.attr("Complex.re"), Query.value(1.0)),
+    };
+
+    private static String failure;
+
+    public static void main(String[] args) throws Exception {
+        ObjectName name = new ObjectName("a:b=c");
+        for (boolean attrWithDot : booleans) {
+            for (boolean mx : booleans) {
+                String what =
+                        (mx ? "MXBean" : "Standard MBean") +
+                        (attrWithDot ? " having attribute with dot in its name" : "");
+                System.out.println("Testing " + what);
+                Class<?> intf = mx ? TestMXBean.class : TestMBean.class;
+                Object impl = mx ? new TestMX() : new Test();
+                if (attrWithDot)
+                    impl = new AttrWithDot(impl, intf);
+                MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+                mbs.registerMBean(impl, name);
+                boolean ismx = "true".equals(
+                        mbs.getMBeanInfo(name).getDescriptor().getFieldValue("mxbean"));
+                if (mx != ismx)
+                    fail("MBean should " + (mx ? "" : "not ") + "be MXBean");
+                test(mbs, name, alwaysTrueQueries, true);
+                test(mbs, name, alwaysFalseQueries, false);
+                test(mbs, name, attrWithDotTrueQueries, attrWithDot);
+                test(mbs, name, attrWithDotFalseQueries, !attrWithDot);
+            }
+        }
+        if (failure != null)
+            throw new Exception("TEST FAILED: " + failure);
+    }
+
+    private static void test(
+            MBeanServer mbs, ObjectName name, QueryExp[] queries, boolean expect)
+            throws Exception {
+        for (QueryExp query : queries) {
+            // Serialize and deserialize the query to ensure that its
+            // serialization is correct
+            ByteArrayOutputStream bout = new ByteArrayOutputStream();
+            ObjectOutputStream oout = new ObjectOutputStream(bout);
+            oout.writeObject(query);
+            oout.close();
+            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+            ObjectInputStream oin = new ObjectInputStream(bin);
+            query = (QueryExp) oin.readObject();
+            Set<ObjectName> names = mbs.queryNames(null, query);
+            if (names.isEmpty()) {
+                if (expect)
+                    fail("Query is false but should be true: " + query);
+            } else if (names.equals(Collections.singleton(name))) {
+                if (!expect)
+                    fail("Query is true but should be false: " + query);
+            } else {
+                fail("Query returned unexpected set: " + names);
+            }
+        }
+    }
+
+    private static void fail(String msg) {
+        failure = msg;
+        System.out.println("..." + msg);
+    }
+}
--- a/test/javax/management/query/QueryExpStringTest.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/test/javax/management/query/QueryExpStringTest.java	Mon Apr 14 11:34:15 2008 -0700
@@ -31,6 +31,10 @@
  * @run main QueryExpStringTest
  */
 
+// This test is mostly obsolete, since we now have Query.fromString.
+// The test includes its own parser, from which Query.fromString was derived.
+// The parsers are not identical and the one here is no longer maintained.
+
 import java.util.*;
 import javax.management.*;
 
@@ -39,6 +43,11 @@
     private static final ValueExp
         attr = Query.attr("attr"),
         qattr = Query.attr("className", "attr"),
+        aa = Query.attr("A"),
+        bb = Query.attr("B"),
+        cc = Query.attr("C"),
+        dd = Query.attr("D"),
+        zero = Query.value(0),
         classattr = Query.classattr(),
         simpleString = Query.value("simpleString"),
         complexString = Query.value("a'b\\'\""),
@@ -66,10 +75,14 @@
                                          (StringValueExp) simpleString),
         initialStar = Query.initialSubString((AttributeValueExp) attr,
                                              Query.value("*")),
+        initialPercent = Query.initialSubString((AttributeValueExp) attr,
+                                                Query.value("%")),
         any = Query.anySubString((AttributeValueExp) attr,
                                  (StringValueExp) simpleString),
         anyStar = Query.anySubString((AttributeValueExp) attr,
                                      Query.value("*")),
+        anyPercent = Query.anySubString((AttributeValueExp) attr,
+                                        Query.value("%")),
         ffinal = Query.finalSubString((AttributeValueExp) attr,
                                       (StringValueExp) simpleString),
         finalMagic = Query.finalSubString((AttributeValueExp) attr,
@@ -77,16 +90,20 @@
         in = Query.in(intValue, new ValueExp[] {intValue, floatValue}),
         and = Query.and(gt, lt),
         or = Query.or(gt, lt),
-        not = Query.not(gt);
+        not = Query.not(gt),
+        aPlusB_PlusC = Query.gt(Query.plus(Query.plus(aa, bb), cc), zero),
+        aPlus_BPlusC = Query.gt(Query.plus(aa, Query.plus(bb, cc)), zero);
 
     // Commented-out tests below require change to implementation
 
     private static final Object tests[] = {
         attr, "attr",
-        qattr, "className.attr",
+//      qattr, "className.attr",
+// Preceding form now appears as className#attr, an incompatible change
+// which we don't mind much because nobody uses the two-arg Query.attr.
         classattr, "Class",
         simpleString, "'simpleString'",
-//      complexString, "'a\\'b\\\\\\'\"'",
+        complexString, "'a''b\\\''\"'",
         intValue, "12345678",
         integerValue, "12345678",
         longValue, "12345678",
@@ -104,16 +121,20 @@
         eq, "(12345678) = (2.5)",
         between, "(12345678) between (2.5) and (2.5)",
         match, "attr like 'simpleString'",
-//      initial, "attr like 'simpleString*'",
-//      initialStar, "attr like '\\\\**'",
-//      any, "attr like '*simpleString*'",
-//      anyStar, "attr like '*\\\\**'",
-//      ffinal, "attr like '*simpleString'",
-//      finalMagic, "attr like '*\\\\?\\\\*\\\\[\\\\\\\\'",
+        initial, "attr like 'simpleString%'",
+        initialStar, "attr like '\\*%'",
+        initialPercent, "attr like '\\%%'",
+        any, "attr like '%simpleString%'",
+        anyStar, "attr like '%\\*%'",
+        anyPercent, "attr like '%\\%%'",
+        ffinal, "attr like '%simpleString'",
+        finalMagic, "attr like '%\\?\\*\\[\\\\'",
         in, "12345678 in (12345678, 2.5)",
         and, "((12345678) > (2.5)) and ((12345678) < (2.5))",
         or, "((12345678) > (2.5)) or ((12345678) < (2.5))",
         not, "not ((12345678) > (2.5))",
+        aPlusB_PlusC, "(A + B + C) > (0)",
+//        aPlus_BPlusC, "(A + (B + C)) > (0)",
     };
 
     public static void main(String[] args) throws Exception {
@@ -185,7 +206,9 @@
                 throw new Exception("Expected types `attr like string': " +
                                     exp + " like " + pat);
             }
-            return Query.match((AttributeValueExp) exp, (StringValueExp) pat);
+            StringValueExp spat = (StringValueExp) pat;
+            spat = Query.value(translateMatch(spat.getValue()));
+            return Query.match((AttributeValueExp) exp, spat);
         }
 
         if (skip(ss, " in (")) {
@@ -203,6 +226,28 @@
         throw new Exception("Expected in or like after expression");
     }
 
+    private static String translateMatch(String s) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < s.length(); i++) {  // logic not correct for wide chars
+            char c = s.charAt(i);
+            switch (c) {
+                case '\\':
+                    sb.append(c).append(s.charAt(++i)); break;
+                case '%':
+                    sb.append('*'); break;
+                case '_':
+                    sb.append('?'); break;
+                case '*':
+                    sb.append("\\*"); break;
+                case '?':
+                    sb.append("\\?"); break;
+                default:
+                    sb.append(c); break;
+            }
+        }
+        return sb.toString();
+    }
+
     private static QueryExp parseQueryAfterParen(String[] ss)
             throws Exception {
         /* This is very ugly.  We might have "(q1) and (q2)" here, or
@@ -229,7 +274,7 @@
             ss[0] = start;
             ValueExp lhs = parseExp(ss);
             if (!skip(ss, ") "))
-                throw new Exception("Expected `) ' after subexpression");
+                throw new Exception("Expected `) ' after subexpression: " + ss[0]);
             String op = scanWord(ss);
             if (!skip(ss, " ("))
                 throw new Exception("Expected ` (' after `" + op + "'");
@@ -258,15 +303,16 @@
     }
 
     private static ValueExp parseExp(String[] ss) throws Exception {
-        final ValueExp prim = parsePrimary(ss);
+        ValueExp lhs = parsePrimary(ss);
 
+        while (true) {
         /* Look ahead to see if we have an arithmetic operator. */
         String back = ss[0];
         if (!skip(ss, " "))
-            return prim;
+                return lhs;
         if (ss[0].equals("") || "+-*/".indexOf(ss[0].charAt(0)) < 0) {
             ss[0] = back;
-            return prim;
+                return lhs;
         }
 
         final String op = scanWord(ss);
@@ -276,15 +322,16 @@
             throw new Exception("Unknown arithmetic operator: " + op);
         if (!skip(ss, " "))
             throw new Exception("Expected space after arithmetic operator");
-        ValueExp rhs = parseExp(ss);
+            ValueExp rhs = parsePrimary(ss);
         switch (op.charAt(0)) {
-        case '+': return Query.plus(prim, rhs);
-        case '-': return Query.minus(prim, rhs);
-        case '*': return Query.times(prim, rhs);
-        case '/': return Query.div(prim, rhs);
+            case '+': lhs = Query.plus(lhs, rhs); break;
+            case '-': lhs = Query.minus(lhs, rhs); break;
+            case '*': lhs = Query.times(lhs, rhs); break;
+            case '/': lhs = Query.div(lhs, rhs); break;
         default: throw new Exception("Can't happen: " + op.charAt(0));
         }
     }
+    }
 
     private static ValueExp parsePrimary(String[] ss) throws Exception {
         String s = ss[0];
@@ -324,14 +371,19 @@
     private static String scanWord(String[] ss) throws Exception {
         String s = ss[0];
         int space = s.indexOf(' ');
-        if (space < 0) {
+        int rpar = s.indexOf(')');
+        if (space < 0 && rpar < 0) {
             ss[0] = "";
             return s;
-        } else {
-            String word = s.substring(0, space);
-            ss[0] = s.substring(space);
-            return word;
         }
+        int stop;
+        if (space >= 0 && rpar >= 0)  // string has both space and ), stop at first
+            stop = Math.min(space, rpar);
+        else                          // string has only one, stop at it
+            stop = Math.max(space, rpar);
+        String word = s.substring(0, stop);
+        ss[0] = s.substring(stop);
+        return word;
     }
 
     private static boolean matchWord(String[] ss, String word)
@@ -381,13 +433,11 @@
         for (i = 0; i < len; i++) {
             char c = s.charAt(i);
             if (c == '\'') {
-                ss[0] = s.substring(i + 1);
+                ++i;
+                if (i >= len || s.charAt(i) != '\'') {
+                    ss[0] = s.substring(i);
                 return Query.value(buf.toString());
             }
-            if (c == '\\') {
-                if (++i == len)
-                    throw new Exception("\\ at end of string");
-                c = s.charAt(i);
             }
             buf.append(c);
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/query/QueryParseTest.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,778 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test QueryParseTest
+ * @bug 6602310 6604768
+ * @summary Test Query.fromString and Query.toString.
+ * @author Eamonn McManus
+ */
+
+import java.util.Collections;
+import java.util.Set;
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerDelegate;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
+import javax.management.Query;
+import javax.management.QueryExp;
+
+public class QueryParseTest {
+    // In this table, each string constant corresponds to a test case.
+    // The objects following the string up to the next string are MBeans.
+    // Each MBean must implement ExpectedValue to return true or false
+    // according as it should return that value for the query parsed
+    // from the given string.  The test will parse the string into a
+    // a query and verify that the MBeans return the expected value
+    // for that query.  Then it will convert the query back into a string
+    // and into a second query, and check that the MBeans return the
+    // expected value for that query too.  The reason we need to do all
+    // this is that the spec talks about "equivalent queries", and gives
+    // the implementation wide scope to rearrange queries.  So we cannot
+    // just compare string values.
+    //
+    // We could also write an implementation-dependent test that knew what
+    // the strings look like, and that would have to be changed if the
+    // implementation changed.  But the approach here is cleaner.
+    //
+    // To simplify the creation of MBeans, most use the expectTrue or
+    // expectFalse methods.  The parameters of these methods end up in
+    // attributes called "A", "B", "C", etc.
+    private static final Object[] queryTests = {
+        // RELATIONS
+
+        "A < B",
+        expectTrue(1, 2), expectTrue(1.0, 2.0), expectTrue("one", "two"),
+        expectTrue(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY),
+        expectFalse(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY),
+        expectFalse(1, 1), expectFalse(1.0, 1.0), expectFalse("one", "one"),
+        expectFalse(2, 1), expectFalse(2.0, 1.0), expectFalse("two", "one"),
+        expectFalse(Double.NaN, Double.NaN),
+
+        "One = two",
+        expectTrueOneTwo(1, 1), expectTrueOneTwo(1.0, 1.0),
+        expectFalseOneTwo(1, 2), expectFalseOneTwo(2, 1),
+
+        "A <= B",
+        expectTrue(1, 1), expectTrue(1, 2), expectTrue("one", "one"),
+        expectTrue("one", "two"),
+        expectFalse(2, 1), expectFalse("two", "one"),
+        expectFalse(Double.NaN, Double.NaN),
+
+        "A >= B",
+        expectTrue(1, 1), expectTrue(2, 1), expectTrue("two", "one"),
+        expectFalse(1, 2), expectFalse("one", "two"),
+
+        "A > B",
+        expectTrue(2, 1), expectTrue("two", "one"),
+        expectFalse(2, 2), expectFalse(1, 2), expectFalse(1.0, 2.0),
+        expectFalse("one", "two"),
+
+        "A <> B",
+        expectTrue(1, 2), expectTrue("foo", "bar"),
+        expectFalse(1, 1), expectFalse("foo", "foo"),
+
+        "A != B",
+        expectTrue(1, 2), expectTrue("foo", "bar"),
+        expectFalse(1, 1), expectFalse("foo", "foo"),
+
+        // PARENTHESES
+
+        "(((A))) = (B)",
+        expectTrue(1, 1), expectFalse(1, 2),
+
+        "(A = B)",
+        expectTrue(1, 1), expectFalse(1, 2),
+
+        "(((A = (B))))",
+        expectTrue(1, 1), expectFalse(1, 2),
+
+        // INTEGER LITERALS
+
+        "A = 1234567890123456789",
+        expectTrue(1234567890123456789L), expectFalse(123456789L),
+
+        "A = +1234567890123456789",
+        expectTrue(1234567890123456789L), expectFalse(123456789L),
+
+        "A = -1234567890123456789",
+        expectTrue(-1234567890123456789L), expectFalse(-123456789L),
+
+
+        "A = + 1234567890123456789",
+        expectTrue(1234567890123456789L), expectFalse(123456789L),
+
+        "A = - 1234567890123456789",
+        expectTrue(-1234567890123456789L), expectFalse(-123456789L),
+
+        "A = " + Long.MAX_VALUE,
+        expectTrue(Long.MAX_VALUE), expectFalse(Long.MIN_VALUE),
+
+        "A = " + Long.MIN_VALUE,
+        expectTrue(Long.MIN_VALUE), expectFalse(Long.MAX_VALUE),
+
+        // DOUBLE LITERALS
+
+        "A = 0.0",
+        expectTrue(0.0), expectFalse(1.0),
+
+        "A = 0.0e23",
+        expectTrue(0.0), expectFalse(1.0),
+
+        "A = 1.2e3",
+        expectTrue(1.2e3), expectFalse(1.2),
+
+        "A = +1.2",
+        expectTrue(1.2), expectFalse(-1.2),
+
+        "A = 1.2e+3",
+        expectTrue(1.2e3), expectFalse(1.2),
+
+        "A = 1.2e-3",
+        expectTrue(1.2e-3), expectFalse(1.2),
+
+        "A = 1.2E3",
+        expectTrue(1.2e3), expectFalse(1.2),
+
+        "A = -1.2e3",
+        expectTrue(-1.2e3), expectFalse(1.2),
+
+        "A = " + Double.MAX_VALUE,
+        expectTrue(Double.MAX_VALUE), expectFalse(Double.MIN_VALUE),
+
+        "A = " + -Double.MAX_VALUE,
+        expectTrue(-Double.MAX_VALUE), expectFalse(-Double.MIN_VALUE),
+
+        "A = " + Double.MIN_VALUE,
+        expectTrue(Double.MIN_VALUE), expectFalse(Double.MAX_VALUE),
+
+        "A = " + -Double.MIN_VALUE,
+        expectTrue(-Double.MIN_VALUE), expectFalse(-Double.MAX_VALUE),
+
+        Query.toString(  // A = Infinity   ->   A = (1.0/0.0)
+                Query.eq(Query.attr("A"), Query.value(Double.POSITIVE_INFINITY))),
+        expectTrue(Double.POSITIVE_INFINITY),
+        expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY),
+
+        Query.toString(  // A = -Infinity   ->   A = (-1.0/0.0)
+                Query.eq(Query.attr("A"), Query.value(Double.NEGATIVE_INFINITY))),
+        expectTrue(Double.NEGATIVE_INFINITY),
+        expectFalse(0.0), expectFalse(Double.POSITIVE_INFINITY),
+
+        Query.toString(  // A < NaN   ->   A < (0.0/0.0)
+                Query.lt(Query.attr("A"), Query.value(Double.NaN))),
+        expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY),
+        expectFalse(Double.POSITIVE_INFINITY), expectFalse(Double.NaN),
+
+        Query.toString(  // A >= NaN   ->   A < (0.0/0.0)
+                Query.geq(Query.attr("A"), Query.value(Double.NaN))),
+        expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY),
+        expectFalse(Double.POSITIVE_INFINITY), expectFalse(Double.NaN),
+
+        // STRING LITERALS
+
+        "A = 'blim'",
+        expectTrue("blim"), expectFalse("blam"),
+
+        "A = 'can''t'",
+        expectTrue("can't"), expectFalse("cant"), expectFalse("can''t"),
+
+        "A = '''blim'''",
+        expectTrue("'blim'"), expectFalse("'blam'"),
+
+        "A = ''",
+        expectTrue(""), expectFalse((Object) null),
+
+        // BOOLEAN LITERALS
+
+        "A = true",
+        expectTrue(true), expectFalse(false), expectFalse((Object) null),
+
+        "A = TRUE",
+        expectTrue(true), expectFalse(false),
+
+        "A = TrUe",
+        expectTrue(true), expectFalse(false),
+
+        "A = false",
+        expectTrue(false), expectFalse(true),
+
+        "A = fAlSe",
+        expectTrue(false), expectFalse(true),
+
+        "A = \"true\"",   // An attribute called "true"
+        expectFalse(true), expectFalse(false), expectFalse("\"true\""),
+        newTester(new String[] {"A", "true"}, new Object[] {2.2, 2.2}, true),
+        newTester(new String[] {"A", "true"}, new Object[] {2.2, 2.3}, false),
+
+        "A = \"False\"",
+        expectFalse(true), expectFalse(false), expectFalse("\"False\""),
+        newTester(new String[] {"A", "False"}, new Object[] {2.2, 2.2}, true),
+        newTester(new String[] {"A", "False"}, new Object[] {2.2, 2.3}, false),
+
+        // ARITHMETIC
+
+        "A + B = 10",
+        expectTrue(4, 6), expectFalse(3, 8),
+
+        "A + B = 'blim'",
+        expectTrue("bl", "im"), expectFalse("bl", "am"),
+
+        "A - B = 10",
+        expectTrue(16, 6), expectFalse(16, 3),
+
+        "A * B = 10",
+        expectTrue(2, 5), expectFalse(3, 3),
+
+        "A / B = 10",
+        expectTrue(70, 7), expectTrue(70.0, 7), expectFalse(70.01, 7),
+
+        "A + B + C = 10",
+        expectTrue(2, 3, 5), expectFalse(2, 4, 8),
+
+        "A+B+C=10",
+        expectTrue(2, 3, 5), expectFalse(2, 4, 8),
+
+        "A + B + C + D = 10",
+        expectTrue(1, 2, 3, 4), expectFalse(2, 3, 4, 5),
+
+        "A + (B + C) = 10",
+        expectTrue(2, 3, 5), expectFalse(2, 4, 8),
+
+        // It is not correct to rearrange A + (B + C) as A + B + C
+        // (which means (A + B) + C), because of overflow.
+        // In particular Query.toString must not do this.
+        "A + (B + C) = " + Double.MAX_VALUE,  // ensure no false associativity
+        expectTrue(Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE),
+        expectFalse(-Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE),
+
+        "A * (B * C) < " + Double.MAX_VALUE,  // same test for multiplication
+        expectTrue(Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE),
+        expectFalse(Double.MIN_VALUE, Double.MAX_VALUE, Double.MAX_VALUE),
+
+        "A * B + C = 10",
+        expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3),
+
+        "A*B+C=10",
+        expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3),
+
+        "(A * B) + C = 10",
+        expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3),
+
+        "A + B * C = 10",
+        expectTrue(1, 3, 3), expectTrue(2, 2, 4), expectFalse(1, 2, 3),
+
+        "A - B * C = 10",
+        expectTrue(16, 2, 3), expectFalse(15, 2, 2),
+
+        "A + B / C = 10",
+        expectTrue(5, 15, 3), expectFalse(5, 16, 4),
+
+        "A - B / C = 10",
+        expectTrue(16, 12, 2), expectFalse(15, 10, 3),
+
+        "A * (B + C) = 10",
+        expectTrue(2, 2, 3), expectFalse(1, 2, 3),
+
+        "A / (B + C) = 10",
+        expectTrue(70, 4, 3), expectFalse(70, 3, 5),
+
+        "A * (B - C) = 10",
+        expectTrue(2, 8, 3), expectFalse(2, 3, 8),
+
+        "A / (B - C) = 10",
+        expectTrue(70, 11, 4), expectFalse(70, 4, 11),
+
+        "A / B / C = 10",
+        expectTrue(140, 2, 7), expectFalse(100, 5, 5),
+
+        "A / (B / C) = 10",
+        expectTrue(70, 14, 2), expectFalse(70, 10, 7),
+
+        // LOGIC
+
+        "A = B or C = D",
+        expectTrue(1, 1, 2, 3), expectTrue(1, 2, 3, 3), expectTrue(1, 1, 2, 2),
+        expectFalse(1, 2, 3, 4), expectFalse("!", "!!", "?", "??"),
+
+        "A = B and C = D",
+        expectTrue(1, 1, 2, 2),
+        expectFalse(1, 1, 2, 3), expectFalse(1, 2, 3, 3),
+
+        "A = 1 and B = 2 and C = 3",
+        expectTrue(1, 2, 3), expectFalse(1, 2, 4),
+
+        "A = 1 or B = 2 or C = 3",
+        expectTrue(1, 2, 3), expectTrue(1, 0, 0), expectTrue(0, 0, 3),
+        expectFalse(2, 3, 4),
+
+        // grouped as (a and b) or (c and d)
+        "A = 1 AND B = 2 OR C = 3 AND D = 4",
+        expectTrue(1, 2, 3, 4), expectTrue(1, 2, 1, 2), expectTrue(3, 4, 3, 4),
+        expectFalse(3, 4, 1, 2), expectFalse(1, 1, 1, 1),
+
+        "(A = 1 AND B = 2) OR (C = 3 AND D = 4)",
+        expectTrue(1, 2, 3, 4), expectTrue(1, 2, 1, 2), expectTrue(3, 4, 3, 4),
+        expectFalse(3, 4, 1, 2), expectFalse(1, 1, 1, 1),
+
+        "(A = 1 or B = 2) AND (C = 3 or C = 4)",
+        expectTrue(1, 1, 3, 3), expectTrue(2, 2, 4, 4), expectTrue(1, 2, 3, 4),
+        expectFalse(1, 2, 1, 2), expectFalse(3, 4, 3, 4),
+
+        // LIKE
+
+        "A like 'b%m'",
+        expectTrue("blim"), expectTrue("bm"),
+        expectFalse(""), expectFalse("blimmo"), expectFalse("mmm"),
+
+        "A not like 'b%m'",
+        expectFalse("blim"), expectFalse("bm"),
+        expectTrue(""), expectTrue("blimmo"), expectTrue("mmm"),
+
+        "A like 'b_m'",
+        expectTrue("bim"), expectFalse("blim"),
+
+        "A like '%can''t%'",
+        expectTrue("can't"),
+        expectTrue("I'm sorry Dave, I'm afraid I can't do that"),
+        expectFalse("cant"), expectFalse("can''t"),
+
+        "A like '\\%%\\%'",
+        expectTrue("%blim%"), expectTrue("%%"),
+        expectFalse("blim"), expectFalse("%asdf"), expectFalse("asdf%"),
+
+        "A LIKE '*%?_'",
+        expectTrue("*blim?!"), expectTrue("*?_"),
+        expectFalse("blim"), expectFalse("blim?"),
+        expectFalse("?*"), expectFalse("??"), expectFalse(""), expectFalse("?"),
+
+        Query.toString(
+                Query.initialSubString(Query.attr("A"), Query.value("*?%_"))),
+        expectTrue("*?%_tiddly"), expectTrue("*?%_"),
+        expectFalse("?%_tiddly"), expectFalse("*!%_"), expectFalse("*??_"),
+        expectFalse("*?%!"), expectFalse("*?%!tiddly"),
+
+        Query.toString(
+                Query.finalSubString(Query.attr("A"), Query.value("*?%_"))),
+        expectTrue("tiddly*?%_"), expectTrue("*?%_"),
+        expectFalse("tiddly?%_"), expectFalse("*!%_"), expectFalse("*??_"),
+        expectFalse("*?%!"), expectFalse("tiddly*?%!"),
+
+        // BETWEEN
+
+        "A between B and C",
+        expectTrue(1, 1, 2), expectTrue(2, 1, 2), expectTrue(2, 1, 3),
+        expectFalse(3, 1, 2), expectFalse(0, 1, 2), expectFalse(2, 3, 1),
+        expectTrue(1.0, 0.0, 2.0), expectFalse(2.0, 0.0, 1.0),
+        expectTrue(0.0, 0.0, 0.0), expectTrue(1.0, 0.0, 1.0),
+        expectTrue(1.0, 0.0, Double.POSITIVE_INFINITY),
+        expectFalse(1.0, Double.NEGATIVE_INFINITY, 0.0),
+        expectFalse(false, false, true), expectFalse(true, false, true),
+        expectTrue("jim", "fred", "sheila"), expectFalse("fred", "jim", "sheila"),
+
+        "A between B and C and 1+2=3",
+        expectTrue(2, 1, 3), expectFalse(2, 3, 1),
+
+        "A not between B and C",
+        expectTrue(1, 2, 3), expectFalse(2, 1, 3),
+
+        // IN
+
+        "A in (1, 2, 3)",
+        expectTrue(1), expectTrue(2), expectTrue(3),
+        expectFalse(0), expectFalse(4),
+
+        "A in (1)",
+        expectTrue(1), expectFalse(0),
+
+        "A in (1.2, 3.4)",
+        expectTrue(1.2), expectTrue(3.4), expectFalse(0.0),
+
+        "A in ('foo', 'bar')",
+        expectTrue("foo"), expectTrue("bar"), expectFalse("baz"),
+
+        "A in ('foo', 'bar') and 'bl'+'im'='blim'",
+        expectTrue("foo"), expectTrue("bar"), expectFalse("baz"),
+
+        "A in (B, C, D)",  // requires fix for CR 6604768
+        expectTrue(1, 1, 2, 3), expectFalse(1, 2, 3, 4),
+
+        "A not in (B, C, D)",
+        expectTrue(1, 2, 3, 4), expectFalse(1, 1, 2, 3),
+
+        // QUOTING
+
+        "\"LIKE\" = 1 and \"NOT\" = 2 and \"INSTANCEOF\" = 3 and " +
+                "\"TRUE\" = 4 and \"FALSE\" = 5",
+        newTester(
+                new String[] {"LIKE", "NOT", "INSTANCEOF", "TRUE", "FALSE"},
+                new Object[] {1, 2, 3, 4, 5},
+                true),
+        newTester(
+                new String[] {"LIKE", "NOT", "INSTANCEOF", "TRUE", "FALSE"},
+                new Object[] {5, 4, 3, 2, 1},
+                false),
+
+        "\"\"\"woo\"\"\" = 5",
+        newTester(new String[] {"\"woo\""}, new Object[] {5}, true),
+        newTester(new String[] {"\"woo\""}, new Object[] {4}, false),
+        expectFalse(),
+
+        // INSTANCEOF
+
+        "instanceof '" + Tester.class.getName() + "'",
+        expectTrue(),
+
+        "instanceof '" + String.class.getName() + "'",
+        expectFalse(),
+
+        // LIKE OBJECTNAME
+
+        // The test MBean is registered as a:b=c
+        "like 'a:b=c'", expectTrue(),
+        "like 'a:*'", expectTrue(),
+        "like '*:b=c'", expectTrue(),
+        "like 'a:b=*'", expectTrue(),
+        "like 'a:b=?'", expectTrue(),
+        "like 'd:b=c'", expectFalse(),
+        "like 'a:b=??*'", expectFalse(),
+        "like 'a:b=\"can''t\"'", expectFalse(),
+
+        // QUALIFIED ATTRIBUTE
+
+        Tester.class.getName() + "#A = 5",
+        expectTrue(5), expectFalse(4),
+
+        Tester.class.getName() + " # A = 5",
+        expectTrue(5), expectFalse(4),
+
+        Tester.class.getSuperclass().getName() + "#A = 5",
+        expectFalse(5),
+
+        DynamicMBean.class.getName() + "#A = 5",
+        expectFalse(5),
+
+        Tester.class.getName() + "#A = 5",
+        new Tester(new String[] {"A"}, new Object[] {5}, false) {},
+        // note the little {} at the end which means this is a subclass
+        // and therefore QualifiedAttributeValue should return false.
+
+        MBeanServerDelegate.class.getName() + "#SpecificationName LIKE '%'",
+        new Wrapped(new MBeanServerDelegate(), true),
+        new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false),
+
+        // DOTTED ATTRIBUTE
+
+        "A.canonicalName = '" +
+                MBeanServerDelegate.DELEGATE_NAME.getCanonicalName() + "'",
+        expectTrue(MBeanServerDelegate.DELEGATE_NAME),
+        expectFalse(ObjectName.WILDCARD),
+
+        "A.class.name = 'java.lang.String'",
+        expectTrue("blim"), expectFalse(95), expectFalse((Object) null),
+
+        "A.canonicalName like 'JMImpl%:%'",
+        expectTrue(MBeanServerDelegate.DELEGATE_NAME),
+        expectFalse(ObjectName.WILDCARD),
+
+        "A.true = 'blim'",
+        new Tester(new String[] {"A.true"}, new Object[] {"blim"}, true),
+        new Tester(new String[] {"A.true"}, new Object[] {"blam"}, false),
+
+        "\"A.true\" = 'blim'",
+        new Tester(new String[] {"A.true"}, new Object[] {"blim"}, true),
+        new Tester(new String[] {"A.true"}, new Object[] {"blam"}, false),
+
+        MBeanServerDelegate.class.getName() +
+                "#SpecificationName.class.name = 'java.lang.String'",
+        new Wrapped(new MBeanServerDelegate(), true),
+        new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false),
+
+        MBeanServerDelegate.class.getName() +
+                " # SpecificationName.class.name = 'java.lang.String'",
+        new Wrapped(new MBeanServerDelegate(), true),
+        new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false),
+
+        // CLASS
+
+        "class = '" + Tester.class.getName() + "'",
+        expectTrue(),
+        new Wrapped(new MBeanServerDelegate(), false),
+
+        "Class = '" + Tester.class.getName() + "'",
+        expectTrue(),
+        new Wrapped(new MBeanServerDelegate(), false),
+    };
+
+    private static final String[] incorrectQueries = {
+        "", " ", "25", "()", "(a = b", "a = b)", "a.3 = 5",
+        "a = " + Long.MAX_VALUE + "0",
+        "a = " + Double.MAX_VALUE + "0",
+        "a = " + Double.MIN_VALUE + "0",
+        "a = 12a5", "a = 12e5e5", "a = 12.23.34",
+        "a = 'can't'", "a = 'unterminated", "a = 'asdf''",
+        "a = \"oops", "a = \"oops\"\"",
+        "a like 5", "true or false",
+        "a ! b", "? = 3", "a = @", "a##b",
+        "a between b , c", "a between and c",
+        "a in b, c", "a in 23", "a in (2, 3", "a in (2, 3x)",
+        "a like \"foo\"", "a like b", "a like 23",
+        "like \"foo\"", "like b", "like 23", "like 'a:b'",
+        "5 like 'a'", "'a' like '%'",
+        "a not= b", "a not = b", "a not b", "a not b c",
+        "a = +b", "a = +'b'", "a = +true", "a = -b", "a = -'b'",
+        "a#5 = b", "a#'b' = c",
+        "a instanceof b", "a instanceof 17", "a instanceof",
+        "a like 'oops\\'", "a like '[oops'",
+
+        // Check that -Long.MIN_VALUE is an illegal constant.  This is one more
+        // than Long.MAX_VALUE and, like the Java language, we only allow it
+        // if it is the operand of unary minus.
+        "a = " + Long.toString(Long.MIN_VALUE).substring(1),
+    };
+
+    public static void main(String[] args) throws Exception {
+        int nexti;
+        String failed = null;
+
+        System.out.println("TESTING CORRECT QUERY STRINGS");
+        for (int i = 0; i < queryTests.length; i = nexti) {
+            for (nexti = i + 1; nexti < queryTests.length; nexti++) {
+                if (queryTests[nexti] instanceof String)
+                    break;
+            }
+            if (!(queryTests[i] instanceof String))
+                throw new Exception("Test bug: should be string: " + queryTests[i]);
+
+            String qs = (String) queryTests[i];
+            System.out.println("Test: " + qs);
+
+            QueryExp qe = Query.fromString(qs);
+            String qes = Query.toString(qe);
+            System.out.println("...parses to: " + qes);
+            final QueryExp[] queries;
+            if (qes.equals(qs))
+                queries = new QueryExp[] {qe};
+            else {
+                QueryExp qe2 = Query.fromString(qes);
+                String qes2 = Query.toString(qe2);
+                System.out.println("...which parses to: " + qes2);
+                if (qes.equals(qes2))
+                    queries = new QueryExp[] {qe};
+                else
+                    queries = new QueryExp[] {qe, qe2};
+            }
+
+            for (int j = i + 1; j < nexti; j++) {
+                Object mbean;
+                if (queryTests[j] instanceof Wrapped)
+                    mbean = ((Wrapped) queryTests[j]).mbean();
+                else
+                    mbean = queryTests[j];
+                boolean expect = ((ExpectedValue) queryTests[j]).expectedValue();
+                for (QueryExp qet : queries) {
+                    boolean actual = runQuery(qet, mbean);
+                    boolean ok = (expect == actual);
+                    System.out.println(
+                            "..." + mbean + " -> " + actual +
+                            (ok ? " (OK)" : " ####INCORRECT####"));
+                    if (!ok)
+                        failed = qs;
+                }
+            }
+        }
+
+        System.out.println();
+        System.out.println("TESTING INCORRECT QUERY STRINGS");
+        for (String s : incorrectQueries) {
+            try {
+                QueryExp qe = Query.fromString(s);
+                System.out.println("###DID NOT GET ERROR:### \"" + s + "\"");
+                failed = s;
+            } catch (IllegalArgumentException e) {
+                String es = (e.getClass() == IllegalArgumentException.class) ?
+                    e.getMessage() : e.toString();
+                System.out.println("OK: exception for \"" + s + "\": " + es);
+            }
+        }
+
+        if (failed == null)
+            System.out.println("TEST PASSED");
+        else
+            throw new Exception("TEST FAILED: Last failure: " + failed);
+    }
+
+    private static boolean runQuery(QueryExp qe, Object mbean)
+    throws Exception {
+        MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+        ObjectName name = new ObjectName("a:b=c");
+        mbs.registerMBean(mbean, name);
+        Set<ObjectName> names = mbs.queryNames(new ObjectName("a:*"), qe);
+        if (names.isEmpty())
+            return false;
+        if (names.equals(Collections.singleton(name)))
+            return true;
+        throw new Exception("Unexpected query result set: " + names);
+    }
+
+    private static interface ExpectedValue {
+        public boolean expectedValue();
+    }
+
+    private static class Wrapped implements ExpectedValue {
+        private final Object mbean;
+        private final boolean expect;
+
+        Wrapped(Object mbean, boolean expect) {
+            this.mbean = mbean;
+            this.expect = expect;
+        }
+
+        Object mbean() {
+            return mbean;
+        }
+
+        public boolean expectedValue() {
+            return expect;
+        }
+    }
+
+    private static class Tester implements DynamicMBean, ExpectedValue {
+        private final AttributeList attributes;
+        private final boolean expectedValue;
+
+        Tester(AttributeList attributes, boolean expectedValue) {
+            this.attributes = attributes;
+            this.expectedValue = expectedValue;
+        }
+
+        Tester(String[] names, Object[] values, boolean expectedValue) {
+            this(makeAttributeList(names, values), expectedValue);
+        }
+
+        private static AttributeList makeAttributeList(
+                String[] names, Object[] values) {
+            if (names.length != values.length)
+                throw new Error("Test bug: names and values different length");
+            AttributeList list = new AttributeList();
+            for (int i = 0; i < names.length; i++)
+                list.add(new Attribute(names[i], values[i]));
+            return list;
+        }
+
+        public Object getAttribute(String attribute)
+        throws AttributeNotFoundException {
+            for (Attribute a : attributes.asList()) {
+                if (a.getName().equals(attribute))
+                    return a.getValue();
+            }
+            throw new AttributeNotFoundException(attribute);
+        }
+
+        public void setAttribute(Attribute attribute) {
+            throw new UnsupportedOperationException();
+        }
+
+        public AttributeList getAttributes(String[] attributes) {
+            AttributeList list = new AttributeList();
+            for (String attribute : attributes) {
+                try {
+                    list.add(new Attribute(attribute, getAttribute(attribute)));
+                } catch (AttributeNotFoundException e) {
+                    // OK: ignore, per semantics of getAttributes
+                }
+            }
+            return list;
+        }
+
+        public AttributeList setAttributes(AttributeList attributes) {
+            throw new UnsupportedOperationException();
+        }
+
+        public Object invoke(String actionName, Object[] params, String[] signature) {
+            throw new UnsupportedOperationException();
+        }
+
+        public MBeanInfo getMBeanInfo() {
+            MBeanAttributeInfo mbais[] = new MBeanAttributeInfo[attributes.size()];
+            for (int i = 0; i < mbais.length; i++) {
+                Attribute attr = attributes.asList().get(i);
+                String name = attr.getName();
+                Object value = attr.getValue();
+                String type =
+                        ((value == null) ? new Object() : value).getClass().getName();
+                mbais[i] = new MBeanAttributeInfo(
+                        name, type, name, true, false, false);
+            }
+            return new MBeanInfo(
+                    getClass().getName(), "descr", mbais, null, null, null);
+        }
+
+        public boolean expectedValue() {
+            return expectedValue;
+        }
+
+        @Override
+        public String toString() {
+            return attributes.toString();
+        }
+    }
+
+    // Method rather than field, to avoid circular init dependencies
+    private static String[] abcd() {
+        return new String[] {"A", "B", "C", "D"};
+    }
+
+    private static String[] onetwo() {
+        return new String[] {"One", "two"};
+    }
+
+    private static Object expectTrue(Object... attrs) {
+        return newTester(abcd(), attrs, true);
+    }
+
+    private static Object expectFalse(Object... attrs) {
+        return newTester(abcd(), attrs, false);
+    }
+
+    private static Object expectTrueOneTwo(Object... attrs) {
+        return newTester(onetwo(), attrs, true);
+    }
+
+    private static Object expectFalseOneTwo(Object... attrs) {
+        return newTester(onetwo(), attrs, false);
+    }
+
+    private static Object newTester(String[] names, Object[] attrs, boolean expect) {
+        AttributeList list = new AttributeList();
+        for (int i = 0; i < attrs.length; i++)
+            list.add(new Attribute(names[i], attrs[i]));
+        return new Tester(list, expect);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/security/auth/x500/X500Principal/RFC4514.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * @test
+ * @bug 6611991
+ * @summary Add support for parsing RFC 4514 DNs to X500Principal
+ *
+ * Ensure RFC 4514 Distinguished Name Strings can be parsed by X500Principal.
+ * RFC 4514 obsoleted RFC 2253 so we should make sure we can parse DNs of
+ * that form that contain subtle differences or clarifications in the grammar.
+ */
+public class RFC4514 {
+
+    private int failed = 0;
+
+    public static void main(String[] args) throws Exception {
+        new RFC4514().test();
+    }
+
+    private void test() throws Exception {
+
+        /**
+         * RFC 4514 allows space to be escaped as '\ '.
+         */
+        parse("CN=\\ Space\\ ,C=US");
+        parse("CN=Sp\\ ace,C=US");
+        /**
+         * RFC 4514 does not require escaping of '=' characters.
+         */
+        parse("CN=Eq=uals,C=US");
+        /**
+         * RFC 4514 requires the null character to be escaped.
+         */
+        parse("CN=\\00,C=US");
+        /**
+         * RFC 4514 does not require escaping of non-leading '#' characters.
+         */
+        parse("CN=Num#ber,C=US");
+        /**
+         * XMLDSig (http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/)
+         * allows implementations to escape trailing whitespace as '\20'.
+         */
+        parse("CN=Trailing \\20,C=US");
+        /**
+         * XMLDSig allows implementations to escape ASCII control characters
+         * (Unicode range \x00 - \x1f) by replacing them with "\" followed by
+         * a two digit hex number showing its Unicode number.
+         */
+        parse("CN=Con\\09trol,C=US");
+
+        if (failed != 0) {
+            throw new Exception("Some RFC4514 tests FAILED");
+        }
+    }
+
+    public void parse(String dnString) throws Exception {
+
+        System.out.println("Parsing " + dnString);
+        X500Principal dn = new X500Principal(dnString);
+        String dnString2 = dn.getName();
+        X500Principal dn2 = new X500Principal(dnString2);
+        if (dn.equals(dn2)) {
+            System.out.println("PASSED");
+        } else {
+            System.out.println("FAILED");
+            failed++;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4981215
+ * @summary Tests that the jvmstat counters published by the out-of-the-box
+ *          management agent for the JMX connection details are correct.
+ * @author Luis-Miguel Alventosa
+ * @run clean JvmstatCountersTest
+ * @run build JvmstatCountersTest
+ * @run main/othervm JvmstatCountersTest 1
+ * @run main/othervm -Dcom.sun.management.jmxremote JvmstatCountersTest 2
+ * @run main/othervm -Dcom.sun.management.jmxremote.port=0 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false JvmstatCountersTest 3
+ * @run main/othervm JvmstatCountersTest 4
+ */
+
+import java.io.*;
+import java.lang.management.*;
+import java.util.*;
+import javax.management.*;
+import javax.management.remote.*;
+import com.sun.tools.attach.*;
+import sun.management.ConnectorAddressLink;
+
+public class JvmstatCountersTest {
+
+    public static void checkAddress(String address) throws IOException {
+        System.out.println("Address = " + address);
+        JMXServiceURL url = new JMXServiceURL(address);
+        JMXConnector jmxc = JMXConnectorFactory.connect(url);
+        MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
+        System.out.println("MBean Count = " + mbsc.getMBeanCount());
+    }
+
+    public static void checkKey(Map<String, String> data, int index,
+            String key, String expectedValue) throws Exception {
+        String counter = "sun.management.JMXConnectorServer." + index + "." + key;
+        if (!data.containsKey(counter)) {
+            System.out.println("Test FAILED! Missing counter " + counter);
+            throw new IllegalArgumentException("Test case failed");
+        }
+        String value = data.get(counter);
+        if (key.equals("remoteAddress")) {
+            checkAddress(value);
+        } else if (!expectedValue.equals(value)) {
+            System.out.println("Test FAILED! Invalid counter " +
+                    counter + "=" + value);
+            throw new IllegalArgumentException("Test case failed");
+        }
+        System.out.println("OK: " + counter + "=" + value);
+    }
+
+    public static void main(String args[]) throws Exception {
+        String localAddress = ConnectorAddressLink.importFrom(0);
+        Map<String, String> remoteData = ConnectorAddressLink.importRemoteFrom(0);
+        final int testCase = Integer.parseInt(args[0]);
+        switch (testCase) {
+            case 1:
+                if (localAddress == null && remoteData.isEmpty()) {
+                    System.out.println("Test PASSED! The OOTB management " +
+                            "agent didn't publish any jvmstat counter.");
+                } else {
+                    System.out.println("Test FAILED! The OOTB management " +
+                            "agent unexpectedly published jvmstat counters.");
+                    throw new IllegalArgumentException("Test case 1 failed");
+                }
+                break;
+            case 2:
+                if (localAddress == null) {
+                    System.out.println("Test FAILED! The OOTB management " +
+                            "agent didn't publish the local connector.");
+                    throw new IllegalArgumentException("Test case 2 failed");
+                }
+                checkAddress(localAddress);
+                if (!remoteData.isEmpty()) {
+                    System.out.println("Test FAILED! The OOTB management " +
+                            "agent shouldn't publish the remote connector.");
+                    throw new IllegalArgumentException("Test case 2 failed");
+                }
+                System.out.println("Test PASSED! The OOTB management " +
+                        "agent only publishes the local connector through " +
+                        "a jvmstat counter.");
+                break;
+            case 3:
+                if (localAddress == null) {
+                    System.out.println("Test FAILED! The OOTB management " +
+                            "agent didn't publish the local connector.");
+                    throw new IllegalArgumentException("Test case 3 failed");
+                }
+                checkAddress(localAddress);
+                if (remoteData.isEmpty()) {
+                    System.out.println("Test FAILED! The OOTB management " +
+                            "agent didnn't publish the remote connector.");
+                    throw new IllegalArgumentException("Test case 3 failed");
+                }
+                for (String key : remoteData.keySet()) {
+                    if (!key.startsWith("sun.management.JMXConnectorServer.0.")) {
+                        System.out.println("Test FAILED! The OOTB management " +
+                                "agent shouldn't publish anything which isn't " +
+                                "related to the remote connector.");
+                        throw new IllegalArgumentException("Test case 3 failed");
+                    }
+                }
+                checkKey(remoteData, 0, "remoteAddress", null);
+                checkKey(remoteData, 0, "authenticate", "false");
+                checkKey(remoteData, 0, "ssl", "false");
+                checkKey(remoteData, 0, "sslRegistry", "false");
+                checkKey(remoteData, 0, "sslNeedClientAuth", "false");
+                System.out.println("Test PASSED! The OOTB management " +
+                        "agent publishes both the local and remote " +
+                        "connector info through jvmstat counters.");
+                break;
+            case 4:
+                if (localAddress != null || !remoteData.isEmpty()) {
+                    System.out.println("Test FAILED! The OOTB management " +
+                            "agent unexpectedly published jvmstat counters.");
+                    throw new IllegalArgumentException("Test case 4 failed");
+                }
+                RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
+                String name = rt.getName();
+                System.out.println("name = " + name);
+                String vmid = name.substring(0, name.indexOf("@"));
+                System.out.println("vmid = " + vmid);
+                VirtualMachine vm = VirtualMachine.attach(vmid);
+                String agent = vm.getSystemProperties().getProperty("java.home") +
+                        File.separator + "lib" + File.separator + "management-agent.jar";
+                vm.loadAgent(agent, "com.sun.management.jmxremote.port=0,com.sun.management.jmxremote.authenticate=false,com.sun.management.jmxremote.ssl=false");
+                vm.detach();
+                String localAddress2 = ConnectorAddressLink.importFrom(0);
+                if (localAddress2 == null) {
+                    System.out.println("Test FAILED! The OOTB management " +
+                            "agent didn't publish the local connector.");
+                    throw new IllegalArgumentException("Test case 4 failed");
+                }
+                checkAddress(localAddress2);
+                Map<String, String> remoteData2 = ConnectorAddressLink.importRemoteFrom(0);
+                if (remoteData2.isEmpty()) {
+                    System.out.println("Test FAILED! The OOTB management " +
+                            "agent didnn't publish the remote connector.");
+                    throw new IllegalArgumentException("Test case 4 failed");
+                }
+                for (String key : remoteData2.keySet()) {
+                    if (!key.startsWith("sun.management.JMXConnectorServer.0.")) {
+                        System.out.println("Test FAILED! The OOTB management " +
+                                "agent shouldn't publish anything which isn't " +
+                                "related to the remote connector.");
+                        throw new IllegalArgumentException("Test case 4 failed");
+                    }
+                }
+                checkKey(remoteData2, 0, "remoteAddress", null);
+                checkKey(remoteData2, 0, "authenticate", "false");
+                checkKey(remoteData2, 0, "ssl", "false");
+                checkKey(remoteData2, 0, "sslRegistry", "false");
+                checkKey(remoteData2, 0, "sslNeedClientAuth", "false");
+                System.out.println("Test PASSED! The OOTB management agent " +
+                        "publishes both the local and remote connector " +
+                        "info through jvmstat counters when the agent is " +
+                        "loaded through the Attach API.");
+        }
+        System.out.println("Bye! Bye!");
+    }
+}
--- a/test/sun/net/www/http/ChunkedOutputStream/Test.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/test/sun/net/www/http/ChunkedOutputStream/Test.java	Mon Apr 14 11:34:15 2008 -0700
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 5026745
+ * @bug 5026745 6631048
  * @run main/othervm/timeout=500 Test
  * @summary Cannot flush output stream when writing to an HttpUrlConnection
  */
@@ -158,6 +158,50 @@
                     exchange.sendResponseHeaders(200, 0);
                 }
                 break;
+            case 10: /* test11 */
+                printRequestURI(exchange);
+                is = exchange.getRequestBody();
+                s = read (is, str1.length());
+
+                error = false;
+                for (int i=10; i< 30 * 1024; i++) {
+                    byte c = (byte)is.read();
+
+                    if (c != (byte)i) {
+                        error = true;
+                        System.out.println ("error at position " + i);
+                    }
+                }
+                if (!s.equals(str1) ) {
+                    System.out.println ("received string : " + s);
+                    exchange.sendResponseHeaders(500, 0);
+                } else if (error) {
+                    System.out.println ("error");
+                    exchange.sendResponseHeaders(500, 0);
+                } else {
+                    exchange.sendResponseHeaders(200, 0);
+                }
+                break;
+            case 11: /* test12 */
+                printRequestURI(exchange);
+                is = exchange.getRequestBody();
+
+                error = false;
+                for (int i=10; i< 30 * 1024; i++) {
+                    byte c = (byte)is.read();
+
+                    if (c != (byte)i) {
+                        error = true;
+                        System.out.println ("error at position " + i);
+                    }
+                }
+                if (error) {
+                    System.out.println ("error");
+                    exchange.sendResponseHeaders(500, 0);
+                } else {
+                    exchange.sendResponseHeaders(200, 0);
+                }
+                break;
             }
             exchange.close();
             count ++;
@@ -390,6 +434,56 @@
         }
     }
 
+    static void test11 (String u) throws Exception {
+        URL url = new URL (u);
+        System.out.println ("client opening connection to: " + u);
+        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
+        urlc.setChunkedStreamingMode (36 * 1024);
+        urlc.setDoOutput(true);
+        urlc.setRequestMethod ("POST");
+        OutputStream os = urlc.getOutputStream ();
+        byte[] buf = new byte [30 * 1024];
+        for (int i=0; i< 30 * 1024; i++) {
+            buf[i] = (byte) i;
+        }
+        /* write a small bit first, and then the large buffer */
+        os.write (str1.getBytes());
+        //os.write (buf, 10, buf.length - 10); /* skip 10 bytes to test offset */
+        os.write (buf, 10, (10 * 1024) - 10);
+        os.write (buf, (10 * 1024), (10 * 1024));
+        os.write (buf, (20 * 1024), (10 * 1024));
+        os.close();
+        InputStream is = urlc.getInputStream();
+        is.close();
+        int ret = urlc.getResponseCode();
+        if (ret != 200) {
+            throw new Exception ("Expected 200: got " + ret);
+        }
+    }
+
+    static void test12 (String u) throws Exception {
+        URL url = new URL (u);
+        System.out.println ("client opening connection to: " + u);
+        HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
+        urlc.setChunkedStreamingMode (36 * 1024);
+        urlc.setDoOutput(true);
+        urlc.setRequestMethod ("POST");
+        OutputStream os = urlc.getOutputStream ();
+        byte[] buf = new byte [30 * 1024];
+        for (int i=0; i< 30 * 1024; i++) {
+            buf[i] = (byte) i;
+        }
+        os.write (buf, 10, buf.length - 10); /* skip 10 bytes to test offset */
+        os.close();
+        InputStream is = urlc.getInputStream();
+        is.close();
+        int ret = urlc.getResponseCode();
+        if (ret != 200) {
+            throw new Exception ("Expected 200: got " + ret);
+        }
+    }
+
+
     static com.sun.net.httpserver.HttpServer httpserver;
 
     public static void main (String[] args) throws Exception {
@@ -411,6 +505,8 @@
             test8("http://localhost:"+ port + "/test/test8");
             test9("http://localhost:"+ port + "/test/test9");
             test10("http://localhost:"+ port + "/test/test10");
+            test11("http://localhost:"+ port + "/test/test11");
+            test12("http://localhost:"+ port + "/test/test12");
         } finally {
             if (httpserver != null)
                 httpserver.stop(0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/net/www/protocol/http/B6641309.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6641309
+ * @summary Wrong Cookie separator used in HttpURLConnection
+ */
+
+import java.net.*;
+import java.util.*;
+import java.io.*;
+import com.sun.net.httpserver.*;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+
+public class B6641309
+{
+    com.sun.net.httpserver.HttpServer httpServer;
+    ExecutorService executorService;
+
+    public static void main(String[] args)
+    {
+        new B6641309();
+    }
+
+    public B6641309()
+    {
+        try {
+            startHttpServer();
+            doClient();
+        } catch (IOException ioe) {
+            System.err.println(ioe);
+        }
+    }
+
+    void doClient() {
+        CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
+        try {
+            InetSocketAddress address = httpServer.getAddress();
+
+            // GET Request
+            URL url = new URL("http://localhost:" + address.getPort() + "/test/");
+            CookieHandler ch = CookieHandler.getDefault();
+            Map<String,List<String>> header = new HashMap<String,List<String>>();
+            List<String> values = new LinkedList<String>();
+            values.add("Test1Cookie=TEST1; path=/test/");
+            values.add("Test2Cookie=TEST2; path=/test/");
+            header.put("Set-Cookie", values);
+
+            // preload the CookieHandler with a cookie for our URL
+            // so that it will be sent during the first request
+            ch.put(url.toURI(), header);
+            HttpURLConnection uc = (HttpURLConnection)url.openConnection();
+            int resp = uc.getResponseCode();
+            if (resp != 200)
+                throw new RuntimeException("Failed: Response code from GET is not 200");
+
+            System.out.println("Response code from GET = 200 OK");
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (URISyntaxException e) {
+            e.printStackTrace();
+        } finally {
+            httpServer.stop(1);
+            executorService.shutdown();
+        }
+    }
+
+    /**
+     * Http Server
+     */
+    public void startHttpServer() throws IOException {
+        httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
+
+        // create HttpServer context
+        HttpContext ctx = httpServer.createContext("/test/", new MyHandler());
+
+        executorService = Executors.newCachedThreadPool();
+        httpServer.setExecutor(executorService);
+        httpServer.start();
+    }
+
+    class MyHandler implements HttpHandler {
+        public void handle(HttpExchange t) throws IOException {
+            InputStream is = t.getRequestBody();
+            Headers reqHeaders = t.getRequestHeaders();
+            int i = 0;
+            // Read till end of stream
+            do {
+                i = is.read();
+            } while (i != -1);
+            is.close();
+
+            List<String> cookies = reqHeaders.get("Cookie");
+            if (cookies != null) {
+                for (String str : cookies) {
+                    // The separator between the 2 cookies should be
+                    // a semi-colon AND a space
+                    if (str.equals("Test1Cookie=TEST1; Test2Cookie=TEST2"))
+                        t.sendResponseHeaders(200, -1);
+                }
+            }
+            t.sendResponseHeaders(400, -1);
+            t.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/net/www/protocol/http/B6660405.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6660405
+ * @summary HttpURLConnection returns the wrong InputStream
+ */
+
+import java.net.*;
+import java.util.*;
+import java.io.*;
+import com.sun.net.httpserver.*;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+
+public class B6660405
+{
+    com.sun.net.httpserver.HttpServer httpServer;
+    ExecutorService executorService;
+
+    static class MyCacheResponse extends CacheResponse {
+        private byte[] buf = new byte[1024];
+
+        public MyCacheResponse() {
+        }
+
+        @Override
+        public Map<String, List<String>> getHeaders() throws IOException
+        {
+            Map<String, List<String>> h = new HashMap<String, List<String>>();
+            ArrayList<String> l = new ArrayList<String>();
+            l.add("HTTP/1.1 200 OK");
+            h.put(null, l);
+            l = new ArrayList<String>();
+            l.add("1024");
+            h.put("Content-Length", l);
+            return h;
+        }
+
+        @Override
+        public InputStream getBody() throws IOException
+        {
+            return new ByteArrayInputStream(buf);
+        }
+
+    }
+    static class MyResponseCache extends ResponseCache {
+
+        public MyResponseCache() {
+        }
+
+        @Override
+        public CacheResponse get(URI uri, String rqstMethod, Map<String, List<String>> rqstHeaders) throws IOException
+        {
+            if (uri.getPath().equals("/redirect/index.html")) {
+                return new MyCacheResponse();
+            }
+            return null;
+        }
+
+        @Override
+        public CacheRequest put(URI uri, URLConnection conn) throws IOException
+        {
+            return null;
+        }
+
+    }
+
+    public static void main(String[] args)
+    {
+        new B6660405();
+    }
+
+    public B6660405()
+    {
+        try {
+            startHttpServer();
+            doClient();
+        } catch (IOException ioe) {
+            System.err.println(ioe);
+        }
+    }
+
+    void doClient() {
+        ResponseCache.setDefault(new MyResponseCache());
+        try {
+            InetSocketAddress address = httpServer.getAddress();
+
+            // GET Request
+            URL url = new URL("http://localhost:" + address.getPort() + "/test/index.html");
+            HttpURLConnection uc = (HttpURLConnection)url.openConnection();
+            int code = uc.getResponseCode();
+            System.err.println("response code = " + code);
+            int l = uc.getContentLength();
+            System.err.println("content-length = " + l);
+            InputStream in = uc.getInputStream();
+            int i = 0;
+            // Read till end of stream
+            do {
+                i = in.read();
+            } while (i != -1);
+            in.close();
+        } catch (IOException e) {
+            throw new RuntimeException("Got the wrong InputStream after checking headers");
+        } finally {
+            httpServer.stop(1);
+            executorService.shutdown();
+        }
+    }
+
+    /**
+     * Http Server
+     */
+    public void startHttpServer() throws IOException {
+        httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
+
+        // create HttpServer context
+        HttpContext ctx = httpServer.createContext("/test/", new MyHandler());
+
+        executorService = Executors.newCachedThreadPool();
+        httpServer.setExecutor(executorService);
+        httpServer.start();
+    }
+
+    class MyHandler implements HttpHandler {
+        public void handle(HttpExchange t) throws IOException {
+            InputStream is = t.getRequestBody();
+            Headers reqHeaders = t.getRequestHeaders();
+            Headers resHeaders = t.getResponseHeaders();
+
+            int i = 0;
+            // Read till end of stream
+            do {
+                i = is.read();
+            } while (i != -1);
+            is.close();
+            resHeaders.add("Location", "http://foo.bar/redirect/index.html");
+            t.sendResponseHeaders(302, -1);
+            t.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/DnsFallback.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+/*
+ * @test
+ * @bug 6673164
+ * @summary dns_fallback parse error
+ */
+
+import sun.security.krb5.*;
+import java.io.*;
+
+public class DnsFallback {
+    public static void main(String[] args) throws Exception {
+        check("true", "true", true);
+        check("false", "true", false);
+        check("true", "false", true);
+        check("false", "false", false);
+        check("true", null, true);
+        check("false", null, false);
+        check(null, "true", true);
+        check(null, "false", false);
+    }
+
+    static void check(String realm, String fallback, boolean output) throws Exception {
+        FileOutputStream fo = new FileOutputStream("dnsfallback.conf");
+        StringBuffer sb = new StringBuffer();
+        sb.append("[libdefaults]\n");
+        if (realm != null) {
+            sb.append("dns_lookup_realm=" + realm + "\n");
+        }
+        if (fallback != null) {
+            sb.append("dns_fallback=" + fallback + "\n");
+        }
+        fo.write(sb.toString().getBytes());
+        fo.close();
+        System.setProperty("java.security.krb5.conf", "dnsfallback.conf");
+        Config.refresh();
+        System.out.println("Testing " + realm + ", " + fallback + ", " + output);
+        if (Config.getInstance().useDNS_Realm() != output) {
+            throw new Exception("Fail");
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/OptionPADataInKDCReq.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+/*
+ * @test
+ * @bug 6648972
+ * @summary KDCReq.init always read padata
+ */
+import sun.security.krb5.internal.ETypeInfo2;
+import sun.security.krb5.internal.KDCReq;
+import sun.security.util.DerValue;
+
+public class OptionPADataInKDCReq {
+    public static void main(String[] args) throws Exception {
+        /*
+         * This is a AS-REQ block without padata. The content is --
+        [APPLICATION 10] SEQUENCE {
+            [1] INTEGER 5
+            [2] INTEGER 10
+            [4] SEQUENCE {
+                [0] BIT STRING 01000000 10000001 00000000 00010000
+                [1] SEQUENCE {
+                    [0] INTEGER 1
+                    [1] SEQUENCE {
+                        STRING administrator
+                    }
+                }
+                [2] STRING N3
+                [3] SEQUENCE {
+                    [0] INTEGER 2
+                    [1] SEQUENCE {
+                        STRING krbtgt
+                        STRING N3
+                    }
+                }
+                [5] TIME Sun Sep 13 10:48:05 CST 2037
+                [6] TIME Sun Sep 13 10:48:05 CST 2037
+                [7] INTEGER 2101281516
+                [8] SEQUENCE {
+                    INTEGER 23
+                    INTEGER -133
+                    INTEGER -128
+                    INTEGER 3
+                    INTEGER 1
+                    INTEGER 24
+                    INTEGER -135
+                }
+                [9] SEQUENCE {
+                    SEQUENCE {
+                        [0] INTEGER 20
+                        [1] OCTET STRING
+                            0000: 58 50 20 20 20 20 20 20   20 20 20 20 20 20 20 20  XP
+                    }
+                }
+            }
+        }
+        */
+        byte[] b = {
+            (byte)0x6a, (byte)0x81, (byte)0xbf, (byte)0x30, (byte)0x81, (byte)0xbc, (byte)0xa1, (byte)0x03,
+            (byte)0x02, (byte)0x01, (byte)0x05, (byte)0xa2, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x0a,
+            (byte)0xa4, (byte)0x81, (byte)0xaf, (byte)0x30, (byte)0x81, (byte)0xac, (byte)0xa0, (byte)0x07,
+            (byte)0x03, (byte)0x05, (byte)0x00, (byte)0x40, (byte)0x81, (byte)0x00, (byte)0x10, (byte)0xa1,
+            (byte)0x1a, (byte)0x30, (byte)0x18, (byte)0xa0, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x01,
+            (byte)0xa1, (byte)0x11, (byte)0x30, (byte)0x0f, (byte)0x1b, (byte)0x0d, (byte)0x61, (byte)0x64,
+            (byte)0x6d, (byte)0x69, (byte)0x6e, (byte)0x69, (byte)0x73, (byte)0x74, (byte)0x72, (byte)0x61,
+            (byte)0x74, (byte)0x6f, (byte)0x72, (byte)0xa2, (byte)0x04, (byte)0x1b, (byte)0x02, (byte)0x4e,
+            (byte)0x33, (byte)0xa3, (byte)0x17, (byte)0x30, (byte)0x15, (byte)0xa0, (byte)0x03, (byte)0x02,
+            (byte)0x01, (byte)0x02, (byte)0xa1, (byte)0x0e, (byte)0x30, (byte)0x0c, (byte)0x1b, (byte)0x06,
+            (byte)0x6b, (byte)0x72, (byte)0x62, (byte)0x74, (byte)0x67, (byte)0x74, (byte)0x1b, (byte)0x02,
+            (byte)0x4e, (byte)0x33, (byte)0xa5, (byte)0x11, (byte)0x18, (byte)0x0f, (byte)0x32, (byte)0x30,
+            (byte)0x33, (byte)0x37, (byte)0x30, (byte)0x39, (byte)0x31, (byte)0x33, (byte)0x30, (byte)0x32,
+            (byte)0x34, (byte)0x38, (byte)0x30, (byte)0x35, (byte)0x5a, (byte)0xa6, (byte)0x11, (byte)0x18,
+            (byte)0x0f, (byte)0x32, (byte)0x30, (byte)0x33, (byte)0x37, (byte)0x30, (byte)0x39, (byte)0x31,
+            (byte)0x33, (byte)0x30, (byte)0x32, (byte)0x34, (byte)0x38, (byte)0x30, (byte)0x35, (byte)0x5a,
+            (byte)0xa7, (byte)0x06, (byte)0x02, (byte)0x04, (byte)0x7d, (byte)0x3f, (byte)0x02, (byte)0xec,
+            (byte)0xa8, (byte)0x19, (byte)0x30, (byte)0x17, (byte)0x02, (byte)0x01, (byte)0x17, (byte)0x02,
+            (byte)0x02, (byte)0xff, (byte)0x7b, (byte)0x02, (byte)0x01, (byte)0x80, (byte)0x02, (byte)0x01,
+            (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x18, (byte)0x02,
+            (byte)0x02, (byte)0xff, (byte)0x79, (byte)0xa9, (byte)0x1d, (byte)0x30, (byte)0x1b, (byte)0x30,
+            (byte)0x19, (byte)0xa0, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x14, (byte)0xa1, (byte)0x12,
+            (byte)0x04, (byte)0x10, (byte)0x58, (byte)0x50, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20,
+            (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20,
+            (byte)0x20, (byte)0x20,
+        };
+        new KDCReq(b, 0x0a);
+
+        /*
+         * This is a fake ETYPEINFO2 block with no salt
+            SEQUENCE {
+                [0] INTEGER 0
+                [2] OCTET STRING 0000: 00                                                 .
+            }
+         */
+        byte[] b2 = {
+            (byte)0x30, (byte)0x0a, (byte)0xa0, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0xa2,
+            (byte)0x03, (byte)0x04, (byte)0x01, (byte)0x00,
+        };
+
+        ETypeInfo2 e2 = new ETypeInfo2(new DerValue(b2));
+        if (e2.getSalt() != null || e2.getParams() == null) {
+            throw new Exception("ETypeInfo2 decoding error");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/TimeInCCache.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+/*
+ * @test
+ * @bug 6590930
+ * @summary read/write does not match for ccache
+ */
+
+import java.io.ByteArrayInputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import sun.security.krb5.internal.ccache.CCacheInputStream;
+import sun.security.krb5.internal.ccache.Credentials;
+
+public class TimeInCCache {
+    public static void main(String[] args) throws Exception {
+        // A trivial cache file, with startdate and renewTill being zero.
+        // The endtime is set to sometime in year 2022, so that isValid()
+        // will always check starttime.
+        byte[] ccache = new byte[]{
+            5, 4, 0, 12, 0, 1, 0, 8, -1, -1, -1, 19, -1, -2, 89, 51,
+            0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 10, 77, 65, 88, 73,
+            46, 76, 79, 67, 65, 76, 0, 0, 0, 5, 100, 117, 109, 109, 121, 0,
+            0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 10, 77, 65, 88, 73, 46,
+            76, 79, 67, 65, 76, 0, 0, 0, 5, 100, 117, 109, 109, 121, 0, 0,
+            0, 0, 0, 0, 0, 2, 0, 0, 0, 10, 77, 65, 88, 73, 46, 76,
+            79, 67, 65, 76, 0, 0, 0, 6, 107, 114, 98, 116, 103, 116, 0, 0,
+            0, 10, 77, 65, 88, 73, 46, 76, 79, 67, 65, 76, 0, 17, 0, 0,
+            0, 16, -78, -85, -90, -50, -68, 115, 68, 8, -39, -109, 91, 61, -17, -27,
+            -122, -120, 71, 69, 16, -121, 0, 0, 0, 0, 98, 69, 16, -121, 0, 0,
+            0, 0, 0, 64, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 1, 0, 97, -127, -3, 48, -127, -6, -96, 3, 2, 1, 5, -95, 12,
+            27, 10, 77, 65, 88, 73, 46, 76, 79, 67, 65, 76, -94, 31, 48, 29,
+            -96, 3, 2, 1, 0, -95, 22, 48, 20, 27, 6, 107, 114, 98, 116, 103,
+            116, 27, 10, 77, 65, 88, 73, 46, 76, 79, 67, 65, 76, -93, -127, -61,
+            48, -127, -64, -96, 3, 2, 1, 17, -95, 3, 2, 1, 1, -94, -127, -77,
+            4, -127, -80, 43, 65, -66, 34, 21, -34, 37, 35, 32, 50, -14, 122, 77,
+            -3, -29, 37, 99, 50, 125, -43, -96, -78, 85, 23, 41, -80, 68, 2, -109,
+            -27, 38, -41, -72, -32, 127, 63, -76, -22, 81, 33, -114, -30, 104, 125, -81,
+            -29, 70, -25, 23, 100, -75, -25, 62, -120, -78, -61, -100, -74, 50, -117, -127,
+            -16, 79, -106, 62, -39, 91, 100, -10, 23, -88, -18, -47, 51, -19, 113, 18,
+            98, -101, 31, 98, 22, -81, 11, -41, -42, 67, 87, 92, -2, 42, -54, 79,
+            49, -90, 43, -37, 90, -102, 125, 62, -88, -77, 100, 102, 23, -57, -51, 38,
+            68, -44, -57, -102, 103, -6, 85, -58, 74, -117, -87, 67, -103, -36, 110, -122,
+            115, 12, 118, -106, -114, -51, 79, 68, 32, -91, -53, -5, -51, 89, 72, 70,
+            123, -12, -95, 9, 40, -30, -117, 74, 77, 38, 91, 126, -82, 17, 98, 98,
+            -49, 78, 36, 36, 103, -76, -100, -23, 118, -92, -8, 80, 103, -23, -98, 56,
+            21, 65, -77, 0, 0, 0, 0
+        };
+        System.setProperty("sun.security.krb5.debug", "true");  // test code changes in DEBUG
+        CCacheInputStream cis = new CCacheInputStream(new ByteArrayInputStream(ccache));
+        cis.readVersion();
+        cis.readTag();
+        cis.readPrincipal(0x504);
+        Method m = CCacheInputStream.class.getDeclaredMethod("readCred", Integer.TYPE);
+        m.setAccessible(true);
+        Credentials c = (Credentials) m.invoke(cis, new Integer(0x504));
+        sun.security.krb5.Credentials cc = c.setKrbCreds();
+
+        // 1. Make sure starttime is still null
+        if (cc.getStartTime() != null) {
+            throw new Exception("Fail, starttime should be zero here");
+        }
+
+        // 2. Make sure renewTill is still null
+        if (cc.getRenewTill() != null) {
+            throw new Exception("Fail, renewTill should be zero here");
+        }
+
+        // 3. Make sure isValid works
+        c.isValid();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6447412
+ * @summary Issue with socket.close() for ssl sockets when poweroff on
+ *          other system
+ */
+
+import javax.net.ssl.*;
+import java.io.*;
+
+public class AsyncSSLSocketClose implements Runnable
+{
+    SSLSocket socket;
+    SSLServerSocket ss;
+
+    // Where do we find the keystores?
+    static String pathToStores = "../../../../../../../etc";
+    static String keyStoreFile = "keystore";
+    static String trustStoreFile = "truststore";
+    static String passwd = "passphrase";
+
+    public static void main(String[] args) {
+        String keyFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + keyStoreFile;
+        String trustFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + trustStoreFile;
+
+        System.setProperty("javax.net.ssl.keyStore", keyFilename);
+        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+        System.setProperty("javax.net.ssl.trustStore", trustFilename);
+        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+        new AsyncSSLSocketClose();
+    }
+
+    public AsyncSSLSocketClose() {
+        try {
+            SSLServerSocketFactory sslssf =
+                (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
+            ss = (SSLServerSocket) sslssf.createServerSocket(0);
+
+            SSLSocketFactory sslsf =
+                (SSLSocketFactory)SSLSocketFactory.getDefault();
+            socket = (SSLSocket)sslsf.createSocket("localhost",
+                                                        ss.getLocalPort());
+            SSLSocket serverSoc = (SSLSocket) ss.accept();
+            ss.close();
+
+            (new Thread(this)).start();
+            serverSoc.startHandshake();
+
+            try {
+                Thread.sleep(5000);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+            socket.setSoLinger(true, 10);
+            System.out.println("Calling Socket.close");
+            socket.close();
+            System.out.println("ssl socket get closed");
+            System.out.flush();
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    // block in write
+    public void run() {
+        try {
+            byte[] ba = new byte[1024];
+            for (int i=0; i<ba.length; i++)
+                ba[i] = 0x7A;
+
+            OutputStream os = socket.getOutputStream();
+            int count = 0;
+            while (true) {
+                count += ba.length;
+                System.out.println(count + " bytes to be written");
+                os.write(ba);
+                System.out.println(count + " bytes written");
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CloseKeepAliveCached.java	Mon Apr 14 11:34:15 2008 -0700
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6618387
+ * @summary SSL client sessions do not close cleanly. A TCP reset occurs
+ *      instead of a close_notify alert.
+ * @run main/othervm -Djavax.net.debug=ssl CloseKeepAliveCached
+ *
+ * @ignore
+ *    After run the test manually, at the end of the debug output,
+ *    if "MainThread, called close()" found, the test passed. Otherwise,
+ *    if "Keep-Alive-Timer: called close()", the test failed.
+ */
+
+import java.net.*;
+import java.util.*;
+import java.io.*;
+import javax.net.ssl.*;
+
+public class CloseKeepAliveCached {
+    static Map cookies;
+    ServerSocket ss;
+
+    /*
+     * =============================================================
+     * Set the various variables needed for the tests, then
+     * specify what tests to run on each side.
+     */
+
+    /*
+     * Should we run the client or server in a separate thread?
+     * Both sides can throw exceptions, but do you have a preference
+     * as to which side should be the main thread.
+     */
+    static boolean separateServerThread = true;
+
+    /*
+     * Where do we find the keystores?
+     */
+    static String pathToStores = "../../../../../../etc";
+    static String keyStoreFile = "keystore";
+    static String trustStoreFile = "truststore";
+    static String passwd = "passphrase";
+
+    /*
+     * Is the server ready to serve?
+     */
+    volatile static boolean serverReady = false;
+
+    /*
+     * Turn on SSL debugging?
+     */
+    static boolean debug = false;
+
+    private SSLServerSocket sslServerSocket = null;
+
+    /*
+     * Define the server side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    void doServerSide() throws Exception {
+        SSLServerSocketFactory sslssf =
+            (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+        sslServerSocket =
+            (SSLServerSocket) sslssf.createServerSocket(serverPort);
+        serverPort = sslServerSocket.getLocalPort();
+
+        /*
+         * Signal Client, we're ready for his connect.
+         */
+        serverReady = true;
+        SSLSocket sslSocket = null;
+        try {
+            sslSocket = (SSLSocket) sslServerSocket.accept();
+            for (int i = 0; i < 3 && !sslSocket.isClosed(); i++) {
+                // read request
+                InputStream is = sslSocket.getInputStream ();
+
+                BufferedReader r = new BufferedReader(
+                                                new InputStreamReader(is));
+                String x;
+                while ((x=r.readLine()) != null) {
+                    if (x.length() ==0) {
+                        break;
+                    }
+                }
+
+
+                PrintStream out = new PrintStream(
+                                 new BufferedOutputStream(
+                                    sslSocket.getOutputStream() ));
+
+                /* send the header */
+                out.print("HTTP/1.1 200 OK\r\n");
+                out.print("Keep-Alive: timeout=15, max=100\r\n");
+                out.print("Connection: Keep-Alive\r\n");
+                out.print("Content-Type: text/html; charset=iso-8859-1\r\n");
+                out.print("Content-Length: 9\r\n");
+                out.print("\r\n");
+                out.print("Testing\r\n");
+                out.flush();
+
+                Thread.sleep(50);
+            }
+            sslSocket.close();
+            sslServerSocket.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /*
+     * Define the client side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    void doClientSide() throws Exception {
+
+        /*
+         * Wait for server to get started.
+         */
+        while (!serverReady) {
+            Thread.sleep(50);
+        }
+        try {
+            HttpsURLConnection http = null;
+
+            /* establish http connection to server */
+            URL url = new URL("https://localhost:" + serverPort+"/");
+            HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
+            http = (HttpsURLConnection)url.openConnection();
+            InputStream is = http.getInputStream ();
+            while (is.read() != -1);
+            is.close();
+
+            url = new URL("https://localhost:" + serverPort+"/");
+            http = (HttpsURLConnection)url.openConnection();
+            is = http.getInputStream ();
+            while (is.read() != -1);
+
+            // if inputstream.close() called, the http.disconnect() will
+            // not able to close the cached connection. If application
+            // wanna close the keep-alive cached connection immediately
+            // with httpURLConnection.disconnect(), they should not call
+            // inputstream.close() explicitly, the
+            // httpURLConnection.disconnect() will do it internally.
+            // is.close();
+
+            // close the connection, sending close_notify to peer.
+            // otherwise, the connection will be closed by Finalizer or
+            // Keep-Alive-Timer if timeout.
+            http.disconnect();
+            // Thread.sleep(5000);
+        } catch (IOException ioex) {
+            if (sslServerSocket != null)
+                sslServerSocket.close();
+            throw ioex;
+        }
+    }
+
+    static class NameVerifier implements HostnameVerifier {
+        public boolean verify(String hostname, SSLSession session) {
+            return true;
+        }
+    }
+
+    /*
+     * =============================================================
+     * The remainder is just support stuff
+     */
+
+    // use any free port by default
+    volatile int serverPort = 0;
+
+    volatile Exception serverException = null;
+    volatile Exception clientException = null;
+
+    public static void main(String args[]) throws Exception {
+        String keyFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + keyStoreFile;
+        String trustFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + trustStoreFile;
+
+        System.setProperty("javax.net.ssl.keyStore", keyFilename);
+        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+        System.setProperty("javax.net.ssl.trustStore", trustFilename);
+        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+        if (debug)
+            System.setProperty("javax.net.debug", "all");
+
+        /*
+         * Start the tests.
+         */
+        new CloseKeepAliveCached();
+    }
+
+    Thread clientThread = null;
+    Thread serverThread = null;
+    /*
+     * Primary constructor, used to drive remainder of the test.
+     *
+     * Fork off the other side, then do your work.
+     */
+    CloseKeepAliveCached() throws Exception {
+        if (separateServerThread) {
+            startServer(true);
+            startClient(false);
+        } else {
+            startClient(true);
+            startServer(false);
+        }
+
+        /*
+         * Wait for other side to close down.
+         */
+        if (separateServerThread) {
+            serverThread.join();
+        } else {
+            clientThread.join();
+        }
+
+        /*
+         * When we get here, the test is pretty much over.
+         *
+         * If the main thread excepted, that propagates back
+         * immediately.  If the other thread threw an exception, we
+         * should report back.
+         */
+        if (serverException != null)
+            throw serverException;
+        if (clientException != null)
+            throw clientException;
+    }
+
+    void startServer(boolean newThread) throws Exception {
+        if (newThread) {
+            serverThread = new Thread() {
+                public void run() {
+                    try {
+                        doServerSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our server thread just died.
+                         *
+                         * Release the client, if not active already...
+                         */
+                        System.err.println("Server died...");
+                        serverReady = true;
+                        serverException = e;
+                    }
+                }
+            };
+            serverThread.start();
+        } else {
+            doServerSide();
+        }
+    }
+
+    void startClient(boolean newThread) throws Exception {
+        if (newThread) {
+            clientThread = new Thread() {
+                public void run() {
+                    try {
+                        doClientSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our client thread just died.
+                         */
+                        System.err.println("Client died...");
+                        clientException = e;
+                    }
+                }
+            };
+            clientThread.start();
+        } else {
+            doClientSide();
+        }
+    }
+}
+
--- a/test/sun/security/tools/keytool/StartDateTest.java	Thu Apr 10 13:57:15 2008 -0700
+++ b/test/sun/security/tools/keytool/StartDateTest.java	Mon Apr 14 11:34:15 2008 -0700
@@ -52,15 +52,15 @@
         cal.setTime(getIssueDate());
         System.out.println(cal);
         if (cal.get(Calendar.YEAR) != year + 1) {
-            throw new Exception("Function #1 check fails");
+            throw new Exception("Function check #1 fails");
         }
 
         run("-keystore jks -storetype jks -storepass changeit -keypass changeit -alias me " +
                 "-selfcert -startdate +1m");
         cal.setTime(getIssueDate());
         System.out.println(cal);
-        if (cal.get(Calendar.MONTH) != month + 1) {
-            throw new Exception("Function #1 check fails");
+        if (cal.get(Calendar.MONTH) != (month + 1) % 12) {
+            throw new Exception("Function check #2 fails");
         }
 
         new File("jks").delete();